diff --git a/README.md b/README.md index 44404c8..7e4a7a6 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,47 @@ Файл документации (README.md) # Схема WireGuard + udp2raw -Данный проект содержит готовые конфигурации для развертывания отказоустойчивого VPN-туннеля между **Удаленным сервером (Ubuntu)** и **Raspberry Pi 4**. +Данный проект содержит конфигурации для развертывания отказоустойчивого VPN-туннеля между **Удаленным сервером (Ubuntu 24.04)** и **Raspberry Pi 4**. -Решение маскирует UDP-трафик WireGuard под стандартные TCP-пакеты (рукопожатие HTTPS на порт 443), что позволяет успешно обходить ограничения провайдеров, блокирующих или урезающих UDP-протокол на интерфейсе `usbnet`. +Решение маскирует UDP-трафик WireGuard под стандартные TCP-пакеты (режим `faketcp`), что позволяет успешно обходить ограничения провайдеров, блокирующих или урезающих UDP-протокол на интерфейсе `usbnet`. + +> **Порт входа — `25565/tcp`, а не `443`.** Порт `443` на сервере занят nginx (reverse-proxy для Gitea `totmaxim.ru`), и `udp2raw` в режиме `faketcp` (через правило `-a`) перехватил бы весь TCP на своём порту, поломав nginx. Поэтому транспорт вынесен на выделенный `25565/tcp`. --- -## Аутентификационные данные проекта +## 0. Справочные данные и пути проекта -Для развертывания используются предварительно сгенерированные и проверенные ключи: +### Архитектура и сетевые параметры +* **Публичный вход сервера:** `95.174.102.77:25565` (TCP, `udp2raw`; `443` занят nginx/Gitea) +* **Внутренний порт WireGuard (Сервер):** `127.0.0.1:51820` +* **Внутренний порт udp2raw (Клиент RPi):** `127.0.0.1:51821` +* **Подсеть VPN:** `10.66.66.0/24` (Сервер: `10.66.66.1`, Клиент: `10.66.66.2`) +### Фактическая топология (важно для маршрутизации) + +**Сервер (Ubuntu 24.04) — за NAT, НЕ имеет публичного IP напрямую:** +* Внешний интерфейс: `enp2s0 = 192.168.31.163/24`, шлюз `192.168.31.1` +* `95.174.102.77` — это WAN-адрес роутера `192.168.31.1`, а НЕ адрес самого сервера +* На хосте работает Docker (бриджи `172.17–172.21.0.0/16`, `docker0`) со своими правилами nftables/iptables — поэтому WG-правила изолированы в отдельной таблице `wgfwd` и маскарадят **только** `10.66.66.0/24` + +**Клиент (Raspberry Pi 4) — роутер для локальной сети:** +* Uplink (в интернет): `usbnet = 192.168.200.13/24`, шлюз и DNS `192.168.200.1` (мобильный канал; провайдер режет UDP → маскировка под TCP) +* Downstream (клиенты): `wlan0 = 192.168.77.0/24` — их трафик уходит в интернет через туннель +* Прочие интерфейсы (`eth0 10.1.1.33`, `eth1 192.168.2.10`) в схеме VPN не участвуют + +### ⚠️ Обязательные требования к окружению (предусловия) + +| # | Требование | Где | Проверка | +|---|-----------|-----|----------| +| 1 | **Проброс порта** `TCP 25565 → 192.168.31.163:25565` на роутере `95.174.102.77` | Роутер сервера | с клиента: `nc -vz 95.174.102.77 25565` | +| 2 | `net.ipv4.ip_forward = 1` (закрепить в `/etc/sysctl.d/`) | Сервер + Клиент | `sysctl net.ipv4.ip_forward` | +| 3 | Порт `25565/tcp` на хосте свободен; `443` оставить за nginx (Gitea) | Сервер | `sudo ss -ltnp 'sport = :25565'` | +| 4 | Одинаковый пароль `-k` в обеих службах `udp2raw` | Сервер + Клиент | сверить `.service` | +| 5 | Маршрут `95.174.102.77/32 via 192.168.200.1 dev usbnet` при поднятом `wg0` | Клиент | `ip route get 95.174.102.77` (должен быть `dev usbnet`, НЕ `wg0`) | + +> **Почему требование #5 критично:** на клиенте `AllowedIPs = 0.0.0.0/0`, поэтому `wg-quick` заворачивает весь трафик в `wg0`. Без закреплённого маршрута сам транспорт `udp2raw` (пакеты к `95.174.102.77:25565`) тоже уйдёт в `wg0` — получится **петля**, и туннель порвётся. Маршрут добавляется автоматически через `PreUp` в `client/wg0.conf`. + +### Актуальные ключи WireGuard * **Сервер (`95.174.102.77`):** * Public Key: `dVIwnwxkjan/K278vzhOjp5A79N98j0O1zsYqT24qzs=` * Private Key: `KMcPBI6LAY/NC1zFNYopsvNXqQ8w8ssluDj4yOh3skk=` @@ -18,131 +49,228 @@ * Public Key: `WWFhoYfIgIhGOsvdJ/F9eWx7hPksrV6riiqo5lFPExI=` * Private Key: `eKiGDY62/9pgFrwzoNIb7URRLPgEHC1W7zHwIIDYQVw=` -> **Внимание:** Перед запуском обязательно измените значение `"MY_CONFIDENTIAL_PASS"` в аргументе `-k` системных сервисов `udp2raw` на сервере и клиенте на ваш собственный секретный пароль. - -Проверка соответствия ключей: - -``` - echo "--- SERVER PUBLIC KEY ---" && sudo cat server_public.key - echo "--- SERVER PRIVATE KEY ---" && sudo cat server_private.key -``` +> ⚠️ **Важно:** Перед запуском служб измените дефолтный пароль `"MY_CONFIDENTIAL_PASS"` в аргументе `-k` в файлах `.service` на ваш собственный секретный пароль. Он должен быть одинаковым везде. --- -## Подготовка и генерация ключей +## 1. Спецификация релиза udp2raw -Перед началом настройки зайдите на любое устройство и сгенерируйте две пары ключей (для сервера и для клиента): +* **Ссылка для скачивания архива:** `https://github.com/wangyu-/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz` +* **Версия:** 20230206.0 +При распаковке архива (`tar -xvf`) используются только два конкретных файла: +1. `udp2raw_amd64` — устанавливается на **Сервер** (архитектура x86_64). +2. `udp2raw_arm_asm_aes` — устанавливается на **Raspberry Pi 4** (оптимизированный ARM-бинарник). + +--- + +## 2. Пошаговое развертывание на СЕРВЕРЕ (Ubuntu) + +Выполняется в терминале сервера (`totserver@95.174.102.77`): + +### Шаг 2.0. Подготовка окружения (проброс порта + форвардинг) ```bash -# Ключи Сервера -wg genkey | tee server_private.key | wg pubkey > server_public.key - -# Ключи Клиента (Raspberry Pi) -wg genkey | tee client_private.key | wg pubkey > client_public.key +# 1) Убедитесь, что на роутере 95.174.102.77 проброшен TCP 25565 -> 192.168.31.163:25565 +# 2) Включаем и ЗАКРЕПЛЯЕМ форвардинг пакетов (wg-quick сам его НЕ включает): +echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-wg.conf +sudo sysctl --system +# 3) Проверяем, что порт 25565 на хосте свободен (udp2raw слушает 0.0.0.0:25565). +# Порт 443 ДОЛЖЕН оставаться за nginx (Gitea) — udp2raw его не трогает: +sudo ss -ltnp 'sport = :25565' ``` -Важно: Замените плейсхолдеры _KEY_HERE во всех файлах конфигурации на сгенерированные строки. Также замените "SUPER_SECRET_PASSWORD" в сервисах udp2raw на ваш собственный секретный общий пароль. - -Инструкция по развертыванию на СЕРВЕРЕ (Ubuntu) - - -Установите WireGuard: - -```Bash +### Шаг 2.1. Установка WireGuard +```bash sudo apt update && sudo apt install wireguard -y -``` -Установите udp2raw: -Скачайте бинарный файл udp2raw_amd64 со страницы релизов проекта wangyu/udp2raw. -```Bash -sudo wget [https://github.com/wangyu/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz](https://github.com/wangyu/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz) +Шаг 2.2. Скачивание и сборка udp2raw + + + +Bash +mkdir -p ~/download && cd ~/download +wget [https://github.com/wangyu-/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz](https://github.com/wangyu-/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz) tar -xvf udp2raw_binaries.tar.gz + +# Копируем x86_64 бинарник в системный путь и даем права sudo cp udp2raw_amd64 /usr/local/bin/udp2raw sudo chmod +x /usr/local/bin/udp2raw -``` -Копирование конфигураций: -Перенесите файл server/wg0.conf в папку /etc/wireguard/wg0.conf. +Шаг 2.3. Создание конфигурационных файлов +Создайте конфиг WireGuard: sudo nano /etc/whiteguard/wg0.conf (или /etc/wireguard/wg0.conf) +Ini, TOML +[Interface] +Address = 10.66.66.1/24 +ListenPort = 51820 +PrivateKey = KMcPBI6LAY/NC1zFNYopsvNXqQ8w8ssluDj4yOh3skk= +MTU = 1200 -Перенесите файл server/udp2raw-server.service в папку /etc/systemd/system/udp2raw-server.service. +# Изолированная таблица wgfwd: masquerade ТОЛЬКО 10.66.66.0/24 (не конфликтует с Docker) +# + MSS-clamp на входе в туннель. PostDown сносит всё одной командой. +PostUp = nft add table ip wgfwd +PostUp = nft add chain ip wgfwd postrouting { type nat hook postrouting priority 100 \; policy accept \; } +PostUp = nft add rule ip wgfwd postrouting ip saddr 10.66.66.0/24 oifname "enp2s0" masquerade +PostUp = nft add chain ip wgfwd mangle { type filter hook forward priority -150 \; policy accept \; } +PostUp = nft add rule ip wgfwd mangle oifname "wg0" tcp flags syn tcp option maxseg size set rt mtu +PostDown = nft delete table ip wgfwd -Запуск сервисов: +[Peer] +PublicKey = WWFhoYfIgIhGOsvdJ/F9eWx7hPksrV6riiqo5lFPExI= +AllowedIPs = 10.66.66.2/32 -```Bash + +Создайте службу демона udp2raw: sudo nano /etc/systemd/system/udp2raw-server.service +Ini, TOML +[Unit] +Description=udp2raw Server (FakeTCP) +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/usr/local/bin/udp2raw -s -l 0.0.0.0:25565 -r 127.0.0.1:51820 -k "MY_CONFIDENTIAL_PASS" --raw-mode faketcp -a +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target + + +Шаг 2.4. Запуск служб на сервере + + + +Bash sudo systemctl daemon-reload sudo systemctl enable --now udp2raw-server sudo systemctl enable --now wg-quick@wg0 -``` -Инструкция по развертыванию на КЛИЕНТЕ (Raspberry Pi 4) -Установите WireGuard: -```Bash + +3. Пошаговое развертывание на КЛИЕНТЕ (Raspberry Pi 4) +Выполняется в терминале малинки (user@raspberrypi): +Шаг 3.1. Установка WireGuard + + + +Bash sudo apt update && sudo apt install wireguard -y -``` -Установите udp2raw (Архитектура ARM64): -```Bash -# Используйте бинарник udp2raw_arm64 из того же архива релизов -sudo cp udp2raw_arm64 /usr/local/bin/udp2raw + +Шаг 3.2. Доставка бинарника udp2raw +Если малинка имеет доступ к интернету, скачайте архив прямо на неё: + + + +Bash +mkdir -p ~/download && cd ~/download +wget [https://github.com/wangyu-/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz](https://github.com/wangyu-/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz) +tar -xvf udp2raw_binaries.tar.gz + +# Переносим специализированный ARM-бинарник в системный путь +sudo cp udp2raw_arm_asm_aes /usr/local/bin/udp2raw sudo chmod +x /usr/local/bin/udp2raw -``` -Настройка межсетевого экрана (nftables): -Откройте ваш рабочий конфиг /etc/nftables.conf и интегрируйте в него правила из файла client/nftables.conf.append. -Примените изменения: -```Bash -sudo nft -f /etc/nftables.conf -``` -Копирование конфигураций: -Перенесите файл client/wg0.conf в папку /etc/wireguard/wg0.conf. +Шаг 3.3. Настройка сетевого экрана (nftables) +Учитывая строгую политику policy drop на вашей Raspberry Pi, откройте текущие правила: -Перенесите файл client/udp2raw-client.service в папку /etc/systemd/system/udp2raw-client.service. -Запуск сервисов: -```Bash +Bash +sudo nano /etc/nftables.conf + + +Добавьте/разрешите следующие строки в соответствующие таблицы: +В table inet filter -> chain input: +Code snippet +iifname "lo" accept +iifname "wg0" accept + + +В table inet filter -> chain forward: +Code snippet +iifname "wlan0" oifname "wg0" accept +iifname "wg0" oifname "wlan0" ct state established,related accept +# MSS-clamp: клиенты (MTU 1500) не знают про туннель 1200 -> иначе крупный TCP залипает +iifname "wlan0" oifname "wg0" tcp flags syn tcp option maxseg size set rt mtu + + +В table ip nat -> chain postrouting: +Code snippet +ip saddr 192.168.77.0/24 oifname "wg0" masquerade + + +Примените изменения: sudo nft -f /etc/nftables.conf +Шаг 3.4. Создание конфигурационных файлов +Создайте конфиг WireGuard: sudo nano /etc/wireguard/wg0.conf +Ini, TOML +[Interface] +Address = 10.66.66.2/24 +PrivateKey = eKiGDY62/9pgFrwzoNIb7URRLPgEHC1W7zHwIIDYQVw= +MTU = 1200 + +# КРИТИЧНО (анти-петля): маршрут к серверу через реальный uplink ДО поднятия default в wg0. +# 192.168.200.1 — шлюз usbnet; при смене канала поправить адрес здесь. +PreUp = ip route replace 95.174.102.77/32 via 192.168.200.1 dev usbnet +PostDown = ip route del 95.174.102.77/32 2>/dev/null || true + +[Peer] +PublicKey = dVIwnwxkjan/K278vzhOjp5A79N98j0O1zsYqT24qzs= +Endpoint = 127.0.0.1:51821 +AllowedIPs = 0.0.0.0/0 +PersistentKeepalive = 25 + + +Создайте службу демона udp2raw: sudo nano /etc/systemd/system/udp2raw-client.service +Ini, TOML +[Unit] +Description=udp2raw Client (FakeTCP) +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/usr/local/bin/udp2raw -c -l 127.0.0.1:51821 -r 95.174.102.77:25565 -k "MY_CONFIDENTIAL_PASS" --raw-mode faketcp -a +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target + + +Шаг 3.5. Запуск служб на клиенте + + + +Bash sudo systemctl daemon-reload sudo systemctl enable --now udp2raw-client sudo systemctl enable --now wg-quick@wg0 -``` - ---- - -## Документация релиза и файлов udp2rawАктуальная ссылка для скачивания: -https://github.com/wangyu-/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz - -Версия (из version.txt): 20230206.0 -Спецификация распакованных файлов -Файл Назначение и Архитектура Куда устанавливаем -udp2raw_amd64 Стандартная 64-битная архитектура x86. Удаленный Сервер (Ubuntu) -udp2raw_amd64_hw_aes 64-битная x86 с аппаратным ускорением AES (если процессор сервера поддерживает). Альтернатива для сервера -udp2raw_arm 32-битная архитектура ARM (подходит для старых Raspberry Pi или 32-битных ОС). Raspberry Pi 4 (если ОС 32-bit) -udp2raw_arm_asm_aes ARM архитектура с ускорением AES на ассемблере. Raspberry Pi 4 (Оптимально) -udp2raw_x86 / _x86_asm_aes Старые 32-битные процессоры Intel/AMD. Не используется -udp2raw_mips24kc_... Архитектуры для домашних роутеров (OpenWrt). Не используется ---- -Диагностика и проверка статуса -В случае проблем проверяйте работу цепочки поочередно: - -Проверка TCP-туннеля (udp2raw): - +4. Диагностика и проверка статуса +При возникновении неполадок проверяйте компоненты строго по цепочке от нижнего уровня к верхнему: +1. Проверка работоспособности FakeTCP (udp2raw) На клиенте: sudo systemctl status udp2raw-client - На сервере: sudo systemctl status udp2raw-server +Критерий успеха: Строка состояния [ready] в логах сервиса и отсутствие циклических перезапусков. +2. Проверка туннеля WireGuard +На любом из устройств: sudo wg show +Критерий успеха: Наличие строчки latest handshake: X seconds ago (данные должны обновляться и не сбрасываться). +3. Проверка сетевого уровня (Пинг) +С Raspberry Pi запустите: ping 10.66.66.1 +Если пинг идет, но интернета на устройствах за малинкой (wlan0) нет — перепроверяйте синтаксис правил в /etc/nftables.conf и masquerade на сервере. -В логах должно быть состояние [ready] и успешные хэндшейки. +4. Проверка отсутствия петли (при поднятом wg0) +На клиенте: `ip route get 95.174.102.77` +Критерий успеха: маршрут идёт через `dev usbnet` (шлюз 192.168.200.1), а НЕ через `dev wg0`. +Если видите `dev wg0` — не отработал `PreUp` из `wg0.conf`, транспорт закольцован. -Проверка WireGuard туннеля: +5. Проверка выхода в интернет через туннель +С устройства за малинкой (192.168.77.0/24): `curl -s https://ifconfig.me` +Критерий успеха: возвращается публичный IP канала сервера (сети `192.168.31.1`), а не мобильного канала клиента. -Выполните команду: sudo wg show - -Должна появиться строчка latest handshake: ... секунд назад и идти обмен данными. - -Проверка пинга: - -С малинки: ping 10.66.66.1 \ No newline at end of file +6. Доступность публичного входа (проброс 25565) +С клиента: `nc -vz 95.174.102.77 25565` — порт должен быть открыт (проброс на роутере сервера). diff --git a/client/nftables.conf b/client/nftables.conf index df2fd8c..e51c25c 100644 --- a/client/nftables.conf +++ b/client/nftables.conf @@ -30,6 +30,10 @@ table inet filter { iifname "wlan0" oifname "wg0" accept iifname "wg0" oifname "wlan0" ct state established,related accept + + # MSS-clamp: клиенты 192.168.77.0/24 имеют MTU 1500 и не знают про туннель 1200. + # Без этого крупные TCP-сессии (сайты, загрузки) залипают при заблокированном PMTUD. + iifname "wlan0" oifname "wg0" tcp flags syn tcp option maxseg size set rt mtu } chain output { diff --git a/client/udp2raw-client.service b/client/udp2raw-client.service index 943a1a9..bb5fe6f 100644 --- a/client/udp2raw-client.service +++ b/client/udp2raw-client.service @@ -5,9 +5,9 @@ After=network.target [Service] Type=simple User=root -# Слушает локальный UDP-порт 51821 и транслирует в TCP на внешний IP сервера 95.174.102.77:443 +# Слушает локальный UDP-порт 51821 и транслирует в TCP на внешний вход сервера 95.174.102.77:25565 # ВАЖНО: Пароль в параметре -k должен строго совпадать с паролем на сервере! -ExecStart=/usr/local/bin/udp2raw -c -l 127.0.0.1:51821 -r 95.174.102.77:443 -k "MY_CONFIDENTIAL_PASS" --raw-mode faketcp -a +ExecStart=/usr/local/bin/udp2raw -c -l 127.0.0.1:51821 -r 95.174.102.77:25565 -k "MY_CONFIDENTIAL_PASS" --raw-mode faketcp -a Restart=always RestartSec=5 diff --git a/client/wg0.conf b/client/wg0.conf index 1a1f2a8..b5081fb 100644 --- a/client/wg0.conf +++ b/client/wg0.conf @@ -1,12 +1,20 @@ -# RASPBERRY PI 4: +# RASPBERRY PI 4 (клиент/роутер) +# uplink : usbnet 192.168.200.13/24, шлюз+DNS 192.168.200.1 (моб. канал, провайдер режет UDP) +# downstream: wlan0 192.168.77.0/24 (клиенты уходят в интернет через туннель) [Interface] Address = 10.66.66.2/24 # Приватный ключ Raspberry Pi (из файла client_private.key) PrivateKey = eKiGDY62/9pgFrwzoNIb7URRLPgEHC1W7zHwIIDYQVw= -# Уменьшенный MTU для компенсации оверхеда фейковых заголовков TCP +# Уменьшенный MTU для компенсации оверхеда WG (+60) и фейковых TCP-заголовков udp2raw (+~40) MTU = 1200 +# КРИТИЧНО: закрепляем маршрут до публичного входа сервера ЧЕРЕЗ реальный uplink. +# Иначе при AllowedIPs=0.0.0.0/0 сам транспорт udp2raw уйдёт в wg0 -> петля, туннель рвётся. +# 192.168.200.1 — шлюз usbnet; при смене канала поправить здесь (см. README). +PreUp = ip route replace 95.174.102.77/32 via 192.168.200.1 dev usbnet +PostDown = ip route del 95.174.102.77/32 2>/dev/null || true + [Peer] # Публичный ключ Сервера (из файла server_public.key) PublicKey = dVIwnwxkjan/K278vzhOjp5A79N98j0O1zsYqT24qzs= @@ -15,4 +23,4 @@ Endpoint = 127.0.0.1:51821 # Маршрутизируем абсолютно весь трафик через VPN туннель AllowedIPs = 0.0.0.0/0 # Пакет удержания сессии через NAT провайдера -PersistentKeepalive = 25 \ No newline at end of file +PersistentKeepalive = 25 diff --git a/server/udp2raw-server.service b/server/udp2raw-server.service index 24e2740..b9c4c56 100644 --- a/server/udp2raw-server.service +++ b/server/udp2raw-server.service @@ -5,9 +5,11 @@ After=network.target [Service] Type=simple User=root -# Слушает внешние TCP подключения на порту 443 и перенаправляет в локальный WireGuard +# Слушает внешние TCP подключения на порту 25565 и перенаправляет в локальный WireGuard. +# Порт 443 НЕ используем: его держит nginx (reverse-proxy для Gitea totmaxim.ru), +# а udp2raw в faketcp через правило -a дропнул бы весь входящий TCP на своём порту. # ВАЖНО: Замените "MY_CONFIDENTIAL_PASS" на ваш секретный пароль для udp2raw -ExecStart=/usr/local/bin/udp2raw -s -l 0.0.0.0:443 -r 127.0.0.1:51820 -k "MY_CONFIDENTIAL_PASS" --raw-mode faketcp -a +ExecStart=/usr/local/bin/udp2raw -s -l 0.0.0.0:25565 -r 127.0.0.1:51820 -k "MY_CONFIDENTIAL_PASS" --raw-mode faketcp -a Restart=always RestartSec=5 diff --git a/server/wg0.conf b/server/wg0.conf index 07e8ce2..05190ed 100644 --- a/server/wg0.conf +++ b/server/wg0.conf @@ -1,16 +1,29 @@ - +# СЕРВЕР (Ubuntu, за NAT: enp2s0 = 192.168.31.163, шлюз 192.168.31.1) +# Публичный вход: 95.174.102.77:25565 (TCP) --проброс на роутере--> 192.168.31.163:25565 +# (443 не используем — его держит nginx/Gitea; см. udp2raw-server.service) [Interface] Address = 10.66.66.1/24 ListenPort = 51820 # Приватный ключ Сервера (из файла server_private.key) PrivateKey = KMcPBI6LAY/NC1zFNYopsvNXqQ8w8ssluDj4yOh3skk= +# Симметрично клиенту: транспорт идёт внутри faketcp, держим запас на оверхед +MTU = 1200 -# Автоматический NAT для выхода клиентов в интернет через основной интерфейс enp2s0 -PostUp = nft add table ip wg_nat; nft add chain ip wg_nat post { type nat hook postrouting priority srcnat\; policy accept\; }; nft add rule ip wg_nat post oifname "enp2s0" masquerade -PostDown = nft delete table ip wg_nat +# Всё хозяйство WG держим в отдельной nft-таблице wgfwd, чтобы: +# - не конфликтовать с правилами Docker/UFW в главных таблицах; +# - на PostDown снести одной командой (идемпотентно). +# NAT: маскарадим ТОЛЬКО подсеть туннеля (не трогаем docker и трафик хоста). +PostUp = nft add table ip wgfwd +PostUp = nft add chain ip wgfwd postrouting { type nat hook postrouting priority 100 \; policy accept \; } +PostUp = nft add rule ip wgfwd postrouting ip saddr 10.66.66.0/24 oifname "enp2s0" masquerade +# MSS-clamp для пакетов, входящих В туннель (SYN-ACK от внешних серверов), +# чтобы large-TCP не «залипал» из-за MTU 1200 и заблокированного PMTUD. +PostUp = nft add chain ip wgfwd mangle { type filter hook forward priority -150 \; policy accept \; } +PostUp = nft add rule ip wgfwd mangle oifname "wg0" tcp flags syn tcp option maxseg size set rt mtu +PostDown = nft delete table ip wgfwd [Peer] # Публичный ключ Raspberry Pi (из файла client_public.key) PublicKey = WWFhoYfIgIhGOsvdJ/F9eWx7hPksrV6riiqo5lFPExI= -AllowedIPs = 10.66.66.2/32 \ No newline at end of file +AllowedIPs = 10.66.66.2/32