Ubuntu 22.04 防火墙管理 ufw 命令与配置详解

Ubuntu 22.04 系统 UFW 防火墙的安装(在线 apt 与离线 deb)与 ufw 全部常用命令参数实测详解,含 allow/deny/delete、应用配置、状态查看与实战演练

Linux 安全与审计UFW防火墙Ubuntu 22.04安全加固2026/10/06

Ubuntu 22.04 防火墙管理 ufw 命令与配置详解

目标:掌握 Ubuntu 22.04 系统 UFW 防火墙的在线(apt)与离线(deb + dpkg)安装,逐条实测 ufw 常用命令与参数,深入理解其 iptables 前端封装原理与规则文件生成机制,并能在真实环境中完成端口放行、IP 封禁、规则编号管理、状态核查与排障。本文所有命令输出均为 Ubuntu 22.04 真实环境实测回显(ufw 0.36.1)。

一、环境信息

项目实测值
操作系统Ubuntu 22.04.5 LTS(/etc/os-release 中 PRETTY_NAME="Ubuntu 22.04.5 LTS")
内核版本6.8.0-138-generic(uname -r 实测输出)
ufw 版本ufw 0.36.1(ufw --version 实测;apt 包为 ufw_0.36.1-4ubuntu0.1_all.deb)
规则后端iptables(安装时自动切换为 iptables-nft:update-alternatives: using /usr/sbin/iptables-nft to provide /usr/sbin/iptables)
主要配置文件/etc/default/ufw(策略主配置)、/etc/ufw/ufw.conf(启用状态)、/etc/ufw/*.rules(规则文件)
默认策略deny (incoming)、allow (outgoing)、deny (routed)(ufw status verbose 实测)
测试机网络eth0:172.17.0.14/16(hostname -I 实测)
systemd 单元ufw.service(Type=oneshot,ExecStart=/lib/ufw/ufw-init start quiet)

二、工具概述

UFW(Uncomplicated Firewall,非复杂防火墙)是 Ubuntu/Debian 生态默认的防火墙管理工具,定位是 iptables 的极简前端封装:用户只需要用 allow / deny / reject 等人类可读的规则描述,UFW 在背后把规则翻译成 iptables 规则并维护一套独立的链体系。

工作原理:iptables 前端 + 配置文件生成机制

  • 用户通过 ufw 命令维护规则时,规则同时被写入:
    • iptables 运行时(立即生效,可通过 iptables -L 查看);
    • 持久化规则文件 /etc/ufw/user.rules(IPv4)与 /etc/ufw/user6.rules(IPv6),以 iptables-restore 格式保存,重启后由 /lib/ufw/ufw-init 自动加载。
  • 启动/重载时,ufw 按固定顺序加载:before*.rules(预置基础规则,如放行回环、established 连接)→ user*.rules(用户规则)→ after*.rules(收尾规则,如默认拒绝日志)。
  • ufw 只操作自己的链(ufw-user-input 等),不会触碰系统内其他 iptables 规则(MANAGE_BUILTINS=no 时连 INPUT 链本身也不接管,只把 ufw-user-input 等链挂到内置链上)。
  • IPv6 默认启用(/etc/default/ufw 中 IPV6=yes),每条规则默认同时生成 v4 与 v6 两条,命令行回显为 Rules updated / Rules updated (v6)。

规则链结构(实测)

启用后 iptables -L INPUT -n --line-numbers 实测回显:

Chain INPUT (policy DROP)
num  target     prot opt source               destination         
1    ufw-before-logging-input  all  --  0.0.0.0/0            0.0.0.0/0           
2    ufw-before-input  all  --  0.0.0.0/0            0.0.0.0/0           
3    ufw-after-input  all  --  0.0.0.0/0            0.0.0.0/0           
4    ufw-after-logging-input  all  --  0.0.0.0/0            0.0.0.0/0           
5    ufw-reject-input  all  --  0.0.0.0/0            0.0.0.0/0           
6    ufw-track-input  all  --  0.0.0.0/0            0.0.0.0/0           

💡 用户的 allow/deny 规则实际挂在 ufw-user-input 链中(见“实战演练”)。

与 firewalld 对比

  • UFW:命令直观、配置集中在少数文件,适合单机、策略简单的服务器;是 Ubuntu/Debian 默认方案。
  • firewalld:区域(zone)化策略模型,适合多网卡、多信任级别的复杂场景;是 RHEL/CentOS 默认方案。
  • 二者不能同时运行(都会接管 iptables/nftables 规则,互相冲突),迁移发行版时需先停用其一。

三、在线安装方案

3.1 apt 在线安装

Ubuntu 22.04 的 ufw 通常预装;未安装时用 apt 安装:

DEBIAN_FRONTEND=noninteractive apt-get install -y ufw

💡 DEBIAN_FRONTEND=noninteractive 跳过安装过程中的交互提示(本环境未装 apt-utils,回显中有 debconf 降级提示,属正常现象)。

实测完整回显:

Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  iptables libip6tc2 libmnl0 libnetfilter-conntrack3 libnfnetlink0 libnftnl11
  libxtables12 netbase ucf
Suggested packages:
  firewalld kmod nftables rsyslog
The following NEW packages will be installed:
  iptables libip6tc2 libmnl0 libnetfilter-conntrack3 libnfnetlink0 libnftnl11
  libxtables12 netbase ucf ufw
0 upgraded, 10 newly installed, 0 to remove and 10 not upgraded.
Need to get 877 kB of archives.
After this operation, 4710 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy/main amd64 libmnl0 amd64 1.0.4-3build2 [13.2 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 libxtables12 amd64 1.8.7-1ubuntu5.2 [31.3 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy/main amd64 netbase all 6.3 [12.9 kB]
Get:4 http://archive.ubuntu.com/ubuntu jammy/main amd64 ucf all 3.0043 [56.1 kB]
Get:5 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 libip6tc2 amd64 1.8.7-1ubuntu5.2 [20.3 kB]
Get:6 http://archive.ubuntu.com/ubuntu jammy/main amd64 libnfnetlink0 amd64 1.0.1-3build3 [14.6 kB]
Get:7 http://archive.ubuntu.com/ubuntu jammy/main amd64 libnetfilter-conntrack3 amd64 1.0.9-1 [45.3 kB]
Get:8 http://archive.ubuntu.com/ubuntu jammy/main amd64 libnftnl11 amd64 1.2.1-1build1 [65.5 kB]
Get:9 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 iptables amd64 1.8.7-1ubuntu5.2 [455 kB]
Get:10 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 ufw all 0.36.1-4ubuntu0.1 [162 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 877 kB in 2s (546 kB/s)
Selecting previously unselected package libmnl0:amd64.
(Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 6535 files and directories currently installed.)
Preparing to unpack .../0-libmnl0_1.0.4-3build2_amd64.deb ...
Unpacking libmnl0:amd64 (1.0.4-3build2) ...
Selecting previously unselected package libxtables12:amd64.
Preparing to unpack .../1-libxtables12_1.8.7-1ubuntu5.2_amd64.deb ...
Unpacking libxtables12:amd64 (1.8.7-1ubuntu5.2) ...
Selecting previously unselected package netbase.
Preparing to unpack .../2-netbase_6.3_all.deb ...
Unpacking netbase (6.3) ...
Selecting previously unselected package ucf.
Preparing to unpack .../3-ucf_3.0043_all.deb ...
Moving old data out of the way
Unpacking ucf (3.0043) ...
Selecting previously unselected package libip6tc2:amd64.
Preparing to unpack .../4-libip6tc2_1.8.7-1ubuntu5.2_amd64.deb ...
Unpacking libip6tc2:amd64 (1.8.7-1ubuntu5.2) ...
Selecting previously unselected package libnfnetlink0:amd64.
Preparing to unpack .../5-libnfnetlink0_1.0.1-3build3_amd64.deb ...
Unpacking libnfnetlink0:amd64 (1.0.1-3build3) ...
Selecting previously unselected package libnetfilter-conntrack3:amd64.
Preparing to unpack .../6-libnetfilter-conntrack3_1.0.9-1_amd64.deb ...
Unpacking libnetfilter-conntrack3:amd64 (1.0.9-1) ...
Selecting previously unselected package libnftnl11:amd64.
Preparing to unpack .../7-libnftnl11_1.2.1-1build1_amd64.deb ...
Unpacking libnftnl11:amd64 (1.2.1-1build1) ...
Selecting previously unselected package iptables.
Preparing to unpack .../8-iptables_1.8.7-1ubuntu5.2_amd64.deb ...
Unpacking iptables (1.8.7-1ubuntu5.2) ...
Selecting previously unselected package ufw.
Preparing to unpack .../9-ufw_0.36.1-4ubuntu0.1_all.deb ...
Unpacking ufw (0.36.1-4ubuntu0.1) ...
Setting up libip6tc2:amd64 (1.8.7-1ubuntu5.2) ...
Setting up libmnl0:amd64 (1.0.4-3build2) ...
Setting up ucf (3.0043) ...
Setting up libxtables12:amd64 (1.8.7-1ubuntu5.2) ...
Setting up libnfnetlink0:amd64 (1.0.1-3build3) ...
Setting up netbase (6.3) ...
Setting up libnftnl11:amd64 (1.2.1-1build1) ...
Setting up libnetfilter-conntrack3:amd64 (1.0.9-1) ...
Setting up iptables (1.8.7-1ubuntu5.2) ...
update-alternatives: using /usr/sbin/iptables-legacy to provide /usr/sbin/iptables (iptables) in auto mode
update-alternatives: using /usr/sbin/ip6tables-legacy to provide /usr/sbin/ip6tables (ip6tables) in auto mode
update-alternatives: using /usr/sbin/iptables-nft to provide /usr/sbin/iptables (iptables) in auto mode
update-alternatives: using /usr/sbin/ip6tables-nft to provide /usr/sbin/ip6tables (ip6tables) in auto mode
update-alternatives: using /usr/sbin/arptables-nft to provide /usr/sbin/arptables (arptables) in auto mode
update-alternatives: using /usr/sbin/ebtables-nft to provide /usr/sbin/ebtables (ebtables) in auto mode
Setting up ufw (0.36.1-4ubuntu0.1) ...

Creating config file /etc/ufw/before.rules with new version

Creating config file /etc/ufw/before6.rules with new version

Creating config file /etc/ufw/after.rules with new version

Creating config file /etc/ufw/after6.rules with new version
Created symlink /etc/systemd/system/multi-user.target.wants/ufw.service → /lib/systemd/system/ufw.service.
Processing triggers for libc-bin (2.35-0ubuntu3.14) ...

💡 关键点:安装时自动创建 before*.rules / after*.rules 配置文件,并注册 ufw.service 开机自启(但此时防火墙默认未启用,规则尚未应用)。

3.2 验证安装

ufw --version
ufw 0.36.1
Copyright 2008-2021 Canonical Ltd.
ufw status
Status: inactive

⚠️ 刚安装完的 ufw 处于 inactive(未启用)状态,此时无任何过滤效果,需先添加放行规则再 ufw enable(见“注意事项”第 1 条)。

四、离线安装方案

离线场景下,先在可联网机器上下载 ufw 及其依赖 deb 包,再拷贝到目标机器安装。

4.1 联网机器下载 deb 包(apt download)

cd /tmp
apt download ufw

实测回显:


WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

下载结果:

ls -lh ufw_0.36.1-4ubuntu0.1_all.deb
-rw-r--r-- 1 root root 159K Jul 21  2023 ufw_0.36.1-4ubuntu0.1_all.deb

💡 apt download 只下载主包,不含依赖。ufw 的依赖(安装时已列出):iptables、lsb-base (>= 3.0-6)、ucf、python3:any、debconf (>= 0.5)。需要一并离线携带时,可逐个 apt download iptables libip6tc2 libmnl0 libnetfilter-conntrack3 libnfnetlink0 libnftnl11 libxtables12 netbase ucf,或在联网机器上用 apt-get --print-uris 输出完整下载清单。deb 包也可在 https://packages.ubuntu.com/ 按发行版(jammy/22.04)与架构手动下载。

4.2 校验 deb 包元数据(可选)

dpkg -I ufw_0.36.1-4ubuntu0.1_all.deb

实测输出(头部):

 new Debian package, version 2.0.
 size 162368 bytes: control archive=15475 bytes.
     102 bytes,     5 lines      conffiles
    1967 bytes,    73 lines   *  config               #!/bin/sh
     609 bytes,    15 lines      control
    5167 bytes,    78 lines      md5sums
    6028 bytes,   197 lines   *  postinst             #!/bin/sh
    2342 bytes,    75 lines   *  postrm               #!/bin/sh
    1188 bytes,    26 lines   *  preinst              #!/bin/sh
     817 bytes,    26 lines   *  prerm                #!/bin/sh
   22655 bytes,   323 lines      templates
      41 bytes,     1 lines      triggers
 Package: ufw
 Version: 0.36.1-4ubuntu0.1
 Architecture: all
 Maintainer: Jamie Strandboge <jdstrand@ubuntu.com>
 Installed-Size: 830
 Depends: iptables, lsb-base (>= 3.0-6), ucf, python3:any, debconf (>= 0.5) | debconf-2.0
 Suggests: rsyslog
 Section: admin
 Priority: optional
 Homepage: https://launchpad.net/ufw

💡 Architecture: all 表示 ufw 是纯脚本/Python 包,不区分架构,任何 x86_64 / arm64 机器都能安装。Depends 字段列出全部依赖,离线安装前需逐一满足。

4.3 目标机器安装(dpkg -i)

把 deb 包拷贝到目标机器后执行:

dpkg -i ufw_0.36.1-4ubuntu0.1_all.deb

实测回显(目标机器已具备全部依赖,直接安装成功):

(Reading database ... 40654 files and directories currently installed.)
Preparing to unpack ufw_0.36.1-4ubuntu0.1_all.deb ...
Unpacking ufw (0.36.1-4ubuntu0.1) over (0.36.1-4ubuntu0.1) ...
Setting up ufw (0.36.1-4ubuntu0.1) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
Processing triggers for rsyslog (8.2112.0-2ubuntu2.5) ...
invoke-rc.d: policy-rc.d denied execution of try-restart.

⚠️ 预期输出差异(全新安装时):以上为“已装同版本再安装”的回显(Unpacking ufw ... over (...))。在未安装过 ufw 的机器上,dpkg -i 的对应行会变为 Selecting previously unselected package ufw. / Unpacking ufw (0.36.1-4ubuntu0.1) ...,其余流程一致(本文未在全新环境实测此差异行)。

若目标机器缺少依赖,dpkg -i 会报 dependency problems - leaving unconfigured,此时需用 apt-get -f install(在线)或补齐 deb 依赖包后再 dpkg -i。离线机器最稳妥的顺序:先装底层依赖(libmnl0、libnfnetlink0、libnftnl11、libxtables12、libip6tc2、iptables、netbase、ucf),最后装 ufw。

安装后验证与启用:

ufw --version
ufw status
ufw 0.36.1
Copyright 2008-2021 Canonical Ltd.
Status: inactive

五、配置详解

5.1 主策略配置 /etc/default/ufw

这是 ufw 最核心的配置文件,控制 IPv6、默认策略与内核参数挂载等。完整内容如下:

cat /etc/default/ufw
# /etc/default/ufw
#

# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take affect.
IPV6=yes

# Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_INPUT_POLICY="DROP"

# Set the default output policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_OUTPUT_POLICY="ACCEPT"

# Set the default forward policy to ACCEPT, DROP or REJECT.  Please note that
# if you change this you will most likely want to adjust your rules
DEFAULT_FORWARD_POLICY="DROP"

# Set the default application policy to ACCEPT, DROP, REJECT or SKIP. Please
# note that setting this to ACCEPT may be a security risk. See 'man ufw' for
# details
DEFAULT_APPLICATION_POLICY="SKIP"

# By default, ufw only touches its own chains. Set this to 'yes' to have ufw
# manage the built-in chains too. Warning: setting this to 'yes' will break
# non-ufw managed firewall rules
MANAGE_BUILTINS=no

#
# IPT backend
#
# only enable if using iptables backend
IPT_SYSCTL=/etc/ufw/sysctl.conf

# Extra connection tracking modules to load. IPT_MODULES should typically be
# empty for new installations and modules added only as needed. See
# 'CONNECTION HELPERS' from 'man ufw-framework' for details. Complete list can
# be found in net/netfilter/Kconfig of your kernel source. Some common modules:
# nf_conntrack_irc, nf_nat_irc: DCC (Direct Client to Client) support
# nf_conntrack_netbios_ns: NetBIOS (samba) client support
# nf_conntrack_pptp, nf_nat_pptp: PPTP over stateful firewall/NAT
# nf_conntrack_ftp, nf_nat_ftp: active FTP support
# nf_conntrack_tftp, nf_nat_tftp: TFTP support (server side)
# nf_conntrack_sane: sane support
IPT_MODULES=""

关键配置项说明:

配置项默认值作用说明
IPV6=yesyes是否应用 IPv6 规则;改为 no 后仅回环 IPv6 放行。修改后需 ufw disable + ufw enable 生效
DEFAULT_INPUT_POLICY="DROP"DROP入站默认策略:DROP(丢弃)/ ACCEPT / REJECT。改宽会暴露端口,需同步调整规则
DEFAULT_OUTPUT_POLICY="ACCEPT"ACCEPT出站默认策略,默认全部放行
DEFAULT_FORWARD_POLICY="DROP"DROP转发默认策略:DROP。做路由器/NAT 网关时需改为 ACCEPT
DEFAULT_APPLICATION_POLICY="SKIP"SKIP应用配置文件的默认策略:SKIP(忽略新 profile)/ ACCEPT / DROP / REJECT。改为 ACCEPT 有安全风险
MANAGE_BUILTINS=nono是否接管内置链(INPUT/OUTPUT/FORWARD)。yes 会破坏其他非 ufw 管理的 iptables 规则(如 docker)
IPT_SYSCTL=/etc/ufw/sysctl.conf/etc/ufw/sysctl.confiptables 后端要挂载的内核参数文件
IPT_MODULES=""空额外加载的连接跟踪模块(FTP/TFTP/IRC 等),按需填写

5.2 启用状态配置 /etc/ufw/ufw.conf

cat /etc/ufw/ufw.conf
# /etc/ufw/ufw.conf
#

# Set to yes to start on boot. If setting this remotely, be sure to add a rule
# to allow your remote connection before starting ufw. Eg: 'ufw allow 22/tcp'
ENABLED=yes

# Please use the 'ufw' command to set the loglevel. Eg: 'ufw logging medium'.
# See 'man ufw' for details.
LOGLEVEL=low
配置项说明
ENABLED=yes是否在开机时应用防火墙规则(由 ufw enable/ufw disable 自动改写)
LOGLEVEL=low日志级别(与 ufw logging 命令联动):off / low / medium / high

5.3 规则文件 /etc/ufw/ 目录

ls -la /etc/ufw/
total 116
drwxr-xr-x 3 root root 4096 Oct  6 06:09 .
drwxr-xr-x 1 root root 4096 Oct  6 05:28 ..
-rw-r----- 1 root root 1126 Oct  6 04:58 after.init
-rw-r----- 1 root root 1004 Oct  6 06:09 after.rules
-rw-r----- 1 root root 1004 Jul 17  2023 after.rules.20261006_053020
-rw-r----- 1 root root 1004 Oct  6 05:31 after.rules.20261006_060943
-rw-r----- 1 root root  915 Oct  6 06:09 after6.rules
-rw-r----- 1 root root  915 Jul 17  2023 after6.rules.20261006_053020
-rw-r----- 1 root root  915 Oct  6 05:31 after6.rules.20261006_060943
drwxr-xr-x 2 root root 4096 Oct  6 05:28 applications.d
-rw-r----- 1 root root 1130 Oct  6 04:58 before.init
-rw-r----- 1 root root 2537 Oct  6 06:09 before.rules
-rw-r----- 1 root root 2537 Jul 17  2023 before.rules.20261006_053020
-rw-r----- 1 root root 2537 Oct  6 05:30 before.rules.20261006_060943
-rw-r----- 1 root root 6700 Oct  6 06:09 before6.rules
-rw-r----- 1 root root 6700 Jul 17  2023 before6.rules.20261006_053020
-rw-r----- 1 root root 6700 Oct  6 05:30 before6.rules.20261006_060943
-rw-r--r-- 1 root root 1391 Sep 19  2021 sysctl.conf
-rw-r--r-- 1 root root  313 Oct  6 06:10 ufw.conf
-rw-r----- 1 root root 1592 Oct  6 06:10 user.rules
-rw-r----- 1 root root 1515 Oct  6 04:58 user.rules.20261006_053020
-rw-r----- 1 root root 1532 Oct  6 06:08 user.rules.20261006_060943
-rw-r----- 1 root root 1431 Oct  6 06:10 user6.rules
-rw-r----- 1 root root 1522 Oct  6 04:58 user6.rules.20261006_053020
-rw-r----- 1 root root 1431 Oct  6 06:08 user6.rules.20261006_060943
文件/目录作用
before.rules / before6.rules用户规则之前加载的基础规则:放行回环、已建立连接、合法 ICMP、DHCP 客户端等
user.rules / user6.rulesufw 命令添加的用户规则(iptables-restore 格式,含 ### tuple ### 注释)
after.rules / after6.rules用户规则之后加载的收尾规则(默认拒绝日志、NAT 等)
before.init / after.init加载前后执行的钩子脚本(可加自定义 iptables 命令)
sysctl.confufw 挂载的内核网络参数(禁用 ICMP 重定向等)
ufw.conf启用状态与日志级别(见 5.2)
applications.d/应用配置(profile)文件,被 ufw app list 读取
*.20261006_053020 等ufw reset 时的自动备份文件,可用作规则恢复

5.4 用户规则文件 user.rules 详解

用户通过 ufw 命令添加的规则保存在 user.rules(IPv4)中,格式为 iptables-restore 语法,每条规则上方有 ### tuple ### 注释记录原始命令。实测完整内容(此时已添加 OpenSSH、3306、80、8080、25、22 限速等规则):

cat /etc/ufw/user.rules
*filter
:ufw-user-input - [0:0]
:ufw-user-output - [0:0]
:ufw-user-forward - [0:0]
:ufw-before-logging-input - [0:0]
:ufw-before-logging-output - [0:0]
:ufw-before-logging-forward - [0:0]
:ufw-user-logging-input - [0:0]
:ufw-user-logging-output - [0:0]
:ufw-user-logging-forward - [0:0]
:ufw-after-logging-input - [0:0]
:ufw-after-logging-output - [0:0]
:ufw-after-logging-forward - [0:0]
:ufw-logging-deny - [0:0]
:ufw-logging-allow - [0:0]
:ufw-user-limit - [0:0]
:ufw-user-limit-accept - [0:0]
### RULES ###

### tuple ### allow tcp 22 0.0.0.0/0 any 0.0.0.0/0 OpenSSH - in
-A ufw-user-input -p tcp --dport 22 -j ACCEPT -m comment --comment 'dapp_OpenSSH'

### tuple ### allow any 3306 0.0.0.0/0 any 10.0.0.5 in
-A ufw-user-input -p tcp --dport 3306 -s 10.0.0.5 -j ACCEPT
-A ufw-user-input -p udp --dport 3306 -s 10.0.0.5 -j ACCEPT

### tuple ### allow tcp 80 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 80 -j ACCEPT

### tuple ### deny tcp 8080 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 8080 -j DROP

### tuple ### reject tcp 25 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 25 -j REJECT --reject-with tcp-reset

### tuple ### limit tcp 22 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
-A ufw-user-input -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 30 --hitcount 6 -j ufw-user-limit
-A ufw-user-input -p tcp --dport 22 -j ufw-user-limit-accept

### END RULES ###

### LOGGING ###
-A ufw-after-logging-input -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-A ufw-after-logging-forward -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-I ufw-logging-deny -m conntrack --ctstate INVALID -j RETURN -m limit --limit 3/min --limit-burst 10
-A ufw-logging-deny -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-A ufw-logging-allow -j LOG --log-prefix "[UFW ALLOW] " -m limit --limit 3/min --limit-burst 10
### END LOGGING ###

### RATE LIMITING ###
-A ufw-user-limit -m limit --limit 3/minute -j LOG --log-prefix "[UFW LIMIT BLOCK] "
-A ufw-user-limit -j REJECT
-A ufw-user-limit-accept -j ACCEPT
### END RATE LIMITING ###
COMMIT

### tuple ### 字段含义(以 allow tcp 22 0.0.0.0/0 any 0.0.0.0/0 OpenSSH - in 为例):

位置值含义
1allow动作(allow/deny/reject/limit)
2tcp协议(tcp/udp/any)
322目标端口
40.0.0.0/0目标地址(any)
5any目标端口(any 表示不限)
60.0.0.0/0源地址
7OpenSSH来源 profile 名(- 表示纯命令行添加)
8-接口(- 表示不限)
9in方向(in/out)

💡 重要:ufw 命令添加的规则都会同步写入该文件;不要手工编辑此文件,除非同时执行 ufw reload。limit 规则会生成 3 条 iptables 规则(recent 追踪 + 30 秒内 6 次触发限速 + 放行),用于 SSH 防爆破。

5.5 before.rules(前置基础规则节选)

head -45 /etc/ufw/before.rules
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines


# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

# quickly process packets for which we already have a connection
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP

# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

# ok icmp code for FORWARD
-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT

# allow dhcp client to work

💡 before.rules 决定了“放行回环、放行已建立连接(RELATED,ESTABLISHED)、丢弃 INVALID 包、放行部分 ICMP、放行 DHCP”等基础行为,这些规则先于用户规则匹配,解释了为何 DEFAULT_INPUT_POLICY="DROP" 下 ssh 已建立的连接仍不断。

5.6 内核参数文件 /etc/ufw/sysctl.conf(节选)

cat /etc/ufw/sysctl.conf
#
# Configuration file for setting network variables. Please note these settings
# override /etc/sysctl.conf and /etc/sysctl.d. If you prefer to use
# /etc/sysctl.conf, please adjust IPT_SYSCTL in /etc/default/ufw. See
# Documentation/networking/ip-sysctl.txt in the kernel source code for more
# information.
#

# Uncomment this to allow this host to route packets between interfaces
#net/ipv4/ip_forward=1
#net/ipv6/conf/default/forwarding=1
#net/ipv6/conf/all/forwarding=1

# Disable ICMP redirects. ICMP redirects are rarely used but can be used in
# MITM (man-in-the-middle) attacks. Disabling ICMP may disrupt legitimate
# traffic to those sites.
net/ipv4/conf/all/accept_redirects=0
net/ipv4/conf/default/accept_redirects=0
net/ipv6/conf/all/accept_redirects=0
net/ipv6/conf/default/accept_redirects=0

# Ignore bogus ICMP errors
net/ipv4/icmp_echo_ignore_broadcasts=1
net/ipv4/icmp_ignore_bogus_error_responses=1
net/ipv4/icmp_echo_ignore_all=0

# Don't log Martian Packets (impossible addresses)
# packets
net/ipv4/conf/all/log_martians=0
net/ipv4/conf/default/log_martians=0

#net/ipv4/tcp_fin_timeout=30
#net/ipv4/tcp_keepalive_intvl=1800

# Uncomment this to turn off ipv6 autoconfiguration
#net/ipv6/conf/default/autoconf=1
#net/ipv6/conf/all/autoconf=1

# Uncomment this to enable ipv6 privacy addressing
#net/ipv6/conf/default/use_tempaddr=2
#net/ipv6/conf/all/use_tempaddr=2

5.7 应用配置(profile)applications.d

应用配置把“服务名 → 端口”映射起来,ufw allow <profile名> 即可放行。文件位于 /etc/ufw/applications.d/:

ls -la /etc/ufw/applications.d/
total 16
drwxr-xr-x 2 root root 4096 Oct  6 05:28 .
drwxr-xr-x 3 root root 4096 Oct  6 06:12 ..
-rw-r--r-- 1 root root  145 Aug 31 18:39 openssh-server
-rw-r--r-- 1 root root  361 May  5 15:48 postfix

OpenSSH profile 内容:

cat /etc/ufw/applications.d/openssh-server
[OpenSSH]
title=Secure shell server, an rshd replacement
description=OpenSSH is a free implementation of the Secure Shell protocol.
ports=22/tcp

Postfix profile 内容(一个文件可定义多个 profile):

cat /etc/ufw/applications.d/postfix
[Postfix]
title=Mail server (SMTP)
description=Postfix is a high-performance mail transport agent
ports=25/tcp

[Postfix SMTPS]
title=Mail server (SMTPS)
description=Postfix is a high-performance mail transport agent
ports=465/tcp

[Postfix Submission]
title=Mail server (Submission)
description=Postfix is a high-performance mail transport agent
ports=587/tcp

💡 只有安装了对应软件(openssh-server、postfix 等)才会出现 profile 文件;纯命令行环境无任何 profile 时 ufw app list 输出为空(见 6.10)。

六、命令详解

以下命令与输出均为 Ubuntu 22.04(ufw 0.36.1)实测。

6.1 ufw --version(查看版本)

  • 用途:显示 ufw 版本与版权信息。
  • 语法:ufw --version
  • 参数:无。
ufw --version
ufw 0.36.1
Copyright 2008-2021 Canonical Ltd.

6.2 ufw status(基本状态)

  • 用途:查看防火墙启用状态与规则列表。
  • 语法:ufw status [verbose|numbered]
  • 参数:verbose 显示详细默认策略与日志级别;numbered 显示规则编号(见 6.4)。

未启用时:

ufw status
Status: inactive

启用后:

ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
3306                       ALLOW       10.0.0.5
OpenSSH (v6)               ALLOW       Anywhere (v6)

6.3 ufw status verbose(详细状态)

  • 用途:在 status 基础上额外显示默认策略(入站/出站/转发)、日志级别与“新 profile 处理方式”。
  • 语法:ufw status verbose
  • 参数:无。
ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere
3306                       ALLOW IN    10.0.0.5
80/tcp                     ALLOW IN    Anywhere
8080/tcp                   DENY IN     Anywhere
25/tcp                     REJECT IN   Anywhere
22/tcp                     LIMIT IN    Anywhere
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
8080/tcp (v6)              DENY IN     Anywhere (v6)
25/tcp (v6)                REJECT IN   Anywhere (v6)
22/tcp (v6)                LIMIT IN    Anywhere (v6)

输出解读:

行含义
Status: active防火墙已启用(规则已应用到 iptables)
Logging: on (low)日志开启,级别 low
Default: deny (incoming), allow (outgoing), deny (routed)入站默认拒绝、出站默认放行、转发默认拒绝
New profiles: skip新增应用 profile 时默认不自动处理(SKIP)
Action 列ALLOW IN / DENY IN / REJECT IN / LIMIT IN / ALLOW OUT 等

6.4 ufw status numbered(编号状态)

  • 用途:给每条规则加编号,配合 ufw delete <编号> 精确删除。
  • 语法:ufw status numbered
  • 参数:无。
ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 3306                       ALLOW IN    10.0.0.5
[ 3] 80/tcp                     ALLOW IN    Anywhere
[ 4] 8080/tcp                   DENY IN     Anywhere
[ 5] 25/tcp                     REJECT IN   Anywhere
[ 6] 22/tcp                     LIMIT IN    Anywhere
[ 7] OpenSSH (v6)               ALLOW IN    Anywhere (v6)
[ 8] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 9] 8080/tcp (v6)              DENY IN     Anywhere (v6)
[10] 25/tcp (v6)                REJECT IN   Anywhere (v6)
[11] 22/tcp (v6)                LIMIT IN    Anywhere (v6)

💡 编号随删除动态重排;ufw delete <编号> 只删除该编号对应的一条规则(v4/v6 分别编号,需各自删除,见 6.12)。

6.5 ufw enable(启用防火墙)

  • 用途:应用全部规则到 iptables 并设置开机自启(改写 ufw.conf 的 ENABLED=yes)。
  • 语法:ufw enable
  • 参数:无(--force 可跳过交互确认,见 6.16)。
ufw enable
Firewall is active and enabled on system startup

⚠️ enable 会立即应用默认拒绝入站策略:若此前未放行 ssh,当前 SSH 连接会马上断开。远程操作前务必先 ufw allow ssh。

6.6 ufw disable(停用防火墙)

  • 用途:停止防火墙并关闭开机自启(ENABLED=no),清空全部 ufw 规则(系统回到无过滤状态)。
  • 语法:ufw disable
  • 参数:无。
ufw disable
Firewall stopped and disabled on system startup

6.7 ufw allow(放行)

  • 用途:放行端口、协议、服务、IP/网段或组合。
  • 语法与参数:
语法说明示例
ufw allow <端口>放行 tcp+udp 的该端口ufw allow 53
ufw allow <端口>/<协议>放行指定协议端口ufw allow 80/tcp
ufw allow <profile名>按应用配置放行(见 6.11)ufw allow OpenSSH
ufw allow from <IP>/<网段>放行指定来源的全部流量ufw allow from 192.168.1.0/24
ufw allow from <IP> to any port <端口>[/<协议>]放行指定来源访问本机某端口ufw allow from 10.0.0.5 to any port 3306
ufw allow out <端口>放行出站ufw allow out 53
ufw allow in on <接口>按网卡放行ufw allow in on eth0 to any port 22

实测 1:放行 22/tcp(已存在 ssh 规则时输出“跳过”):

ufw allow 22/tcp
Skipping adding existing rule
Skipping adding existing rule (v6)

💡 Skipping adding existing rule 表示规则已存在(此前 ufw allow ssh 已添加),不重复添加。首次添加的回显为 Rule added / Rule added (v6)。

实测 2:放行 80/tcp:

ufw allow 80/tcp
Rule added
Rule added (v6)

实测 3:放行整个网段:

ufw allow from 192.168.1.0/24
Rule added
ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 3306/tcp                   ALLOW IN    10.0.0.5
[ 3] Anywhere                   ALLOW IN    192.168.1.0/24
[ 4] OpenSSH (v6)               ALLOW IN    Anywhere (v6)

💡 该规则只有 v4(192.168.1.0/24 是 IPv4 网段,不生成 v6 规则)。

实测 4:放行指定来源访问指定端口(注意:to any port 3306 未写协议时会同时放行 tcp+udp):

ufw allow from 10.0.0.5 to any port 3306
Rules updated

对应的 iptables 规则(实测,udp 也被放行):

2        0     0 ACCEPT     tcp  --  *      *       10.0.0.5             0.0.0.0/0            tcp dpt:3306
3        0     0 ACCEPT     udp  --  *      *       10.0.0.5             0.0.0.0/0            udp dpt:3306

💡 只放行 tcp 应写 ufw allow from 10.0.0.5 to any port 3306 proto tcp(proto 参数见 man ufw)。

6.8 ufw deny(拒绝)

  • 用途:丢弃匹配流量(客户端表现为超时,无任何回应)。
  • 语法:ufw deny <端口>[/<协议>]、ufw deny from <IP>/<网段>、ufw deny out <端口> 等,参数同 allow。

实测 1:拒绝 8080/tcp:

ufw deny 8080/tcp
Rule added
Rule added (v6)

实测 2:拒绝指定 IP(新增一条 Anywhere DENY IN 192.168.1.100):

ufw deny from 192.168.1.100
Rule added
ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 3306                       ALLOW IN    10.0.0.5
[ 3] Anywhere                   DENY IN     192.168.1.100
[ 4] OpenSSH (v6)               ALLOW IN    Anywhere (v6)
[ 5] 22/tcp (v6)                LIMIT IN    Anywhere (v6)

实测 3:拒绝出站 25 端口(邮件外发管控):

ufw deny out 25
Rules updated
Rules updated (v6)
ufw show added
Added user rules (see 'ufw status' for running firewall):
ufw deny out 25

6.9 ufw reject(拒绝并回显)

  • 用途:拒绝流量并返回 ICMP/TCP RST 错误(客户端能立即感知“被拒绝”,常用于内部策略提示)。
  • 语法:同 deny(ufw reject <端口>[/<协议>]、ufw reject from <IP> 等)。
  • 与 deny(DROP,静默丢弃)的区别是客户端体验:reject 秒失败,deny 表现为超时。
ufw reject 25/tcp
Rule added
Rule added (v6)

6.10 ufw limit(限速防爆破)

  • 用途:对匹配流量限速:同一来源 30 秒内超过 6 次新建连接则拒绝(用于 SSH 防暴力破解)。
  • 语法:ufw limit <端口>[/<协议>]、ufw limit ssh、ufw limit from <IP> 等。
  • 实现:生成 3 条 iptables 规则(recent 计数 + 超限跳转 ufw-user-limit + 放行),实测见 user.rules 中 ### tuple ### limit tcp 22 段。
ufw limit ssh
Rule added
Rule added (v6)
ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 3306                       ALLOW IN    10.0.0.5
[ 3] 80/tcp                     ALLOW IN    Anywhere
[ 4] 8080/tcp                   DENY IN     Anywhere
[ 5] 25/tcp                     REJECT IN   Anywhere
[ 6] 22/tcp                     LIMIT IN    Anywhere
[ 7] OpenSSH (v6)               ALLOW IN    Anywhere (v6)
[ 8] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 9] 8080/tcp (v6)              DENY IN     Anywhere (v6)
[10] 25/tcp (v6)                REJECT IN   Anywhere (v6)
[11] 22/tcp (v6)                LIMIT IN    Anywhere (v6)

💡 已用 ufw limit 保护 22 端口后,无需再 ufw allow 22/tcp;两者同时存在时 allow 规则在前(见 iptables 输出中 22 的 ACCEPT 在 LIMIT 之前),仍会放行,限速不生效——二选一即可。

6.11 ufw app list / ufw app info(应用配置)

  • 用途:查看可用的应用 profile 及详情。
  • 语法:ufw app list;ufw app info <profile>
ufw app list
Available applications:
  OpenSSH
  Postfix
  Postfix SMTPS
  Postfix Submission
ufw app info OpenSSH
Profile: OpenSSH
Title: Secure shell server, an rshd replacement
Description: OpenSSH is a free implementation of the Secure Shell protocol.

Port:
  22/tcp

💡 profile 由已安装软件提供(/etc/ufw/applications.d/);无任何 profile 时 ufw app list 输出为空。ufw allow OpenSSH 等价于 ufw allow 22/tcp,但会在规则中带 dapp_OpenSSH 注释,便于识别来源。profile 名不存在时 ufw allow OpenSSH 会报错(见“常见问题”)。

6.12 ufw delete(删除规则)

  • 用途:按规则文本或编号删除规则。
  • 语法:
ufw delete allow <端口>[/<协议>]
ufw delete deny from <IP>/<网段>
ufw delete reject 25/tcp
ufw delete limit ssh
ufw delete <编号>

实测 1:按规则文本删除(自动删 v4+v6 两条):

ufw delete allow 80/tcp
Rule deleted
Rule deleted (v6)

实测 2:按编号删除(只删该编号对应的一条,需要交互确认):

ufw delete 6
Deleting:
 limit 22/tcp
Proceed with operation (y|n)? Rule deleted

💡 不加 echo y 时确认环节会中止(实测回显 Proceed with operation (y|n)? Aborted)。脚本化可用 echo y | ufw delete 6。注意:按编号删除只删除编号对应的单条规则,其 v6 配对规则仍在(实测删除 [ 6] 22/tcp LIMIT IN 后 [10] 22/tcp (v6) LIMIT IN 保留)。

6.13 ufw show added(查看已添加的用户规则)

  • 用途:按原始命令格式显示用户通过命令行添加的规则(不包含默认策略)。
  • 语法:ufw show added
ufw show added
Added user rules (see 'ufw status' for running firewall):
ufw deny out 25

无规则时:

ufw show added
Added user rules (see 'ufw status' for running firewall):
(None)

6.14 ufw reload(重载规则)

  • 用途:从规则文件重新加载规则(手工改过 user.rules / before.rules 后执行)。
  • 语法:ufw reload
  • 参数:无。
ufw reload
Firewall reloaded

6.15 ufw logging(日志级别)

  • 用途:设置防火墙日志级别(同时改写 ufw.conf 的 LOGLEVEL)。
  • 语法:ufw logging on|off|low|medium|high
  • 级别说明:off 关闭;low(默认,只记被拒绝包);medium(含无效包与限速触发);high(最详细,量大慎用);on 等价于 low。
ufw logging off
Logging disabled
ufw logging on
Logging enabled

💡 日志输出到内核日志,查看:tail -f /var/log/syslog | grep UFW 或 dmesg | grep UFW。

6.16 ufw --dry-run(预演,不实际生效)

  • 用途:显示命令将生成的 iptables 规则,不真正修改防火墙,用于核对规则内容。
  • 语法:ufw --dry-run <其他命令>
  • 参数:无独立参数,配合 allow/deny/delete 等使用。

实测(预演 ufw allow 53,输出将追加到 user.rules 的完整 iptables-restore 内容节选):

ufw --dry-run allow 53
*filter
:ufw-user-input - [0:0]
:ufw-user-output - [0:0]
:ufw-user-forward - [0:0]
:ufw-before-logging-input - [0:0]
:ufw-before-logging-output - [0:0]
:ufw-before-logging-forward - [0:0]
:ufw-user-logging-input - [0:0]
:ufw-user-logging-output - [0:0]
:ufw-user-logging-forward - [0:0]
:ufw-after-logging-input - [0:0]
:ufw-after-logging-output - [0:0]
:ufw-after-logging-forward - [0:0]
:ufw-logging-deny - [0:0]
:ufw-logging-allow - [0:0]
:ufw-user-limit - [0:0]
:ufw-user-limit-accept - [0:0]
### RULES ###

### tuple ### allow tcp 22 0.0.0.0/0 any 0.0.0.0/0 OpenSSH - in
-A ufw-user-input -p tcp --dport 22 -j ACCEPT -m comment --comment 'dapp_OpenSSH'

### tuple ### allow tcp 3306 0.0.0.0/0 any 10.0.0.5 in
-A ufw-user-input -p tcp --dport 3306 -s 10.0.0.5 -j ACCEPT

### tuple ### allow any 53 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 53 -j ACCEPT
-A ufw-user-input -p udp --dport 53 -j ACCEPT

### END RULES ###

### LOGGING ###
-A ufw-after-logging-input -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-A ufw-after-logging-forward -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-I ufw-logging-deny -m conntrack --ctstate INVALID -j RETURN -m limit --limit 3/min --limit-burst 10
-A ufw-logging-deny -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-A ufw-logging-allow -j LOG --log-prefix "[UFW ALLOW] " -m limit --limit 3/min --limit-burst 10
### END LOGGING ###

### RATE LIMITING ###
-A ufw-user-limit -m limit --limit 3/minute -j LOG --log-prefix "[UFW LIMIT BLOCK] "
-A ufw-user-limit -j REJECT
-A ufw-user-limit-accept -j ACCEPT
### END RATE LIMITING ###
COMMIT

💡 重点看新增的 ### tuple ### allow any 53 段:allow 53(不带协议)会生成 tcp 和 udp 两条规则;执行后 ufw status 中才会出现 53 端口。dry-run 输出中同时包含全部既有规则,方便核对增删后的完整规则集。

6.17 ufw --force(跳过交互确认)

  • 用途:跳过 ufw reset 等命令的 Proceed with operation (y|n)? 交互确认,用于脚本化。
  • 语法:ufw --force reset(--force 置于命令前)
  • 实测见 6.18(ufw reset 的实测即使用了 ufw --force reset)。

6.18 ufw reset(重置所有规则)

  • 用途:删除全部用户规则,恢复出厂规则文件,并自动备份旧规则(user.rules.时间戳 等)。防火墙默认回到禁用状态。
  • 语法:ufw reset(交互确认)或 ufw --force reset(跳过确认)。
  • 参数:无。
ufw --force reset
Backing up 'user.rules' to '/etc/ufw/user.rules.20261006_060943'
Backing up 'before.rules' to '/etc/ufw/before.rules.20261006_060943'
Backing up 'after.rules' to '/etc/ufw/after.rules.20261006_060943'
Backing up 'user6.rules' to '/etc/ufw/user6.rules.20261006_060943'
Backing up 'before6.rules' to '/etc/ufw/before6.rules.20261006_060943'
Backing up 'after6.rules' to '/etc/ufw/after6.rules.20261006_060943'

重置后状态:

ufw status
Status: inactive

⚠️ reset 会清空全部放行规则(含 ssh),生产环境执行后需重新添加规则并 ufw enable,否则系统无防火墙保护。

6.19 规则动作小结

动作iptables target客户端体验适用场景
allowACCEPT正常访问放行服务/来源
denyDROP超时无响应封禁恶意 IP(慢,隐蔽)
rejectREJECT(tcp-reset / icmp-port-unreachable)立即报错明确拒绝(快,易感知)
limitrecent + ufw-user-limit超过 6 次/30 秒后拒绝SSH 等端口防爆破

七、实战演练

7.1 场景一:开放 SSH 与 HTTP 端口

需求:服务器需要对外提供 SSH(22)与 Web(80)服务。

# 放行 ssh(应用 profile 方式)
ufw allow OpenSSH
Rule added
Rule added (v6)
# 放行 http(端口方式)
ufw allow 80/tcp
Rule added
Rule added (v6)
# 启用防火墙(务必在放行 ssh 之后)
ufw enable
Firewall is active and enabled on system startup
# 确认状态
ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)

7.2 场景二:拒绝指定 IP

需求:封禁恶意来源 192.168.1.100。

ufw deny from 192.168.1.100
Rule added
ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 3306                       ALLOW IN    10.0.0.5
[ 3] Anywhere                   DENY IN     192.168.1.100
[ 4] OpenSSH (v6)               ALLOW IN    Anywhere (v6)
[ 5] 22/tcp (v6)                LIMIT IN    Anywhere (v6)

撤销封禁:

ufw delete deny from 192.168.1.100
Rule deleted

💡 想封禁整个网段:ufw deny from 192.168.2.0/24;想只封该 IP 对某端口的访问:ufw deny from 192.168.1.100 to any port 22 proto tcp。

7.3 场景三:按编号查看与删除规则

需求:规则多了以后按编号精确定位并删除(模拟删除 8080 的 DENY 规则)。

ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 3306                       ALLOW IN    10.0.0.5
[ 3] 80/tcp                     ALLOW IN    Anywhere
[ 4] 8080/tcp                   DENY IN     Anywhere
[ 5] 25/tcp                     REJECT IN   Anywhere
[ 6] 22/tcp                     LIMIT IN    Anywhere
[ 7] OpenSSH (v6)               ALLOW IN    Anywhere (v6)
[ 8] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 9] 8080/tcp (v6)              DENY IN     Anywhere (v6)
[10] 25/tcp (v6)                REJECT IN   Anywhere (v6)
[11] 22/tcp (v6)                LIMIT IN    Anywhere (v6)

删除编号 6(22/tcp 的 LIMIT 规则):

echo y | ufw delete 6
Deleting:
 limit 22/tcp
Proceed with operation (y|n)? Rule deleted
ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 3306                       ALLOW IN    10.0.0.5
[ 3] 80/tcp                     ALLOW IN    Anywhere
[ 4] 8080/tcp                   DENY IN     Anywhere
[ 5] 25/tcp                     REJECT IN   Anywhere
[ 6] OpenSSH (v6)               ALLOW IN    Anywhere (v6)
[ 7] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 8] 8080/tcp (v6)              DENY IN     Anywhere (v6)
[ 9] 25/tcp (v6)                REJECT IN   Anywhere (v6)
[10] 22/tcp (v6)                LIMIT IN    Anywhere (v6)

💡 注意编号会立即重排,且按编号删除只删单条(v6 的 LIMIT 规则仍保留在 [10]);要同时删 v4/v6 请用规则文本方式:ufw delete limit ssh。

7.4 场景四:验证策略真实生效(iptables 核查)

ufw 的规则最终落在 iptables。查看 INPUT 链整体结构:

iptables -L INPUT -n --line-numbers
Chain INPUT (policy DROP)
num  target     prot opt source               destination         
1    ufw-before-logging-input  all  --  0.0.0.0/0            0.0.0.0/0           
2    ufw-before-input  all  --  0.0.0.0/0            0.0.0.0/0           
3    ufw-after-input  all  --  0.0.0.0/0            0.0.0.0/0           
4    ufw-after-logging-input  all  --  0.0.0.0/0            0.0.0.0/0           
5    ufw-reject-input  all  --  0.0.0.0/0            0.0.0.0/0           
6    ufw-track-input  all  --  0.0.0.0/0            0.0.0.0/0           

查看用户规则链(allow/deny/reject/limit 落在这里):

iptables -L ufw-user-input -n -v --line-numbers
Chain ufw-user-input (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 /* 'dapp_OpenSSH' */
2        0     0 ACCEPT     tcp  --  *      *       10.0.0.5             0.0.0.0/0            tcp dpt:3306
3        0     0 ACCEPT     udp  --  *      *       10.0.0.5             0.0.0.0/0            udp dpt:3306
4        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
5        0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080
6        0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:25 reject-with tcp-reset
7        0     0            tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
8        0     0 ufw-user-limit  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW recent: UPDATE seconds: 30 hit_count: 6 name: DEFAULT side: source mask: 255.255.255.255
9        0     0 ufw-user-limit-accept  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22

💡 字段解读:pkts/bytes 为命中统计(排查“规则是否被匹配到”非常有用);tcp dpt:80 即 80 端口规则;reject-with tcp-reset 即 reject 的实现;第 7-9 行为 limit ssh 生成的三条限速规则。INPUT 链 policy DROP + before 链放行 established/回环,是“默认拒绝入站但 SSH 不断连”的原因。

7.5 场景五:临时调试与清理

临时放行 53 端口调试 DNS(用 dry-run 先看规则,再真正执行):

ufw --dry-run allow 53 | grep -A2 "tuple.*allow any 53"
### tuple ### allow any 53 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 53 -j ACCEPT
-A ufw-user-input -p udp --dport 53 -j ACCEPT
ufw allow 53
Rule added
Rule added (v6)

调试完成后删除并恢复:

ufw delete allow 53
Rule deleted
Rule deleted (v6)

八、systemd 服务管理

ufw 由 ufw.service(Type=oneshot,ExecStart=/lib/ufw/ufw-init start quiet,ExecStop=/lib/ufw/ufw-init stop,WantedBy=multi-user.target)承载开机加载。常用操作(每行一个单元名):

systemctl enable ufw
systemctl start ufw
systemctl stop ufw
systemctl restart ufw
systemctl status ufw
systemctl is-active ufw
systemctl is-enabled ufw

实测回显:

systemctl is-enabled ufw
enabled
systemctl status ufw
○ ufw.service - Uncomplicated firewall
     Loaded: loaded (/lib/systemd/system/ufw.service; enabled; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:ufw(8)

💡 关键细节:systemctl is-active ufw 显示 inactive 不代表防火墙没生效。ufw 的实际启停由 ufw enable/ufw disable 命令控制(改写 ufw.conf 的 ENABLED=yes/no 并直接调用 ufw-init);ufw.service 是 oneshot 辅助单元,只有经 systemd 启动过才显示 active。验证防火墙状态请以 ufw status 为准。

执行 systemctl start ufw(等价于手工运行 ufw-init start,规则按 ENABLED=yes 应用):

systemctl start ufw
systemctl is-active ufw
active
systemctl status ufw
● ufw.service - Uncomplicated firewall
     Loaded: loaded (/lib/systemd/system/ufw.service; enabled; vendor preset: enabled)
     Active: active (exited) since Tue 2026-10-06 06:19:19 UTC; 15ms ago
       Docs: man:ufw(8)
    Process: 271973 ExecStart=/lib/ufw/ufw-init start quiet (code=exited, status=0/SUCCESS)
   Main PID: 271973 (code=exited, status=0/SUCCESS)

💡 RemainAfterExit=yes 使 oneshot 单元执行成功后保持 active(exited) 状态。日常管理仍建议使用 ufw enable/ufw disable 命令而非 systemctl。

九、注意事项

⚠️ 以下为生产环境中的高频坑点:

  1. 先放行 SSH 再 enable:ufw enable 会立即应用 DEFAULT_INPUT_POLICY="DROP"(默认拒绝所有入站),若未先 ufw allow ssh,当前远程会话立刻断开。标准顺序:ufw allow OpenSSH → ufw enable。
  2. 默认策略是 deny incoming / allow outgoing:所有未显式放行的入站流量默认被丢弃(DROP);出站默认全放行。修改 DEFAULT_INPUT_POLICY 为 ACCEPT 等于打开大门,务必谨慎。
  3. enable/disable 是全部或全无:ufw disable 会清空全部 ufw 规则并关闭自启,系统回到无过滤状态;不要在防火墙上做“暂时停一下”的操作,应精细删除单条规则。
  4. 按编号删除只删单条(v4/v6 分开):ufw status numbered 中 v4 与 v6 规则各自编号,ufw delete <编号> 只删一条;要成对删除请用规则文本(如 ufw delete allow 80/tcp)。
  5. ufw allow 53 会同时放行 tcp+udp:不带协议时默认双协议;只想放行 tcp 必须写 ufw allow 53/tcp。端口规则同理(allow 3306 与 allow 3306/tcp 不同)。
  6. reset 是核弹按钮:ufw reset 清空全部规则并自动备份旧文件;生产上执行前确认已有规则清单(ufw show added)。
  7. 不要与 firewalld 共存:两者都接管 iptables/nftables,同时启用规则互相覆盖;迁移系统前先 ufw disable 或停用 firewalld。
  8. Docker 等第三方 iptables 管理工具冲突:MANAGE_BUILTINS=no 时 ufw 不接管内置链,但 docker 发布的端口仍可能绕过 ufw(详见“常见问题”)。
  9. 改 /etc/default/ufw 后需 disable+enable 或 reload:直接改文件不会立即生效,需 ufw disable + ufw enable(或 ufw reload)使新策略生效。
  10. 云环境双重保险:云厂商安全组与系统 ufw 是两层独立过滤,端口不通时先查安全组规则,再查 ufw。

十、常见问题(FAQ)

10.1 ufw enable 报 iptables 相关错误怎么办?

常见报错及处理:

  • ERROR: Couldn't determine iptables version:iptables 命令异常。检查 iptables --version 是否可用,必要时重装 iptables:apt-get install --reinstall -y iptables。
  • ERROR: problem running iptables-restore / ...iptables: No chain/target/match by that name:多为规则文件损坏或后端不一致。处理:
    1. ufw disable(清理半应用状态);
    2. 检查 update-alternatives --display iptables(Ubuntu 22.04 默认 iptables-nft,实测安装回显 using /usr/sbin/iptables-nft to provide /usr/sbin/iptables);
    3. 用备份恢复或 ufw --force reset 重置规则文件;
    4. 重新 ufw allow ssh 后 ufw enable。
  • 排查日志:journalctl -u ufw.service、/var/log/syslog | grep ufw。

💡 注意:Ubuntu 22.04 同时提供 iptables-legacy 与 iptables-nft,ufw 依赖 iptables-nft 链路;若曾手工切换过 alternatives,可能导致 ufw 与 docker 规则互相不可见(见 10.4)。

10.2 ufw 规则重启后会丢失吗?

不会。ufw 命令添加的规则会同步写入 /etc/ufw/user.rules / user6.rules,ufw enable 后由 ufw.service 在开机时自动加载。验证:

ufw status verbose

显示 Status: active 即规则已应用。

💡 会丢的场景:① 执行了 ufw reset(已自动备份);② 手工编辑 user.rules 后未 ufw reload;③ 执行 ufw disable(规则被清空)。

10.3 误封 SSH 无法远程登录怎么办?

  1. 通过云控制台 VNC / 机房带外管理进入系统,执行 ufw disable 恢复连接,再重新精确放行。
  2. 若还能登录(部分网段被放行),删除误加的规则:ufw status numbered 找到编号后 echo y | ufw delete <编号>,或 ufw delete deny from <误封IP>。
  3. 预防措施:把管理网段单独放行并限制来源,例如:
ufw allow from 10.0.0.0/8 to any port 22 proto tcp
ufw limit 22/tcp

10.4 ufw 与 docker 一起用时,Docker 发布端口为何绕过防火墙?

原因:docker 通过 iptables 的 DNAT 规则把宿主机端口转发到 Docker 网络,而 ufw 默认只管理自己的链(MANAGE_BUILTINS=no);请求先命中 docker 的 nat 表 DNAT 规则,ufw 的 INPUT 过滤链无法拦截,表现为“ufw deny 了 8080,Docker 8080 仍可访问”。

解决思路(按优先级):

  1. Docker 端口只绑定回环:docker run -p 127.0.0.1:8080:8080 ...,对外再由 Nginx 等代理。
  2. 修改 docker 的 iptables 集成策略(如关闭 --iptables=false 并用 ufw 的 before.rules 显式 DNAT,较复杂,需评估 Docker 网络影响)。
  3. 若需严格管控,可将 DEFAULT_FORWARD_POLICY="DROP" 配合 docker 的 --ip-forward 配置评估(注意会阻断 Docker 网络间通信)。
  4. 遵循最小暴露:仅发布必要端口,避免 -p 0.0.0.0:port。

💡 同机如也运行 firewalld 会进一步加剧规则冲突;生产建议:Docker 服务走反向代理暴露,防火墙只管宿主机端口。

10.5 ufw allow OpenSSH 报 “Could not find a profile matching” 怎么办?

ufw allow OpenSSH
ERROR: Could not find a profile matching 'OpenSSH'

原因:/etc/ufw/applications.d/ 下没有名为 OpenSSH 的 profile(通常因未安装 openssh-server,或 profile 名不同)。

解决:

  1. 查看可用 profile:ufw app list(本文实测环境安装 openssh-server 后输出 OpenSSH / Postfix / Postfix SMTPS / Postfix Submission)。
  2. 没有对应 profile 时直接用端口:ufw allow 22/tcp。
  3. 大小写敏感:profile 名必须与 ufw app list 输出完全一致。

10.6 ufw status 里看不到我添加的规则?

可能原因:

  1. 防火墙未启用:ufw status 显示 Status: inactive 时只记录规则文件、不显示规则列表。执行 ufw enable 后再查看。
  2. 查看方式:ufw status / ufw status verbose / ufw status numbered 查看当前生效规则;已添加但未 enable 的规则用 ufw show added 查看原始命令记录。
  3. 被默认策略覆盖:DEFAULT_INPUT_POLICY="DROP" 下未放行的端口本来就不可达,属预期行为。

10.7 如何删除全部规则恢复出厂?

ufw --force reset
ufw allow OpenSSH
ufw enable

reset 会备份旧规则文件(/etc/ufw/user.rules.时间戳)后清空,重置后需重新放行 ssh 并 enable。想保留当前规则清单可先 ufw show added 导出。

10.8 如何查看被拦截流量的日志?

ufw logging on
tail -f /var/log/syslog | grep -i ufw
dmesg | grep -i "UFW BLOCK"

日志示例前缀:[UFW BLOCK] IN=eth0 OUT= MAC=... SRC=1.2.3.4 DST=... LEN=60 TOS=... PROTO=TCP SPT=12345 DPT=22 ...。Logging: on (low) 只记录被拒包;排障需要更细时可 ufw logging medium(含 INVALID 包),量大时及时调回 low/off。

十一、卸载方式

systemctl stop ufw
ufw disable
apt purge -y ufw

⚠️ 预期输出(本文未实测,按 apt 常规行为给出):

(Reading database ... 40654 files and directories currently installed.)
Removing ufw (0.36.1-4ubuntu0.1) ...
Purging configuration files for ufw (0.36.1-4ubuntu0.1) ...
Removing ufw.service ...
Processing triggers for rsyslog (8.2112.0-2ubuntu2.5) ...

purge 会删除 /etc/ufw/ 下全部配置(含 user.rules,不可恢复),卸载后 ufw 规则不再加载,系统回到无防火墙状态,请先确认替代防护方案(如直接使用 iptables/nftables 或重新安装)。

仅停止使用、保留配置:

ufw disable

十二、参考链接

Ubuntu 22.04 防火墙管理 ufw 命令与配置详解 - Quzuo