今天发现个非常有趣的问题,即netstat并没有发现80端口,但外部却可以正常访问,而更奇怪的是使用127.0.0.1或localhost访问时提示’Connection refused’.

一般情况是本地可以访问,但外部是无法访问,这个一般是由于服务只开启了本地监听。比如下面这个服务:

tcp        0      0 127.0.0.1:18089             0.0.0.0:*                   LISTEN      28729/ssh

然而在本例中,却是相反,想到了iptables端口转发,大家可以去看下我的另一篇文章 《iptables简述》

iptables

端口转发是在NAT-PREROUTING进行的,从上图可以看出,内部访问是不走NAT-PREROUTING,这就解释了为何内部访问不了,那我们实际来看下iptables规则

volumio@volumio:~$ sudo iptables -t nat --list
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 3000

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

从上面可以看到PREROUTING链有一个规则,即转发http端口至3000端口

那iptables如何配置端口转发?

volumio@volumio:/volumio$ sudo iptables -t nat -A PREROUTING -p tcp --dport 10022 -j REDIRECT --to-port 22
volumio@volumio:~$ sudo iptables -t nat --list
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 3000
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:10022 redir ports 22

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

以上内容很清楚的解释了”外部可以访问而内部访问不了”,其实用的就是iptables的端口转发功能。