跳转至

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 实践任务

  1. 登录 linuxdc(SecureCRT 端口 2222,ops 用户,密钥认证,sudo -i 切换 root)。
  2. 使用 ss -tulnp 查看当前所有监听端口,确认 SSH 2222 端口在列。
  3. 查询 /etc/services 中 MySQL 和 PostgreSQL 的标准端口。
  4. 使用服务名方式为 HTTP 和 HTTPS 添加防火墙规则:

    firewall-cmd --permanent --add-service=http
    firewall-cmd --permanent --add-service=https
    firewall-cmd --reload
    firewall-cmd --list-services
    
  5. 为端口 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"
    
  6. 执行 14.5.3 节的端口审计脚本,查看输出报告。


14.8 自测问题

Q1:ss -tulnss -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 服务对外提供访问的完整路径。定期执行端口审计,确保仅开放业务必需端口,是持续安全运维的基本要求。

至此,第二阶段安全强化与基线治理全部完成。系统已建立起完整的服务管理、内核调优、安全加固、性能监控与端口管控体系,具备进入第三阶段(数据存储与管理架构)的基础条件。