Назад | Перейти на главную страницу

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 - это инструмент, который, вероятно, будет делать то, что я хочу, но я бы предпочел избегать еще одного уровня.

Теро Килканен указал мне в этом правильном направлении, хотя мне потребовалось время, чтобы проработать синтаксис. Похоже, что 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 +" не нужно) Но спасибо, что все равно нашли время, чтобы ответить.