Linux 防火墙配置:UFW 与 iptables 实践
防火墙是服务器对外暴露的第一道防线。默认情况下 Linux 并不限制入站流量,新装系统若直接开放业务端口,等于把 MySQL、Redis 等管理端口也暴露在公网。合理的做法是"默认拒绝入站、按需放行",并针对 SSH 等管理入口做限速与来源限制。
如果你还没有做基础安全配置,建议先参考服务器初始化安全脚本,再按本文细化规则。
UFW:最易用的默认配置
UFW 是面向 iptables/nftables 的前端封装,语法直观,适合绝大多数单机场景。
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw limit ssh
ufw enable
ufw allow 51312放行 TCP+UDP,ufw allow 51312/udp只放行 UDP,端口区间用51312:51314;ufw limit ssh会对 30 秒内发起 6 次以上连接的 IP 自动限速,适合管理入口;- 用
ufw status verbose查看规则,用户规则保存在/etc/ufw/user.rules。
注意:Docker 默认会绕过 UFW 直接写 iptables 规则,需要配合 ufw-docker 之类的方案才能让容器流量也受控。
iptables:规则链与持久化
需要精细控制时直接使用 iptables。基础入站规则示例:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -j DROP
iptables 规则默认不持久化,重启即失效,需要用 iptables-save > /etc/iptables/rules.v4 并安装 iptables-persistent 保存。
只放行指定来源 IP 的场景也很常见,例如仅允许办公室出口网段访问管理端口:
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
对 SSH 这种高频被爆破的入口,还可以用 hashlimit 做连接级限速,比 ufw limit 更可控:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
-m hashlimit --hashlimit-above 3/min --hashlimit-burst 5 \
--hashlimit-name ssh -j DROP
nftables:新一代框架
nftables 取代 iptables 成为内核默认框架,语法更统一。可以用一张 inet 表同时处理 IPv4/IPv6:
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
tcp dport { 22, 80, 443 } accept
}
}
规则用 nft list ruleset > /etc/nftables.conf 保存,重启后由 nftables.service 自动加载。需要端口转发(例如把公网 8443 转发到内网主机的 443)时,用一张 nat 表:
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
tcp dport 8443 dnat to 192.168.1.10:443
}
}
常见场景清单
- Web 服务器:放行 80/443,必要时 22,其余关闭;
- 数据库:只允许内网网段访问 3306/5432,不暴露公网;
- 管理入口:SSH 限制来源 IP 并对连接限速,配合SSH 安全加固;
- 定时审计:用
nft list ruleset或iptables -S定期导出规则复核。
规则设计原则
防火墙规则的优先级与匹配顺序直接决定安全性,设计时把握三条原则:
- 默认拒绝:入站白名单制,没写清楚的一律拒绝;
- 最少开放:只放行业务与运维必需端口,数据库、Redis、管理面板一律不对外开放;
- 来源最小化:能用 IP/网段限制的就不要对全世界开放,管理入口优先限源。
规则变更先小范围验证再推广,避免在流量高峰误断业务。规则文件建议纳入版本管理,配合服务器运维技巧做变更记录。
实战案例:一台 WordPress 业务机的收敛过程
以一台典型的 WordPress 业务机为例,完整收敛通常分四步:先盘点这台机器必须对外提供的端口——80/443 交给 Web 与证书续期、22 仅保留给运维、数据库与 Redis 一律监听内网;接着用 UFW 三行放行 22/80/443,其余默认拒绝;然后把 SSH 限制到公司出口 IP 段并开启 ufw limit ssh;最后给面板、phpMyAdmin 这类高价值入口再加一层来源限制。完成后用 ufw status numbered 导出规则清单存档,方便日后核对。
常用端口放行清单可参考下表,未列出的服务默认不开:
| 服务 | 端口 | 建议 |
|---|---|---|
| SSH | 22 | 限源 + 限速 |
| HTTP/HTTPS | 80/443 | 对全世界开放 |
| MySQL/PostgreSQL | 3306/5432 | 仅内网 |
| Redis | 6379 | 仅内网,禁用 0.0.0.0 绑定 |
| 管理面板 | 自定义 | 限源或走 VPN |
常见问题
UFW 与 iptables 能否共存? UFW 只是 iptables/nftables 的封装,不要同时手动维护,避免规则互相覆盖;nftables 与 iptables 后端选一种即可。
为什么 Docker 发布端口后防火墙失效? Docker 默认直接操作 iptables 的 FORWARD 链,绕过 UFW 的 INPUT 策略。可启用 ufw-docker 或在容器编排层用 NetworkPolicy 收敛。
云平台安全组还需要服务器防火墙吗? 需要。安全组在虚拟网络层过滤,服务器本地防火墙是纵深防御的最后一层,两者都要配置。
IPv6 忘了管怎么办? 不少机器默认放行 IPv6 却只配了 IPv4 规则,等于留了个后门。UFW 对 v4/v6 统一管理;用 iptables 时记得为 ip6tables 单独配置;nftables 用 inet 表即可同时覆盖两套协议。
启用与验证
规则写好后不要只凭"感觉",用命令核对:ufw status verbose 查看生效策略、ufw show added 查看待生效规则、nft list ruleset(nftables 后端)或 iptables -S(iptables 后端)核对实际规则链。上线后建议保留一段时间的防火墙日志(ufw logging on),观察是否有合法流量被误拦,再决定是否进一步收紧密集策略。
一个常见的翻车点:ufw enable 在远程会话里执行时会立刻应用规则,如果 SSH 端口忘了放行,会话会当场断掉。稳妥做法是先放行 SSH、再执行 ufw enable --force,并把当前会话保留住做验证;万一被锁在门外,还可以通过云厂商的 VNC/串口控制台进去恢复。
16IDC 观察
对大多数站点,UFW 的默认拒绝策略加三行放行已经足够;需要端口转发、多网卡或容器网络时再升级到 iptables/nftables。防火墙之外,别忘了把安全响应头、Web 应用防火墙等应用层防护与网络层规则叠加,才能形成纵深防御。完整清单可回到安全加固分类查看。
原文来源:https://wiki.archlinux.org/title/Uncomplicated_Firewall
参考:nftables 维基 https://wiki.nftables.org/;UFW 手册 https://manpages.debian.org/ufw