Ubuntu 中用 iptables 限制端口(实战版)🔒
iptables 的核心价值很简单:把服务器的“暴露面”做最小化,只放行业务必需端口,其余一律拒绝。这样做等于把攻击者的“入口”从几十个缩到个位数,ROI 直接拉满。
0)上手前的两条底线(不做就容易翻车)😅
不要在断开 SSH 的情况下改规则:建议在同一台机器开两个 SSH 会话,一个改规则,一个随时验证。
Ubuntu 上若启用了UFW,它可能会覆盖/干扰规则。先检查:
sudo ufw status解释:
这条命令用于查看 UFW 是否启用。若显示
Status: active,你要么用 UFW 管理防火墙,要么明确停用它再用 iptables(避免两套策略“打架”)。
1)先备份现有规则(可回滚)✅
sudo iptables-save > ~/iptables.backup.v4解释:
iptables-save会把当前 IPv4 规则完整导出。输出到
~/iptables.backup.v4,后续一旦误封 SSH,可快速恢复(相当于“保险丝”)。
2)推荐的“最小暴露面”基线策略(先放行再收口)🧱
下面是一套通用模板:只允许 SSH、HTTP/HTTPS,其余默认拒绝。
假设:你的管理 IP 是
1.2.3.4/32(请替换成你的真实出口 IP)
# 1) 默认策略:入站丢弃、转发丢弃、出站放行 sudo iptables -P INPUT DROP sudo iptables -P FORWARD DROP sudo iptables -P OUTPUT ACCEPT # 2) 放行本机回环 sudo iptables -A INPUT -i lo -j ACCEPT # 3) 放行已建立/相关连接(避免把自己业务“打断流”) sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # 4) 只允许管理IP访问SSH 22 sudo iptables -A INPUT -p tcp --dport 22 -s 1.2.3.4/32 -m conntrack --ctstate NEW -j ACCEPT # 5) 放行Web端口 80/443 sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT # 6) 可选:限制 ICMP(让 ping 不至于被滥用) sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second --limit-burst 5 -j ACCEPT逐段解释:
-P INPUT DROP:把入站默认策略设为拒绝,这是“关门再开窗”的安全基线。-A INPUT -i lo -j ACCEPT:放行lo回环,否则很多本机服务会异常(例如本地进程互访)。-m conntrack --ctstate ESTABLISHED,RELATED:放行已建立连接与相关连接,避免你一改规则,现有会话/业务瞬间断流。--dport 22 -s 1.2.3.4/32:SSH 只允许指定来源 IP 访问。把 SSH 端口开放给全网,相当于给扫描器发“邀请函”。-m multiport --dports 80,443:一次性放行 80/443,更利于维护。-m limit:对 ping 做速率限制,属于“成本很低但很有效”的稳态防护。
3)按业务精细化:只允许内网访问数据库端口(示例:3306)🧩
sudo iptables -A INPUT -p tcp --dport 3306 -s 10.0.0.0/8 -m conntrack --ctstate NEW -j ACCEPT解释:
仅允许
10.0.0.0/8内网段访问 3306。因为前面
INPUT默认是 DROP,所以不需要再写一条“拒绝 3306”的规则;不匹配就会被默认策略挡掉。这类做法本质是把数据库端口从“公网资产”降级为“内网资产”,风险面直接缩小几个数量级。
4)查看与删除规则(运维必会)🛠️
sudo iptables -L INPUT -n -v --line-numbers解释:
-L列出规则,-n不做 DNS 解析(更快更准),-v显示命中计数,--line-numbers给每条规则编号。命中计数可以帮你判断:规则是否真正生效、是否有异常流量。
删除某条规则(假设编号为 7):
sudo iptables -D INPUT 7解释:
-D按编号删除,适合快速回滚“刚加错的那条”。
5)让规则重启后仍然生效(持久化)💾
Ubuntu 现在常见是 iptables 走 nft 后端,但持久化思路不变:把规则保存到系统启动时加载。
sudo apt update sudo apt install -y iptables-persistent sudo netfilter-persistent save sudo systemctl enable netfilter-persistent解释:
iptables-persistent:提供规则落盘与开机加载能力。netfilter-persistent save:把当前规则写入持久化配置。systemctl enable:确保开机自动加载规则。
原理与落地对照表(便于你团队标准化)📌
| 组件/动作 | 你在做什么 | 为什么重要 | 常见踩坑 |
|---|---|---|---|
默认策略INPUT DROP | 先收口再放行 | 把攻击面压到最低 | 忘了先放行 SSH 导致断连 |
ESTABLISHED,RELATED | 放行已有连接 | 避免业务瞬断 | 不加会造成“改规则=断业务” |
| SSH 限来源 IP | 管理面白名单 | 直接降低暴力探测 | 动态 IP 场景需同步更新 |
| 端口按需开放 | 只开放 80/443/必要端口 | 控制暴露面与合规面 | 规则太散,后续难维护 |
| 持久化保存 | 重启后仍加载规则 | 保证策略一致性 | 只改不存,重启全部失效 |
补充:如果你有 IPv6
iptables 管 IPv4,IPv6 需要对应的ip6tables另配,否则会出现“IPv4 封住了、IPv6 还开着”的尴尬局面。
如果你告诉我:你要限制的具体端口清单(例如 SSH 是否改端口、业务端口有哪些、是否需要放行某些固定 IP 段),我可以把规则收敛成一套可直接上线的“最小权限”策略模板,并按你的业务分层(管理面 / 业务面 / 数据面)做成可复制的标准。