如何在 Linux 上检查开放的端口并关闭不需要的端口

检查服务器开放端口并关闭不必要的端口是网络安全管理中的关键环节,开放端口如同服务器的"窗口",若其中存在未被利用或未受保护的端口,就如同为潜在的攻击者敞开了大门,他们可能会利用这些端口的漏洞来入侵系统、窃取数据或进行恶意操作。通过检查开放端口,可以明确哪些端口正在被合法服务使用,哪些可能是被遗忘或未授权的端口,从而及时发现潜在的安全隐患。关闭不必要的端口则能有效减少攻击面,降低服务器被攻击的风险,同时也有助于优化系统性能,避免资源被无效占用,确保服务器的安全、稳定和高效运行。

本文介绍如何在本地和远程检查服务器上开放的端口,以及如何关闭它们。

1.在本地检查Linux上开放的端口

所有计算机操作系统(OS)都包含netstat命令,用于监控网络连接。

以下命令使用netstat显示使用 TCP 协议的所有监听端口:

复制代码
[root@monitor ~]# netstat -lt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
tcp        0      0 localhost:ipp           0.0.0.0:*               LISTEN
tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN
tcp        0      0 localhos:x11-ssh-offset 0.0.0.0:*               LISTEN
tcp        0      0 localhost:6011          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:sunrpc          0.0.0.0:*               LISTEN
tcp        0      0 monitor:domain          0.0.0.0:*               LISTEN
tcp6       0      0 [::]:ssh                [::]:*                  LISTEN
tcp6       0      0 localhost:ipp           [::]:*                  LISTEN
tcp6       0      0 localhost:smtp          [::]:*                  LISTEN
tcp6       0      0 localhos:x11-ssh-offset [::]:*                  LISTEN
tcp6       0      0 localhost:6011          [::]:*                  LISTEN
tcp6       0      0 [::]:sunrpc             [::]:*                  LISTEN
[root@monitor ~]#

其中:

  • netstat:调用程序
  • -l:列出监听端口
  • -t:指定TCP协议

输出内容以人类友好的方式排列,按列显示协议接收发送的数据包本地和远程IP地址 以及端口状态

如果将TCP协议替换为UDP,结果只会显示开放端口(至少在Linux上),而不会指定状态。与TCP协议不同,UDP协议是无状态的。

复制代码
[root@monitor ~]# netstat -lu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
udp        0      0 monitor:domain          0.0.0.0:*
udp        0      0 0.0.0.0:bootps          0.0.0.0:*
udp        0      0 0.0.0.0:sunrpc          0.0.0.0:*
udp        0      0 localhost:323           0.0.0.0:*
udp        0      0 0.0.0.0:824             0.0.0.0:*
udp        0      0 0.0.0.0:37740           0.0.0.0:*
udp        0      0 0.0.0.0:mdns            0.0.0.0:*
udp6       0      0 [::]:sunrpc             [::]:*
udp6       0      0 localhost:323           [::]:*
udp6       0      0 [::]:824                [::]:*
[root@monitor ~]#

也可以不指定协议,仅使用-l或--listen选项来获取所有监听端口的信息,无论其使用何种协议:

复制代码
[root@monitor ~]# netstat --listen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
tcp        0      0 localhost:ipp           0.0.0.0:*               LISTEN
tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN
tcp        0      0 localhost:6011          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:sunrpc          0.0.0.0:*               LISTEN
tcp        0      0 monitor:domain          0.0.0.0:*               LISTEN
tcp6       0      0 [::]:ssh                [::]:*                  LISTEN
tcp6       0      0 localhost:ipp           [::]:*                  LISTEN
tcp6       0      0 localhost:smtp          [::]:*                  LISTEN
tcp6       0      0 localhost:6011          [::]:*                  LISTEN
tcp6       0      0 [::]:sunrpc             [::]:*                  LISTEN
udp        0      0 monitor:domain          0.0.0.0:*
udp        0      0 0.0.0.0:bootps          0.0.0.0:*
udp        0      0 0.0.0.0:sunrpc          0.0.0.0:*
udp        0      0 localhost:323           0.0.0.0:*
udp        0      0 0.0.0.0:824             0.0.0.0:*
udp        0      0 0.0.0.0:37740           0.0.0.0:*
udp        0      0 0.0.0.0:mdns            0.0.0.0:*
udp6       0      0 [::]:sunrpc             [::]:*
udp6       0      0 localhost:323           [::]:*
udp6       0      0 [::]:824                [::]:*
raw6    4608      0 [::]:ipv6-icmp          [::]:*                  7
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  2      [ ACC ]     STREAM     LISTENING     26821    @/tmp/dbus-VWpRiaqJ
unix  2      [ ACC ]     STREAM     LISTENING     19199    /var/run/spice-vdagentd/spice-vdagent-sock
unix  2      [ ACC ]     STREAM     LISTENING     19201    /run/dbus/system_bus_socket
unix  2      [ ACC ]     STREAM     LISTENING     19204    /var/run/libvirt/virtlockd-sock
......

如上,显示了 TCP、UDP和Unix套接字协议的信息。

前面所有示例都展示了如何显示没有建立连接的监听端口信息。以下命令展示了如何显示监听端口和已建立的连接:

复制代码
netstat -vatn

其中:

  • netstat:调用程序

  • -v:详细信息

  • -a:显示活动连接

  • -t:显示TCP连接

  • -n:以数字形式显示端口

    # 实例:假设现在系统中发现了一个可疑进程,想要检查与之关联的端口。

    根据这个问题,我们可以使用lsof命令,该命令用于列出与进程相关联的打开文件。

    复制代码
    lsof -i 4 -a -p <进程数字>

    比如,现在要检查进程 1593:

    复制代码
    [root@monitor ~]# lsof -i 4 -a -p 1593
    COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    master  1593 root   13u  IPv4  29723      0t0  TCP localhost:smtp (LISTEN)

    其中

    • lsof:调用程序
    • -i:列出与互联网交互的文件,选项4表示仅打印IPv4,选项6可用于IPv6。
    • -a:指示输出结果进行逻辑与操作
    • -p:指定要检查的进程的PID编号

    正如前面所看到的,该进程与监听的SMTP端口相关联。

    2.远程检查 linux 上的开放的端口

    如果想要检测远程系统的端口,最常用的工具是Nmap (网络映射器)。下面对远程服务器 haopython.com 进行端口扫描:

    复制代码
    nmap www.haopython.com

    输出分为 3 列,分别显示端口、端口状态和在端口后面侦听的服务:

    复制代码
    [root@monitor ~]# nmap www.haopython.com
    
    Starting Nmap 6.40 ( http://nmap.org ) at 2025-05-08 10:03 CST
    Nmap scan report for www.haopython.com (147.94.44.183)
    Host is up (0.022s latency).
    Not shown: 994 filtered ports
    PORT     STATE SERVICE
    22/tcp   open  ssh
    80/tcp   open  http
    443/tcp  open  https
    888/tcp  open  accessbuilder
    3306/tcp open  mysql
    8888/tcp open  sun-answerbook
    
    Nmap done: 1 IP address (1 host up) scanned in 9.97 seconds
    [root@monitor ~]#

    默认情况下,Nmap仅扫描最常用的1000个端口。如果要Nmap扫描所有端口,则添加下面参数并运行:

    复制代码
    nmap -p- www.haopython.com

    3.在CentOS 8上移除httpd服务

    为确保服务器的安全,除了防火墙规则以保持端口被阻止外,还建议删除不必要的服务。

    下面举例删除CentOS 8上已经安装且不提供服务的httpd服务。

    1)确认服务状态

    复制代码
    systemctl status httpd

    2)停止服务并禁用自动启动

    复制代码
    systemctl stop httpd
    systemctl disable httpd

    3)移除服务

    使用 yum 或 dnf(CentOS 8 默认使用 dnf)来移除 httpd 服务及其相关文件:

    复制代码
    dnf remove httpd

    4)验证移除结果

    复制代码
    dnf list installed | grep httpd

    如果没有输出,说明 httpd 服务及其相关文件已被成功移除。

    通过以上步骤,成功移除了 CentOS 8 系统中不再需要的 httpd 服务,减少了系统资源的占用,同时也降低了因未使用服务可能带来的安全风险。

    4.使用 UFW 关闭 Linux 上的开放的端口

    如果我们发现有不需要开放的端口,最简单的解决方案是使用UFW(简单防火墙)将其关闭,某些Linux 系统可能需要先安装UFW。

    关闭端口有两种方式,一种是使用deny选项,另一种是使用reject选项,两者的区别在于reject指令会告知另一端连接已被拒绝。

    要使用deny 规则阻止22端口,则运行:

    复制代码
    ufw deny 22

    要使用 reject 规则阻止 22端口,请运行:

    复制代码
    ufw reject 22

    5.使用 iptables 关闭 Linux 上的开放的端口

    虽然 UFW 是管理端口的最简单方法,但它是 Iptables 的前端。

    以下示例显示如何使用 iptables 拒绝与端口 22 的连接:

    复制代码
    iptables -I INPUT -p tcp --dport 22 -j REJECT

    上述规则表示拒绝所有目标端口(dport)为 22 的TCP传入(INPUT)连接。被拒绝后,源端将被告知连接已被拒绝。

    下面规则只是丢弃所有数据包,而不通知源连接被拒绝:

    复制代码
    iptables -A INPUT -p tcp --dport 22 -j DROP

    6.使用firewalld在Linux上关闭开放的端口

    确保 firewalld 防火墙已经运行,假设现在想关闭端口80/tcp,可以使用以下命令:

    复制代码
    firewall-cmd --zone=public --remove-port=80/tcp --permanent

    然后重新加载:

    复制代码
    firewall-cmd --reload

    最后确认端口是否已关闭:

    复制代码
    firewall-cmd --list-all