14. 端口与服务映射
本章介绍 RHEL 9 的端口状态检查、服务与端口映射关系、firewalld 防火墙规则管理(服务名方式与端口方式),以及 SELinux 端口上下文配置。正确管理端口是安全基线的重要组成部分:仅开放业务必需的端口,关闭一切不必要的监听。
本章与前序章节的关系
第 5 章已完成 SSH 端口 2222 的 SELinux 和 firewalld 配置,第 12 章介绍了安全加固整体框架。本章在此基础上,系统化介绍端口管理的工具体系与操作规范,可作为日常运维的参考手册使用。
14.1 前提条件
- 已完成第二阶段第 10–13 章配置。
- 通过 SecureCRT(SSH 端口 2222)以
ops用户、密钥认证方式登录192.168.1.100,执行sudo -i切换至 root 环境。 - SELinux 处于 Enforcing 模式,firewalld 已启用。
安装本章所需工具:
dnf install -y nmap net-tools
14.2 端口状态检查
14.2.1 ss — 查看本机监听端口(推荐)
ss(Socket Statistics)是 netstat 的现代替代,查询速度更快,是 RHEL 9 的推荐工具。
# 查看所有 TCP/UDP 监听端口
ss -tuln
# 查看监听端口并显示关联进程
ss -tulnp
# 仅查看 TCP 连接
ss -tn
# 仅查看 UDP
ss -un
# 查看特定端口是否监听
ss -tuln | grep :2222
ss -tuln | grep ':80\|:443\|:2222'
# 查看连接统计摘要
ss -s
ss -tulnp 输出字段解读:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 128 0.0.0.0:2222 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
| 字段 | 含义 |
|---|---|
State=LISTEN |
服务正在监听等待连接 |
Local Address |
0.0.0.0 监听所有 IPv4 接口;127.0.0.1 仅本机访问 |
Process |
占用该端口的进程名与 PID |
14.2.2 netstat — 备选工具
# 查看监听端口(netstat 已标记为过时,但仍广泛使用)
netstat -tuln
# 查看监听端口及进程
netstat -tulnp
14.2.3 /etc/services — 标准服务端口映射表
# 查看标准服务的默认端口
grep -E "^ssh|^http|^ftp|^smtp" /etc/services
# 查找特定服务
grep "^mysql" /etc/services
grep "^postgresql" /etc/services
# 查找特定端口对应的服务名
grep "[[:space:]]80/" /etc/services
grep "[[:space:]]443/" /etc/services
常用标准服务端口参考:
| 服务 | 端口 / 协议 |
|---|---|
| SSH | 22/tcp |
| HTTP | 80/tcp |
| HTTPS | 443/tcp |
| MySQL | 3306/tcp |
| PostgreSQL | 5432/tcp |
| Redis | 6379/tcp |
| DNS | 53/tcp + 53/udp |
| NTP | 123/udp |
| SMTP | 25/tcp |
| IMAP | 143/tcp |
14.2.4 nmap — 端口扫描
# 扫描本机常用端口(前 1000 个)
nmap localhost
# 扫描指定端口范围
nmap -p 1-1024 localhost
# 扫描所有 65535 个端口(耗时较长)
nmap -p- localhost
# TCP SYN 扫描(更快)
nmap -sS -p 22,80,443,2222,3306 localhost
# UDP 端口扫描
nmap -sU -p 53,123,161 localhost
# 扫描远程主机(生产环境需提前获得授权)
nmap -sT -p 80,443 192.168.1.1
nmap 使用提示
在生产网络中扫描他人的服务器前,必须获得明确授权。未授权的端口扫描可能触发安全告警或违反法规。localhost 和自己管理的服务器例外。
14.3 firewalld 防火墙管理
firewalld 是 RHEL 9 默认防火墙,基于 zone 概念管理规则。所有永久规则变更需执行 --reload 才能生效。
14.3.1 查看防火墙状态
# 查看当前 zone 的完整规则
firewall-cmd --list-all
# 查看所有 zone
firewall-cmd --list-all-zones
# 查看当前激活的 zone
firewall-cmd --get-active-zones
# 查看已开放的端口和服务
firewall-cmd --list-ports
firewall-cmd --list-services
14.3.2 两种规则添加方式
方式一:服务名方式(适用于标准服务,推荐)
firewalld 内置了数百个服务定义,包含服务名、端口、协议的映射,语义清晰:
# 查看 firewalld 内置的服务列表
firewall-cmd --get-services
# 查看特定服务的定义(端口和协议)
firewall-cmd --info-service=http
firewall-cmd --info-service=mysql
# 永久开放标准服务
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=mysql
firewall-cmd --permanent --add-service=postgresql
firewall-cmd --permanent --add-service=dns
# 关闭服务
firewall-cmd --permanent --remove-service=ftp
# 重载使规则生效
firewall-cmd --reload
# 验证
firewall-cmd --list-services
方式二:端口方式(适用于非标准端口,如 SSH 2222)
# 永久开放自定义端口
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --permanent --add-port=9090/tcp
# 开放端口范围
firewall-cmd --permanent --add-port=10000-10050/tcp
# 关闭端口
firewall-cmd --permanent --remove-port=8080/tcp
# 重载并验证
firewall-cmd --reload
firewall-cmd --list-ports
两种方式的选择原则
优先使用服务名方式:语义更清晰,便于审计(看服务名即知用途);firewalld 升级时服务定义自动更新。非标准端口使用端口方式:如 SSH 2222、自定义应用端口等 /etc/services 中无对应服务名的情况。
14.3.3 富规则(Rich Rules)
富规则支持更精细的控制(源 IP 限制、速率限制等):
# 仅允许指定网段访问 SSH(2222 端口)
firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="192.168.1.0/24"
port protocol="tcp" port="2222"
accept'
# 拒绝特定 IP 的所有访问
firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="10.0.0.99"
reject'
# 查看已配置的富规则
firewall-cmd --list-rich-rules
firewall-cmd --reload
14.3.4 临时规则与持久规则
# 临时规则(不加 --permanent,重启后消失,用于临时测试)
firewall-cmd --add-port=9000/tcp
# 确认临时规则有效后,转为永久规则
firewall-cmd --runtime-to-permanent
# 或直接加 --permanent 一步到位
firewall-cmd --permanent --add-port=9000/tcp
firewall-cmd --reload
14.4 SELinux 端口上下文管理
在 RHEL 9 Enforcing 模式下,服务只能监听 SELinux 策略中明确允许的端口类型。
14.4.1 查看端口类型定义
# 查看所有端口类型定义
semanage port -l
# 过滤常用类型
semanage port -l | grep -E "ssh|http|mysql|postgres|ftp"
# 查看特定类型允许的端口
semanage port -l | grep "ssh_port_t"
semanage port -l | grep "http_port_t"
14.4.2 添加自定义端口上下文
# 为 SSH 添加非标准端口(如第 5 章所做)
semanage port -a -t ssh_port_t -p tcp 2222
# 为 HTTP 添加额外端口(如应用监听 8080)
semanage port -a -t http_port_t -p tcp 8080
# 为自定义应用添加端口
semanage port -a -t http_port_t -p tcp 9090
# 验证
semanage port -l | grep "ssh_port_t"
semanage port -l | grep "http_port_t"
14.4.3 修改与删除端口上下文
# 修改已存在的端口类型(-m 修改,-a 新增)
semanage port -m -t http_port_t -p tcp 8888
# 删除自定义端口策略(恢复默认)
semanage port -d -t http_port_t -p tcp 8080
# 查看本地自定义的端口策略(区别于系统默认)
semanage port -l -C
14.5 端口安全审计
定期审计开放端口是安全运维的基本工作,确保没有意料之外的监听服务。
14.5.1 端口与防火墙一致性检查
# 检查实际监听端口
ss -tulnp
# 检查防火墙开放端口
firewall-cmd --list-all
# 对比:监听但未在防火墙开放的端口(内部服务,正常)
# 防火墙开放但未监听的端口(服务未启动,需排查)
14.5.2 查找异常监听端口
# 列出所有监听端口及关联进程
ss -tulnp | grep LISTEN
# 检查监听在 0.0.0.0(所有接口)的端口(高风险,对外可见)
ss -tulnp | grep "0.0.0.0:"
# 仅监听 127.0.0.1 的端口(本机内部,相对安全)
ss -tulnp | grep "127.0.0.1:"
# 用 nmap 从外部视角扫描(模拟攻击者视角)
nmap -sS -p 1-1024 192.168.1.100
14.5.3 生成端口审计报告
tee /tmp/port-audit.txt << EOF
=== 端口审计报告 - $(date) ===
--- 监听端口列表 ---
$(ss -tulnp)
--- firewalld 开放规则 ---
$(firewall-cmd --list-all)
--- SELinux 自定义端口策略 ---
$(semanage port -l -C)
EOF
echo "报告已保存至 /tmp/port-audit.txt"
cat /tmp/port-audit.txt
14.6 常见问题与排查
| 问题现象 | 排查步骤 |
|---|---|
| 服务启动但外部无法访问 | ① ss -tulnp 确认监听;② firewall-cmd --list-all 确认防火墙;③ semanage port -l 确认 SELinux 端口类型 |
| 添加 SELinux 端口后服务仍失败 | ausearch -m avc -ts recent 查看是否还有其他 SELinux 拒绝 |
| firewalld reload 后规则丢失 | 确认使用了 --permanent 参数;检查 /etc/firewalld/zones/ 目录下是否有配置文件 |
| nmap 扫描显示端口 filtered | 防火墙丢弃了探测包(DROP 策略),该端口可能开放也可能关闭,需在目标机器上用 ss 确认 |
# firewalld 服务日志
journalctl -u firewalld -n 30
# 检查 firewalld 服务状态
systemctl status firewalld
# 验证 firewalld 配置完整性
firewall-cmd --check-config
14.7 实践任务
- 登录
linuxdc(SecureCRT 端口 2222,ops用户,密钥认证,sudo -i切换 root)。 - 使用
ss -tulnp查看当前所有监听端口,确认 SSH 2222 端口在列。 - 查询
/etc/services中 MySQL 和 PostgreSQL 的标准端口。 -
使用服务名方式为 HTTP 和 HTTPS 添加防火墙规则:
firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload firewall-cmd --list-services -
为端口 8080 添加 firewalld 规则(端口方式)和 SELinux 上下文:
firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --reload semanage port -a -t http_port_t -p tcp 8080 semanage port -l | grep "http_port_t" -
执行 14.5.3 节的端口审计脚本,查看输出报告。
14.8 自测问题
Q1:ss -tuln 与 ss -tulnp 有什么区别,何时需要用 -p?
-p 参数显示占用端口的进程信息(进程名和 PID)。查看"哪个服务在用这个端口"时使用 -p,需要 root 权限才能看到其他用户的进程信息。日常检查用 -tuln 即可;排查"端口被意外占用"时用 ss -tulnp。
Q2:firewalld 为什么分为临时规则和永久规则两种?
临时规则(不加 --permanent)立即生效但重启丢失,适合测试新规则是否正确;永久规则(加 --permanent)持久化保存但需要 --reload 才生效。分离设计允许"先测试、再固化",防止配置错误的规则在重启后永久生效影响生产。
Q3:为什么不能只配置 firewalld 开放端口,还需要配置 SELinux 端口上下文?
firewalld 是网络层防火墙,控制"哪些 IP/端口的流量可以进入系统";SELinux 是内核级强制访问控制,控制"哪些进程可以绑定哪些端口"。两者在不同层面工作:即使防火墙放行了 2222 端口,如果 SELinux 没有允许 sshd 绑定 2222,sshd 进程启动时绑定操作就会被 SELinux 阻止,服务无法启动。两者都必须正确配置。
14.9 章节总结
本章系统介绍了 RHEL 9 端口管理的完整工具体系:ss(本机端口查看)、nmap(端口扫描)、/etc/services(标准端口参考),以及 firewalld 的两种规则添加方式(服务名优先、端口方式补充)和 SELinux 端口上下文管理。三者的协同配置(服务监听 + firewalld 放行 + SELinux 授权)是 RHEL 9 服务对外提供访问的完整路径。定期执行端口审计,确保仅开放业务必需端口,是持续安全运维的基本要求。
至此,第二阶段安全强化与基线治理全部完成。系统已建立起完整的服务管理、内核调优、安全加固、性能监控与端口管控体系,具备进入第三阶段(数据存储与管理架构)的基础条件。