根本原因是tcp有连接状态可追踪而udp无连接,所有包均为独立事件;tcp依赖conntrack识别new/established状态精准放行,udp必须用--ctstate new,established或速率限制;udp更需防反射攻击,禁用reject改用drop,并配合hashlimit限流,同时调优udp接收缓冲区参数。

Linux防火墙对UDP和TCP的策略配置不能套用同一套规则,根本原因在于二者协议机制不同:TCP有连接状态可追踪,UDP无连接、每个包都是独立事件。照搬TCP思路配UDP规则,容易放行攻击流量或误拦正常请求。
连接状态判断方式不同
TCP依赖conntrack模块识别连接阶段(NEW/ESTABLISHED/RELATED),可精准放行合法会话:
- 允许新连接:
-m conntrack --ctstate NEW -p tcp --dport 22 -j ACCEPT - 仅放行已建立连接:
-m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
UDP没有“连接建立”过程,所有数据包默认被标记为NEW,无法用--ctstate NEW区分首次请求与后续交互。必须改用:
-
-m conntrack --ctstate NEW,ESTABLISHED(兼容性写法) - 或直接按端口+速率控制,避免依赖状态判断
防攻击策略侧重点不同
TCP天然具备握手和窗口机制,有一定自限流能力;UDP极易被用于反射放大攻击(如DNS/NTP洪水),必须主动限流:
- TCP服务(如Web):通常只需开放目标端口(80/443),靠三次握手自然抑制无效连接
- UDP服务(如DNS 53端口):必须叠加
hashlimit或limit模块,例如:-p udp --dport 53 -m hashlimit --hashlimit-above 50/sec --hashlimit-mode srcip -j ACCEPT - 禁用高危UDP端口(137/138/161/162):直接
-p udp -m multiport --dports 137,138,161,162 -j DROP
错误响应处理必须区分
UDP收到REJECT规则时会触发ICMP port-unreachable报文,该响应可能被攻击者利用为反射跳板;TCP的--reject-with tcp-reset则相对安全:
- UDP场景下,生产环境应统一使用
-j DROP,不返回任何响应 - 如需调试,可临时记录ICMP不可达事件:
-p icmp --icmp-type port-unreachable -j LOG --log-prefix "UDP-ICMP-DROP: " - 避免在UDP规则中出现
-j REJECT,尤其在公网暴露的服务上
内核参数调优方向不同
防火墙规则只是第一道防线,UDP和TCP还分别受不同内核缓冲区机制影响:
- UDP接收丢包常因
net.core.rmem_max过小导致缓冲区溢出,建议设为16777216(16MB) - TCP连接数受限于
net.ipv4.ip_local_port_range和net.ipv4.tcp_fin_timeout,可用connlimit限制单IP并发连接数 - UDP无连接数概念,但可通过
hashlimit限制单IP单位时间请求数,防止泛洪











