为什么 Linux 防火墙配置不能只会开端口?
Linux 防火墙不是单纯“把端口打开”这么简单,真正重要的是按业务需要控制访问范围、降低暴露面,并在改规则时避免把自己锁在服务器外面。下面结合 iptables、firewalld 和 UFW 三套常见方案,把实用操作和常见坑一次讲清。

目录
前言
搞Linux运维,防火墙这关你绕不过去。不管你是管一台VPS还是上千台服务器,端口开错了、规则写反了,轻则服务挂掉,重则被人打穿。本文把iptables、firewalld、ufw三套主流方案一网打尽,全是实战中摸爬滚打出来的经验,不灌水,直接上干货。
一、iptables — 经典永不过时
1.1 基础概念
iptables基于Netfilter内核模块,通过**表(table)→ 链(chain)→ 规则(rule)**三级结构处理数据包。日常最常用的是`filter`表(包过滤)和`nat`表(地址转换)。
四表五链不用死记,记住:`filter`管放行/拦截,`nat`管转发,够了。
1.2 开放/关闭端口
# 开放80端口(HTTP)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 开放443端口(HTTPS)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 关闭某端口(注意:用-D删除对应规则)
iptables -D INPUT -p tcp --dport 8080 -j ACCEPT
# 拒绝所有未匹配的入站流量(放最后!)
iptables -A INPUT -j DROP
# 查看当前规则(带行号,方便删除)
iptables -L INPUT -n --line-numbers
**⚠️ 避坑:** `DROP`规则一定要放在最后,写早了你SSH直接断了,只能去机房哭。
1.3 允许指定IP访问
# 只允许 10.0.0.5 访问 3306(MySQL)
iptables -A INPUT -p tcp -s 10.0.0.5 --dport 3306 -j ACCEPT
# 拒绝某个IP段的所有访问
iptables -A INPUT -s 192.168.100.0/24 -j DROP
# 允许本机回环通信(别忘了这条)
iptables -A INPUT -i lo -j ACCEPT
1.4 NAT转发
# 开启内核转发(必须!)
echo 1 > /proc/sys/net/ipv4/ip_forward
# SNAT:内网机器通过公网IP出去
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
# DNAT:把公网8080转发到内网80
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 8080 -j DNAT --to-destination 192.168.1.100:80
1.5 限速防刷
# 限制SSH(22端口)每分钟最多5个新连接,超过的直接扔
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 限制ICMP(防ping洪水)
iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p icmp -j DROP
1.6 规则持久化
iptables重启就没了,必须持久化:
# CentOS/RHEL
iptables-save > /etc/sysconfig/iptables
# Debian/Ubuntu
apt install iptables-persistent
iptables-save > /etc/iptables/rules.v4
二、firewalld — CentOS 7+ 的新宠
如果你的业务部署在云服务器上,系统内的防火墙规则和云平台侧的安全组最好配合使用。像 速维云 这类云服务器场景,常见做法就是在云平台先收口公网入口,再在 Linux 本机做更细的端口与来源控制,这样更稳,也更不容易因为误开放端口留下风险。
2.1 核心概念
firewalld是iptables的前端封装,用**区域(zone)**和**服务(service)**的概念简化了管理。配合systemd启动,是RHEL系的新标配。
# 启动并设为开机自启
systemctl enable --now firewalld
# 查看状态
firewall-cmd --state
# 查看当前激活的区域和规则
firewall-cmd --list-all
2.2 开放/关闭端口与服务
# 开放HTTP服务(--permanent必须加,否则重启失效)
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
# 直接开放端口
firewall-cmd --permanent --add-port=8080/tcp
# 关闭端口
firewall-cmd --permanent --remove-port=8080/tcp
# ⚠️ 改完规则必须reload!
firewall-cmd --reload
# 查看已开放的端口和服务
firewall-cmd --list-ports
firewall-cmd --list-services
2.3 富规则:精准控制
# 只允许 10.0.0.5 访问 MySQL
firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="10.0.0.5"
port port="3306" protocol="tcp"
accept'
# 拒绝某IP的所有访问
firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="192.168.100.0/24"
reject'
# 限速:SSH每分钟最多5个连接
firewall-cmd --permanent --add-rich-rule='
rule service name="ssh"
log prefix="ssh limited" level="notice"
limit value="5/m"
accept'
2.4 NAT与端口转发
# 开启masquerade(SNAT)
firewall-cmd --permanent --add-masquerade
# 端口转发:外部8080 → 内网 192.168.1.100:80
firewall-cmd --permanent --add-forward-port=port=8080:proto=tcp:toaddr=192.168.1.100:toport=80
firewall-cmd --reload
2.5 Panic模式
紧急情况一键断网:
# 启用panic模式(拒绝所有连接)
firewall-cmd --panic-on
# 关闭panic模式
firewall-cmd --panic-off
三、UFW — Ubuntu用户的懒人神器
UFW是Ubuntu默认的防火墙前端,底层还是iptables,但语法极其简洁:
# 启用(首次启用会自动开放当前SSH连接,别怕)
ufw enable
# 开放端口
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow from 10.0.0.5 to any port 3306 # 指定IP+端口
# 关闭端口
ufw deny 8080/tcp
# 限速
ufw limit 22/tcp # 自带防暴力破解,每6个连接限制一次
# 查看状态
ufw status verbose
# 删除规则(先编号再删)
ufw status numbered
ufw delete 3
四、排坑指南
五、选型建议
• **Ubuntu服务器** → UFW,语法简单,够用
• **CentOS/RHEL 7+** → firewalld,系统默认,配合systemd无缝
• **需要精细控制(NAT、限速、自定义链)** → 直接上iptables,最灵活
• **容器环境(Docker/K8s)** → 慎用手动iptables,容易和CNI插件打架
记住一条铁律:**先保证SSH能连,再往下改规则。** 每次操作前问自己一句"这条规则会不会把我关在门外",能少踩80%的坑。











暂无评论内容