У меня есть сервер с двумя сетевыми адаптерами: 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 - это инструмент, который, вероятно, будет делать то, что я хочу, но я бы предпочел избегать еще одного уровня.
Теро Килканен указал мне в этом правильном направлении, хотя мне потребовалось время, чтобы проработать синтаксис. Похоже, что 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: установка входного nic с подстановочным знаком не имеет значения. (тем более, что по умолчанию iptables в любом случае устанавливает подстановочный знак для входного nic, поэтому указывать "eth +" не нужно) Но спасибо, что все равно нашли время, чтобы ответить.