У меня 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
Надеюсь, это поможет вашим измученным умам решить эту странную проблему. хорошего дня.