Как настроить на VPS два сетевых интерфейса так, чтобы сервер выполнял роль шлюза (маршрутизатора)?

Всем привет!<br/>Есть VPS с двумя сетевыми интерфейсами: eth0 — 10.129.0.11 и eth1 — 10.129.0.12 (их внешние адреса отличаются и проброшены через one‑to‑one NAT, обозначим их как 11.1.1.1 и 22.2.2.2).<br/><br/>Эта VPS соединена с другой VPS через GRE-туннель: на моей стороне 172.30.0.1 (шлюз), на удалённой — 172.30.0.2 (дальняя).<br/><br/>На удалённой VPS работает сервис, слушающий порт 11336. На первой (шлюзовой) VPS настроен проброс этого порта через GRE с помощью правил iptables:
  • 18 февраля 2026 г. 22:01
Ответы на вопрос 2
Ниже — практическая пошаговая инструкция, как превратить вашу VPS с двумя интерфейсами в маршрутизатор / портовый форвардер для сервиса, доступного через GRE. Я опираюсь на вашу схему: eth0 (10.129.x) ↔ внешний 11.1.1.1, eth1 (10.129.x) ↔ внешний 22.2.2.2, GRE: локально 172.30.0.1 — удалённо 172.30.0.2, сервис на удалённой VPS слушает 11336.

1) Включить маршрутизацию IPv4
- Временно:
  sudo sysctl -w net.ipv4.ip_forward=1
- Навсегда: в /etc/sysctl.conf или /etc/sysctl.d/99-sysctl.conf добавить:
  net.ipv4.ip_forward=1
+ применить sudo sysctl --system

2) Отключить строгую проверку маршрута (rp_filter)
Ассиметричный трафик (приход через один интерфейс, уход через другой / через GRE) может блокироваться rp_filter. Отключите:
  sudo sysctl -w net.ipv4.conf.all.rp_filter=0
  sudo sysctl -w net.ipv4.conf.default.rp_filter=0
и/или для конкретных интерфейсов:
  sudo sysctl -w net.ipv4.conf.eth0.rp_filter=0
  sudo sysctl -w net.ipv4.conf.eth1.rp_filter=0
Сохранить в /etc/sysctl.d/99-custom.conf.

3) Правила iptables для проброса порта через GRE
Вариант простой (DNAT + SNAT к туннельному IP):

- DNAT: перенаправляем пакеты, приходящие на публичный 11.1.1.1:11336, на удалённый конец GRE 172.30.0.2:11336
  sudo iptables -t nat -A PREROUTING -d 11.1.1.1/32 -p tcp --dport 11336 -j DNAT --to-destination 172.30.0.2:11336

- Разрешение пересылки (FORWARD):
  sudo iptables -A FORWARD -d 172.30.0.2/32 -p tcp --dport 11336 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
  sudo iptables -A FORWARD -s 172.30.0.2/32 -p tcp --sport 11336 -m conntrack --ctstate ESTABLISHED -j ACCEPT

- SNAT: менять исходящий адрес на tunnel IP 172.30.0.1, чтобы ответы от 172.30.0.2 шли обратно по GRE (иначе удалённая VPS попытается ответить напрямую клиенту и ответ может уйти в интернет в обход туннеля):
  sudo iptables -t nat -A POSTROUTING -s 0/0 -d 172.30.0.2/32 -p tcp --dport 11336 -j SNAT --to-source 172.30.0.1

Пояснение: DNAT меняет destination на 172.30.0.2; SNAT делает так, чтобы на удалённой стороне исходный IP выглядел как 172.30.0.1, поэтому все ответы придут обратно по GRE и снова будут де‑SNAT/DE‑DNAT в исходящие пакеты.

Если хотите пробрасывать весь трафик через GRE (не только порт), можно SNAT/MASQUERADE для интерфейса greX:
  sudo iptables -t nat -A POSTROUTING -o gre0 -j MASQUERADE

4) Политическая маршрутизация (если нужно, чтобы ответы с разных внешних IP уходили через правильный «хост‑GW»)
Если ваша VPS имеет два разных провайдера/маршрута и вам важно, чтобы трафик с исходным IP 11.1.1.1 уходил именно через соответствующий gateway, используйте ip rule + отдельные таблицы:

Пример (надо подставить реальные шлюзы, которые видит ваша VPS, например 10.129.0.1 и 10.129.0.1 — если они разные):
  sudo ip route add default via <GW_ETH0> dev eth0 table T0
  sudo ip rule add from 10.129.x.11/32 table T0
  sudo ip route add default via <GW_ETH1> dev eth1 table T1
  sudo ip rule add from 10.129.x.12/32 table T1
  sudo ip route flush cache

Это нужно, если на VPS есть исходящие соединения с привязкой к конкретному внешнему адресу и провайдеры/маршруты различаются.

5) Разрешить GRE (протокол 47) в firewall
Если host firewall блокирует GRE:
  sudo iptables -A INPUT -p 47 -j ACCEPT
  sudo iptables -A FORWARD -p 47 -j ACCEPT

6) Сохранение правил
- Сохраните iptables правила (iptables-save > /etc/iptables/rules.v4) либо используйте iptables-persistent, nftables или systemd‑unit/скрипт в /etc/network/if-up.d для восстановления при старте.

7) Тестирование и отладка
- Проверить sysctl: sysctl net.ipv4.ip_forward
- Посмотреть таблицы NAT и FORWARD: sudo iptables -t nat -L -n -v; sudo iptables -L FORWARD -n -v
- tcpdump на интерфейсах:
  sudo tcpdump -nni eth0 tcp port 11336
  sudo tcpdump -nni gre0
- На удалённой стороне посмотреть, видит ли она соединение от 172.30.0.1: tcpdump -nni any port 11336
- Проверить conntrack: sudo conntrack -L | grep 11336

FAQ / типичные ошибки
- Без SNAT/маскарадинга удалённая VPS будет пытаться отвечать напрямую клиенту (ассиметрия) — пакеты потеряются.
- rp_filter по умолчанию может отбрасывать пакеты, если они приходят на интерфейс, где не ожидается исходный адрес — отключите или переведите в loose mode.
- Если используете облачный провайдер с one‑to‑one NAT (как у вас), внутренний «gw» для eth0/eth1 может быть одинаковым — тогда policy routing может и не понадобиться.

Если хотите, могу:
- привести конкретные команды под вашу конфигурацию (укажите текущие ip route show, ip addr, ip rule show, название GRE интерфейса),
- или показать вариант правил для nftables.
отмени правило masquerade в iptables 

и настрой SNAT - чтоб уходило через то тже интерфейс, на который пришло
Похожие вопросы