Здесь много вопросов о настройках iptables DNAT / SNAT, но я не нашел ни одного, которое решило бы мою текущую проблему.
У меня есть службы, привязанные к IP-адресу eth0 (например, 192.168.0.20), и у меня также есть IP-адрес на eth0: 0 (192.168.0.40), который используется совместно с другим сервером. Активен только один сервер, поэтому этот интерфейс псевдонима появляется и исчезает в зависимости от того, какой сервер активен. Чтобы получить трафик, принятый службой, используется правило DNAT для изменения IP-адреса назначения.
iptables -t nat -A PREROUTING -d 192.168.0.40 -p udp --dport 7100 -j DNAT --to-destination 192.168.0.20
Я также хочу, чтобы весь исходящий трафик от этой службы выглядел как исходящий с общего IP-адреса, чтобы ответные ответы работали в случае переключения между активным резервным и резервным.
iptables -t nat -A POSTROUTING -p udp --sport 7100 -j SNAT --to-source 192.168.0.40
Моя проблема в том, что правило SNAT не всегда выполняется. Входящий трафик вызывает запись отслеживания соединения, подобную этой.
[root]# conntrack -L -p udp
udp 17 170 src=192.168.0.185 dst=192.168.0.40 sport=7100 dport=7100 src=192.168.0.20 dst=192.168.0.185 sport=7100 dport=7100 [ASSURED] mark=0 secmark=0 use=2
это означает, что цепочка POSTROUTING не запускается, и исходящий трафик уходит с реальным IP-адресом в качестве источника.
Я думаю, что могу настроить правило NOTRACK в необработанной таблице, чтобы предотвратить отслеживание для этого номера порта, но есть ли лучший или более эффективный способ заставить эту работу?
Изменить - Альтернативный вопрос: есть ли способ (в CentOS / Linux) иметь интерфейс, который можно привязать, но не использовать, например, подключить к сети или отсоединить, когда общий IP-адрес переключается между серверами?
Я нашел решение своей проблемы.
Используя параметр ядра net.ipv4.ip_nonlocal_bind=1
, Я могу заставить свою службу привязаться к адресам, которые еще не существуют.
При подключении интерфейса eth0: 0 трафик принимается службой. ARP и т. Д. Обрабатываются ucarp / network. При этом правила DNAT / SNAT вообще не нужны.
Я могу предложить две альтернативы, вы можете выбрать одну из них или свою собственную.
Вы можете настроить свою службу так, чтобы она прослушивала групповой адрес и, таким образом, полностью избегала правила DNAT. Затем к исходящим пакетам будет применено правило SNAT.
Или, в зависимости от того, какое решение высокой доступности вы используете, вы можете настроить его так, чтобы ваша служба слушала плавающий IP-адрес (192.168.0.40) по мере его миграции.
Не связанное с этим примечание, но такого рода неприятностей нет в OpenBSD CARP. С CARP виртуальный IP-адрес настроен на всех узлах, но активен только на одном. Это, конечно, означает, что ваша служба может прослушивать виртуальный IP-адрес на всех узлах.
Это не очень красиво, но вы можете настроить виртуальный IP на всех узлах (и даже поднять его) и использовать arptables
чтобы отключить ARP-ответы или объявления для этого IP-адреса. Затем вы можете настроить ucarp включить или отключить правило ARP, когда узел станет ведущим или ведомым.