Debian虚拟机Iptables配置问题:局域网SSH连接受阻排查
解决Iptables启用INVALID包DROP规则后SSH无法连接的问题
我来帮你排查这个问题——你遇到的情况是VirtualBox NAT环境下,Iptables的INVALID包过滤规则误杀了合法的SSH连接,结合你的需求,我给你梳理原因和修复方案:
问题根源
当你启用-t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP时,VirtualBox的NAT地址转换过程会导致conntrack模块无法完整跟踪SSH连接的状态(比如初始SYN包的NAT转换记录未及时同步到后续ACK包),进而把合法的SSH包误标记为INVALID并丢弃。另外,你的原规则顺序也有问题:INPUT链默认DROP,但放行合法流量的规则放在了DDoS防护规则之后,可能导致正常流量被提前拦截。
修复方案
关键调整点
- 优化规则顺序:把允许本地回环、已建立连接、SSH的规则放在最前面,确保合法流量优先通过。
- SSH端口豁免INVALID检查:在执行INVALID包DROP前,先放行目标端口2222的新连接,避免NAT环境下的误判。
- 适配内部流量需求:保持OUTPUT链默认ACCEPT,满足“放行内部所有流量”的要求。
完整的正确Iptables脚本
#!/bin/bash # 初始化默认策略 sudo iptables -P INPUT DROP sudo iptables -P FORWARD DROP sudo iptables -P OUTPUT ACCEPT # 1: 允许本地回环接口流量(必须优先设置,避免内部服务异常) sudo iptables -A INPUT -i lo -j ACCEPT # 2: 允许已建立/相关的连接通过(放行合法的后续流量,比如SSH会话的交互包) sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # 3: 允许SSH端口2222的新连接 sudo iptables -A INPUT -p tcp --dport 2222 -m conntrack --ctstate NEW -j ACCEPT ### DDoS防护规则(放在放行规则之后,避免误拦合法流量) # 3.1: 先豁免SSH端口的新连接,避免NAT环境下被标记为INVALID sudo iptables -t mangle -A PREROUTING -p tcp --dport 2222 -m conntrack --ctstate NEW -j ACCEPT # 3.2: 安全启用DROP无效包规则 sudo iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP # 3.3: 拦截非SYN的新TCP连接 sudo iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP # 3.4: 拦截异常MSS值的SYN包 sudo iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP # 3.5: 拦截伪造的TCP标志位包 sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP # 3.6: 可选:保留必要ICMP(如需ping虚拟机则启用,否则取消注释DROP) # sudo iptables -t mangle -A PREROUTING -p icmp -j DROP # 3.7: 拦截分片包 sudo iptables -t mangle -A PREROUTING -f -j DROP # 3.8: 限制单IP并发连接数 sudo iptables -A INPUT -p tcp -m connlimit --connlimit-above 111 -j REJECT --reject-with tcp-reset # 3.9: 限制RST包速率 sudo iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT sudo iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP # 3.10: 限制单IP每秒新建TCP连接数(SSH已豁免,不影响正常连接) sudo iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT sudo iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP ### SSH暴力破解防护 sudo iptables -A INPUT -p tcp --dport 2222 -m conntrack --ctstate NEW -m recent --set sudo iptables -A INPUT -p tcp --dport 2222 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP ### 端口扫描防护 sudo iptables -N port-scanning sudo iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN sudo iptables -A port-scanning -j DROP # 持久化规则(重启后生效) sudo mkdir -p /etc/iptables sudo bash -c "iptables-save > /etc/iptables/rules.v4" echo "Iptables规则配置完成!已启用INVALID包过滤,同时保证SSH可正常连接"
验证方法
- 执行脚本后,从外部局域网尝试连接SSH:
ssh -p 2222 your_username@10.0.2.3 - 检查Iptables规则是否生效:
sudo iptables -L -n -v - 若仍有问题,可临时清空规则排查:
sudo iptables -F && sudo iptables -t mangle -F
内容的提问来源于stack exchange,提问作者fassn




