Я пытаюсь выполнить следующее: у меня есть ящик со службой, прослушивающей фиктивный интерфейс (скажем, 172.16.0.1), порт udp 5555. Теперь я бы хотел принимать пакеты, которые поступают на интерфейсы eth0 ( 1.1.1.1:5555) и eth1 (2.2.2.2:5555) и пересылает их службе на фиктивном интерфейсе, а ответы возвращаются клиентам через тот же физический интерфейс, в который они вошли. Клиенты должны думать, что они разговаривают с 1.1.1.1:5555 или 2.2.2.2:5555. Я думаю, мне нужно сочетание правил iptables и маркировки пакетов, а также некоторые правила iproute (если это вообще возможно). Я пробовал перехватывать пакеты, приходящие от eth0 и eth1, udp-порта 5555, и отмечать их 1 и 2 соответственно и --save-mark в connmark. Затем я использовал DNAT для 172.16.0.1. Служба, похоже, получает пакеты. Теперь я не знаю, как сделать наоборот. Кажется, что для пакетов, исходящих из ящика, вы не можете ничего сделать до решения о маршрутизации, но это было бы место для восстановления меток и, таким образом, принятия решения о маршрутизации на их основе. Вот что у меня есть на данный момент:
iptables -t mangle -A PREROUTING -d 1.1.1.1 -p udp --port 5555 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -d 2.2.2.2 -p udp --port 5555 -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -d 1.1.1.1 -p udp --port 5555 -j CONNMARK --save-mark
iptables -t mangle -A PREROUTING -d 2.2.2.2 -p udp --port 5555 -j CONNMARK --save-mark
iptables -t nat -A PREROUTING -m mark --mark 1 -j DNAT --to-destination 172.16.0.1
iptables -t nat -A PREROUTING -m mark --mark 2 -j DNAT --to-destination 172.16.0.1
# What next?
Как я уже сказал, я даже не уверен, что это возможно. Чтобы дать немного предыстории, это старая установка OpenVPN, которую нельзя обновить (в противном случае я бы установил последнюю версию, которая изначально поддерживает множественную адресацию).
Спасибо за любую помощь.
Я думаю, что у меня это вроде заработало, вот что я сделал на случай, если это может быть полезно кому-то еще в будущем:
iptables -t mangle -A PREROUTING -i eth0 -d 1.1.1.1 -p udp --dport 5555 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth1 -d 2.2.2.2 -p udp --dport 5555 -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i eth0 -p udp --dport 5555 -j CONNMARK --save-mark
iptables -t mangle -A PREROUTING -i eth1 -p udp --dport 5555 -j CONNMARK --save-mark
# nat PREROUTING comes after mangle PREROUTING
iptables -t nat -A PREROUTING -m mark --mark 1 -j DNAT --to-destination 172.16.0.1
iptables -t nat -A PREROUTING -m mark --mark 2 -j DNAT --to-destination 172.16.0.1
# restore mark from packets originating from 172.16.0.1, as it triggers a new routing decision
iptables -t mangle -A OUTPUT -s 172.16.0.1 -p udp --sport 5555 -j CONNMARK --restore-mark
ip rule add prio 20 fwmark 1 lookup upstream0
ip rule add prio 21 fwmark 2 lookup upstream1
OpenVPN привязан только к 172.16.0.1 (назначен интерфейсу dummy0) и получает весь трафик, который клиенты отправляют на 1.1.1.1:5555 или 2.2.2.2:5555.
Вы пробовали просто использовать для этого прямой NAT (через цель REDIRECT)? Conntrack должен позаботиться о возвращаемых пакетах, нет необходимости в ручной маркировке.
Не понимаю, как это могло помочь:
Он перенаправляет пакет на саму машину, изменяя IP-адрес назначения на первичный адрес входящего интерфейса.
Входящие пакеты уже адресованы на адрес входящего интерфейса (т.е. 1.1.1.1 или 2.2.2.2). Или, может быть, я не понял, что вы имеете в виду, в таком случае извинения.
Я забыл добавить, если это решение кажется излишним, это потому, что я сначала попробовал более простой, то есть, когда служба прослушивала 0.0.0.0:5555 и использовала маркировку пакетов, но снова я не вижу, где восстановить маркировку локально -сгенерированные пакеты UDP.
Если я перейду на TCP, все будет работать правильно, даже без маркировки (не знаю, почему именно); Конечно, мне все еще нужны исходные правила маршрутизации, но тогда они «просто работают». Я, вероятно, переключусь на TCP, если я не смогу заставить его работать с использованием UDP (хотя TCP имеет худшую производительность). Я предполагаю, почему TCP работает, а UDP нет, потому что для пакетов UDP / IP не задан исходный адрес при выборе решения о маршрутизации, поэтому адрес «заполняется» после маршрутизации, которая выберет либо маршрут по умолчанию, либо или случайный маршрут в группе с несколькими путями, который не будет соответствовать исходному входящему интерфейсу (или будет, но только случайно). С другой стороны, пакеты TCP / IP уже имеют адрес источника (и это правильный), когда они достигают фазы маршрутизации, поэтому можно использовать правила маршрутизации на основе источника. Это всего лишь предположение, если кто-то заметит какую-то ошибку, я буду счастлив, что поправлюсь.
Спасибо.