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+") Но спасибо, что нашли время ответить в любом случае.

Другие вопросы по тегам