Назад | Перейти на главную страницу

iptables: внутренняя переадресация портов с помощью fwmark и таблиц маршрутизации

У меня 2 сервера, и мне нужно перенаправить на внутренний порт.

Чтобы объяснить, я использую сервер с двумя интерфейсами (внутренний / внешний) в качестве сервера A и внутренний сервер в качестве сервера B.

На сервере A я использую

iptables -A PREROUTING -t nat -i $extif -p tcp --dport $extif_port -j DNAT --to-destination $dst_ip:$dst_port"
iptables -A FORWARD -t filter -d $dst_ip -j ACCEPT"
iptables -A POSTROUTING -t nat -p tcp -s $dst_ip --sport $dst_port -j SNAT --to-source $extif_ip"

А на сервере B я использую fwmark и маршрутизацию на сервер A с помощью fwmark и iproute2:

ip rule  $command  fwmark 1 lookup 1
ip route $command  default via $rt_ip table 1

-

iptables -A PREROUTING -t mangle -p tcp -i $intif ! -s $intif_net --dport $port -j MARK --set-mark 1
iptables -A PREROUTING -t mangle -p tcp -i $intif -s $intif_ip --sport $port -j MARK --set-mark 1
iptables -A POSTROUTING -t mangle -p tcp -o $intif -s $intif_ip --sport $port -j MARK --set-mark 1

Играя с тремя приведенными выше правилами на сервере B, соединения застряли только в состоянии SYN_RECV, и в журнале не отправляется ACK в соединении, в некоторой части пакет теряется внутри, но я не знаю почему.

Любая помощь приветствуется, хорошего дня.

Я видел несколько ответов с неправильным использованием цели CONNMARK. Используйте цель MARK в цепочке калорифера, и она должна сработать.

Я решаю эту проблему с помощью CONNMARK на сервере B.

С использованием маскарада он работает быстро, но поскольку это веб-сервер, мне нужны исходные IP-адреса, и маскарад изменяет исходный IP-адрес на $ intif_ip моего сервера A, поэтому я не могу использовать маскарад.

Поскольку я не использую межсетевой экран с помощью iptables, я отбрасываю правило цепочки FOWRARD, поэтому у меня есть только правила DNAT и SNAT на сервере A.

iptables -A PREROUTING -t nat -i $extif -p tcp --dport $extif_port -d $extif_ip -j DNAT --to-destination $dst_ip:$dst_port"
iptables -A POSTROUTING -t nat -s $dst_ip -p tcp --sport $dst_port -j SNAT --to-source $extif_ip:$extif_port"

Затем на сервере B у меня возникла проблема, потому что он не маршрутизирует пакет, я пробую 1001 способ принудительно использовать $ intif_ip сервера A в качестве шлюза, но, наконец, я нашел его !.

Теория заключается в том, чтобы применить МАРКУ к пакету, и его поток попадает в IP шлюза, для которого установлена ​​метка fwmark, но маржа теряется при решении маршрутизации, поэтому я начинаю использовать CONNMARK для сохранения этой метки fwmark.

При использовании CONNMARK он все равно не работает, пока не будут зарегистрированы все цепочки. Поскольку я читал о CONNMARK, примеры восстанавливают правила в цепочке POSTROUTING mangle, но первая цепочка, которая проходит, - это OUTPUT mangle. Итак, я меняю CONNMARK на искажение цепочки OUTPUT и работает как шарм.

Это набор правил для сервера B.

iptables -A PREROUTING -t mangle ! -s $int_net -p tcp -i $int_if --dport $int_port -j MARK --set-mark 1
iptables -A PREROUTING -t mangle -m mark --mark 0x1 -j CONNMARK --save-mark
iptables -A OUTPUT -t mangle -j CONNMARK --restore-mark

И команды iproute2 (сервер B)

ip route flush table 1
ip rule add fwmark 1 lookup 1
ip route add default via $intif_ip_serverA table 1
ip route flush cache

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