13 10 月 2026

服务器每天被扫描成千上万次。防火墙是第一道门——它决定哪些端口能被外面访问。

很多人的做法是"端口不通就先关防火墙试试",这是把门锁拆了找钥匙。正确做法是只放行必要的端口,其他一律拒绝。

这篇讲三种主流防火墙工具的实际用法,并说明云平台安全组的关系。

财富云计算 的云服务器支持安全组配置;做内网服务、游戏服务端可选 NAT 型(无独立公网 IP,价格比独立 IP 机型省一半以上,配合端口映射使用)。

一、先分清两道防火墙

云服务器通常有两层:

用户请求
   ↓
① 云平台安全组(在云厂商控制台配置,在虚拟机外面)
   ↓
② 系统防火墙(iptables/ufw/firewalld,在操作系统里面)
   ↓
服务进程

两层都要放行,端口才通。 排查"端口不通"时两层都要检查,这是最常见的踩坑点。

安全组系统防火墙
位置云平台控制台服务器内
配置方式网页命令
粒度整机单台机器
能否防内网否能
优先级先经过后经过

建议:两层都开。安全组做粗粒度大门口,系统防火墙做细粒度控制(比如限制来源 IP)。


二、三款工具怎么选

工具底层适用系统难度
ufwiptables/nftablesUbuntu/Debian简单,推荐新手
firewalldnftables/iptablesCentOS/RHEL/Rocky中等,概念清晰
iptables内核 netfilter所有难,但最通用
底层其实都是 netfilter,ufw 和 firewalld 只是更友好的封装。不要同时启用多个,会互相打架。
# 查看当前用的是哪个
systemctl status ufw firewalld 2>/dev/null | head

三、ufw(Ubuntu / Debian 推荐)

基本操作

apt install ufw -y

ufw status                # 查看状态
ufw status verbose        # 详细
ufw status numbered       # 带编号(方便删除)
ufw enable                # 启用(会设为开机自启)
ufw disable               # 关闭
ufw reload                # 重载
ufw reset                 # 重置所有规则

放行端口

ufw allow 22/tcp                    # 放行 TCP 22
ufw allow 80
ufw allow 443
ufw allow 27015/udp                 # UDP 端口(游戏服常用)
ufw allow 6000:7000/tcp             # 端口范围
ufw allow from 1.2.3.4              # 放行某个 IP 的所有访问
ufw allow from 1.2.3.4 to any port 22    # 只允许某 IP 访问 22
ufw allow from 192.168.1.0/24 to any port 3306   # 只允许内网访问 MySQL
ufw allow 'Nginx Full'              # 按应用名(80+443)
ufw allow OpenSSH                   # 按应用名
ufw app list                        # 查看可用应用名

拒绝

ufw deny 3306                       # 拒绝(明确拒绝)
ufw deny from 5.6.7.8               # 拒绝某 IP
ufw reject 8080                     # 拒绝并返回拒绝包(deny 是直接丢弃)

删除规则

ufw status numbered
ufw delete 3                        # 按编号删
ufw delete allow 80                 # 按规则删

默认策略

ufw default deny incoming           # 默认拒绝入站(推荐)
ufw default allow outgoing          # 默认允许出站(推荐)
ufw default deny outgoing           # 严格模式(出站也要逐个放行)

限速(防暴力破解)

ufw limit 22/tcp
# 30 秒内超过 6 次连接就临时拒绝,能挡 SSH 爆破

日志

ufw logging on
ufw logging medium        # low/medium/high/full
tail -f /var/log/ufw.log

⚠️ 启用前必做:先放行 SSH

ufw allow 22/tcp          # 或者你改过的 SSH 端口
ufw enable

否则会把自己锁在外面(只能走云控制台 VNC 救)。


四、firewalld(CentOS / Rocky 推荐)

概念:zone(区域)

firewalld 用"区域"管理信任级别:

zone含义
drop丢弃所有入站,不回应
block拒绝所有入站
public公开网络,只放行指定服务(默认)
external外部网络,启用伪装(NAT)
internal内部网络,信任度高
trusted全部放行
firewall-cmd --get-default-zone
firewall-cmd --set-default-zone=public
firewall-cmd --get-active-zones

基本操作

systemctl enable --now firewalld
firewall-cmd --state
firewall-cmd --reload               # 重载(不会断现有连接)
firewall-cmd --list-all             # 查看当前 zone 的全部规则
firewall-cmd --list-all-zones

放行

# 临时(重启后失效)
firewall-cmd --add-port=80/tcp

# 永久(--permanent 后需 --reload)
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload

# 按服务名
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=ssh
firewall-cmd --get-services            # 查看所有服务名

# 端口范围
firewall-cmd --permanent --add-port=27000-27020/udp

# 移除
firewall-cmd --permanent --remove-port=8080/tcp
firewall-cmd --reload

富规则(rich rules,精细控制)

# 只允许某 IP 访问 3306
firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4"
  source address="192.168.1.0/24"
  port protocol="tcp" port="3306" accept'

# 拒绝某 IP
firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4" source address="5.6.7.8" drop'

# 限制 SSH 每分钟最多 3 个新连接
firewall-cmd --permanent --add-rich-rule='
  rule service name="ssh" limit value="3/m" accept'

# 端口转发(把 80 转到 8080)
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080

# 查看
firewall-cmd --list-rich-rules

端口转发 / NAT(NAT 型服务器常用)

# 开启 IP 伪装(SNAT,让内网机器能上网)
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload

# 端口转发(DNAT)
firewall-cmd --permanent --add-forward-port=port=27015:proto=udp:toport=27015:toaddr=192.168.1.100
firewall-cmd --reload

# 验证
firewall-cmd --list-all

五、iptables(通用底层,了解一下)

ufw/firewalld 底层还是它,某些场景(Docker、复杂 NAT)需要直接操作。

四表五链

filter 表(默认,做过滤)
  ├── INPUT     入站
  ├── FORWARD   转发
  └── OUTPUT    出站

nat 表(做地址转换)
  ├── PREROUTING   路由前(DNAT)
  ├── POSTROUTING  路由后(SNAT/ MASQUERADE)
  └── OUTPUT

常用命令

iptables -L -n -v                  # 查看 filter 表
iptables -t nat -L -n -v           # 查看 nat 表
iptables -L -n --line-numbers      # 带行号

# 放行端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# 放行已建立的连接(关键!否则出站回包进不来)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT

# 允许某 IP
iptables -A INPUT -s 1.2.3.4 -j ACCEPT

# 拒绝某 IP
iptables -A INPUT -s 5.6.7.8 -j DROP

# 限制 SSH 新连接频率(防爆破)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
  -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
  -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP

# 删除规则(按行号)
iptables -D INPUT 3

# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

保存规则(重启后不丢)

# Debian/Ubuntu
apt install iptables-persistent -y
iptables-save > /etc/iptables/rules.v4
netfilter-persistent save

# CentOS
yum install iptables-services -y
service iptables save
# 或
iptables-save > /etc/sysconfig/iptables

NAT 端口转发(NAT 型服务器核心)

# 开启内核转发
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p

# DNAT:把访问本机 27015/udp 的包转到内网机器
iptables -t nat -A PREROUTING -p udp --dport 27015 \
  -j DNAT --to-destination 192.168.1.100:27015

# SNAT / MASQUERADE:让回包能正常回去
iptables -t nat -A POSTROUTING -j MASQUERADE
# 或指定出口 IP
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# 允许转发
iptables -A FORWARD -p udp -d 192.168.1.100 --dport 27015 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

更详细的端口映射说明见本站《NAT 端口映射完全指南》。


六、Docker 与防火墙的冲突(经典大坑)

Docker 会直接写 iptables 规则,绕过 ufw/firewalld。结果是:你在 ufw 里 deny 了某端口,但 Docker 映射的端口照样能从外面访问。

验证:

ufw status                    # 显示 8080 被拒绝
curl http://服务器IP:8080      # 却能访问

解决办法:

方案一:Docker 只监听内网

docker run -p 127.0.0.1:8080:80 nginx
# 只有 127.0.0.1:8080 可访问,外网访问不到,再由 Nginx 反代

这是最推荐的做法——容器不要直接暴露公网,用 Nginx 反代。

方案二:禁用 Docker 的 iptables 操作

nano /etc/docker/daemon.json
{
  "iptables": false
}
systemctl restart docker

⚠️ 副作用:容器可能无法访问外网(需自己配 MASQUERADE)。

方案三:把 Docker 规则放到 ufw 之前(较复杂,生产环境常用)


七、安全组配置(云平台侧)

以常见云平台为例,配置思路一致:

入站规则建议:

端口协议来源说明
22(或自定义)TCP你的 IP 或 0.0.0.0/0SSH
80TCP0.0.0.0/0HTTP
443TCP0.0.0.0/0HTTPS
游戏端口(如 27015)UDP0.0.0.0/0游戏服
3306TCP仅内网网段数据库绝不对外开放
6379TCP仅内网Redis 绝不对外开放

常见错误:

  • 数据库、Redis、Memcached 端口对 0.0.0.0/0 开放 → 极高风险(勒索软件最爱 Redis 未授权访问)
  • 测试时开了 全部端口 / 全部 IP,之后忘了收回
  • 出站规则设成了全部拒绝,导致服务器无法更新软件

原则:

  1. 默认拒绝,需要什么开什么
  2. 管理类端口(SSH、数据库)限制来源 IP
  3. 定期审计,清理临时规则

八、端口不通的排查流程

# 1. 服务是否真的在监听
ss -tulnp | grep 端口

# 2. 本机能否访问(绕过防火墙)
curl http://127.0.0.1:端口

# 3. 系统防火墙是否放行
ufw status / firewall-cmd --list-all / iptables -L -n

# 4. 安全组是否放行(去控制台看)

# 5. 从外部测试
telnet 服务器IP 端口
nc -zv 服务器IP 端口
# 或在线端口扫描工具

# 6. 服务是否只监听了 127.0.0.1
ss -tulnp | grep 端口
# 看到 127.0.0.1:8080 说明只监听本地,外网访问不到
# 需要改成 0.0.0.0:8080(在程序配置里改,或用 Nginx 反代)

第 6 条是最容易忽略的:很多程序(MySQL、Redis、某些面板)默认只监听 127.0.0.1,防火墙全开也访问不了。


九、一份安全的基础配置

Ubuntu(ufw)

# 1. 设置默认策略
ufw default deny incoming
ufw default allow outgoing

# 2. 放行必要服务
ufw allow 2299/tcp          # SSH(改成你的端口)
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 27015/udp         # 游戏服

# 3. 限制 SSH 频率
ufw limit 2299/tcp

# 4. 内网才允许访问数据库
ufw allow from 10.0.0.0/8 to any port 3306

# 5. 启用
ufw enable
ufw status verbose

CentOS(firewalld)

systemctl enable --now firewalld

firewall-cmd --permanent --remove-service=ssh     # 如果默认放行的是 22
firewall-cmd --permanent --add-port=2299/tcp
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-port=27015/udp

firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4" source address="10.0.0.0/8"
  port protocol="tcp" port="3306" accept'

firewall-cmd --reload
firewall-cmd --list-all

十、常见误区

误区正确做法
"先关防火墙试试"应该放行端口,而不是关闭整个防火墙
只配了系统防火墙安全组也要配,两层都要放行
数据库端口对外开放只允许内网,或直接不监听公网
开了 ufw 又开 firewalld只用一个
Docker 端口绕过防火墙容器监听 127.0.0.1 + Nginx 反代
临时全开端口忘了收回加备注,定期审计
改 SSH 端口后没放行新端口就重启先放行再重启,且保留旧连接窗口

十一、进阶:防扫描与防攻击

# 禁止 ping(可选,防探测)
# ufw:编辑 /etc/ufw/before.rules,把 icmp echo-request 的 ACCEPT 改成 DROP
# firewalld:
firewall-cmd --permanent --add-icmp-block=echo-request
firewall-cmd --reload

# iptables 直接封整个网段
iptables -A INPUT -s 5.6.7.0/24 -j DROP

# 防止端口扫描(记录并丢弃)
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

但防火墙不是万能的:它挡不住 80/443 上的应用层攻击(SQL 注入、CC)。那些要靠 fail2ban、WAF、程序本身的安全,见本站《网站常见漏洞与基础防护》。


配置防火墙是上线第一步。财富云计算 的云服务器支持在控制台配置安全组,与系统内防火墙配合形成双层防护。做内网服务、游戏服务端推荐 NAT 型(无独立公网 IP,价格比带独立 IP 机型省一半以上),通过端口映射按需暴露需要的端口,暴露面更小。

相关阅读:

  • 《fail2ban 防暴力破解实战配置》
  • 《SSH 密钥登录与账号安全配置》
  • 《NAT 端口映射完全指南》
  • 《网站常见漏洞与基础防护》
延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:网站打开慢的排查流程:从感觉卡到定位具体原因
  2. 下一篇:fail2ban 防暴力破解实战配置:自动封禁所有可疑 IP
发表评论 7