From df24ccb96a89125d217c28e09de1296431f1f27c Mon Sep 17 00:00:00 2001 From: Ruslan Date: Tue, 14 Apr 2026 10:59:51 +0300 Subject: [PATCH] Client: auto-detect LAN subnets and auto-fill split allowed-ips --- README.md | 2 ++ client/install_client.sh | 41 ++++++++++++++++++++++++++++++---------- server/wg-peerctl.sh | 2 ++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3890745..ba323ca 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,8 @@ tmp="$(mktemp -d)" && curl -fL "https://git.ruslan.xyz/ruslan/Wireguard_server/a По умолчанию адрес интерфейса клиента пишется как `/24` (например `10.66.66.2/24`). При необходимости можно изменить маску параметром `--client-address-prefix <1-32>`. Если за клиентом есть локальная сеть (например `192.168.33.0/24`), передайте `--advertise-subnets 192.168.33.0/24`, чтобы сервер маршрутизировал эту сеть через клиента. +Если `--advertise-subnets` не задан, скрипт автоматически пытается определить LAN-сети клиента и объявить их на сервере. +В режиме `split`, если `--allowed-ips` не задан, скрипт автоматически использует сеть WG сервера. ### Non-interactive пример (SSH-ключ) diff --git a/client/install_client.sh b/client/install_client.sh index f65d08f..9c665b1 100755 --- a/client/install_client.sh +++ b/client/install_client.sh @@ -112,8 +112,7 @@ validate_inputs() { die "Не указан --server-host" fi - if [[ "$TUNNEL_MODE" == "split" ]]; then - [[ -n "$SPLIT_ALLOWED_IPS" ]] || die "Для режима split укажите --allowed-ips" + if [[ -n "$SPLIT_ALLOWED_IPS" ]]; then is_valid_cidr_list "$SPLIT_ALLOWED_IPS" || die "Некорректный список --allowed-ips" fi } @@ -145,13 +144,6 @@ collect_inputs() { fi fi - if [[ "$TUNNEL_MODE" == "split" && -z "$SPLIT_ALLOWED_IPS" ]]; then - if ((NON_INTERACTIVE)); then - die "В non-interactive для split укажите --allowed-ips" - fi - read -r -p "Введите CIDR-сети через запятую (например 10.0.0.0/8,192.168.0.0/16): " SPLIT_ALLOWED_IPS - fi - if [[ "$SSH_AUTH_METHOD" == "password" && -z "$SSH_PASSWORD" ]]; then if ((NON_INTERACTIVE)); then die "Для --ssh-auth password нужно указать --ssh-password" @@ -162,6 +154,21 @@ collect_inputs() { validate_inputs } +detect_client_lan_subnets() { + ip -o -4 route show scope link 2>/dev/null | awk ' + { + cidr=$1 + dev="" + for (i=1; i<=NF; i++) { + if ($i=="dev") { dev=$(i+1); break } + } + if (cidr ~ /^127\./ || cidr ~ /^169\.254\./) next + if (dev ~ /^(lo|wg|docker|veth|br-|tun|tap)/) next + if (cidr ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}\/[0-9]+$/) print cidr + } + ' | sort -u | paste -sd, - +} + install_packages() { apt_install_if_missing wireguard wireguard-tools iproute2 openssh-client sshpass ca-certificates @@ -264,6 +271,7 @@ register_peer_on_server() { SERVER_PUBLIC_KEY="$(kv_get SERVER_PUBLIC_KEY)" SERVER_ENDPOINT="$(kv_get SERVER_ENDPOINT)" SERVER_DNS_REMOTE="$(kv_get SERVER_DNS)" + SERVER_WG_NETWORK="$(kv_get WG_NETWORK)" [[ -n "$SERVER_PUBLIC_KEY" ]] || die "Сервер не вернул SERVER_PUBLIC_KEY" [[ -n "$CLIENT_ADDRESS" ]] || die "Сервер не вернул CLIENT_ADDRESS" @@ -274,7 +282,14 @@ build_allowed_ips() { if [[ "$TUNNEL_MODE" == "full" ]]; then ALLOWED_IPS="0.0.0.0/0,::/0" else - ALLOWED_IPS="$SPLIT_ALLOWED_IPS" + if [[ -n "$SPLIT_ALLOWED_IPS" ]]; then + ALLOWED_IPS="$SPLIT_ALLOWED_IPS" + elif [[ -n "${SERVER_WG_NETWORK:-}" ]]; then + ALLOWED_IPS="$SERVER_WG_NETWORK" + log_info "Режим split: --allowed-ips не задан, использую сеть WG сервера: ${ALLOWED_IPS}" + else + die "Режим split: не удалось определить --allowed-ips автоматически" + fi fi } @@ -397,6 +412,12 @@ main() { print_routes_info install_packages generate_keys + if [[ -z "$ADVERTISE_SUBNETS" ]]; then + ADVERTISE_SUBNETS="$(detect_client_lan_subnets || true)" + if [[ -n "$ADVERTISE_SUBNETS" ]]; then + log_info "Автоопределены сети за клиентом: ${ADVERTISE_SUBNETS}" + fi + fi register_peer_on_server build_allowed_ips build_client_interface_address diff --git a/server/wg-peerctl.sh b/server/wg-peerctl.sh index 10dc88d..de09546 100755 --- a/server/wg-peerctl.sh +++ b/server/wg-peerctl.sh @@ -188,6 +188,7 @@ SERVER_PUBLIC_KEY=$server_pubkey SERVER_ENDPOINT=${SERVER_PUBLIC_IP}:${WG_PORT} SERVER_DNS=${SERVER_DNS} WG_INTERFACE=${WG_INTERFACE} +WG_NETWORK=${WG_NETWORK} EOF_OUT return 0 fi @@ -227,6 +228,7 @@ SERVER_PUBLIC_KEY=$server_pubkey SERVER_ENDPOINT=${SERVER_PUBLIC_IP}:${WG_PORT} SERVER_DNS=${SERVER_DNS} WG_INTERFACE=${WG_INTERFACE} +WG_NETWORK=${WG_NETWORK} EOF_OUT }