From 530e93c1df2b8cc1b7246f2bdde4d5332dba9f6b Mon Sep 17 00:00:00 2001 From: Ruslan Date: Tue, 14 Apr 2026 13:01:30 +0300 Subject: [PATCH] WG: apply advertised routes on server immediately; relax rp_filter for routed clients --- client/install_client.sh | 2 ++ server/wg-peerctl.sh | 72 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/client/install_client.sh b/client/install_client.sh index c8a79dc..5fcad97 100755 --- a/client/install_client.sh +++ b/client/install_client.sh @@ -347,6 +347,8 @@ build_lan_nat_hooks_if_needed() { local fwd="/etc/sysctl.d/99-wireguard-client-forwarding.conf" cat > "$fwd" </dev/null || true diff --git a/server/wg-peerctl.sh b/server/wg-peerctl.sh index e99f916..2e20d97 100755 --- a/server/wg-peerctl.sh +++ b/server/wg-peerctl.sh @@ -207,6 +207,71 @@ extract_peer_address_by_pubkey() { ' "$WG_CONF" | awk -F',' '{print $1}' | xargs } +extract_peer_allowed_ips_by_pubkey() { + local pubkey="$1" + awk -v pk="$pubkey" ' + $0 ~ /^\[Peer\]/ {in_peer=1; key=""; allowed=""} + in_peer && $0 ~ /^PublicKey[[:space:]]*=/ { + sub(/^[^=]*=[[:space:]]*/, "", $0); key=$0 + } + in_peer && $0 ~ /^AllowedIPs[[:space:]]*=/ { + sub(/^[^=]*=[[:space:]]*/, "", $0); allowed=$0 + } + in_peer && key==pk && allowed!="" {print allowed; exit} + ' "$WG_CONF" | xargs +} + +routes_without_primary_address() { + local allowed_ips="$1" + local primary_addr="$2" + local out="" + local item + local norm_primary + norm_primary="$(echo "$primary_addr" | xargs)" + + IFS=',' read -ra items <<< "$allowed_ips" + for item in "${items[@]}"; do + item="$(echo "$item" | xargs)" + [[ -z "$item" ]] && continue + if [[ -n "$norm_primary" && "$item" == "$norm_primary" ]]; then + continue + fi + if [[ -z "$out" ]]; then + out="$item" + else + out="${out},${item}" + fi + done + + echo "$out" +} + +apply_client_routes_now() { + local routes="${1:-}" + [[ -n "$routes" ]] || return 0 + + local cidr + IFS=',' read -ra cidrs <<< "$routes" + for cidr in "${cidrs[@]}"; do + cidr="$(echo "$cidr" | xargs)" + [[ -n "$cidr" ]] || continue + ip route replace "$cidr" dev "$WG_INTERFACE" proto static >/dev/null 2>&1 || true + done +} + +remove_client_routes_now() { + local routes="${1:-}" + [[ -n "$routes" ]] || return 0 + + local cidr + IFS=',' read -ra cidrs <<< "$routes" + for cidr in "${cidrs[@]}"; do + cidr="$(echo "$cidr" | xargs)" + [[ -n "$cidr" ]] || continue + ip route del "$cidr" dev "$WG_INTERFACE" >/dev/null 2>&1 || true + done +} + apply_config() { if systemctl is-active --quiet "wg-quick@${WG_INTERFACE}"; then wg syncconf "$WG_INTERFACE" <(wg-quick strip "$WG_CONF") @@ -262,6 +327,7 @@ cmd_add() { existing_allowed="${existing_addr:-}" if [[ -n "$client_routes" ]]; then existing_allowed="${existing_allowed},${client_routes}" + apply_client_routes_now "$client_routes" fi sync_gui_db_upsert_peer "$client_name" "$client_pubkey" "${existing_addr:-}" "$client_routes" "$client_psk" "${existing_allowed}" 1 cat <> "$WG_CONF" apply_config + apply_client_routes_now "$client_routes" sync_gui_db_upsert_peer "$client_name" "$client_pubkey" "$client_address" "$client_routes" "$client_psk" "$peer_allowed_ips" 1 cat <