. У меня странный случай использования, когда модулю, работающему в Azure Kubernetes, необходимо направлять трафик от определенных портов к определенным целям через выделенный VPN-туннель. Но эти цели являются частными IP-адресами и, следовательно, могут иметь один и тот же IP-адрес для разных целей. Модуль помимо маршрутизации также является сервером OpenVPN, к которому подключаются цели. Пример:
Сообщения, поступающие на порт 10, маршрутизируются на IP 10.0.0.4:80 через VPN IP 10.118.0.2
, и в то же время мы можем иметь:
Сообщения, поступающие на порт 20, маршрутизируются на IP 10.0.0.4:80 через VPN IP 10.118.0.3
Несмотря на одинаковый целевой IP-адрес, это разные машины. Итак, чтобы достичь этого, я придумал следующее возможное решение:
/sbin/iptables --table mangle --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "10" --jump MARK --set-mark "10"
/sbin/iptables --table nat --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "10" --jump DNAT --to-destination "10.0.0.4:80"
/sbin/ip rule add prio "10" from all fwmark "10" lookup "10"
/sbin/ip route add "10.0.0.4" via "10.118.0.2" table 10
Это позволило бы работать обеим коммуникациям одновременно с маршрутизацией трафика на правильную машину. Но я вижу, что пакеты отмечены в таблице искажений. Но тогда никогда не добраться до таблиц NAT. Я выяснил, что это связано с rt_filter. Подробнее об этом ниже. Сейчас он работает и выглядит так:
/sbin/iptables --table nat --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "10" --jump DNAT --to-destination "10.0.0.4:80"
/sbin/ip route add "10.0.0.4" via "10.118.0.2"
Однако, если второй маршрут установлен, как в первом примере, команда будет выглядеть так:
/sbin/iptables --table nat --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "20" --jump DNAT --to-destination "10.0.0.4:80"
/sbin/ip route add "10.0.0.4" via "10.118.0.3"
Это создаст другой маршрут в главном Таблица маршрутов для той же цели. Но тогда пользователь при доступе к 192.168.0.100 может быть перенаправлен на машину, подключенную к 10.118.0.3 или 10.118.0.2.
Помимо этих правил, для всех из них это всегда было включено, чтобы разрешить трафику возвращаться к интерфейсу tap0, где идет связь с 10.118.0.X:
iptables -t nat -A POSTROUTING -o tap0 -j MASQUERADE
К сожалению, я не могу знать источник пользователя IP, иначе было бы просто решить. Исходный IP-адрес для любого сообщения, поступающего на этот порт, всегда будет одним и тем же, потому что сообщение должно проходить через другую службу, которая маскирует реальный исходный IP-адрес.
В других разделах я видел, что для маркировки входящих пакетов в контейнере / модуле мне нужно отключить rt_filter. Однако я не могу этого сделать, он говорит, что это файловая система только для чтения, и я не знаю, можно ли изменить это в кластерах Azure Kubernetes.
Есть ли другое решение, кроме маркировки пакетов? Или чего-то еще не хватает в маркировке пакетов?
Итак, я наконец нашел решение. Проблема заключалась в искажении пакетов в PREROUTING. Коверкая пакеты в POSTROUTING (то есть на выходе из eth0), они затем смогли вернуться из tap0 в eth0, а затем к клиенту. Конечный результат выглядит следующим образом:
/sbin/iptables --table mangle --insert POSTROUTING --destination "192.168.0.100" -o eth0 -p tcp --dport "10" --jump MARK --set-mark "10"
/sbin/iptables --table nat --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "10" --jump DNAT --to-destination "10.0.0.4:80"
/sbin/ip rule add prio "10" from all fwmark "10" lookup "10"
/sbin/ip route add "10.0.0.4" via "10.118.0.2" table 10