Настройка маршрутизации между удаленными сетями через VPN: WireGuard и OpenVPN | AdminWiki

Настройка маршрутизации между удаленными сетями через VPN: WireGuard и OpenVPN

07 сентября 2026 22 мин. чтения
Содержание статьи

Маршрутизация между удаленными подсетями через VPN работает, когда согласованы пять элементов: адресация туннеля, маршруты в прямом и обратном направлениях, IPv4 forwarding, правила FORWARD и схема NAT. Статус Connected или успешный handshake подтверждает работу VPN-соединения, но не доказывает, что пакеты проходят между LAN.

Рабочий порядок такой: определить топологию и уникальные подсети, настроить VPN-интерфейсы, объявить удаленные LAN в WireGuard или OpenVPN, добавить маршруты на сервере, VPN-пирах и шлюзах, включить net.ipv4.ip_forward, разрешить транзит в firewall, выбрать маршрутизацию без NAT либо ограниченный MASQUERADE, затем проверить путь пакета через ip route get и tcpdump.

В WireGuard выбор пира для исходящего трафика связан с параметром AllowedIPs. В OpenVPN используются разные уровни маршрутизации: route создает маршрут в ядре сервера, push route передает маршрут клиенту, а iroute связывает удаленную сеть с конкретным клиентом. Ниже приведена схема, которую можно адаптировать для двух площадок.

Как настроить маршрутизацию между сетями через VPN: краткий алгоритм

Минимальные условия для связи удаленных подсетей

Перед изменением конфигурации зафиксируйте следующие параметры:

  • подсеть Site A, например 10.10.0.0/24;
  • подсеть Site B, например 10.20.0.0/24;
  • отдельную VPN-подсеть, например 10.255.0.0/24 для WireGuard или 10.254.0.0/24 для OpenVPN;
  • VPN-интерфейс сервера, например wg0 или tun0;
  • LAN-интерфейс каждого удаленного шлюза;
  • основной интерфейс и SSH-порт центрального сервера;
  • маршрут обратного трафика на удаленных шлюзах и конечных хостах.

Подсети не должны пересекаться. Если Site A и Site B используют одинаковый диапазон, например 192.168.1.0/24, ядро не сможет однозначно выбрать нужный интерфейс. Потребуется перенумерация, NAT или отдельная схема трансляции адресов.

Сервер маршрутизации должен принимать пакеты из VPN и передавать их в другой VPN-пир либо в LAN. На Linux это требует включенного forwarding:

sysctl net.ipv4.ip_forward
sysctl -w net.ipv4.ip_forward=1

Значение 1 разрешает пересылку IPv4, но firewall по-прежнему может блокировать пакеты в цепочке FORWARD. На конечном хосте должен работать нужный сервис, а его локальный firewall должен разрешать соединения от адресов удаленной сети.

Проверяйте маршрут на каждом узле, который инициирует соединение. Если рабочая станция Site A использует шлюз 10.10.0.1, статический маршрут до Site B можно добавить на этом шлюзе. Когда конечный хост использует другой default gateway, маршрут придется добавить на самом хосте или на его фактическом маршрутизаторе.

Маршрутизация без NAT и с MASQUERADE

СхемаЧто происходитПреимуществаОграничения
Без NATСохраняются реальные адреса источников, например 10.10.0.50Прозрачные журналы, точные правила доступа, удобный аудитНа удаленных шлюзах нужны обратные маршруты
MASQUERADEИсходный адрес заменяется адресом VPN-интерфейсаМожно подключить сеть без настройки маршрута возврата на удаленном LANУдаленный узел видит адрес NAT, а контроль и аудит становятся менее точными
SNATИсходный адрес заменяется на заданный постоянный адресПредсказуемый результат для сервера со статическим VPN-адресомПри смене адреса правило придется обновить

Для постоянной site-to-site схемы выбирайте маршрутизацию без NAT. Она сохраняет адрес источника и позволяет ограничивать доступ по конкретным подсетям и хостам. MASQUERADE используйте, когда вы не контролируете обратный маршрут на удаленной площадке или подключаете временный сегмент.

Если VPN нужен для выбранных сетей, а основной default route сервера должен сохраниться, подойдет отдельная таблица policy routing. Практические примеры split tunneling для WireGuard и OpenVPN собраны в руководстве по маршрутизации нужного трафика через VPN.

Схема сети и адресный план для VPN-сервера маршрутизации

Пример топологии: сервер, VPN-пиры и удаленные LAN

В примере центральный Linux-сервер соединяет две площадки. Его публичный адрес условный, он нужен только для обозначения внешнего интерфейса. Для рабочего сервера используйте реальный адрес провайдера и заранее разрешите UDP-порт VPN во внешнем firewall.

УзелИнтерфейсАдресНазначение
Центральный серверeth0203.0.113.10Публичный доступ и SSH
Центральный серверwg010.255.0.1/24VPN-шлюз
Шлюз Site Awg010.255.0.2/24VPN-пир A
Шлюз Site Aeth110.10.0.1/24Шлюз LAN Site A
Шлюз Site Bwg010.255.0.3/24VPN-пир B
Шлюз Site Beth110.20.0.1/24Шлюз LAN Site B
Хост Site Aeth010.10.0.50/24Источник тестового трафика
Хост Site Beth010.20.0.60/24Целевой сервис

Путь запроса от 10.10.0.50 к 10.20.0.60 выглядит так: хост Site A, шлюз 10.10.0.1, VPN-пир A, центральный сервер, VPN-пир B, шлюз 10.20.0.1, хост Site B. Ответ должен пройти в обратном направлении. Каждый переход требует маршрута и разрешения firewall.

Центральный сервер выполняет роль маршрутизатора. Шлюзы Site A и Site B выполняют сразу две функции: завершают VPN и передают пакеты между VPN-интерфейсом и локальной сетью. Конечные хосты остаются обычными узлами LAN, если их default gateway уже указывает на соответствующий удаленный шлюз.

Публичный VDS с отдельным VPN-интерфейсом подходит для центрального узла, если площадки находятся за NAT или у них нет входящего публичного адреса. Для такого размещения можно использовать инфраструктуру Timeweb Cloud, заранее проверив доступность нужного UDP-порта и наличие консольного доступа.

Проверка конфликтов до настройки

Снимите текущее состояние сети до добавления VPN:

ip -br addr
ip route
ip route show table all
ip rule show
ss -lntup
wg show
ip link show
iptables-save
nft list ruleset

Проверьте четыре группы конфликтов:

  • пересекающиеся LAN-подсети и одинаковые адреса VPN-интерфейсов;
  • существующие маршруты по умолчанию, метрики и статические маршруты;
  • policy rules, пользовательские таблицы, маркировку пакетов и правила Docker;
  • сторонние VPN-интерфейсы, WARP, сетевые агенты и отдельные firewall-службы.

Отдельно запишите имя основного сетевого интерфейса, SSH-порт, адрес текущего шлюза и способ доступа к консоли. Основной или SSH-интерфейс не включайте в автоматический список интерфейсов для изменения маршрутизации без проверки результата. Изменение default route всего сервера способно отправить ответ SSH в VPN и оборвать сессию.

Кто должен знать маршрут до удаленной сети

УзелЧто должно быть настроено
Центральный серверМаршрут до 10.10.0.0/24 через пир A и до 10.20.0.0/24 через пир B
Шлюз Site AМаршрут до Site B через wg0, forwarding между eth1 и wg0
Шлюз Site BМаршрут до Site A через wg0, forwarding между eth1 и wg0
Шлюз LAN Site AМаршрут до Site B через 10.10.0.1, если он не совпадает с VPN-шлюзом
Шлюз LAN Site BМаршрут до Site A через 10.20.0.1, если он не совпадает с VPN-шлюзом
Конечный хостDefault gateway или статический маршрут, который отправляет ответ на локальный VPN-шлюз

Если весь Site A использует 10.10.0.1 как default gateway, отдельные маршруты на хостах не нужны. При смешанной схеме проверьте gateway командой ip route на Linux или route print на Windows.

Настройка WireGuard site-to-site

Конфигурация WireGuard на сервере маршрутизации

Центральный сервер получает адрес 10.255.0.1 и два пира. Для каждого пира AllowedIPs содержит его адрес в VPN и LAN, которая находится за этим пиром. Эти значения одновременно участвуют в выборе пира для исходящего трафика и проверке допустимых адресов источника.

[Interface]
Address = 10.255.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY

[Peer]
PublicKey = SITE_A_PUBLIC_KEY
AllowedIPs = 10.255.0.2/32, 10.10.0.0/24

[Peer]
PublicKey = SITE_B_PUBLIC_KEY
AllowedIPs = 10.255.0.3/32, 10.20.0.0/24

Сохраните конфигурацию в /etc/wireguard/wg0.conf с правами 600. Поднимите интерфейс и проверьте его состояние:

chmod 600 /etc/wireguard/wg0.conf
systemctl enable --now wg-quick@wg0
wg show wg0
ip route

При использовании wg-quick маршруты из AllowedIPs обычно добавляются автоматически. Если в конфигурации указано Table = off, добавьте маршруты вручную:

ip route add 10.10.0.0/24 dev wg0
ip route add 10.20.0.0/24 dev wg0
ip route get 10.10.0.50
ip route get 10.20.0.60

В выводе должен быть выбран wg0, а для каждого адреса должен определяться правильный peer по его AllowedIPs. Маршрут до Site A нельзя добавить в секцию пира B и наоборот: WireGuard направит пакет не тому узлу.

Настройка удаленного WireGuard-пира как шлюза LAN

Шлюз Site A имеет локальный адрес 10.10.0.1, VPN-адрес 10.255.0.2 и объявляет центральному серверу сеть 10.10.0.0/24. На этом шлюзе разрешите forwarding, а маршрут до Site B направьте в wg0.

[Interface]
Address = 10.255.0.2/24
PrivateKey = SITE_A_PRIVATE_KEY

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = VPN_SERVER_PUBLIC_ADDRESS:51820
AllowedIPs = 10.255.0.0/24, 10.20.0.0/24
PersistentKeepalive = 25

Конфигурация Site B отличается адресами и удаленной сетью:

[Interface]
Address = 10.255.0.3/24
PrivateKey = SITE_B_PRIVATE_KEY

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = VPN_SERVER_PUBLIC_ADDRESS:51820
AllowedIPs = 10.255.0.0/24, 10.10.0.0/24
PersistentKeepalive = 25

Параметр PersistentKeepalive = 25 отправляет небольшой пакет примерно раз в 25 секунд и помогает сохранять UDP-сопоставление на NAT-шлюзе. Он полезен, когда пир находится за NAT или входящий трафик к нему запрещен. PersistentKeepalive не исправляет неверный AllowedIPs, отсутствие маршрута и блокировку в FORWARD.

На обоих удаленных шлюзах включите пересылку:

sysctl -w net.ipv4.ip_forward=1
ip route get 10.20.0.60
ip route get 10.10.0.50

Маршрут до локальной LAN обычно создается ядром как connected route через физический интерфейс. Если локальный шлюз находится на другом устройстве, добавьте на нем маршруты:

ip route add 10.20.0.0/24 via 10.10.0.1
ip route add 10.10.0.0/24 via 10.20.0.1

Для выборочной маршрутизации через WireGuard полезно отделить маршруты VPN от основного default route. Приоритеты, пользовательские таблицы и маркировка подробно разобраны в руководстве по Policy-Based Routing в Linux.

Настройка маршрутизации между подсетями через OpenVPN

Маршруты OpenVPN: route, push route и iroute

OpenVPN разделяет маршрут в таблице ядра и внутреннее сопоставление сети с клиентом. Для site-to-site конфигурации нужны оба уровня.

ПараметрГде задаетсяНазначение
routeКонфигурация OpenVPN-сервераДобавляет маршрут до удаленной сети через TUN-интерфейс сервера
push routeСервер или CCD-файлПередает клиенту маршрут до сети, расположенной за другим пиром
irouteCCD-файл конкретного клиентаСообщает OpenVPN, за каким клиентом находится удаленная подсеть

Пример серверной конфигурации:

server 10.254.0.0 255.255.255.0
topology subnet
client-config-dir /etc/openvpn/ccd
client-to-client
route 10.10.0.0 255.255.255.0
route 10.20.0.0 255.255.255.0

Создайте CCD-файл с именем Common Name сертификата каждого шлюза. Для клиента Site A файл /etc/openvpn/ccd/site-a может содержать:

ifconfig-push 10.254.0.2 255.255.255.0
iroute 10.10.0.0 255.255.255.0
push "route 10.20.0.0 255.255.255.0"

Для Site B используйте файл /etc/openvpn/ccd/site-b:

ifconfig-push 10.254.0.3 255.255.255.0
iroute 10.20.0.0 255.255.255.0
push "route 10.10.0.0 255.255.255.0"

route создает путь на сервере, iroute отправляет пакет нужному OpenVPN-клиенту, а push route сообщает клиенту, куда направлять трафик. push route не заменяет серверный route, iroute и обратный маршрут на LAN.

Директива client-to-client позволяет серверу передавать трафик между подключенными клиентами внутри OpenVPN. Она не отменяет IP forwarding на шлюзах Site A и Site B и не настраивает маршруты на локальных хостах.

Подключение удаленного шлюза к локальной сети

OpenVPN-клиент Site A должен иметь TUN-интерфейс, адрес 10.254.0.2, локальный интерфейс с адресом 10.10.0.1 и маршрут до Site B. Шлюз Site B настраивается зеркально.

sysctl -w net.ipv4.ip_forward=1
ip addr show tun0
ip route
ip route get 10.20.0.60

На шлюзе Site A пакет к 10.20.0.60 должен войти через LAN-интерфейс и выйти через tun0. На шлюзе Site B он должен войти через tun0 и выйти в локальную LAN. Правила firewall должны разрешать оба направления, а локальные хосты должны отправлять ответы на свои VPN-шлюзы.

Если локальные устройства Site A используют другой маршрутизатор, добавьте на нем маршрут:

ip route add 10.20.0.0/24 via 10.10.0.1

Аналогичный маршрут на маршрутизаторе Site B:

ip route add 10.10.0.0/24 via 10.20.0.1

Проверка OpenVPN после внесения изменений

Проверьте процесс OpenVPN, TUN-интерфейс и журнал:

systemctl status openvpn-server@server
ip addr show tun0
ip route show
journalctl -u openvpn-server@server -n 100 --no-pager

В журнале ищите успешное подключение нужного Common Name, назначенный VPN-адрес и отсутствие ошибок TLS. На сервере проверьте наличие маршрутов 10.10.0.0/24 и 10.20.0.0/24, а в CCD-файлах, правильные iroute. Для теста используйте адрес источника:

ping -I 10.10.0.1 10.20.0.60
ip route get 10.20.0.60 from 10.10.0.1

Если TUN-интерфейс и TLS работают, но счетчики пакетов не растут, проблема находится в маршруте, forwarding или firewall. Состояние процесса OpenVPN само по себе не подтверждает связность удаленных LAN.

Добавление маршрутов и policy routing

Маршруты в основной таблице

В простой схеме маршруты до удаленных LAN можно поместить в основную таблицу. Для WireGuard укажите интерфейс wg0, для OpenVPN используйте tun0:

ip route add 10.10.0.0/24 dev wg0
ip route add 10.20.0.0/24 dev wg0
ip route add 10.10.0.0/24 dev tun0
ip route add 10.20.0.0/24 dev tun0

Добавляйте только команды для используемого VPN. Если удаленная сеть доступна через промежуточный VPN-шлюз, укажите next hop:

ip route add 10.20.0.0/24 via 10.255.0.3 dev wg0

Проверьте выбранный путь и источник:

ip route get 10.20.0.60
ip route get 10.20.0.60 from 10.10.0.50
ip route show table main

Временная команда ip route add исчезнет после перезагрузки. Для WireGuard храните маршруты в wg0.conf и запускайте wg-quick@wg0. Для OpenVPN оставляйте route в серверной конфигурации. Маршруты LAN на шлюзах сохраняйте средствами NetworkManager, systemd-networkd или используемого сетевого менеджера.

Обратные маршруты и асимметричный трафик

Запрос от 10.10.0.50 может дойти до 10.20.0.60, а ответ уйти через другой default gateway. В результате клиент видит тайм-аут, хотя на центральном сервере есть маршрут в прямом направлении.

Проверьте маршрут возврата на хосте Site B или его шлюзе:

ip route get 10.10.0.50
ip route get 10.10.0.50 from 10.20.0.60

Исправления три:

  1. добавить статический маршрут 10.10.0.0/24 via 10.20.0.1 на маршрутизаторе Site B;
  2. указать VPN-шлюз как next hop для удаленной сети на каждом локальном маршрутизаторе;
  3. использовать контролируемый MASQUERADE, если изменить обратный маршрут нельзя.

Асимметрия возникает и при policy routing. Пакет может попасть в VPN по правилу источника, а ответ серверного процесса уйдет через основной default route. Сравнивайте путь для обоих направлений и проверяйте источник командой ip route get.

Отдельная таблица policy routing

Отдельная таблица полезна, когда VPN должен обслуживать выбранные сети или источники, а основной default route сервера должен остаться в main. Пример таблицы с номером 200:

grep -q '^200 vpn$' /etc/iproute2/rt_tables || echo '200 vpn' >> /etc/iproute2/rt_tables
ip route add 10.20.0.0/24 dev wg0 table vpn
ip rule add from 10.10.0.0/24 to 10.20.0.0/24 priority 100 table vpn
ip rule show
ip route show table vpn
ip route get 10.20.0.60 from 10.10.0.50

В этой схеме правило с приоритетом 100 проверяется раньше стандартных правил. Таблица vpn содержит только нужный маршрут, поэтому default route из main не заменяется VPN-маршрутом.

Для более сложной схемы можно маркировать пакеты:

iptables -t mangle -A PREROUTING -s 10.10.0.0/24 -d 10.20.0.0/24 -j MARK --set-mark 32
ip rule add fwmark 32 priority 100 table vpn

Перед добавлением правил сравните ip rule show и ip route show table all. WARP, Docker, облачные агенты и другие виртуальные интерфейсы могут уже использовать собственные таблицы и приоритеты. Конфликт policy rules способен изменить маршрут только для части соединений. Дополнительные схемы таблиц, ip rule и маркировки приведены в руководстве по маршрутизации в Linux.

IP forwarding, NAT и правила межсетевого экрана

Включение IPv4 forwarding

Включите forwarding временно для проверки:

sysctl -w net.ipv4.ip_forward=1
sysctl net.ipv4.ip_forward

Для постоянного значения создайте файл /etc/sysctl.d/99-vpn-routing.conf с содержимым:

net.ipv4.ip_forward = 1

Загрузите настройку и проверьте результат:

sysctl --system
sysctl net.ipv4.ip_forward

Включите forwarding на центральном сервере и на каждом удаленном шлюзе. На обычных конечных хостах эта настройка не требуется, если они не маршрутизируют трафик для других устройств.

Разрешение транзитного трафика в FORWARD

Сначала разрешите уже установленные соединения, затем добавьте узкие правила для новых пакетов. На центральном сервере, где оба направления проходят через wg0, базовый набор для двустороннего обмена выглядит так:

iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wg0 -o wg0 -s 10.10.0.0/24 -d 10.20.0.0/24 -j ACCEPT
iptables -A FORWARD -i wg0 -o wg0 -s 10.20.0.0/24 -d 10.10.0.0/24 -j ACCEPT

На шлюзе Site A используйте LAN-интерфейс и VPN-интерфейс:

iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -o wg0 -s 10.10.0.0/24 -d 10.20.0.0/24 -j ACCEPT
iptables -A FORWARD -i wg0 -o eth1 -s 10.20.0.0/24 -d 10.10.0.0/24 -j ACCEPT

На Site B направления зеркальные:

iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -o wg0 -s 10.20.0.0/24 -d 10.10.0.0/24 -j ACCEPT
iptables -A FORWARD -i wg0 -o eth1 -s 10.10.0.0/24 -d 10.20.0.0/24 -j ACCEPT

Если политика FORWARD DROP, эти разрешения должны находиться перед общим запретом. Проверьте порядок и счетчики:

iptables -L FORWARD -n -v --line-numbers
iptables -S FORWARD

Когда система использует nftables или iptables с nft backend, проверяйте оба уровня:

iptables -V
nft list ruleset

Не добавляйте параллельные правила в разные менеджеры firewall без понимания их порядка загрузки. Подробное сравнение iptables и nftables для VPN-маршрутизации есть в руководстве по VPN-маршрутизации на Linux.

MASQUERADE и SNAT для удаленных подсетей

Добавляйте NAT на узле, через который трафик выходит в VPN, и ограничивайте правило исходной и целевой подсетями. Пример для центрального сервера:

iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -d 10.20.0.0/24 -o wg0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.20.0.0/24 -d 10.10.0.0/24 -o wg0 -j MASQUERADE
iptables -t nat -L POSTROUTING -n -v

MASQUERADE меняет адрес источника на адрес выходного интерфейса. В примере хост Site B увидит адрес VPN-шлюза, а не 10.10.0.50. Для постоянного адреса можно использовать SNAT:

iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -d 10.20.0.0/24 -o wg0 -j SNAT --to-source 10.255.0.1

Не маскируйте весь трафик интерфейса без фильтра по назначениям. Такое правило может скрыть ошибки маршрутизации и повлиять на доступ к другим VPN-сетям. NAT остается stateful, поэтому для ответа на уже установленное соединение отдельное правило DNAT обычно не нужно.

Ограничение доступа к отдельным хостам и сервисам

Разрешение по всей сети 10.20.0.0/24 подходит для диагностики, но для постоянной схемы лучше указать конкретный хост и порт. Например, Site A должен подключаться к SSH и HTTPS на 10.20.0.60, а остальные адреса Site B должны быть закрыты:

iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wg0 -o wg0 -s 10.10.0.0/24 -d 10.20.0.60 -p tcp -m multiport --dports 22,443 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i wg0 -o wg0 -s 10.10.0.0/24 -d 10.20.0.0/24 -j DROP

Для DNS добавьте отдельное правило с UDP-портом 53, а для DNS по TCP разрешите TCP 53 отдельной строкой:

iptables -A FORWARD -i wg0 -o wg0 -s 10.10.0.50 -d 10.20.0.53 -p udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i wg0 -o wg0 -s 10.10.0.50 -d 10.20.0.53 -p tcp --dport 53 -m conntrack --ctstate NEW -j ACCEPT

Порядок правил определяет результат. Сначала разместите ESTABLISHED,RELATED, затем разрешения для конкретных адресов, протоколов и портов, после этого общий запрет. Тестируйте разрешенный путь к 10.20.0.60:443 и запрещенный путь к другому порту или хосту. Аналогичные ограничения нужно применять на каждом узле, где проходит пакет: центральном сервере и удаленных шлюзах.

Проверка маршрутизации и прохождения трафика

Проверка состояния WireGuard и OpenVPN

Для WireGuard проверьте peer, время последнего handshake и счетчики передачи:

wg show wg0
wg show wg0 latest-handshakes
wg show wg0 transfer

Свежий handshake подтверждает обмен зашифрованными пакетами между пирами. Увеличение счетчиков transfer во время теста показывает движение трафика внутри туннеля. Эти признаки не подтверждают прохождение пакета в LAN.

Для OpenVPN проверьте процесс, TUN-интерфейс, адрес и журнал:

systemctl status openvpn-server@server
ip -br addr show tun0
ip route show dev tun0
journalctl -u openvpn-server@server -n 100 --no-pager

На клиенте ищите успешное подключение, выданный адрес и отсутствие повторяющихся переподключений. Ошибки TLS, сертификатов, времени системы и внешнего UDP-порта относятся к установлению туннеля. Отсутствующий маршрут, iroute или блокировка FORWARD относятся к передаче трафика.

Проверка таблиц маршрутизации

Начните проверку с маршрута на сервере маршрутизации:

ip route
ip route show table all
ip rule show
ip route get 10.20.0.60
ip route get 10.20.0.60 from 10.10.0.50

Ожидаемый результат для WireGuard содержит интерфейс wg0 и корректный peer, для OpenVPN, интерфейс tun0. Затем выполните такие же команды на VPN-шлюзе и маршрутизаторе удаленной LAN. Особое внимание уделите маршруту ответа к адресу источника.

При policy routing сравните основную и пользовательскую таблицы:

ip rule show
ip route show table main
ip route show table vpn
ip route get 10.20.0.60 from 10.10.0.50 mark 32

Если команда выбирает eth0 вместо wg0 или tun0, исправляйте правило, таблицу, приоритет либо более специфичный маршрут.

Проверка пакетов через tcpdump

Запустите захват одновременно на VPN-интерфейсе и LAN-интерфейсе. На центральном сервере:

tcpdump -ni wg0 'host 10.10.0.50 or host 10.20.0.60'
 tcpdump -ni eth0 'host 10.10.0.50 or host 10.20.0.60'

На удаленном шлюзе Site B снимайте трафик на обоих направлениях:

tcpdump -ni wg0 'host 10.10.0.50 or host 10.20.0.60'
tcpdump -ni eth1 'host 10.10.0.50 or host 10.20.0.60'

Интерпретируйте результат по точке исчезновения:

  • пакет не появился на wg0, ищите маршрут или AllowedIPs;
  • пакет есть на wg0, но отсутствует на LAN-интерфейсе, проверяйте forwarding и FORWARD;
  • запрос вышел в LAN, но ответ отсутствует, проверяйте firewall конечного хоста и обратный маршрут;
  • ответ виден на LAN, но не возвращается в VPN, проверяйте gateway, policy routing и NAT;
  • адрес источника изменился, правило NAT сработало, проверьте его счетчик и соответствие выбранной схеме.

Проверка firewall, NAT и конечного сервиса

Проверьте счетчики правил и активные соединения:

iptables -L FORWARD -n -v --line-numbers
iptables -t nat -L POSTROUTING -n -v
conntrack -L
nft list ruleset

На целевом хосте проверьте прослушивание порта:

ss -lntup
ss -lntup | grep ':443'

Проверяйте ICMP и TCP раздельно. Запрет ping не всегда означает отсутствие маршрута, а успешный ping не подтверждает доступность приложения. Для TCP используйте конкретный сервис:

nc -vz 10.20.0.60 22
nc -vz 10.20.0.60 443
curl --interface 10.10.0.50 http://10.20.0.60:8080/

Когда сервис слушает только 127.0.0.1, маршрутизация не поможет. Сервис должен слушать адрес LAN или нужный VPN-адрес, а локальный firewall должен принимать соединения от разрешенной подсети.

Типовые проблемы: VPN подключен, но подсети не связаны

СимптомПроверкаВероятная причина и исправление
Handshake есть, но пакеты не доходят до LANsysctl net.ipv4.ip_forward, ip route get, счетчики FORWARD, tcpdumpВыключен forwarding, нет маршрута, пакет блокирует firewall. В WireGuard проверьте AllowedIPs, в OpenVPN, route и iroute.
Запрос проходит в одну сторонуip route get для адреса источника на целевом шлюзе, захват на LANОтсутствует обратный маршрут, неверный gateway или ответ уходит через default route. Добавьте статический маршрут или контролируемый NAT.
Туннель не устанавливаетсяwg show, внешний firewall, UDP-порт, журналы OpenVPNНеверный endpoint, публичный ключ, сертификат, порт или системное время. Для пира за NAT проверьте PersistentKeepalive.
Handshake устарел, счетчики не меняютсяВремя последнего handshake, transfer, журналы и доступность endpointПир недоступен, UDP-сопоставление NAT удалено или внешний firewall блокирует трафик. Проверьте маршрут до endpoint через основной интерфейс.
Подсети имеют одинаковые адресаip route на всех площадках и адресный планЯдро выбирает локальный connected route вместо VPN. Перенумеруйте LAN либо примените согласованную схему NAT.
Маршрут есть, но соединение обрывается или работает с малыми пакетамиПинг с разным размером и флагом DF, tcpdump, значение MTUMTU туннеля слишком велик, пакеты фрагментируются или ICMP блокируется. Уменьшите MTU VPN-интерфейса и при необходимости настройте MSS clamping.
После изменения маршрутов пропал SSH-доступКонсоль провайдера, текущая default route, ip ruleОтвет SSH ушел через VPN или новую default route. Через web console или Rescue Mode удалите последнее правило, восстановите маршрут и верните основной интерфейс.
Доступ разрешен к сети, хотя нужен один сервисПорядок правил FORWARD и счетчики совпаденийОбщее ACCEPT стоит перед узким правилом. Переместите точечное разрешение выше общего запрета и удалите широкое правило.

Handshake есть, но пакеты не доходят до LAN

Проверяйте проблему по цепочке: маршрут на источнике, маршрут на VPN-шлюзе, AllowedIPs или связку route/iroute, forwarding, FORWARD, LAN-маршрут и локальный firewall целевого хоста.

Для WireGuard на сервере Site A должна быть сеть 10.20.0.0/24 в AllowedIPs пира сервера, а на центральном сервере сеть 10.10.0.0/24 должна относиться к пиру Site A. Для OpenVPN CCD-файл Site B должен содержать iroute 10.20.0.0 255.255.255.0, а серверная конфигурация, route 10.20.0.0 255.255.255.0.

Запрос проходит только в одну сторону

Запустите tcpdump на LAN-интерфейсе целевой площадки. Если запрос виден, а ответ не появляется, проблема находится на конечном хосте, его локальном firewall или default gateway. Если ответ появляется на LAN, но не в VPN, проверяйте обратный маршрут на шлюзе и policy rules.

NAT может временно подтвердить гипотезу. Добавьте ограниченный MASQUERADE только между двумя подсетями, проверьте счетчик правила и повторите тест. Если соединение заработало, настройте постоянные обратные маршруты и удалите NAT, когда прозрачная адресация нужна для аудита.

Туннель не устанавливается или handshake устарел

WireGuard требует правильных private/public key, endpoint, UDP-порта и адресации. Убедитесь, что системное время синхронизировано, внешний firewall пропускает UDP, а маршрут до публичного endpoint не попал в VPN.

В OpenVPN проверьте сертификаты, TLS-ошибки, Common Name и журнал сервиса. Для пира за NAT добавьте PersistentKeepalive = 25 в WireGuard-конфигурацию клиента. Этот параметр поддерживает доступность UDP-сопоставления, но не заменяет корректную настройку маршрутов.

Маршрут есть, но соединение обрывается или работает только с малыми пакетами

Проверьте MTU тестом с запрещенной фрагментацией. Например, для IPv4 можно постепенно уменьшать размер ICMP-пакета и отслеживать момент, когда ответы прекращаются. Фильтрация ICMP способна скрыть сообщение о слишком большом пакете, поэтому проверяйте реальный TCP-сервис.

Снизьте MTU на wg0 или tun0, затем повторите тест. Для TCP-соединений между площадками может потребоваться MSS clamping в firewall. Изменение MTU применяйте одинаково к маршрутам, где проходит проблемный трафик, и проверяйте результат через tcpdump.

После изменения маршрутов пропал SSH-доступ

Не меняйте default route удаленного сервера без второго канала управления. Подготовьте web console, KVM или Rescue Mode провайдера. Для важного VPS это обязательная часть процедуры, потому что защита SSH не гарантирует сохранение маршрута ответа для других служб.

Через альтернативную консоль проверьте:

ip route
ip rule show
ss -lntp | grep ':22'

Удалите ошибочное правило или маршрут:

ip rule del priority 100
ip route del 10.20.0.0/24 dev wg0

Если проблема вызвана firewall, восстановите сохраненный набор правил. Не удаляйте все правила без копии текущей конфигурации, иначе можно потерять доступ к серверу и другим сервисам.

Безопасное применение, сохранение и откат конфигурации

Предварительная фиксация состояния сети

Сохраните состояние до начала работ:

ip -br addr > /root/network-before.txt
ip route show table all > /root/routes-before.txt
ip rule show > /root/rules-before.txt
iptables-save > /root/iptables-before.txt
nft list ruleset > /root/nft-before.txt
wg show > /root/wireguard-before.txt
journalctl -u wg-quick@wg0 -n 100 --no-pager > /root/wireguard-log-before.txt

Сохраните конфигурации WireGuard и OpenVPN отдельно, но не публикуйте private key в тикетах, чатах и открытых журналах. Запишите текущие policy rules, Docker-маршруты, WARP, имена виртуальных адаптеров, SSH-порт и доступный канал консоли.

Порядок безопасного включения маршрутизации

  1. Проверьте уникальность LAN-подсетей и VPN-адресов.
  2. Сохраните конфигурации и убедитесь, что SSH и консоль доступны.
  3. Настройте VPN-интерфейс и проверьте handshake.
  4. Добавьте узкие маршруты до удаленных подсетей без изменения default route.
  5. Включите IPv4 forwarding на центральном сервере и удаленных шлюзах.
  6. Добавьте разрешения FORWARD между конкретными интерфейсами и подсетями.
  7. Настройте NAT только при отсутствии обратного маршрута.
  8. Проверьте ICMP, TCP-сервис, обратный путь и счетчики firewall.
  9. Проверьте запрещенный хост или порт, чтобы убедиться в работе сегментации.

После каждого шага выполняйте ip route get и сохраняйте SSH-сессию открытой до завершения проверки. Для изменений всего сервера подготовьте отдельное окно обслуживания, особенно если на узле работают Docker, WARP, несколько VPN или облачный сетевой агент.

Контрольный чек-лист после перезагрузки

  • WireGuard запускается через wg-quick@wg0, либо OpenVPN запускается через сервис нужного профиля;
  • VPN-интерфейс получает ожидаемый адрес;
  • маршруты до 10.10.0.0/24 и 10.20.0.0/24 присутствуют после перезагрузки;
  • net.ipv4.ip_forward сохраняет значение 1;
  • policy rules и пользовательская таблица загружаются в правильном порядке;
  • правила FORWARD и NAT присутствуют, а их счетчики растут во время теста;
  • handshake WireGuard обновляется, OpenVPN сохраняет подключение и корректный TUN-интерфейс;
  • разрешенные сервисы доступны с нужной подсети;
  • запрещенные адреса и порты не принимают соединения;
  • SSH доступен через основной интерфейс и альтернативную консоль.

Для отката удалите временные маршруты и policy rules, затем удалите соответствующие правила firewall по тем же параметрам:

ip rule del from 10.10.0.0/24 to 10.20.0.0/24 priority 100 table vpn
ip route del 10.20.0.0/24 table vpn
iptables -D FORWARD -i wg0 -o wg0 -s 10.10.0.0/24 -d 10.20.0.0/24 -j ACCEPT
iptables -t nat -D POSTROUTING -s 10.10.0.0/24 -d 10.20.0.0/24 -o wg0 -j MASQUERADE

При необходимости восстановите сохраненные правила командой iptables-restore < /root/iptables-before.txt или верните конфигурацию nftables штатным способом. После отката снова проверьте SSH, основной default route, таблицу маршрутизации и журнал VPN.

Полная схема считается рабочей, когда handshake стабилен, маршрут выбран ожидаемым интерфейсом, счетчики FORWARD и NAT соответствуют тесту, пакет виден на VPN и LAN-интерфейсах, ответ возвращается тем же логическим путем, а разрешения ограничены нужными хостами и портами.

Поделиться:
Сохранить гайд? В закладки браузера