![iptables 端口转发(预路由端口 80)和防火墙无法协同工作](https://linux22.com/image/629774/iptables%20%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91%EF%BC%88%E9%A2%84%E8%B7%AF%E7%94%B1%E7%AB%AF%E5%8F%A3%2080%EF%BC%89%E5%92%8C%E9%98%B2%E7%81%AB%E5%A2%99%E6%97%A0%E6%B3%95%E5%8D%8F%E5%90%8C%E5%B7%A5%E4%BD%9C.png)
我已经阅读了很多关于这个主题的文章和答案,并且与 Linode 支持人员进行过讨论,但似乎没有人能够回答我的确切问题。
看起来很简单 - 我想使用 iptables 防火墙来限制对除 22、80 和 443 之外的所有端口的访问。Linode 在这里有一篇很棒的文章:https://library.linode.com/securing-your-server#sph_creating-a-firewall我照原样使用了他们的防火墙规则。防火墙运行良好。
我还想预先路由一些端口,因为这是一个 nodejs 应用程序。所以我使用了:
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 3000
如果没有防火墙规则,这些规则仍然有效。事实上,我现在正在使用它们,但我不得不关闭防火墙。
如果我添加防火墙规则,它PREROUTING
就会停止工作。如果我将活动的 iptables 规则保存到文件中以供查看,防火墙(过滤规则)和PREROUTING
(nat 规则)都存在,但只有防火墙规则有效。请参见此处:
# Generated by iptables-save v1.4.18 on Wed Mar 26 02:40:04 2014
*security
:INPUT ACCEPT [1606:135329]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1206:144815]
COMMIT
# Completed on Wed Mar 26 02:40:04 2014
# Generated by iptables-save v1.4.18 on Wed Mar 26 02:40:04 2014
*raw
:PREROUTING ACCEPT [1620:139613]
:OUTPUT ACCEPT [1206:144815]
COMMIT
# Completed on Wed Mar 26 02:40:04 2014
# Generated by iptables-save v1.4.18 on Wed Mar 26 02:40:04 2014
*nat
:PREROUTING ACCEPT [4:248]
:INPUT ACCEPT [6:376]
:OUTPUT ACCEPT [12:728]
:POSTROUTING ACCEPT [12:728]
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 3000
COMMIT
# Completed on Wed Mar 26 02:40:04 2014
# Generated by iptables-save v1.4.18 on Wed Mar 26 02:40:04 2014
*mangle
:PREROUTING ACCEPT [1620:139613]
:INPUT ACCEPT [1606:135329]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1206:144815]
:POSTROUTING ACCEPT [1206:144815]
COMMIT
# Completed on Wed Mar 26 02:40:04 2014
# Generated by iptables-save v1.4.18 on Wed Mar 26 02:40:04 2014
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A INPUT -j DROP
-A FORWARD -j DROP
-A OUTPUT -j ACCEPT
COMMIT
# Completed on Wed Mar 26 02:40:04 2014
如果我使用iptables -F
,它将仅刷新防火墙(过滤器)规则,并且PREROUTING
将重新开始工作。所以这肯定是冲突。规则块的顺序似乎并不重要,因为无论我将规则保存到 iptables 的顺序如何,这(上面)都是 iptables 的标准输出。
对我来说,这似乎是以下两件事之一:
PREROUTING
还具有 ACCEPT 规则的端口可能意味着预路由被忽略- 我所在
PREROUTING
的端口在技术上已被阻止(但我认为这就是“PRE”出现的原因)
有人知道吗?
谢谢!
保罗
答案1
在 PREROUTING 之后,本地数据包将进入本地过滤器,并在那里被丢弃(您的情况 2)。
因此您只需要在 iptables 中允许传入流量到这些端口:
iptables -A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 3000 -j ACCEPT
由于您将 http(s) 流量从 80/443 重定向到 8080/3000,就像后者的端口是开放的并且暴露在互联网上,所以与外界没有区别,也没有进一步的安全隐患。