我有一台具有公共 IP 的工作服务器(serv05),分别在两个不同的私有网络 - 192.168.122.0 和 192.168.100.0 - 中托管两个 KVM 客户机 - vtest1 和 vtest2,方式如下:
[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 转发和伪装:
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
iptables --append FORWARD --in-interface virbr0 -j ACCEPT
到目前为止一切正常。如果我想远程访问测试1(或 vtest2)首先我通过 ssh 连接到 serv05,然后从那里通过 ssh 连接到 vtest1。有没有办法设置端口转发,以便测试1可以直接从外界访问吗?这是我可能需要设置的:
external_ip (tcp port 4444) -> DNAT -> 192.168.122.50 (tcp port 22)
我知道使用 SOHO 路由器可以轻松实现这一点但不知道如何在 Linux 上实现这一点。
更新:1
现在我已经让 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
知道我还缺少什么吗?
更新:2
我删除了第三个接口,病毒1,来自 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
同样的事情也在这里发生,病毒1被有意地从输出中删除。
[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
更新:3
SSH 不再监听端口 4444:
[root@serv05 sysconfig]# netstat -tulpn | grep ssh
tcp 0 0 xxx.xxx.xx.197:22 0.0.0.0:* LISTEN 15231/sshd
FORWARD 顺序是固定的:
[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
还有其他灰色区域需要覆盖吗?
答案1
您需要一个 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
。
编辑: 这命令iptables -L -n -v
规则的制定非常重要。在错误的地方使用正确的规则不会有任何好处。您能用和的结果替换上面的 grep 输出吗iptables -t nat -L -n -v
?如果您希望转发端口 4444,不运行一个也绑定到该端口的本地 sshd。
编辑2:这就是你的问题。你在 FORWARD 链中添加的 ACCEPT 是第 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
在 INPUT 链中为 4444 也设置一个类似的规则吗?小心一点前有任何拒绝吗?