我不明白为什么 iptables 会阻止我的环回接口流量。
场景如下:
- 我将INPUT链的默认策略设置为DROP。
- 我允许流量到端口 8080。
- 我的过滤表如下所示(NAT 和 MANGLE 表为空):
#Make the default policy of the INPUT chain DROP
root@debian10:~#iptables -P INPUT DROP
#Allow traffic to port 8080
root@debian10:~#iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
#That how my filter tables looks like (NAT and MANGLE tables are empty)
root@debian10:~# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:http-alt
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
- 为了测试目的,我使用 Python3 启动了一个 SimpleHTTPServer。
root@debian10:~# python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/)
- 我从局域网中的另一台 PC 检查该端口是否打开,一切似乎正常。
root@moxie:~# nc -z -v 192.168.122.107 8080
Connection to 192.168.122.107 8080 port [tcp/http-alt] succeeded!
- 我尝试从本地主机检查端口是否打开,但网络过滤器丢弃了数据包。
root@debian10:~# nc -z -v localhost 8080
localhost [127.0.0.1] 8080 (http-alt) : Connection timed out
当我将 INPUT 链的默认策略改回 ACCEPT 时,netcat 能够成功从 localhost 连接到 127.0.0.1 的端口 8080。
我不明白为什么当我尝试连接到本地主机时网络过滤器会丢弃数据包。
答案1
您正在禁用本地案例的回复,从而阻止成功通信。让我们检查一下这两种情况。
从远程(工作案例):
查询包
源:192.168.122.2 端口 12345
目标 192.168.122.107 端口 8080过滤器/INPUT 规则匹配:数据包被接受
回复包
源:192.168.122.107 端口 8080
目标:192.168.122.2 端口 12345过滤器/OUTPUT 规则接受任何内容:数据包被接受
沟通是双向的
从本地系统到其自身(不起作用,将 OP 的本地主机替换为 192.168.122.107,是一样的):
查询包
源:192.168.122.107 端口 12345
目标:192.168.122.107 端口 8080- 首先发出:过滤器/输出接受任何东西:数据包被接受
- 数据包通过环回洛界面
- 收到回复:过滤器/输入匹配:数据包被接受
回复包
源:192.168.122.107 端口 8080
目标:192.168.122.107 端口 12345- 首先发出:过滤器/输出接受任何东西:数据包被接受
- 数据包通过环回洛界面
- 收到回复:过滤器/INPUT 与目标端口 12345 不匹配:数据包丢失
沟通不畅。
你需要一个状态防火墙当默认策略是丢弃已建立的流时,始终接受它们,因为无法提前猜到随机选择的源端口(该端口将成为回复中的目的地)。
在 Linux 的 Netfilter 框架中,这是由连接跟踪和iptables匹配将查询它的模块。这里可以使用iptables‘conntrack
匹配模块:
iptables -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
这样,任何来自已建立的流的数据包都会被自动接受。对于 OP 的环回情况,这将允许服务器成功回复自身,而无需提前知道初始查询的动态选择源端口。该RELATED
部分还允许接受相关错误,例如 ICMP 目标不可达(即使对于 TCP,它也是有用的,例如路径 MTU 发现)。
更简单的是,大多数设置,包括具有状态防火墙规则的设置,无论如何都会接受本地通信。您也可以改用(如果出于某种原因您不想激活连接跟踪子系统),或者另外:
iptables -A INPUT -i lo -j ACCEPT