最近在维护BZETU服务器(腾讯云轻量应用服务器)时,遇到了一个诡异的网络问题:v2ray服务正常监听端口,安全组也已放行,但手机客户端始终无法连接,日志报 i/o timeout。
经过反复排查,最终发现罪魁祸首不是安全组,而是腾讯云主机安全(云镜/Aegis)在服务器iptables中植入的NFQUEUE组件。这篇文章记录了完整的排查过程和解决方案。
问题现象
服务器上v2ray使用vless+reality协议,端口8444,配置一切正常:
$ ss -tlnp | grep 8444
LISTEN 0 128 [::]:8444 users:(("v2ray",pid=29919,fd=6))
手机Clash Meta客户端报错:
[TCP] dial Proxy (match Match/) --> youtubei.googleapis.com:443 error: www.bzetu.com:8444 connect error: connect failed: dial tcp 43.135.136.107:8444: i/o timeout
排查过程
1. 安全组检查
首先检查腾讯云控制台的安全组规则,确认8444端口已放行(ALL协议,来源0.0.0.0/0)。但外部测试仍然超时:
$ curl -v --connect-timeout 5 telnet://43.135.136.107:8444 * Trying 43.135.136.107:8444... * Connection timed out after 5015 milliseconds curl: (28) Connection timed out
这说明问题不在安全组层面。
2. 服务器内部检查
在服务器内部连接8444端口完全正常:
# TCP连接正常 $ bash -c 'echo > /dev/tcp/127.0.0.1/8444' && echo OK OK # v2ray日志显示有流量 $ journalctl -u v2ray --no-pager -n 10 # youtubei.googleapis.com:443 等YouTube流量
这说明v2ray本身工作正常,问题出在网络层面的某个包过滤环节。
3. iptables链分析
检查iptables的INPUT链,发现了问题所在:
$ iptables -L INPUT -n --line-numbers num target prot source destination 1 YJ-FIREWALL-INPUT all -- 0.0.0.0/0 0.0.0.0/0 2 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x17/0x02 match-set YJ-GLOBAL-INBLOCK src 3 NFQUEUE all -- 0.0.0.0/0 0.0.0.0/0 NFQUEUE num 0
这里有三层过滤:
- YJ-FIREWALL-INPUT:云镜的IP封禁链,包含1800+条针对恶意IP的规则
- YJ-GLOBAL-INBLOCK:自动封禁扫描IP的SYN包
- NFQUEUE:云镜的实时包检测组件,拦截所有入站流量
关键在于第3条 NFQUEUE。这是腾讯云主机安全(Aegis/云镜)的核心组件,它通过NFQUEUE机制对每个入站包做实时分析。我们的8444端口不在它的白名单中,所以被静默丢弃了。
根因总结
腾讯云有两层独立的防火墙:
| 层级 | 名称 | 位置 | 8444状态 |
|---|---|---|---|
| 云层 | 安全组(Security Group) | 腾讯云控制台 | ✅ 已放行 |
| 主机层 | 云镜 NFQUEUE | 服务器iptables | ❌ 被拦截 |
安全组放行只意味着流量能到达服务器网卡,但服务器内部的云镜Agent又用iptables做了二次过滤。
解决方案
在iptables的INPUT链最前面插入一条ACCEPT规则,让8444端口的包在到达云镜的NFQUEUE之前就被放行:
# 放行8444端口(必须在链最前面) iptables -I INPUT 1 -p tcp --dport 8444 -j ACCEPT
执行后验证:
$ iptables -L INPUT -n --line-numbers num target prot source destination 1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8444 2 YJ-FIREWALL-INPUT all -- 0.0.0.0/0 0.0.0.0/0 3 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x17/0x02 match-set YJ-GLOBAL-INBLOCK src 4 NFQUEUE all -- 0.0.0.0/0 0.0.0.0/0 NFQUEUE num 0
外部立即可以连通:
$ curl -v --connect-timeout 5 telnet://43.135.136.107:8444 * Trying 43.135.136.107:8444... * Connected to 43.135.136.107 port 8444
持久化
iptables规则重启后会丢失,需要持久化:
echo 'iptables -I INPUT 1 -p tcp --dport 8444 -j ACCEPT' >> /etc/rc.local chmod +x /etc/rc.local
排查技巧
当遇到端口不通但服务正常的情况,按以下顺序排查:
- 确认服务在监听:
ss -tlnp | grep PORT - 确认本地可连接:
bash -c 'echo > /dev/tcp/127.0.0.1/PORT' - 确认安全组已放行(腾讯云控制台)
- 检查iptables:
iptables -L INPUT -n --line-numbers— 看是否有NFQUEUE或DROP规则 - 从外部测试:
curl -v --connect-timeout 5 telnet://IP:PORT
如果前4步都正常但外部不通,大概率是iptables中有隐藏的过滤规则。腾讯云主机安全的NFQUEUE是最常见的元凶。