Iptables не может NAT несколько IP-адресов
У меня есть сервер с двумя сетевыми адаптерами: eth0 и eth1. На этом сервере запущены два разных веб-сервера https: один слушает eth0 (172.29.49.112:8443), другой слушает eth1 (172.29.49.113:4443)
У меня есть правила NAT для iptables, которые успешно перенаправляют стандартный порт https (443) для обоих этих приложений, но правила iptables будут работать только для ОДНОГО из правил за раз (какое из них активируется, кажется, случайным при перезагрузке).
Вот правила, загруженные во время загрузки из rc.local (да, я знаю, что запускать правила брандмауэра из rc.local не рекомендуется):
#!/bin/sh -e
# setup port forwarding for gerrit and jenkins instances
su root -c "/sbin/iptables -t nat -A PREROUTING -i eth1 -d 172.29.49.113 -p tcp --dport 443 -j REDIRECT --to-port 4443"
su root -c "/sbin/iptables -t nat -A PREROUTING -i eth0 -d 172.29.49.112 -p tcp --dport 443 -j REDIRECT --to-port 8443"
# start gerrit (jenkins should auto-start as a service)
su gerrit2 -c "/home/gerrit2/gerrit/bin/gerrit.sh start"
exit 0
А вот вывод "iptables -t nat -L -n -v":
Chain PREROUTING (policy ACCEPT 14458 packets, 1446K bytes)
pkts bytes target prot opt in out source destination
6 360 REDIRECT tcp -- eth0 * 0.0.0.0/0 172.29.49.112 tcp dpt:443 redir ports 8443
0 0 REDIRECT tcp -- eth1 * 0.0.0.0/0 172.29.49.113 tcp dpt:443 redir ports 4443
Chain INPUT (policy ACCEPT 7436 packets, 874K bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 94 packets, 7050 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 94 packets, 7050 bytes)
pkts bytes target prot opt in out source destination
Как видите, других загружаемых правил нет.
Когда я запускаю только одно из двух правил, все работает правильно (для этого правила), но тогда, даже если я очищаю правила с помощью "iptables -t nat -F", я не могу включить другое правило (если я не перезагружаюсь - это кажется чтобы очистить вещи правильно).
Почему я пытаюсь это сделать? Я хочу, чтобы мои пользователи имели доступ к jenkins.servername.localnet и gerrit.servername.localnet, а не к jenkins.servername.localnet:4443 и т. Д. (Очевидно, что jenkins.servername.localnet разрешает 172.29.49.113 и.112 для gerrit).
В какой-то момент я подумал, что это могут быть веб-серверы jenkins/gerrit, прослушивающие все IP-адреса, вызывающие проблему. Но оба они настроены на прослушивание только по одному IP (jenkins - 172.29.49.113, gerrit - 172.29.49.112).
Это, вероятно, не требуется, но только в том случае, если это поможет - вот вывод ifconfig:
eth0 Link encap:Ethernet HWaddr 00:0c:29:99:52:e8
inet addr:172.29.49.112 Bcast:172.29.63.255 Mask:255.255.240.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:78588 errors:0 dropped:0 overruns:0 frame:0
TX packets:27399 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:16180230 (15.4 MiB) TX bytes:6329245 (6.0 MiB)
eth1 Link encap:Ethernet HWaddr 00:0c:29:99:52:f2
inet addr:172.29.49.113 Bcast:172.29.63.255 Mask:255.255.240.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:45058 errors:0 dropped:0 overruns:0 frame:0
TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3496805 (3.3 MiB) TX bytes:378 (378.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:1090 errors:0 dropped:0 overruns:0 frame:0
TX packets:1090 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:268078 (261.7 KiB) TX bytes:268078 (261.7 KiB)
Это невероятно расстраивает, так как это ПОЧТИ работает.
Я использую Debian Wheezy, Gerrit 2.10 и Jenkins 1.604.
Вещи, на которые я уже смотрел: CAP_NET_BIND_SERVICE - нелегкое решение, потому что gerrit инициализируется с помощью скрипта. authbind - это инструмент, который, вероятно, будет делать то, что я хочу, но я бы предпочел избегать еще одного слоя.
1 ответ
Теро Килканен указал мне правильное направление, хотя мне потребовалось некоторое время, чтобы выработать синтаксис. Похоже, что iptables был сбит с толку относительно того, по какому IP должны идти новые перенаправленные данные.
DNAT указывает целевой порт и целевой IP, поэтому теперь он работает правильно. Последние команды, которые я использовал, были следующими:
su root -c "/sbin/iptables -t nat -A PREROUTING -p tcp -m tcp -d 172.29.49.113 --dport 443 -j DNAT --to 172.29.49.113:4443"
su root -c "/sbin/iptables -t nat -A PREROUTING -p tcp -m tcp -d 172.29.49.112 --dport 443 -j DNAT --to 172.29.49.112:8443"
Примечание для wurtel и user1036745: установка имени входа с подстановочным знаком не имела значения. (тем более, что по умолчанию iptables в любом случае устанавливает подстановочный знак для входного имени, поэтому не нужно указывать "eth+") Но спасибо, что нашли время ответить в любом случае.