数字化技能提升教程,数字化时代生存宝典

FreeBSD端口占用排查

浏览:55

服务启动提示端口被占用,或进程已经运行但外部仍然无法连接,通常需要从监听地址和所属进程入手排查。FreeBSD 自带的 sockstat 可以查看套接字,procstat 则能继续核查进程的可执行文件、启动参数和文件描述符。把这两组信息对应起来,比直接重启或结束进程更容易找到原因。

一、先确定需要检查的对象

开始前记录目标协议、端口、访问地址,以及服务是否运行在 Jail 中。TCP 和 UDP 即使使用相同端口号,也不能混为一谈。

本文主要以 TCP 8080 为例。命令中的 PID、Jail 名称和地址均为示例,操作时要替换为实际值。需要查看其他账号进程的完整信息时,以 root 身份执行。

先查看 IPv4 和 IPv6 的 TCP 监听:

sockstat -46 -l -P tcp

参数含义:

  • -4:显示 IPv4 套接字。
  • -6:显示 IPv6 套接字。
  • -l:筛选监听套接字。
  • -P tcp:限定 TCP 协议。

只检查目标端口:

sockstat -46 -l -P tcp -p 8080

没有输出时,说明在当前可见范围内没有匹配的监听记录。继续检查服务是否退出、端口是否配置错误,以及是否需要进入对应的 Jail 查看。

二、看懂sockstat输出

下面是一条简化的示意记录,不代表实际服务器状态:

USER   COMMAND   PID   FD   PROTO   LOCAL ADDRESS    FOREIGN ADDRESS
www    app       1234  7    tcp4    127.0.0.1:8080   *:*

各列的作用如下:

  • USER:持有套接字的用户。
  • COMMAND:对应进程的命令名称。
  • PID:进程编号。
  • FD:文件描述符编号。
  • PROTO:协议及地址族信息。
  • LOCAL ADDRESS:本地绑定地址和端口。
  • FOREIGN ADDRESS:远端地址,监听记录通常没有确定的远端连接。

排查时先记录 PID 和 LOCAL ADDRESS,不要只记住端口号。

回环地址监听

示例中的:

127.0.0.1:8080

表示该 IPv4 监听绑定在本机回环地址上。外部客户端无法直接通过服务器网卡地址连接这个监听。

如果服务设计为仅供本机反向代理调用,这种设置可能完全正常。不能为了让外部访问成功,就不加判断地改成所有网卡监听。

通配地址监听

显示为 *:8080 等通配形式时,需要结合 PROTO 判断具体地址族。IPv4 和 IPv6 应分别检查,不要看到一个 IPv6 监听就认定 IPv4 客户端也一定可以连接。

sockstat -4 -l -P tcp -p 8080
sockstat -6 -l -P tcp -p 8080

即使绑定在通配地址上,外部访问仍可能受到防火墙、路由、云网络或应用访问控制的影响。

三、根据PID定位程序

假设确认目标进程 PID 为 1234,查看进程及父进程信息:

ps -ww -p 1234 -o pid,ppid,user,stat,command

继续核对二进制信息和启动参数:

procstat -b 1234
procstat -c 1234

这一步可以帮助判断:

  • 占用端口的是预期服务还是另一套程序。
  • 当前运行的是哪个安装路径下的可执行文件。
  • 是否使用了不同于预期的配置路径或启动参数。

命令名称可能被截断,也可能只显示解释器名称,因此不应只凭 sockstat 中的 COMMAND 判断服务身份。

命令行也不一定包含所有配置来源。如果程序通过配置文件或环境读取端口,还需要结合它的实际启动方式继续确认。

查看打开的文件与套接字

procstat -f 1234

将输出中的文件描述符与 sockstat 的 FD 对照,可以继续查看进程持有哪些文件或套接字。

不过,程序读取配置后可能已经关闭对应文件。没有在文件描述符列表中看到配置文件,不代表它从未被加载。

分享排查结果前,应检查启动参数和文件路径中是否包含业务敏感信息。

四、处理端口被其他进程占用

如果启动日志包含类似 Address already in use 的错误,先重新执行:

sockstat -46 -l -P tcp -p 8080

核对占用者是否属于以下情况:

  1. 同一服务被手动和服务脚本分别启动。
  2. 旧进程仍然运行,新进程试图使用同一地址和端口。
  3. 另一套应用误用了相同端口。
  4. 原本计划使用不同地址的两个服务,实际都绑定了通配地址。

确认后,再决定停止重复实例、修正监听地址或更换端口。

优先通过应用对应的服务脚本停止服务。例如,占用者确认是已安装的 Nginx 服务,并且本次维护允许停止它时,可以执行:

service nginx status
service nginx stop

这里只是服务管理示例,需要替换为实际确认的服务名称。

不要从 sockstat 输出中直接批量取 PID 后强制终止。一个监听套接字可能被多个进程或文件描述符持有,多条记录也不一定意味着重复启动了多套服务。

处理后重新检查端口,启动预期服务,再验证它是否绑定到正确的地址。

五、本机能连接,外部却无法访问

先确认服务实际监听在哪个地址上,再分别从本机和另一台设备验证。

如果服务监听本机回环地址,可以在服务器上检测:

nc -vz -w 3 127.0.0.1 8080

如果只绑定某个网卡地址,则应将测试目标改为该地址。

从另一台具备 nc 的设备测试:

nc -vz -w 3 192.0.2.10 8080

192.0.2.10 是文档示例地址,必须替换成实际服务器地址。

测试结果可以帮助缩小范围:

  • 本机也无法建立连接:先检查监听地址、进程状态和本机访问规则。
  • 本机能连接、外部超时:继续检查网络路径、安全组和防火墙。
  • TCP 连接成功、应用仍报错:继续检查协议、应用日志、域名配置和后端依赖。

连接成功只代表 TCP 层建立了连接,不证明应用已经正常处理请求。超时或拒绝连接也只能作为排查线索,不能仅凭一次测试确定唯一原因。

不要通过整体关闭防火墙来代替定位具体规则。

六、查看已建立连接和UDP端口

查看已连接的 TCP 套接字:

sockstat -46 -c -P tcp

筛选与443端口相关的记录:

sockstat -46 -c -P tcp -p 443

这里的 -p 443 会匹配本地或远端端口。因此,结果既可能包含客户端访问本机 HTTPS 服务的连接,也可能包含本机程序访问外部 HTTPS 服务的连接。

区分连接方向时,要同时看 LOCAL ADDRESS 和 FOREIGN ADDRESS。不能把这些行数直接当作网站访客数或 HTTP 请求数。

检查 UDP 53:

sockstat -46 -P udp -p 53

UDP 没有 TCP 相同的连接建立过程。看到 UDP 套接字只说明程序持有相关端点,仍需通过对应协议的请求验证业务是否正常。

七、服务运行在Jail中的情况

先在宿主机查看 Jail:

jls

按 Jail 名称筛选宿主机可见的记录:

sockstat -j webjail -l -P tcp

webjail 是示例名称,也可以使用实际 Jail ID。

对于使用独立网络栈的 VNET Jail,应进入相应环境检查:

jexec webjail sockstat -46 -l -P tcp -p 8080

如果容器内有监听,而宿主机入口无法访问,还应检查该 Jail 的地址、路由和入口映射。不能仅凭宿主机没有显示预期监听,就认定 Jail 内服务没有启动。

八、常见问题

1、为什么同一个端口出现多个PID?

可能是主进程和工作进程继承了相同监听套接字,也可能涉及套接字复用。应结合父进程、启动参数和服务架构判断,不能直接认定端口冲突。

2、为什么显示正在监听,网站仍然打不开?

监听只说明程序绑定了相应端点。外部网络、HTTPS 配置、请求处理或后端服务仍可能存在问题,需要逐层验证。

3、为什么端口查询没有结果,启动时却提示占用?

检查是否查错协议、地址族或 Jail,也可能是程序状态变化较快。应在报错出现时及时查看,并结合应用日志定位具体绑定地址。

4、是否需要额外安装lsof?

本文的端口到进程排查可以先使用系统自带的 sockstat、procstat 和 ps 完成。确认需要更具体的能力后,再决定是否增加其他工具。

广告合作

广告合作

QQ群号:4114653

QQ群号:4114653

温馨提示:
  1. 本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。
  2. 本站原创内容未经允许不得转载,转载请注明出处“站长百科”和原文地址。