iptables端口REDIRECT规则本地生效但外部无法访问的问题求助
iptables端口REDIRECT规则本地生效但外部无法访问的问题求助
你遇到的问题核心是iptables链的作用范围搞混了——你当前加的OUTPUT链规则只负责处理本地发起的请求,而外部过来的流量根本走不到这个链上,自然无法被转发到23006端口。
解决方法:添加PREROUTING链的转发规则
外部访问的流量会先经过PREROUTING链(nat表),所以你需要给这个链加一条REDIRECT规则,把443端口的外部请求转发到23006:
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 23006
加上这条规则后,外部访问443端口的流量就会被iptables转发到你的23006端口了,而且后端nginx能直接拿到客户端的真实IP(这比socat的方式更优,不会丢失源IP)。
同时保留本地访问能力
如果你还需要本地访问127.0.0.1:443也能转到23006,那之前的OUTPUT链规则可以保留,两条规则是互补的:
# 外部流量转发 sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 23006 # 本地流量转发 sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 443 -j REDIRECT --to-port 23006
别忘了保存规则(防止重启失效)
大多数Linux发行版重启后iptables规则会清空,所以要把当前规则保存下来:
- Debian/Ubuntu系:
sudo iptables-save > /etc/iptables/rules.v4 - RHEL/CentOS系:
sudo iptables-save > /etc/sysconfig/iptables
补充说明
你用socat能成功是因为socat直接监听了443端口,主动接收外部流量并转发,但它相当于做了一层代理,所以后端服务器看不到真实客户端IP;而iptables的REDIRECT是在内核层面修改端口,不会改变源IP,nginx能直接获取到客户端的真实地址,这更适合你的场景。
另外,你测试时nginx返回400是因为你用HTTP访问了HTTPS端口,这个是正常的——如果你的nginx配置的是HTTPS监听23006,那外部访问443时也应该用https://开头的URL,否则就会触发这个错误。
备注:内容来源于stack exchange,提问作者Aario
相关产品推荐
相关产品推荐

