世界再美我始终如一 2025-12-09 19:50 采纳率: 98.5%
浏览 0
已采纳

如何查看firewalld已开放的端口?

如何查看firewalld当前已开放的端口?使用`firewall-cmd --list-ports`命令只能显示通过`--add-port`方式直接添加的端口,但无法展示通过服务(如http、ssh)间接开放的端口。许多用户因此误以为某些端口未开放。如何准确查看系统中所有实际生效的开放端口,包括通过服务启用的端口?此外,`--list-all`输出信息繁多,如何快速提取关键端口信息?在使用firewalld的生产环境中,如何结合`--permanent`选项正确查看持久化规则中的开放端口配置?
  • 写回答

1条回答 默认 最新

  • 娟娟童装 2025-12-09 19:57
    关注

    一、firewalld端口管理机制解析

    在现代Linux系统中,firewalld作为动态防火墙管理工具,广泛应用于RHEL、CentOS、Fedora等发行版。其核心优势在于支持运行时配置与永久配置分离,并通过“区域(zone)”和“服务(service)”抽象简化网络策略管理。

    然而,在实际运维过程中,许多工程师发现使用 firewall-cmd --list-ports 命令仅能显示通过 --add-port 显式添加的端口,而无法反映由预定义服务(如 http、https、ssh)所开放的端口。这导致对“哪些端口真正对外开放”的误判,进而影响故障排查与安全审计。

    1.1 理解 firewalld 的端口开放机制

    • 直接端口添加:通过 --add-port=8080/tcp 添加的端口会被 --list-ports 显示。
    • 服务级开放:启用服务如 --add-service=http,会自动加载该服务定义的所有端口(例如80/tcp),但这些不会出现在 --list-ports 中。
    • 服务定义文件位置/usr/lib/firewalld/services//etc/firewalld/services/

    1.2 查看当前运行时所有生效端口的完整方法

    要准确获取当前实际开放的端口列表(包括服务引入的端口),需结合以下命令:

    # 查看默认区域中所有信息
    firewall-cmd --list-all
    
    # 示例输出:
    # public (active)
    #   target: default
    #   icmp-block-inversion: no
    #   interfaces: eth0
    #   sources: 
    #   services: ssh dhcpv6-client http https
    #   ports: 8080/tcp
    #   forward-ports: 
    #   source-ports: 
    #   protocols: 
    #   masquerade: no
    #   forward-ports: 
    #   icmp-blocks: 
    #   rich rules:

    从上述输出可见,services 字段包含 http、https 等服务,需进一步解析其对应端口。

    1.3 提取服务对应端口:自动化脚本示例

    为快速提取所有已启用服务的实际端口,可编写如下 Bash 脚本:

    #!/bin/bash
    ZONE=$(firewall-cmd --get-default-zone)
    SERVICES=$(firewall-cmd --zone=$ZONE --list-services)
    
    echo "Active services in zone '$ZONE': $SERVICES"
    echo "Resolved ports:"
    
    for svc in $SERVICES; do
        PORTS=$(grep -E "^<port" /usr/lib/firewalld/services/${svc}.xml | \
                sed -E 's/.*port="([^"]+)".*protocol="([^"]+).*/\1\/\2/')
        echo "$svc: $PORTS"
    done

    1.4 综合列出所有实际开放端口(含服务与直接端口)

    以下命令组合可用于生成完整的开放端口清单:

    命令说明
    firewall-cmd --list-ports仅显示直接添加的端口
    firewall-cmd --list-services列出当前区域启用的服务
    firewall-cmd --list-all显示完整配置,适合人工分析
    firewall-cmd --permanent --list-all查看持久化规则(重启后仍生效)
    firewall-cmd --info-service=http查看特定服务详情(含端口)

    1.5 生产环境中如何正确查看持久化规则

    在生产系统中,必须区分运行时规则与永久规则。常见误区是修改了永久规则但未重载,或只查看运行时状态。

    1. 查看永久开放的端口:
      firewall-cmd --permanent --list-ports
    2. 查看永久启用的服务:
      firewall-cmd --permanent --list-services
    3. 合并两者并解析服务端口:
    PERM_PORTS=$(firewall-cmd --permanent --list-ports)
    PERM_SVCS=$(firewall-cmd --permanent --list-services)
    ZONE=$(firewall-cmd --get-default-zone)
    
    echo "Permanent Ports:"
    echo "$PERM_PORTS"
    
    echo "Permanent Services and Their Ports:"
    for s in $PERM_SVCS; do
        grep -E "^<port" /usr/lib/firewalld/services/$s.xml 2>/dev/null | \
        sed -E "s/.+port=\"([^\"]+)\" protocol=\"([^\"]+).*/$s: \1\/\2/"
    done

    1.6 使用流程图展示端口查询逻辑

    graph TD A[开始] --> B{是否需要查看持久化规则?} B -- 是 --> C[使用 --permanent 选项] B -- 否 --> D[使用运行时命令] C --> E[执行 firewall-cmd --permanent --list-all] D --> F[执行 firewall-cmd --list-all] E --> G[提取 services 和 ports] F --> G G --> H[解析每个 service 的 XML 定义] H --> I[合并 direct ports 与 service ports] I --> J[输出完整开放端口列表]

    1.7 高级技巧:构建统一端口视图工具

    建议在生产环境部署一个自定义脚本,定期输出标准化报告。示例功能包括:

    • 自动识别默认区域
    • 同时检查运行时与永久配置差异
    • 输出JSON格式便于集成监控系统
    • 标记潜在风险端口(如 23/telnet, 21/ftp)
    #!/bin/bash
    # get-open-ports.sh - 获取全量开放端口
    output_json() {
        local runtime_ports=$(firewall-cmd --list-ports | tr ' ' '\n')
        local perm_ports=$(firewall-cmd --permanent --list-ports | tr ' ' '\n')
        local svcs=$(firewall-cmd --list-services | tr ' ' '\n')
    
        echo "{ \"runtime_ports\": [$(echo $runtime_ports | sed 's/$/"/; s/^/"/; s/ /", "/g')],"
        echo "  \"services\": {"
        first=true
        while read svc; do
            [ -z "$svc" ] && continue
            ports=$(grep -E '<port' /usr/lib/firewalld/services/$svc.xml | sed -E 's/.+port="([^"]+)".protocol="([^"]+).*/"\1\/\2"/')
            if [ "$first" = true ]; then first=false; else echo -n ", "; fi
            echo -n "\"$svc\": [$ports]"
        done <<< "$svcs"
        echo "  }"
        echo "}"
    }

    1.8 安全与审计建议

    在企业级部署中,应建立如下最佳实践:

    • 避免混合使用 direct 规则与 zone/service 模型
    • 定期导出并版本控制 /etc/firewalld/ 下的配置
    • 使用 firewall-offlines-cmd 在离线镜像中验证策略
    • 结合 ss -tulnnetstat 验证内核层实际监听状态
    • 将 firewalld 输出与主机入侵检测系统(HIDS)联动
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 12月10日
  • 创建了问题 12月9日