UFW防火墙最全用法指南

从基础到生产级 — 涵盖安装配置、规则语法、默认策略、速率限制、日志、应用配置文件、IPv6、Docker 兼容、端口转发与实战场景


目录

  1. 基础概念
  2. 安装与启用
  3. 默认策略
  4. 基础规则语法
  5. 端口与服务管理
  6. IP 地址与子网规则
  7. 网络接口规则
  8. 协议规则(TCP/UDP/ICMP)
  9. 速率限制(Rate Limiting)
  10. 日志管理
  11. 应用配置文件(Application Profiles)
  12. 规则管理(查看/删除/插入/重置)
  13. IPv6 支持
  14. 配置文件详解
  15. 端口转发与 NAT
  16. UFW 与 Docker
  17. UFW 与 Fail2Ban 集成
  18. 出站流量控制
  19. 实战场景合集
  20. 故障排查
  21. 常用速查表

1. 基础概念

1.1 什么是 UFW

UFW(Uncomplicated Firewall)是 iptables/netfilter 的前端工具,专为简化 Linux 防火墙管理而设计。

用户命令 (ufw allow 22/tcp)
        ↓
UFW (Uncomplicated Firewall) — 简化语法层
        ↓
iptables / netfilter — 内核级包过滤
        ↓
网卡 (eth0 / wlan0 / ...)

1.2 核心特点

特点 说明
简单语法 ufw allow 22/tcp 替代复杂的 iptables 命令
基于 iptables 底层仍然是 iptables/netfilter
应用配置文件 按服务名(如 Nginx、OpenSSH)管理规则
IPv4 / IPv6 双栈 自动同时生成两套规则
Debian/Ubuntu 默认 Ubuntu/Debian 系预装

1.3 UFW vs iptables vs firewalld

特性 UFW iptables firewalld
易用性 ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐
功能完整度 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
适用发行版 Ubuntu/Debian 所有 Linux RHEL/CentOS/Fedora
学习曲线 低 高 中
适合场景 个人服务器/VPS 复杂网络 企业网络

2. 安装与启用

2.1 安装

# Ubuntu/Debian(通常预装)
sudo apt update
sudo apt install ufw

# 验证安装
sudo ufw version
# 输出示例:ufw 0.36.2
# Copyright 2008-2023 Canonical Ltd.

2.2 ⚠️ 启用前的重要提醒

🚨 关键:启用 UFW 前必须先放行 SSH!
如果你通过 SSH 连接服务器,直接启用 UFW 会断开你的连接!
# ✅ 正确顺序
sudo ufw allow ssh          # 先放行 SSH(端口 22)
sudo ufw allow 22/tcp       # 或明确指定端口
sudo ufw enable             # 然后再启用

# ❌ 错误做法(会锁死自己)
sudo ufw enable             # 直接触发,SSH 被默认 deny 拦截

2.3 启用与禁用

# 启用防火墙
sudo ufw enable
# 输出:Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
# Firewall is active and enabled on system startup

# 禁用防火墙(规则保留,只是不生效)
sudo ufw disable
# 输出:Firewall stopped and disabled on system startup

# 重载规则(修改配置文件后)
sudo ufw reload

# 检查启动状态
sudo ufw status
# 输出:Status: active

# 查看是否开机自启
sudo systemctl is-enabled ufw
# 输出:enabled

2.4 设置开机自启

# UFW 通过 systemd 服务管理
sudo systemctl enable ufw
sudo systemctl start ufw

# 查看服务状态
sudo systemctl status ufw

3. 默认策略

默认策略决定了没有匹配到任何规则的流量如何处理。

3.1 查看当前默认策略

sudo ufw status verbose
# 输出:
# Status: active
# Logging: on (low)
# Default: deny (incoming), allow (outgoing), deny (routed)
# New profiles: skip

3.2 设置默认策略

# === 入站流量(推荐 deny) ===
sudo ufw default deny incoming    # 拒绝所有入站(推荐)
sudo ufw default allow incoming   # 允许所有入站(不推荐)
sudo ufw default reject incoming  # 拒绝并通知发送方(返回 RST/ICMP)

# === 出站流量(推荐 allow) ===
sudo ufw default allow outgoing   # 允许所有出站(推荐)
sudo ufw default deny outgoing    # 拒绝所有出站(需逐条放行)

# === 转发流量(路由/NAT 场景) ===
sudo ufw default deny routed      # 拒绝转发(默认,推荐)
sudo ufw default allow routed     # 允许转发(路由器/网关场景)

3.3 deny vs reject 的区别

策略 行为 适用场景
deny (DROP) 直接丢弃数据包,不回复 生产环境(更安全,攻击者无法判断端口状态)
reject 丢弃并回复 ICMP/TCP RST 内网/测试环境(客户端快速知道端口不可用)
allow (ACCEPT) 允许通过 需要放行的服务

3.4 推荐初始配置

# 标准生产服务器初始化
sudo ufw default deny incoming      # 拒绝所有入站
sudo ufw default allow outgoing     # 允许所有出站
sudo ufw default deny routed        # 拒绝转发

4. 基础规则语法

4.1 完整语法

ufw [--dry-run] [delete] [insert NUM] [prepend] \
    allow|deny|reject|limit \
    [in|out] [on INTERFACE] \
    [log|log-all] \
    [proto PROTOCOL] \
    [from ADDRESS [port PORT]] \
    [to ADDRESS [port PORT]] \
    [comment COMMENT]

4.2 语法元素

元素 说明 示例
allow 允许连接 ufw allow 80/tcp
deny 丢弃连接(DROP) ufw deny 3306
reject 拒绝连接(回复发送方) ufw reject 3306
limit 速率限制(防暴力破解) ufw limit ssh
in 入站方向 ufw allow in 80/tcp
out 出站方向 ufw deny out 25/tcp
on 指定网卡 ufw allow in on eth0 80/tcp
proto 指定协议 ufw allow proto tcp 80
from 源地址 ufw allow from 192.168.1.0/24
to 目标地址 ufw allow to any port 80
port 端口 ufw allow to any port 443
app 应用配置文件 ufw allow OpenSSH
log 记录匹配日志 ufw allow log 22/tcp
comment 规则注释 ufw allow 80/tcp comment 'Web Server'
--dry-run 预览不执行 ufw --dry-run allow 80/tcp

4.3 --dry-run 预览

# 只预览规则,不实际添加
sudo ufw --dry-run allow 80/tcp
# 输出:
# Skipping adding existing rule
# Skipping adding existing rule (v6)

5. 端口与服务管理

5.1 按端口号放行

# 放行 TCP 80 端口(HTTP)
sudo ufw allow 80/tcp

# 放行 UDP 53 端口(DNS)
sudo ufw allow 53/udp

# 放行 TCP 443 端口(HTTPS)
sudo ufw allow 443/tcp

# 不指定协议(同时放行 TCP 和 UDP)
sudo ufw allow 53

5.2 按服务名放行

# UFW 会查询 /etc/services 文件
sudo ufw allow ssh       # → 22/tcp
sudo ufw allow http      # → 80/tcp
sudo ufw allow https     # → 443/tcp
sudo ufw allow ftp       # → 21/tcp
sudo ufw allow dns       # → 53/tcp 和 53/udp
sudo ufw allow smtp      # → 25/tcp

5.3 完整语法(推荐)

# 更明确、可读性更高的写法
sudo ufw allow to any port 80 proto tcp
sudo ufw allow to any port 443 proto tcp
sudo ufw allow to any port 22 proto tcp

# 添加注释(强烈推荐)
sudo ufw allow 22/tcp comment 'SSH 远程管理'
sudo ufw allow 80/tcp comment 'HTTP Web 服务'
sudo ufw allow 443/tcp comment 'HTTPS Web 服务'
sudo ufw allow 3306/tcp comment 'MySQL 仅内网'

5.4 端口范围

# 放行端口范围(必须指定协议)
sudo ufw allow 3000:3100/tcp     # 3000-3100 TCP
sudo ufw allow 5000:5100/udp     # 5000-5100 UDP

# 被动 FTP 端口范围
sudo ufw allow 49000:50000/tcp comment 'FTP 被动模式'

5.5 拒绝特定端口

# 拒绝 MySQL 外部访问
sudo ufw deny 3306/tcp

# 拒绝 Redis 外部访问
sudo ufw deny 6379/tcp

# 拒绝 SMTP(防止服务器被用于发垃圾邮件)
sudo ufw deny out 25/tcp comment '禁止外发邮件'

5.6 常用服务端口参考

服务 端口 协议
SSH 22 TCP
HTTP 80 TCP
HTTPS 443 TCP
DNS 53 TCP/UDP
FTP 21 TCP
FTP 被动 49152-65535 TCP
SMTP 25 TCP
SMTPS 465 TCP
SMTP Submission 587 TCP
IMAP 143 TCP
IMAPS 993 TCP
POP3 110 TCP
POP3S 995 TCP
MySQL 3306 TCP
PostgreSQL 5432 TCP
Redis 6379 TCP
MongoDB 27017 TCP
RDP 3389 TCP
VNC 5900 TCP
NTP 123 UDP
SNMP 161 UDP
Syslog 514 UDP
WireGuard 51820 UDP
OpenVPN 1194 UDP

6. IP 地址与子网规则

6.1 允许特定 IP

# 允许特定 IP 的所有连接
sudo ufw allow from 192.168.1.100

# 允许特定 IP 访问特定端口
sudo ufw allow from 192.168.1.100 to any port 22 proto tcp
sudo ufw allow from 192.168.1.100 to any port 3306 proto tcp

# 允许特定 IP 访问多个端口(逐条添加)
sudo ufw allow from 192.168.1.100 to any port 80 proto tcp
sudo ufw allow from 192.168.1.100 to any port 443 proto tcp

6.2 允许子网(CIDR)

# 允许整个内网
sudo ufw allow from 192.168.1.0/24

# 允许内网访问 SSH
sudo ufw allow from 10.0.0.0/8 to any port 22 proto tcp

# 允许内网访问数据库
sudo ufw allow from 192.168.1.0/24 to any port 3306 proto tcp comment '内网 MySQL'
sudo ufw allow from 192.168.1.0/24 to any port 5432 proto tcp comment '内网 PostgreSQL'
sudo ufw allow from 192.168.1.0/24 to any port 6379 proto tcp comment '内网 Redis'

# 允许管理子网访问所有端口
sudo ufw allow from 172.16.0.0/12 comment '管理网段'

6.3 拒绝特定 IP

# 封禁单个 IP
sudo ufw deny from 203.0.113.50

# 封禁子网
sudo ufw deny from 203.0.113.0/24

# 封禁 IP 访问特定端口
sudo ufw deny from 203.0.113.50 to any port 22 proto tcp

# 封禁 IP 并记录日志
sudo ufw deny log from 203.0.113.50 comment '恶意 IP'

6.4 源端口限制

# 允许来自特定源端口的连接(较少使用)
sudo ufw allow from any port 53 proto udp

6.5 组合规则示例

# 仅允许办公网络访问 SSH
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp comment '办公网络 SSH'

# 仅允许特定 IP 访问管理面板
sudo ufw allow from 192.168.1.50 to any port 8080 proto tcp comment '管理员面板'

# 允许 VPN 子网访问所有服务
sudo ufw allow from 10.8.0.0/24 comment 'VPN 网段'

7. 网络接口规则

7.1 按网卡过滤

# 查看网卡列表
ip addr
# 常见:eth0(公网)、eth1(内网)、lo(回环)、docker0(Docker)

# 仅允许公网网卡上的 HTTP
sudo ufw allow in on eth0 to any port 80 proto tcp

# 仅允许内网网卡上的数据库
sudo ufw allow in on eth1 to any port 3306 proto tcp

# 拒绝公网网卡上的 Redis
sudo ufw deny in on eth0 to any port 6379 proto tcp

# 允许回环接口(通常默认已放行)
sudo ufw allow in on lo
sudo ufw allow out on lo

7.2 接口 + IP 组合

# 仅允许内网网卡上的内网 IP 访问数据库
sudo ufw allow in on eth1 from 192.168.1.0/24 to any port 3306 proto tcp

# 仅允许公网网卡上的 HTTPS
sudo ufw allow in on eth0 to any port 443 proto tcp

7.3 多网卡服务器场景

# Web 服务器(双网卡)
sudo ufw allow in on eth0 to any port 80 proto tcp comment '公网 HTTP'
sudo ufw allow in on eth0 to any port 443 proto tcp comment '公网 HTTPS'
sudo ufw allow in on eth1 from 192.168.1.0/24 to any port 3306 proto tcp comment '内网 MySQL'
sudo ufw allow in on eth1 from 192.168.1.0/24 to any port 6379 proto tcp comment '内网 Redis'

8. 协议规则(TCP/UDP/ICMP)

8.1 指定协议

# TCP
sudo ufw allow proto tcp to any port 80

# UDP
sudo ufw allow proto udp to any port 53

# 同时放行 TCP 和 UDP(不指定 proto)
sudo ufw allow 53

8.2 ICMP(Ping)

UFW 默认通过 before.rules 处理 ICMP。控制 ICMP 有两种方式:

方式一:编辑 before.rules(推荐)

# 查看当前 ICMP 规则
grep icmp /etc/ufw/before.rules

# 禁止 Ping(注释掉或删除以下行)
# -A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT
# 改为:
# -A ufw-before-input -p icmp --icmp-type echo-request -j DROP
# 禁止 Ping 的快捷方法
sudo sed -i '/icmp-type echo-request/s/ACCEPT/DROP/' /etc/ufw/before.rules
sudo sed -i '/icmp-type echo-request/s/ACCEPT/DROP/' /etc/ufw/before6.rules
sudo ufw reload

方式二:允许特定 IP Ping

# 编辑 /etc/ufw/before.rules
# 在 icmp echo-request 规则前添加:
# -A ufw-before-input -p icmp --icmp-type echo-request -s 192.168.1.0/24 -j ACCEPT
# -A ufw-before-input -p icmp --icmp-type echo-request -j DROP

8.3 其他协议

# GRE(VPN/隧道协议)
sudo ufw allow proto 47

# ESP(IPsec)
sudo ufw allow proto 50
sudo ufw allow proto 51

# AH(IPsec 认证头)
# 通过 before.rules 配置

9. 速率限制(Rate Limiting)

9.1 基本用法

limit 规则会自动限制频繁连接的 IP:30 秒内超过 6 次连接将被拒绝。

# 限制 SSH(防暴力破解,强烈推荐)
sudo ufw limit ssh

# 或指定端口
sudo ufw limit 22/tcp

# 限制其他服务
sudo ufw limit 3389/tcp comment '限制 RDP'
sudo ufw limit 21/tcp comment '限制 FTP'

9.2 限制特定 IP

# 限制特定网段的连接频率
sudo ufw limit from 0.0.0.0/0 to any port 22 proto tcp

9.3 limit 的工作原理

UFW limit 底层使用 recent 模块:

1. 记录每个源 IP 的连接尝试
2. 30 秒滑动窗口内:
   - 前 6 次连接:允许(ACCEPT)
   - 第 7 次及以后:丢弃(DROP)
3. 30 秒内无新连接:清除记录

⚠️ 注意:limit 规则是"如果不超过限制就 ACCEPT",不是"如果不匹配就继续下一条规则"。limit 匹配后会直接放行,不再检查后续规则。

9.4 修改默认限制参数

默认参数存储在 /etc/ufw/user.rules 中:

# 查看生成的 limit 规则
grep -A5 "limit" /etc/ufw/user.rules

# 底层规则类似:
# -A ufw-user-limit-accept -m limit --limit 6/30 -j ACCEPT
# -A ufw-user-limit -j REJECT --reject-with icmp-port-unreachable

如需自定义(如改为 5 次/60 秒),需编辑 user.rules 文件或直接写 iptables 规则在 before.rules 中。


10. 日志管理

10.1 开启日志

# 开启日志
sudo ufw logging on

# 设置日志级别
sudo ufw logging low       # 记录被阻断的包(默认)
sudo ufw logging medium    # + 记录允许的包、计数器
sudo ufw logging high      # + 记录所有尝试认证的包
sudo ufw logging full      # + 记录所有包(日志量巨大,谨慎使用)

# 关闭日志
sudo ufw logging off

10.2 日志级别对比

级别 记录内容 日志量 适用场景
off 不记录 无 不推荐
low 被阻断的包 少 生产推荐
medium 阻断 + 允许 + 计数 中 调试/审计
high + 认证尝试 较多 安全审计
full 所有包 + 带源/目标 巨大 仅排障时临时使用

10.3 查看日志

# 实时查看 UFW 日志
sudo tail -f /var/log/ufw.log

# 或通过 syslog
sudo tail -f /var/log/syslog | grep UFW

# 查看最近的阻断记录
sudo grep "UFW BLOCK" /var/log/ufw.log | tail -20

# 统计被阻断的 IP(排查攻击)
sudo grep "UFW BLOCK" /var/log/ufw.log | \
  grep -oP 'SRC=\K[0-9.]+' | sort | uniq -c | sort -rn | head -20

# 查看特定端口的阻断记录
sudo grep "UFW BLOCK.*DPT=22" /var/log/ufw.log | tail -20

10.4 日志格式解析

Feb 3 14:40:48 hostname kernel: [UFW BLOCK] IN=eth0 OUT= \
  MAC=00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff \
  SRC=203.0.113.50 DST=192.168.1.100 \
  LEN=40 TOS=0x00 PREC=0x00 TTL=55 ID=33554 \
  PROTO=TCP SPT=1702 DPT=22 \
  WINDOW=65535 RES=0x00 ACK FIN URGP=0
字段 含义
UFW BLOCK 动作(BLOCK/ALLOW/LIMIT)
IN=eth0 入站网卡
OUT= 出站网卡(空表示入站)
SRC=203.0.113.50 源 IP
DST=192.168.1.100 目标 IP
PROTO=TCP 协议
SPT=1702 源端口
DPT=22 目标端口
LEN=40 数据包长度

10.5 按规则记录日志

# 只记录特定规则的日志(不依赖全局日志级别)
sudo ufw allow log 22/tcp comment 'SSH 登录记录'
sudo ufw deny log from 203.0.113.0/24 comment '记录恶意网段'

# log-all 记录所有匹配(包括允许和拒绝)
sudo ufw allow log-all 80/tcp comment '记录所有 HTTP 访问'

11. 应用配置文件(Application Profiles)

11.1 查看内置应用配置

# 列出所有可用应用配置文件
sudo ufw app list

# 输出示例:
# Available applications:
#   CIFS
#   DNS
#   IMAP
#   IMAPS
#   OpenSSH
#   POP3
#   POP3S
#   SMTP
#   SSH
#   ...

11.2 查看应用详情

# 查看应用配置详情
sudo ufw app info OpenSSH

# 输出:
# Profile: OpenSSH
# Title: OpenSSH server (Remote Shell)
# Description: OpenSSH is a free version of the SSH protocol suite.
#
# Ports:
#   22/tcp
# 查看所有应用详情
sudo ufw app info all

11.3 使用应用配置

# 按应用名放行
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'    # 同时放行 80 和 443
sudo ufw allow 'Nginx HTTP'    # 仅放行 80
sudo ufw allow 'Nginx HTTPS'   # 仅放行 443
sudo ufw allow 'Apache Full'
sudo ufw allow 'Postfix'

# 限制应用
sudo ufw limit OpenSSH

# 仅允许特定 IP 使用应用
sudo ufw allow from 192.168.1.0/24 to any app OpenSSH

11.4 创建自定义应用配置

应用配置文件存储在 /etc/ufw/applications.d/ 目录。

# 创建自定义应用配置
sudo tee /etc/ufw/applications.d/custom-apps << 'EOF'
[MyWebApp]
title=My Web Application
description=Custom web application with API
ports=8080/tcp

[MyDatabase]
title=Internal Database Cluster
description=Database cluster for internal use
ports=3306,5432/tcp

[GameServer]
title=Game Server
description=Multiplayer game server ports
ports=27015:27030/udp|27015/tcp
EOF

# 更新 UFW 应用列表
sudo ufw app update MyWebApp
sudo ufw app update MyDatabase
sudo ufw app update GameServer

# 使用自定义配置
sudo ufw allow MyWebApp comment '自定义 Web 应用'
sudo ufw allow from 10.0.0.0/8 to any app MyDatabase comment '内网数据库'

11.5 Nginx 应用配置示例

# 查看 Nginx 配置(安装 nginx 后自动生成)
sudo ufw app info "Nginx Full"
# Profile: Nginx Full
# Ports: 80,443/tcp

# 一行放行 HTTP + HTTPS
sudo ufw allow "Nginx Full"

12. 规则管理(查看/删除/插入/重置)

12.1 查看规则

# 基本状态
sudo ufw status

# 详细状态(含默认策略、日志)
sudo ufw status verbose

# 带编号的规则列表(删除/插入时需要)
sudo ufw status numbered

# 输出示例:
# Status: active
#      To                         Action      From
#      --                         ------      ----
# [ 1] 22/tcp                     ALLOW IN    Anywhere
# [ 2] 22/tcp (v6)                ALLOW IN    Anywhere (v6)
# [ 3] 80/tcp                     ALLOW IN    Anywhere
# [ 4] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
# [ 5] 443/tcp                    ALLOW IN    Anywhere
# [ 6] 443/tcp (v6)               ALLOW IN    Anywhere (v6)
# [ 7] 3306/tcp                   ALLOW IN    192.168.1.0/24
# [ 8] 22/tcp                     LIMIT IN    Anywhere

12.2 删除规则

# 方式一:按编号删除(推荐)
sudo ufw status numbered
sudo ufw delete 3      # 删除第 3 条规则

# 方式二:按规则语法删除
sudo ufw delete allow 80/tcp
sudo ufw delete allow from 192.168.1.0/24 to any port 3306 proto tcp
sudo ufw delete limit ssh

# 删除时会确认
# Proceed with operation (y|n)? y
# Rule deleted

12.3 插入规则

# 在指定位置插入规则(规则顺序很重要!)
sudo ufw insert 1 allow from 192.168.1.0/24 to any port 22 proto tcp

# 在最前面插入(prepend)
sudo ufw prepend deny from 203.0.113.50

# 注意:UFW 规则是从上到下匹配的
# 先匹配到的规则优先生效

12.4 规则顺序的重要性

规则匹配是自上而下的:

规则 1: ALLOW from 192.168.1.0/24 port 22   ← 内网允许 SSH
规则 2: DENY  from anywhere port 22          ← 其他拒绝 SSH

如果调换顺序:
规则 1: DENY  from anywhere port 22          ← 所有 IP 被拒绝
规则 2: ALLOW from 192.168.1.0/24 port 22   ← 永远不会匹配!
# 使用 insert 确保规则顺序正确
sudo ufw insert 1 allow from 192.168.1.0/24 to any port 22 proto tcp
sudo ufw insert 2 deny to any port 22 proto tcp

12.5 重置防火墙

# ⚠️ 重置所有规则(不可恢复!)
sudo ufw reset

# 输出:
# Resetting all rules to installed defaults. Proceed with operation (y|n)? y
#
# Backing up 'user.rules' to '/etc/ufw/user.rules.20260731_000000'
# Backing up 'user6.rules' to '/etc/ufw/user6.rules.20260731_000000'
# Backing up 'before.rules' to '/etc/ufw/before.rules.20260731_000000'
# Backing up 'after.rules' to '/etc/ufw/after.rules.20260731_000000'

# 好消息:reset 会自动备份旧规则

12.6 显示报告

# 显示各种报告
sudo ufw show added       # 显示已添加的规则
sudo ufw show listening   # 显示监听端口
sudo ufw show raw         # 显示原始 iptables 规则

# 示例输出(listening)
# Listening on:
#   22/tcp (OpenSSH)
#   80/tcp (nginx)
#   443/tcp (nginx)
#   3306/tcp (mysqld)

13. IPv6 支持

13.1 检查 IPv6 是否启用

# 查看配置文件
cat /etc/default/ufw | grep IPV6
# 输出:IPV6=yes 表示已启用

13.2 启用/禁用 IPv6

# 编辑配置文件
sudo nano /etc/default/ufw

# 确保 IPv6=yes
IPV6=yes

# 重载配置
sudo ufw reload

13.3 IPv6 规则示例

# 启用 IPv6 后,ufw allow 会同时生成 IPv4 和 IPv6 规则
sudo ufw allow 80/tcp
# 生成:
# [1] 80/tcp    ALLOW IN  Anywhere       (IPv4)
# [2] 80/tcp    ALLOW IN  Anywhere (v6)  (IPv6)

# 仅允许 IPv6(需要在规则文件中手动配置)
# 编辑 /etc/ufw/user6.rules

13.4 IPv6 地址语法

# 允许 IPv6 地址
sudo ufw allow from 2001:db8::1 to any port 22 proto tcp

# 允许 IPv6 子网
sudo ufw allow from 2001:db8::/32 to any port 80 proto tcp

14. 配置文件详解

14.1 配置文件目录

/etc/ufw/
├── ufw.conf           # 主配置(启用状态、日志级别)
├── default/           # 默认策略配置
│   ├──.ufw           # 核心默认策略
│   └── forward       # 转发默认策略
├── before.rules       # IPv4 前置规则(NAT/ICMP/回环)
├── before6.rules      # IPv6 前置规则
├── user.rules         # IPv4 用户规则(ufw allow/deny 生成)
├── user6.rules        # IPv6 用户规则
├── after.rules        # IPv4 后置规则
├── after6.rules       # IPv6 后置规则
├── applications.d/    # 应用配置文件目录
│   ├── nginx
│   ├── openssh-server
│   └── ...
└── sysctl.conf        # 内核网络参数(转发等)

14.2 /etc/default/ufw

# 主配置文件
cat /etc/default/ufw

# 关键配置项:
IPV6=yes                    # 启用 IPv6 支持
IPT_SYSCTL=/etc/ufw/sysctl.conf  # sysctl 配置路径
IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_netlink_nflog"  # 加载内核模块

14.3 /etc/ufw/before.rules

前置规则在用户规则之前执行,用于配置 NAT、ICMP、回环等:

# 查看 before.rules
sudo cat /etc/ufw/before.rules

重要部分:

# 回环接口(localhost)
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

# 已建立连接(关键!允许已建立的连接返回)
-A ufw-before-input -m conntrack --ct-state RELATED,ESTABLISHED -j ACCEPT

# ICMP(Ping)
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

# DHCP 回复
-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT

14.4 直接编辑规则文件

# 备份原文件
sudo cp /etc/ufw/before.rules /etc/ufw/before.rules.bak

# 编辑 before.rules
sudo nano /etc/ufw/before.rules

# 修改后重载
sudo ufw reload

15. 端口转发与 NAT

15.1 开启 IP 转发

# 编辑 sysctl 配置
sudo nano /etc/ufw/sysctl.conf

# 取消注释或添加
net/ipv4/ip_forward=1
net/ipv6/conf/all/forwarding=1

# 应用更改
sudo sysctl -p

15.2 设置默认转发策略

# 允许转发
sudo ufw default allow routed

15.3 配置端口转发

编辑 /etc/ufw/before.rules,在 filter 段之前添加 NAT 规则:

sudo nano /etc/ufw/before.rules
# 在文件顶部,*filter 段之前添加:

*nat
:PREROUTING ACCEPT [0:0]

# 端口转发:外部 8080 → 内部 10.0.0.10:80
-A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.10:80

# 端口转发:外部 2222 → 内部 10.0.0.20:22
-A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 10.0.0.20:22

# MASQUERADE(内网共享上网)
-A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

COMMIT
# === filter 段在下面 ===
# 重载
sudo ufw reload

15.4 转发规则示例

# 添加 UFW 转发规则(允许转发到内部服务器的流量)
sudo ufw route allow proto tcp to 10.0.0.10 port 80 comment '转发到内部 Web'
sudo ufw route allow proto tcp to 10.0.0.20 port 22 comment '转发到内部 SSH'

# 拒绝某些转发
sudo ufw route deny proto tcp to 10.0.0.0/24 port 3306 comment '禁止转发到数据库'

16. UFW 与 Docker

⚠️ 重大问题:Docker 会直接修改 iptables,绕过 UFW 规则!

16.1 问题说明

Docker 容器端口映射(-p 8080:80)时:
1. Docker 直接向 iptables 的 DOCKER 链添加 DNAT 规则
2. 这些规则在 UFW 的 filter 规则之前执行
3. 导致即使 UFW deny 了 8080 端口,外部仍然可以访问

结果:你以为 UFW 保护了服务器,实际上 Docker 端口全部暴露在公网!

16.2 解决方案一:绑定到 127.0.0.1(推荐)

# 将 Docker 端口绑定到本地回环地址
docker run -p 127.0.0.1:8080:80 nginx

# 或在 docker-compose.yml 中
services:
  web:
    image: nginx
    ports:
      - "127.0.0.1:8080:80"    # 仅本地可访问
    # 配合反向代理(Nginx)对外提供服务

16.3 解决方案二:使用 ufw-docker 脚本

# 下载 ufw-docker 工具
sudo wget -O /usr/local/bin/ufw-docker \
  https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker

# 安装(会修改 UFW after.rules 拦截 Docker 流量)
sudo ufw-docker install
sudo ufw reload

# 为容器添加 UFW 规则
sudo ufw-docker allow <容器名> 80/tcp
sudo ufw-docker allow <容器名> 443/tcp

# 查看容器规则
sudo ufw-docker status <容器名>

16.4 解决方案三:禁用 Docker iptables 管理

# 编辑 /etc/docker/daemon.json
sudo nano /etc/docker/daemon.json

{
  "iptables": false
}

# 重启 Docker
sudo systemctl restart docker

# ⚠️ 副作用:Docker 容器网络功能受限(NAT、DNS 等可能不正常)
# 仅适合简单场景,不推荐生产环境

17. UFW 与 Fail2Ban 集成

17.1 安装 Fail2Ban

sudo apt install fail2ban

17.2 配置 Fail2Ban 使用 UFW

# 创建本地配置
sudo tee /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# 使用 UFW 作为封禁动作
banaction = ufw

# 封禁时间:1 小时
bantime = 3600

# 检测时间窗口:10 分钟
findtime = 600

# 最大尝试次数
maxretry = 3

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
EOF

# 重启 Fail2Ban
sudo systemctl restart fail2ban

17.3 验证集成

# 查看 Fail2Ban 状态
sudo fail2ban-client status sshd

# 查看被 UFW 封禁的 IP
sudo ufw status | grep -i "f2b"

# 手动解封
sudo fail2ban-client set sshd unbanip 203.0.113.50

18. 出站流量控制

18.1 默认允许出站

# 默认策略(推荐)
sudo ufw default allow outgoing

18.2 限制出站(高安全场景)

# 切换为默认拒绝出站
sudo ufw default deny outgoing

# 逐条放行必要服务
sudo ufw allow out 53/udp comment 'DNS 查询'
sudo ufw allow out 80/tcp comment 'HTTP'
sudo ufw allow out 443/tcp comment 'HTTPS'
sudo ufw allow out 123/udp comment 'NTP 时间同步'

# 放行软件源
sudo ufw allow out to any port 80 proto tcp comment 'APT 更新'

# 放行 SMTP(按需)
sudo ufw allow out 587/tcp comment 'SMTP 发信'

18.3 出站规则示例

# 仅允许特定服务器外发 DNS
sudo ufw allow out from any to 8.8.8.8 port 53 proto udp comment 'Google DNS'

# 禁止服务器外发邮件(防止垃圾邮件)
sudo ufw deny out 25/tcp comment '禁止直接 SMTP'

# 禁止特定 IP 出站
sudo ufw deny out to 203.0.113.50 comment '禁止访问恶意 IP'

19. 实战场景合集

场景 1:Web 服务器安全配置

#!/bin/bash
# === Web 服务器标准 UFW 配置 ===

# 重置
sudo ufw reset

# 默认策略
sudo ufw default deny incoming
sudo ufw default allow outgoing

# 放行 SSH(限制频率防暴力破解)
sudo ufw limit 22/tcp comment 'SSH 限频'

# 放行 Web 服务
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# 日志
sudo ufw logging low

# 启用
sudo ufw enable

# 验证
sudo ufw status verbose

场景 2:数据库服务器

#!/bin/bash
# === 数据库服务器配置(仅内网访问) ===

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH 仅限管理网段
sudo ufw allow from 10.0.0.0/8 to any port 22 proto tcp comment '管理网段 SSH'

# MySQL 仅限内网
sudo ufw allow from 10.0.0.0/8 to any port 3306 proto tcp comment '内网 MySQL'

# PostgreSQL 仅限内网
sudo ufw allow from 10.0.0.0/8 to any port 5432 proto tcp comment '内网 PostgreSQL'

# Redis 仅限内网
sudo ufw allow from 10.0.0.0/8 to any port 6379 proto tcp comment '内网 Redis'

# MongoDB 仅限内网
sudo ufw allow from 10.0.0.0/8 to any port 27017 proto tcp comment '内网 MongoDB'

# 禁止 Ping
sudo sed -i '/icmp-type echo-request/s/ACCEPT/DROP/' /etc/ufw/before.rules

sudo ufw logging low
sudo ufw enable

场景 3:邮件服务器

#!/bin/bash
# === 邮件服务器配置 ===

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH
sudo ufw limit 22/tcp comment 'SSH'

# SMTP(接收邮件)
sudo ufw allow 25/tcp comment 'SMTP'

# SMTP Submission(客户端发信认证)
sudo ufw allow 587/tcp comment 'SMTP Submission'

# SMTPS(加密 SMTP)
sudo ufw allow 465/tcp comment 'SMTPS'

# IMAP
sudo ufw allow 143/tcp comment 'IMAP'

# IMAPS(加密 IMAP)
sudo ufw allow 993/tcp comment 'IMAPS'

# POP3
sudo ufw allow 110/tcp comment 'POP3'

# POP3S(加密 POP3)
sudo ufw allow 995/tcp comment 'POP3S'

# 限制出站:只允许必要的邮件相关端口
sudo ufw logging medium
sudo ufw enable

场景 4:VPN 服务器(WireGuard)

#!/bin/bash
# === WireGuard VPN 服务器 ===

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH
sudo ufw limit 22/tcp comment 'SSH'

# WireGuard
sudo ufw allow 51820/udp comment 'WireGuard VPN'

# 开启转发(VPN 需要路由流量)
sudo ufw default allow routed

# 编辑 /etc/ufw/before.rules 添加 NAT
# *nat
# :POSTROUTING ACCEPT [0:0]
# -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
# COMMIT

# 编辑 /etc/ufw/sysctl.conf
# net/ipv4/ip_forward=1

# 允许 VPN 客户端之间的流量
sudo ufw allow in on wg0
sudo ufw allow out on wg0

sudo ufw logging low
sudo ufw enable

场景 5:游戏服务器

#!/bin/bash
# === Minecraft 游戏服务器 ===

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH
sudo ufw limit 22/tcp comment 'SSH'

# Minecraft Java 版
sudo ufw allow 25565/tcp comment 'Minecraft Java'

# Minecraft 基岩版
sudo ufw allow 19132/udp comment 'Minecraft Bedrock'

# RCON(远程控制台,仅限内网)
sudo ufw allow from 192.168.1.0/24 to any port 25575/tcp comment 'RCON 内网'

# 限制查询频率
sudo ufw logging medium
sudo ufw enable

场景 6:Docker + 反向代理服务器

#!/bin/bash
# === Docker + Nginx 反向代理 ===

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH
sudo ufw limit 22/tcp comment 'SSH'

# 公网 Web
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# Docker 容器绑定 127.0.0.1(不直接暴露)
# docker run -p 127.0.0.1:3000:3000 my-app

# 内部服务(仅本地)
# Nginx 反向代理 127.0.0.1:3000 → 公网 443

# 安装 ufw-docker 防护
sudo wget -O /usr/local/bin/ufw-docker \
  https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker
sudo ufw-docker install

sudo ufw logging low
sudo ufw enable
sudo ufw reload

场景 7:多网卡 Web+DB 服务器

#!/bin/bash
# === 双网卡服务器:eth0 公网,eth1 内网 ===

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH 仅内网
sudo ufw allow in on eth1 from 192.168.1.0/24 to any port 22 proto tcp comment '内网 SSH'

# 公网 Web
sudo ufw allow in on eth0 to any port 80 proto tcp comment '公网 HTTP'
sudo ufw allow in on eth0 to any port 443 proto tcp comment '公网 HTTPS'

# 内网数据库
sudo ufw allow in on eth1 from 192.168.1.0/24 to any port 3306 proto tcp comment '内网 MySQL'
sudo ufw allow in on eth1 from 192.168.1.0/24 to any port 6379 proto tcp comment '内网 Redis'

# 内网监控(Prometheus node_exporter)
sudo ufw allow in on eth1 from 192.168.1.100 to any port 9100 proto tcp comment 'Prometheus'

# 禁止公网网卡访问数据库
sudo ufw deny in on eth0 to any port 3306 proto tcp
sudo ufw deny in on eth0 to any port 6379 proto tcp

sudo ufw logging low
sudo ufw enable

场景 8:CI/CD Runner 服务器

#!/bin/bash
# === GitLab Runner / GitHub Actions Runner ===

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH
sudo ufw limit 22/tcp comment 'SSH'

# Docker 远程 API(仅限内网 CI 服务器)
sudo ufw allow from 192.168.1.0/24 to any port 2376 proto tcp comment 'Docker API 内网'

# 允许出站拉取镜像、推送等
sudo ufw allow out 443/tcp comment 'HTTPS'
sudo ufw allow out 53/udp comment 'DNS'

sudo ufw logging low
sudo ufw enable

20. 故障排查

20.1 常见问题

问题 原因 解决方案
SSH 连不上 启用 UFW 前没放行 SSH 通过 VNC/控制台登录,ufw allow ssh 或 ufw disable
网站打不开 80/443 未放行 ufw allow 80/tcp && ufw allow 443/tcp
Docker 端口绕过 UFW Docker 直接操作 iptables 使用 ufw-docker 或绑定 127.0.0.1
Ping 不通 before.rules 中 ICMP 被 DROP 改回 ACCEPT 或检查 before.rules
DNS 解析失败 出站 UDP 53 被拦截 ufw allow out 53/udp
apt 更新失败 出站 80/443 被拦截 ufw allow out 80/tcp && ufw allow out 443/tcp
规则不生效 未重载 ufw reload
IPv6 规则缺失 IPV6=no 编辑 /etc/default/ufw 设为 yes

20.2 调试命令

# 查看 UFW 生成的完整 iptables 规则
sudo iptables -L -n -v | grep -i ufw

# 查看 NAT 表
sudo iptables -t nat -L -n -v

# 查看某个端口的规则链
sudo iptables -L -n -v | grep -E "dpt:(80|443)"

# 测试端口是否可达(从外部)
nc -zv <服务器IP> 80
curl -I http://<服务器IP>

# 检查监听端口
sudo ss -tlnp
sudo netstat -tlnp

# 查看规则匹配计数(判断规则是否被命中)
sudo ufw status verbose

20.3 紧急恢复

# 情况:SSH 被锁,通过 VNC/控制台登录后

# 方案一:禁用 UFW
sudo ufw disable

# 方案二:放行 SSH
sudo ufw allow ssh

# 方案三:重置所有规则
sudo ufw reset
sudo ufw allow ssh
sudo ufw enable

20.4 规则备份与恢复

# 备份规则
sudo cp /etc/ufw/user.rules ~/user.rules.backup
sudo cp /etc/ufw/user6.rules ~/user6.rules.backup

# 恢复规则
sudo cp ~/user.rules.backup /etc/ufw/user.rules
sudo cp ~/user6.rules.backup /etc/ufw/user6.rules
sudo ufw reload

21. 常用速查表

21.1 命令速查

# === 基础 ===
sudo ufw enable/disable           # 启用/禁用
sudo ufw reload                   # 重载
sudo ufw reset                    # 重置
sudo ufw status                   # 查看状态
sudo ufw status verbose           # 详细状态
sudo ufw status numbered          # 带编号

# === 默认策略 ===
sudo ufw default deny incoming    # 拒绝入站
sudo ufw default allow outgoing   # 允许出站
sudo ufw default deny routed      # 拒绝转发

# === 放行 ===
sudo ufw allow 80/tcp             # 放行端口
sudo ufw allow ssh                # 放行服务名
sudo ufw allow "Nginx Full"       # 放行应用
sudo ufw allow from 10.0.0.0/8    # 放行网段
sudo ufw allow out 443/tcp        # 放行出站

# === 拒绝 ===
sudo ufw deny 3306/tcp            # 拒绝端口
sudo ufw deny from 203.0.113.50   # 封禁 IP
sudo ufw reject 3306              # 拒绝并通知

# === 限制 ===
sudo ufw limit ssh                # 限频(防暴力破解)
sudo ufw limit 22/tcp

# === 删除 ===
sudo ufw delete 3                 # 按编号删除
sudo ufw delete allow 80/tcp      # 按语法删除

# === 插入 ===
sudo ufw insert 1 allow from 10.0.0.0/8  # 插入到第 1 位

# === 日志 ===
sudo ufw logging on               # 开启日志
sudo ufw logging medium            # 设置级别
sudo ufw logging off              # 关闭日志

# === 应用 ===
sudo ufw app list                 # 列出应用
sudo ufw app info OpenSSH         # 查看应用详情

# === 报告 ===
sudo ufw show added               # 已添加规则
sudo ufw show listening           # 监听端口
sudo ufw show raw                 # 原始规则

21.2 常用端口速查

# Web
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# SSH
sudo ufw limit 22/tcp comment 'SSH'

# 数据库
sudo ufw allow from 10.0.0.0/8 to any port 3306/tcp comment 'MySQL 内网'
sudo ufw allow from 10.0.0.0/8 to any port 5432/tcp comment 'PostgreSQL 内网'
sudo ufw allow from 10.0.0.0/8 to any port 6379/tcp comment 'Redis 内网'
sudo ufw allow from 10.0.0.0/8 to any port 27017/tcp comment 'MongoDB 内网'

# 邮件
sudo ufw allow 25/tcp comment 'SMTP'
sudo ufw allow 587/tcp comment 'SMTP Submission'
sudo ufw allow 993/tcp comment 'IMAPS'

# DNS
sudo ufw allow 53/tcp comment 'DNS TCP'
sudo ufw allow 53/udp comment 'DNS UDP'

# FTP
sudo ufw allow 21/tcp comment 'FTP'
sudo ufw allow 49000:50000/tcp comment 'FTP 被动'

# VPN
sudo ufw allow 51820/udp comment 'WireGuard'
sudo ufw allow 1194/udp comment 'OpenVPN'

# 其他
sudo ufw allow 123/udp comment 'NTP'
sudo ufw allow 3389/tcp comment 'RDP'

21.3 一键初始化脚本

#!/bin/bash
# === UFW 标准初始化 ===

echo "配置 UFW 防火墙..."

# 重置
sudo ufw --force reset

# 默认策略
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw default deny routed

# 放行 SSH(限频)
sudo ufw limit 22/tcp comment 'SSH'

# 放行 Web
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# 日志
sudo ufw logging low

# 启用
sudo ufw --force enable

# 显示结果
sudo ufw status verbose

echo "✅ UFW 配置完成"

21.4 规则语法完整参考

ufw allow|deny|reject|limit \
  [in|out] \
  [on INTERFACE] \
  [log|log-all] \
  [proto tcp|udp] \
  [from ADDRESS[/CIDR] [port PORT]] \
  [to ADDRESS[/CIDR] [port PORT]] \
  [comment '描述']

# 简写
ufw allow PORT[/PROTOCOL]
ufw allow SERVICE_NAME
ufw allow APP_NAME

# 方向
ufw allow in PORT       # 入站
ufw allow out PORT      # 出站

# 完整示例
ufw allow in on eth0 proto tcp from 192.168.1.0/24 to any port 22 comment '内网 SSH'

提示:UFW 是 iptables 的前端工具,适合大多数服务器防火墙管理场景。如需更复杂的网络功能(如深度包检测、多层 NAT、流量整形等),请直接使用 iptables/nftables。最新文档请参考 man ufw。

posted @ 2026-09-29 10:48  直角漫步  阅读(224)  评论(0)    收藏  举报