Ubuntu 22.04 防火墙管理 ufw 命令与配置详解
Ubuntu 22.04 系统 UFW 防火墙的安装(在线 apt 与离线 deb)与 ufw 全部常用命令参数实测详解,含 allow/deny/delete、应用配置、状态查看与实战演练
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自动加载。
- iptables 运行时(立即生效,可通过
- 启动/重载时,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=yes | yes | 是否应用 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=no | no | 是否接管内置链(INPUT/OUTPUT/FORWARD)。yes 会破坏其他非 ufw 管理的 iptables 规则(如 docker) |
IPT_SYSCTL=/etc/ufw/sysctl.conf | /etc/ufw/sysctl.conf | iptables 后端要挂载的内核参数文件 |
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.rules | ufw 命令添加的用户规则(iptables-restore 格式,含 ### tuple ### 注释) |
after.rules / after6.rules | 用户规则之后加载的收尾规则(默认拒绝日志、NAT 等) |
before.init / after.init | 加载前后执行的钩子脚本(可加自定义 iptables 命令) |
sysctl.conf | ufw 挂载的内核网络参数(禁用 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 为例):
| 位置 | 值 | 含义 |
|---|---|---|
| 1 | allow | 动作(allow/deny/reject/limit) |
| 2 | tcp | 协议(tcp/udp/any) |
| 3 | 22 | 目标端口 |
| 4 | 0.0.0.0/0 | 目标地址(any) |
| 5 | any | 目标端口(any 表示不限) |
| 6 | 0.0.0.0/0 | 源地址 |
| 7 | OpenSSH | 来源 profile 名(- 表示纯命令行添加) |
| 8 | - | 接口(- 表示不限) |
| 9 | in | 方向(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 | 客户端体验 | 适用场景 |
|---|---|---|---|
allow | ACCEPT | 正常访问 | 放行服务/来源 |
deny | DROP | 超时无响应 | 封禁恶意 IP(慢,隐蔽) |
reject | REJECT(tcp-reset / icmp-port-unreachable) | 立即报错 | 明确拒绝(快,易感知) |
limit | recent + 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。
九、注意事项
⚠️ 以下为生产环境中的高频坑点:
- 先放行 SSH 再 enable:
ufw enable会立即应用DEFAULT_INPUT_POLICY="DROP"(默认拒绝所有入站),若未先ufw allow ssh,当前远程会话立刻断开。标准顺序:ufw allow OpenSSH→ufw enable。 - 默认策略是 deny incoming / allow outgoing:所有未显式放行的入站流量默认被丢弃(DROP);出站默认全放行。修改
DEFAULT_INPUT_POLICY为 ACCEPT 等于打开大门,务必谨慎。 - enable/disable 是全部或全无:
ufw disable会清空全部 ufw 规则并关闭自启,系统回到无过滤状态;不要在防火墙上做“暂时停一下”的操作,应精细删除单条规则。 - 按编号删除只删单条(v4/v6 分开):
ufw status numbered中 v4 与 v6 规则各自编号,ufw delete <编号>只删一条;要成对删除请用规则文本(如ufw delete allow 80/tcp)。 ufw allow 53会同时放行 tcp+udp:不带协议时默认双协议;只想放行 tcp 必须写ufw allow 53/tcp。端口规则同理(allow 3306与allow 3306/tcp不同)。- reset 是核弹按钮:
ufw reset清空全部规则并自动备份旧文件;生产上执行前确认已有规则清单(ufw show added)。 - 不要与 firewalld 共存:两者都接管 iptables/nftables,同时启用规则互相覆盖;迁移系统前先
ufw disable或停用 firewalld。 - Docker 等第三方 iptables 管理工具冲突:
MANAGE_BUILTINS=no时 ufw 不接管内置链,但 docker 发布的端口仍可能绕过 ufw(详见“常见问题”)。 - 改 /etc/default/ufw 后需 disable+enable 或 reload:直接改文件不会立即生效,需
ufw disable+ufw enable(或ufw reload)使新策略生效。 - 云环境双重保险:云厂商安全组与系统 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:多为规则文件损坏或后端不一致。处理:ufw disable(清理半应用状态);- 检查
update-alternatives --display iptables(Ubuntu 22.04 默认iptables-nft,实测安装回显using /usr/sbin/iptables-nft to provide /usr/sbin/iptables); - 用备份恢复或
ufw --force reset重置规则文件; - 重新
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 无法远程登录怎么办?
- 通过云控制台 VNC / 机房带外管理进入系统,执行
ufw disable恢复连接,再重新精确放行。 - 若还能登录(部分网段被放行),删除误加的规则:
ufw status numbered找到编号后echo y | ufw delete <编号>,或ufw delete deny from <误封IP>。 - 预防措施:把管理网段单独放行并限制来源,例如:
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 仍可访问”。
解决思路(按优先级):
- Docker 端口只绑定回环:
docker run -p 127.0.0.1:8080:8080 ...,对外再由 Nginx 等代理。 - 修改 docker 的 iptables 集成策略(如关闭
--iptables=false并用 ufw 的before.rules显式 DNAT,较复杂,需评估 Docker 网络影响)。 - 若需严格管控,可将
DEFAULT_FORWARD_POLICY="DROP"配合 docker 的--ip-forward配置评估(注意会阻断 Docker 网络间通信)。 - 遵循最小暴露:仅发布必要端口,避免
-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 名不同)。
解决:
- 查看可用 profile:
ufw app list(本文实测环境安装 openssh-server 后输出 OpenSSH / Postfix / Postfix SMTPS / Postfix Submission)。 - 没有对应 profile 时直接用端口:
ufw allow 22/tcp。 - 大小写敏感:profile 名必须与
ufw app list输出完全一致。
10.6 ufw status 里看不到我添加的规则?
可能原因:
- 防火墙未启用:
ufw status显示Status: inactive时只记录规则文件、不显示规则列表。执行ufw enable后再查看。 - 查看方式:
ufw status/ufw status verbose/ufw status numbered查看当前生效规则;已添加但未 enable 的规则用ufw show added查看原始命令记录。 - 被默认策略覆盖:
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
十二、参考链接
- ufw 官方手册(man ufw):https://manpages.ubuntu.com/manpages/jammy/en/man8/ufw.8.html
- Ubuntu Wiki(UncomplicatedFirewall):https://wiki.ubuntu.com/UncomplicatedFirewall
- Ubuntu 帮助文档(UFW):https://help.ubuntu.com/community/UFW
- Ubuntu 软件包(jammy ufw):https://packages.ubuntu.com/jammy/ufw
- Launchpad ufw 项目:https://launchpad.net/ufw
- iptables 手册:https://manpages.ubuntu.com/manpages/jammy/en/man8/iptables.8.html
- ufw-framework 手册(规则文件格式):https://manpages.ubuntu.com/manpages/jammy/en/man8/ufw-framework.8.html