Флаг: English English

Направляем трафик из локальной подссети через удаленный сервер (IPIP + Policy Routing)

Опубликовано 29.10.2025

Это руководство покажет, как настроить два Linux-сервера, чтобы весь интернет-трафик из определенной локальной подсети (например, 10.100.10.0/24) направлялся не через её шлюз по умолчанию, а через IPIP-туннель на удаленный сервер, который уже будет выпускать этот трафик в интернет.

Это полезно, если вам нужно, чтобы сервисы в одной подсети выходили в мир с IP-адреса другого сервера — например, для обхода блокировок, централизованного NAT или маскировки источника.


Действующие лица (вымышленные)

РольИмяВнешний (WAN) IPИнтерфейс WANВнутренний (Tunnel) IPПримечание
Сервер АЛокальный Шлюз198.51.100.10eth010.254.0.1/30Шлюз подсети 10.100.10.0/24
Сервер БУдалённый Узел Выхода203.0.113.20eth010.254.0.2/30Выпускает трафик в интернет
  • Подсеть для маршрутизации: 10.100.10.0/24
  • Имя туннеля: ipip0
  • Туннельная сеть: 10.254.0.0/30

Шаг 1: Настройка Сервера Б (Удалённый Узел Выхода)

Цель: Принять IPIP-туннель от Сервера А и выпускать трафик из подсети 10.100.10.0/24 в интернет через NAT с использованием внешнего IP 203.0.113.20.

1.1. Включаем IP Forwarding

sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf

1.2. Настройка туннеля, firewall и NAT

#!/bin/sh
set -e

TUN_NAME="ipip0"
REMOTE_IP="198.51.100.10"
LOCAL_IP="203.0.113.20"
TUN_NET="10.254.0.2/30"
TUN_PEER="10.254.0.1"
WAN_IFACE="eth0"
CLIENT_NET="10.100.10.0/24"

echo "[*] Создаю туннель $TUN_NAME"
ip tunnel del "$TUN_NAME" 2>/dev/null || true
ip tunnel add "$TUN_NAME" mode ipip remote "$REMOTE_IP" local "$LOCAL_IP" ttl 64
ip addr add "$TUN_NET" dev "$TUN_NAME"
ip link set "$TUN_NAME" up mtu 1480

echo "[*] Настраиваю iptables"

iptables -I INPUT -p 4 -s "$REMOTE_IP" -j ACCEPT
iptables -A FORWARD -i "$TUN_NAME" -s "$CLIENT_NET" -o "$WAN_IFACE" -j ACCEPT
iptables -A FORWARD -i "$WAN_IFACE" -d "$CLIENT_NET" -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -t nat -A POSTROUTING -s "$CLIENT_NET" -o "$WAN_IFACE" -j SNAT --to-source "$LOCAL_IP"

iptables -t mangle -A FORWARD -o "$WAN_IFACE" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

echo "[OK] Сервер Б готов."

Установлен MTU=1480 и TCPMSS clamp, чтобы избежать проблем с PMTU Discovery.


Шаг 2: Настройка Сервера А (Локальный шлюз)

Цель: Перенаправить трафик из 10.100.10.0/24, идущий в интернет, в туннель к Серверу Б.

2.1. Включаем IP Forwarding и настраиваем rp_filter

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.rp_filter=2
sysctl -w net.ipv4.conf.default.rp_filter=2

cat <<EOF >> /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
EOF

rp_filter=2loose mode, обязателен при асимметричной маршрутизации.


2.2. Создаём IPIP-туннель

#!/bin/sh
set -e

TUN_NAME="ipip0"
REMOTE_IP="203.0.113.20"
LOCAL_IP="198.51.100.10"
TUN_NET="10.254.0.1/30"
TUN_PEER="10.254.0.2"

echo "[*] Поднимаю туннель $TUN_NAME"
ip tunnel del "$TUN_NAME" 2>/dev/null || true
ip tunnel add "$TUN_NAME" mode ipip remote "$REMOTE_IP" local "$LOCAL_IP" ttl 64
ip addr add "$TUN_NET" dev "$TUN_NAME"
ip link set "$TUN_NAME" up mtu 1480

echo "[OK] Туннель поднят."

2.3. Policy Routing

Добавляем таблицу маршрутизации:

grep -q "100[[:space:]]tunnel_route" /etc/iproute2/rt_tables || echo "100 tunnel_route" >> /etc/iproute2/rt_tables

Добавляем маршрут по умолчанию:

ip route add default via 10.254.0.2 dev ipip0 table tunnel_route

Создаём правило:

ip rule add from 10.100.10.0/24 table tunnel_route pref 1000
ip route flush cache

2.4. Настраиваем Firewall

CLIENT_NET="10.100.10.0/24"
TUN_NAME="ipip0"

iptables -A FORWARD -s "$CLIENT_NET" -o "$TUN_NAME" -j ACCEPT
iptables -A FORWARD -i "$TUN_NAME" -d "$CLIENT_NET" -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t mangle -A FORWARD -o "$TUN_NAME" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

echo "[OK] Firewall и policy routing настроены."

Шаг 3: Проверка

Проверяем обычный маршрут:

ip route get 8.8.8.8

Ожидаемо:

8.8.8.8 via <ваш_шлюз> dev eth0 src 198.51.100.10 ...

Проверяем маршрут из подсети:

ip route get 8.8.8.8 from 10.100.10.50

Ожидаемо:

8.8.8.8 from 10.100.10.50 via 10.254.0.2 dev ipip0 src 198.51.100.10 ...

🧩 Troubleshooting (диагностика и отладка)

1. Проверка туннеля

ip addr show dev ipip0
ip -s tunnel show
ping -I ipip0 10.254.0.2

Если ping не идёт — проверь разрешение IPIP (протокол 4) в firewall.


2. Проверка policy routing

ip rule show
ip route show table tunnel_route

Должна быть строка:

1000: from 10.100.10.0/24 lookup tunnel_route

3. Проверка NAT

iptables -t nat -L POSTROUTING -v -n

Счётчики SNAT должны расти при активном трафике.


4. Проверка внешнего IP внутри подсети

curl -4 ifconfig.me

Ожидаемо — 203.0.113.20.


5. MTU и MSS

Если TCP-зависания:

ip link show ipip0
ping -M do -s 1472 8.8.8.8

Настрой mtu 1480 и --clamp-mss-to-pmtu.


6. tcpdump

tcpdump -ni ipip0
tcpdump -ni eth0 host 8.8.8.8

7. Временное логирование

iptables -I FORWARD 1 -j LOG --log-prefix "[FORWARD DROP] "
tail -f /var/log/kern.log

8. Проверка обратного маршрута

traceroute -s 10.100.10.10 8.8.8.8

и с Сервера Б:

traceroute -s 10.254.0.2 10.100.10.10

9. Сохранение состояния

iptables-save > /etc/iptables/rules.v4
ip rule show > /etc/iprules.conf

⚙️ Дополнительные рекомендации

ПунктРекомендация
MTUУстановите 1480 и включите TCPMSS clamp
FirewallНа новых системах предпочтителен nftables
PersistencyАвтоматизируйте запуск туннеля через systemd
Мониторингtcpdump -i ipip0 покажет трафик в туннеле
БезопасностьОграничьте IPIP-доступ и добавьте IPSec/WireGuard при необходимости

✅ Готово

Теперь весь интернет-трафик из 10.100.10.0/24 выходит через IP Сервера Б (203.0.113.20), а сам Сервер А продолжает использовать свой обычный маршрут.

Это простая и надёжная схема для централизованного NAT, обхода ограничений или организации внутреннего VPN на чистом Linux.

Нужна помощь?

Свяжись со мной и я помогу решить проблему

Похожие посты