技术解析

关于 iptables 的问题
0
2021-07-05 07:17:16
idczone

开机成功执行脚本 iptables.sh ,脚本内容如下:
iptables -F
iptables -X
iptables -Z
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

这里并未开启 SSH 端口,为何可以 SSH 连接?哪里出问题了吗?


是不是没设置重启后,规则不失效。

iptables-save 有什么输出?

INPUT ACCEPT?
哈哈

不好意思,看错

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
这句决定了已建立的连接不会断开

有生效的,去掉下面两条,再开机执行脚本,就无法连接了
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
执行 iptables-save -t filter 的结果如下
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
但是默认是 DROP 的,没有开放端口,应该是无法建立连接才对

那么规则应该是符合预期的, 估计 iptables 模块就没有生效;

你不会是从本地连吧……
本地连走 lo 当然不受限制

去掉最后两条规则就连不上了。。。
不是从本地连

1. 又不是路由器, FORWARD 链直接 drop 就好
2. 如果是本机连接,直接匹配 INPUT 链的第一条规则走 lo 了
3. 如果不是本地连接,已经连接的不会受影响,连接可能建立在 iptables 服务开启之前或者以上命令执行之前。
4. 用开机脚本也太蛋疼了吧,最好直接修改配置文件

那你确定一下到底是那一条的作用啊
去掉其中一条试试看




是下面那条的 ESTABLISHED 起作用

楼上不说了吗,已建立的链接不会断开。

之前在 vps 测试过,好像去掉
-A INPUT -i lo -j ACCEPT
就可以生效。





怀疑是 vps 上装的 net_speeder 有问题,但应该不是后门,跟它的发包机制有关,规则是没问题的
具体表现为保持上面的规则不变,关闭 net_speeder , SSH 怎么也连接不上,开启 net_speeder , SSH 就连上了,有条件的请帮忙测试下

这不是很正常吗?
你的 input 都 accept 了呀
-A INPUT -j REJECT --reject-with icmp-host-prohibited
你加上这句试试

默认是 DROP 的, iptables -P INPUT DROP
在主贴的规则基础上加上 16 楼这条,关闭 net_speeder,SSH 连接不上,开启 net_speeder,SSH 连上了


说的做法可以解决你的问题,但问题不是他所说的那样。
iptables 对 ESTABLISHED 的定义并不是连接已经完成握手,而是之前见过相同连接的包。 netspeeder 对入站的连接也会双倍。第一个包确实 drop 了,第二个包 iptable 已经见过,所以允许了。然而因为是复制包,所以两个包中都是 syn ,任何一个都可以建立连接。
如果用 reject 的话,因为远端机器已经收到 rst 包,所以连接终止。即使你的机器返回 synack ,对方也不会处理。但是如果有人知道你是这样做的话,还是很容易绕过这个的。因为他只要 drop rst 包就行。
靠谱的解决也很简单:不要双倍 syn 就好了
'tcp[tcpflags] & tcp-syn == 0'
不过这样不能过滤 ipv6 ,偷懒不想查了,你要用的话自己查一下 tcpdump 怎么 dump ipv6 的 syn ,逻辑反过来就行。

-A INPUT -m state --state RELATED,ESTABLISHED ! --syn -j ACCEPT
这样应该也可以

命令不加-p tcp 会报错,即应该是 iptables -A INPUT -m state --state RELATED,ESTABLISHED -p tcp ! --syn -j ACCEPT ,执行后开启 net_speeder 依旧可以 SSH 连接。。。看来 net_speeder 有个很隐蔽的坑

以前没有接触过 net_speeder , 刚才看了一下 net_speeder 的原理, 我理解问题是出在 net_speeder 的机制上, 如果说错了请大家打脸。
net speeder 原理就是把网卡收到或者发出去的包根据规则过滤出来复制一份再写入协议栈;
在你这个场景下, 收到的 ssh syn 包会被复制。 原始的 syn 包经过协议栈, 而复制的包是通过了的。
原因就是复制出来的包是本地复制的, 所以再进入协议栈时是通过 loopback 进入;
所以先匹配到 iptables -A INPUT -i lo -j ACCEPT
而之后的包无论是匹配 state 还是匹配 loopback interface 都会被放过;

应该是这样没错,复制的包被当做本地的包处理了
另外基于 iptables 的 UFW 也有此问题 https://www.v2ex.com/t/244523



把 iptables -A INPUT -i lo -j ACCEPT 分拆为两条
iptables -A INPUT -i lo -p tcp ! --syn -j ACCEPT
iptables -A INPUT -i lo -p udp -j ACCEPT
搞定了,哈哈

恭喜,但是你这样会有个问题,就是无法再访问本地服务了。拒掉前先放过本地流量
-A INPUT -i lo -p tcp --src 127.0.0.1/8 -j ACCEPT
-A INPUT -i lo -p tcp ! --syn -j ACCEPT

看了下 net_speeder ,感觉并没有使用这个的必要啊

没用。我试过了,你这招照样能连上

我现在直接把这条 iptables -A INPUT -i lo -j ACCEPT 去掉,然后再配合协议( tcp/udp )或端口(--sport/--dport )开白名单,毕竟不是全部流量都需要 net_speeder

说错,不是所有流量都需要 lo

https://www.v2ex.com/t/251740

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服