在 CentOS 系统中“开启”一个 UDP 端口,实际上是一个涉及两个层面的操作:首先是确保有应用程序在该端口上进行监听,其次是配置系统防火墙允许特定端口的流量通过,大多数情况下,用户遇到的问题都出在防火墙配置上,本文将详细讲解如何在现代 CentOS 版本(7 及以上)使用 firewalld 以及在旧版本(6)使用 iptables 来开启 UDP 端口,并提供相关的验证与排错方法。

理解 UDP 协议
在深入操作之前,简要了解 UDP(User Datagram Protocol,用户数据报协议)的特性是很有帮助的,与 TCP(Transmission Control Protocol,传输控制协议)相比,UDP 是一种无连接的协议,它不保证数据包的顺序、可靠性或重复性,但其开销非常小,传输速度快,这使得 UDP 非常适用于对实时性要求高、能容忍少量丢包的应用场景,例如视频流、在线游戏、DNS 查询和 NTP(网络时间协议)同步。
现代方法:使用 firewalld (CentOS 7/8/9)
从 CentOS 7 开始,firewalld 取代了 iptables 成为默认的防火墙管理工具,它引入了“区域”和“服务”的概念,使得防火墙配置更加动态和易于管理。
检查防火墙状态
在进行任何更改之前,首先需要确认 firewalld 是否正在运行。
sudo firewall-cmd --state
如果返回 running,则表示防火墙正在运行,如果未运行,可以使用以下命令启动并设置开机自启:
sudo systemctl start firewalld sudo systemctl enable firewalld
永久开启 UDP 端口
开启端口的操作分为“运行时模式”和“永久模式”,运行时模式的规则会在系统重启或防火墙服务重启后失效,而永久模式的规则会被保存下来,推荐直接使用永久模式进行配置。
假设我们要开启的 UDP 端口号是 12345,并将其添加到默认的 public 区域。
核心命令:
sudo firewall-cmd --zone=public --add-port=12345/udp --permanent
命令详解:
firewall-cmd:firewalld的命令行工具。--zone=public: 指定要操作的区域。public是默认区域,适用于公共网络,你可以通过firewall-cmd --get-active-zones查看当前活动的区域。--add-port=12345/udp: 指定要添加的端口,格式为端口号/协议,这里明确指定了协议为udp。--permanent: 表示此规则为永久规则,会被写入配置文件。
重要步骤:重新加载防火墙
添加永久规则后,firewalld 的运行时配置并不会立即更新,你需要手动重新加载防火墙配置,使新规则生效。

sudo firewall-cmd --reload
执行 reload 命令后,所有永久规则才会被加载到运行时环境中,端口 12345 的 UDP 流量现在就可以通过防火墙了。
验证端口是否已开启
验证是确认操作成功的关键一步,你可以使用以下命令列出 public 区域中所有已开放的端口:
sudo firewall-cmd --zone=public --list-ports
如果输出中包含 12345/udp,那么恭喜你,防火墙层面的配置已经成功。
为了进行更彻底的验证,你可以从另一台机器使用 nmap 工具来扫描目标服务器的端口:
nmap -sU -p 12345 <你的服务器IP地址>
-sU: 指定进行 UDP 扫描。-p 12345: 指定扫描的端口。
如果端口确实是开放的(并且有应用程序在监听),nmap 的状态可能会显示为 open 或 open|filtered,由于 UDP 的无连接特性,nmap 有时难以准确判断端口状态,open|filtered 也是一个常见的结果。
通过服务名称开启端口
对于一些知名的服务,如 DNS(端口 53)、NTP(端口 123),firewalld 提供了预定义的服务,通过服务名称来开启端口是更好的实践,因为它更易于管理和理解。
开启 DNS 服务的 UDP 端口:
sudo firewall-cmd --zone=public --add-service=dns --permanent sudo firewall-cmd --reload
你可以使用 firewall-cmd --get-services 命令查看所有可用的预定义服务。
传统方法:使用 iptables (CentOS 6)
在 CentOS 6 等旧版本上,iptables 是标准的防火墙工具,其配置方式相对直接,但规则是静态的。
添加规则
要允许 UDP 端口 12345 的流量,你需要向 INPUT 链中添加一条规则。

sudo iptables -I INPUT -p udp --dport 12345 -j ACCEPT
命令详解:
-I INPUT: 将规则插入到INPUT链的开头(-A表示追加到末尾)。-p udp: 指定协议为udp。--dport 12345: 指定目标端口为12345。-j ACCEPT: 指定匹配该规则的数据包的处理动作为ACCEPT(接受)。
保存规则
与 firewalld 不同,iptables 的规则在系统重启后会丢失,你必须手动保存它们。
sudo service iptables save
此命令会将当前的 iptables 规则保存到 /etc/sysconfig/iptables 文件中,确保系统重启后规则能够自动加载。
应用程序层:确保有程序在监听
请务必记住,防火墙只是“守门员”,如果门后没有人(应用程序)接收数据,那么即使门是开的,数据包也会被系统丢弃,你可以使用 netstat 或 ss 命令来检查是否有程序在监听指定的 UDP 端口。
# 使用 netstat sudo netstat -ulnp | grep 12345 # 或使用更现代的 ss sudo ss -ulnp | grep 12345
-u: 显示 UDP 套接字。-l: 显示处于监听状态的套接字。-n: 以数字形式显示地址和端口号。-p: 显示使用该套接字的进程信息。
如果没有任何输出,说明没有应用程序在监听这个端口,你可以使用 netcat 等工具进行简单的测试:
# 在服务器上监听 UDP 端口 12345 nc -ul 12345
然后从另一台机器向该端口发送数据,观察服务器是否有输出。
小编总结与对比
为了更清晰地理解两种工具的区别,下表进行了小编总结:
| 特性 | firewalld (CentOS 7+) |
iptables (CentOS 6) |
|---|---|---|
| 配置理念 | 动态、基于区域和服务 | 静态、基于规则链 |
| 命令行工具 | firewall-cmd |
iptables |
| 持久化 | 使用 --permanent 和 --reload |
使用 service iptables save |
| 易用性 | 更高,概念更抽象 | 较低,需要理解链、表、动作 |
| 适用版本 | CentOS 7, 8, 9 Stream | CentOS 6, RHEL 6 |
相关问答FAQs
问题1:我已经使用了 --permanent 参数添加了端口,但重启服务器后规则还是消失了,为什么?
解答: 这是一个常见的问题,通常发生在忘记执行 firewall-cmd --reload 命令。--permanent 参数只是将你的更改写入了防火墙的永久配置文件中,但并没有立即应用到当前运行的防火墙实例上,系统重启时,firewalld 服务会从永久配置文件中加载规则,如果你在添加永久规则后没有 reload,那么在下次重启前,运行的防火墙规则集中并不包含你的新规则,正确的流程是:add-port (带 --permanent) -> reload。
问题2:--add-port 和 --add-service 有什么区别,我应该优先使用哪个?
解答: --add-port 直接操作一个或多个具体的端口号,--add-port=53/udp,而 --add-service 操作的是一个预定义的服务集合,这个服务可能关联一个或多个端口和协议。--add-service=dns 会同时开放 TCP 和 UDP 的 53 端口。强烈建议优先使用 --add-service,这样做的好处是配置更具可读性和可维护性,当别人看到你的防火墙规则时,dns 服务比 53/tcp 和 53/udp 更容易理解,如果某个服务的标准端口发生变化,firewalld 更新服务定义后,你的规则无需修改就能自动适应,只有当你要开放一个非标准端口或没有预定义服务的端口时,才使用 --add-port。