У меня есть сервер (serv05) на работе с общедоступным IP-адресом, на котором размещены два гостя KVM - vtest1 и vtest2 - в двух разных частных сетях - 192.168.122.0 и 192.168.100.0 - соответственно, таким образом:
[root@serv05 ~]# ip -o addr show | grep -w inet
1: lo inet 127.0.0.1/8 scope host lo
2: eth0 inet xxx.xxx.xx.197/24 brd xxx.xxx.xx.255 scope global eth0
4: virbr1 inet 192.168.100.1/24 brd 192.168.100.255 scope global virbr1
6: virbr0 inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
#
[root@serv05 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.100.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr1
xxx.xxx.xx.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
0.0.0.0 xxx.xxx.xx.62 0.0.0.0 UG 0 0 0 eth0
Я также настроил IP FORWARDing и Masquerading следующим образом:
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
iptables --append FORWARD --in-interface virbr0 -j ACCEPT
Все работает до этого момента. Если я хочу удаленный доступ vtest1 (или vtest2) сначала я ssh на serv05, а затем оттуда ssh на vtest1. Есть ли способ настроить переадресацию портов, чтобы vtest1 можно получить доступ напрямую из внешнего мира? Вот что мне, наверное, нужно настроить:
external_ip (tcp port 4444) -> DNAT -> 192.168.122.50 (tcp port 22)
Я знаю, что это легко сделать с помощью маршрутизатора SOHO, но не могу понять, как это сделать в системе Linux.
Теперь я заставил ssh прослушивать оба порта:
[root@serv05 ssh]# netstat -tulpn | grep ssh
tcp 0 0 xxx.xxx.xx.197:22 0.0.0.0:* LISTEN 5092/sshd
tcp 0 0 xxx.xxx.xx.197:4444 0.0.0.0:* LISTEN 5092/sshd
и порт 4444 разрешено правилами iptables:
[root@serv05 sysconfig]# grep 4444 iptables
-A PREROUTING -i eth0 -p tcp -m tcp --dport 4444 -j DNAT --to-destination 192.168.122.50:22
-A INPUT -p tcp -m state --state NEW -m tcp --dport 4444 -j ACCEPT
-A FORWARD -i eth0 -p tcp -m tcp --dport 4444 -j ACCEPT
Но я получаю В соединении отказано:
maci:~ santa$ telnet serv05 4444
Trying xxx.xxx.xx.197...
telnet: connect to address xxx.xxx.xx.197: Connection refused
telnet: Unable to connect to remote host
Есть идеи, что мне еще не хватает?
Я удалил третий интерфейс, virbr1, из iptables просто сделайте вывод короче.
[root@serv05 sysconfig]# iptables -vL -n
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
108 8112 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
189 42273 ACCEPT all -- eth0 * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * xxx.xxx.xx.0/24 0.0.0.0/0 state NEW tcp dpt:21
0 0 ACCEPT tcp -- * * 192.168.122.0/24 0.0.0.0/0 state NEW tcp dpt:21
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:4444
0 0 ACCEPT tcp -- * * xxx.xxx.xx.0/24 0.0.0.0/0 state NEW tcp dpt:80
0 0 ACCEPT tcp -- * * 192.168.122.0/24 0.0.0.0/0 state NEW tcp dpt:80
2 64 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 state RELATED,ESTABLISHED
0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
0 0 ACCEPT tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:4444
Chain OUTPUT (policy ACCEPT 57 packets, 11124 bytes)
pkts bytes target prot opt in out source destination
То же самое и здесь, virbr1 намеренно удален из вывода.
[root@serv05 sysconfig]# iptables -t nat -vL -n
Chain PREROUTING (policy ACCEPT 611 packets, 105K bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:4444 to:192.168.122.50:22
Chain POSTROUTING (policy ACCEPT 4 packets, 344 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
0 0 MASQUERADE tcp -- * * 192.168.100.0/24 !192.168.100.0/24 masq ports: 1024-65535
0 0 MASQUERADE udp -- * * 192.168.100.0/24 !192.168.100.0/24 masq ports: 1024-65535
0 0 MASQUERADE all -- * * 192.168.100.0/24 !192.168.100.0/24
Chain OUTPUT (policy ACCEPT 4 packets, 344 bytes)
pkts bytes target prot opt in out source destination
SSH больше не слушает порт 4444:
[root@serv05 sysconfig]# netstat -tulpn | grep ssh
tcp 0 0 xxx.xxx.xx.197:22 0.0.0.0:* LISTEN 15231/sshd
Порядок ВПЕРЕД фиксирован:
[root@serv05 sysconfig]# iptables -vL -n
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
[ .... ]
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 state RELATED,ESTABLISHED
0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:4444
1 64 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 5 packets, 612 bytes)
pkts bytes target prot opt in out source destination
но в соединении все еще отказано:
maci:~ santa$ telnet serv05 4444
Trying xxx.xxx.xx.197...
telnet: connect to address xxx.xxx.xx.197: Connection refused
telnet: Unable to connect to remote host
Есть ли еще какие-то серые зоны, которые нужно покрыть?
Вам нужно правило NAT (для направления трафика) и обычное правило брандмауэра (для разрешения).
Первый будет выглядеть примерно так
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 4444 -j DNAT --to-destination 192.168.122.50:22
Последний будет выглядеть примерно так
iptables -A FORWARD -i eth0 -p tcp --dport 4444 -j ACCEPT
Вам решать, чтобы они попали в нужный момент в существующей PREROUTING
и FORWARD
цепочки, и, кроме того, вам может потребоваться второе правило брандмауэра, чтобы разрешить обратную половину этих подключений, если у вас еще нет общего ACCEPT
для ESTABLISHED
пакеты.
редактировать: the порядок ваших правил чрезвычайно важен. Правильное правило в неправильном месте никуда не годится. Не могли бы вы заменить вывод grep выше на результат iptables -L -n -v
и iptables -t nat -L -n -v
? И если вы хотите, чтобы порт 4444 был перенаправлен, не запустите локальный sshd, также связанный с этим портом.
Редактировать 2: а вот твоя проблема. ACCEPT, который вы добавили в цепочку FORWARD, - это строка 7, но строка 4 уже явно запретила весь ранее не разрешенный трафик отовсюду (*
) к virbr0
. Вам необходимо подготовиться к добавленной вами очереди. перед строка 4, возможно, добавив правило с
iptables -I FORWARD 4 -i eth0 -p tcp --dport 4444 -j ACCEPT
который вставит его в строку 4, заменив текущую строку 4 на строку 5 (и так далее).
Что касается текущего sshd, я имею в виду то, что я сказал: у вас не должно быть демона, привязанного к порту 4444, если вы пытаетесь перенаправить этот порт. Меня не волнует, к каким еще портам он привязан, только то, что 4444 - плохая идея.
Редактировать 3: машина, с которой вы это тестируете, находится вне системы serv05, да? И (после очень тяжелого дня установки Fedora 16 на несколько коробок), боюсь, вы правы, не могли бы вы поставить сопоставимый ACCEPT
правило для 4444 в цепочке INPUT, стараясь получить его перед какие-либо ОТКЛОНЕНИЯ?