如何调试 Linux 网络:地址已被使用

如何调试 Linux 网络:地址已被使用

我有一台 Slackware Linux 机器,无法启动任何监听本地主机上某个特定端口的服务。通过使用 strace,我发现错误发生在调用上bind(),错误如下EADDRINUSE (Address already in use)

bind(3, {sa_family=AF_INET, sin_port=htons(874), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EADDRINUSE (Address already in use)

在我尝试启动任何侦听该端口的进程时都会发生这种情况,因此这与进程本身无关。上面的 strace 输出来自命令strace -ff nc -l -p 874 -s 127.0.0.1

因此,这表明已有一个进程在监听本地主机端口 874。但是,我似乎找不到它。以下命令均未返回任何内容:

netstat -aplunt | grep :874
netstat -na | grep :874
lsof -i :874
lsof -i tcp | grep 874
fuser 874/tcp
socklist | grep 874
iptables -t filter -S | grep 874
iptables -t nat -S | grep 874
iptables -t mangle -S | grep 874
conntrack -L | grep 874

如果我尝试监听,0.0.0.0:874它会失败并出现相同的错误。监听网卡上配置的其中一个 IP 地址可以正常工作,监听127.0.0.2:874也可以正常工作。监听其他端口也可以正常工作,也可以在127.0.0.1或上正常工作0.0.0.0

所以,现在我很好奇。我如何才能找出网络堆栈在此处返回 EADDRINUSE 的原因?我还可以查看哪些其他内容,或者我可以运行哪些其他命令来获取更多信息?

附加信息:

  • 内核 4.1.31。
  • 这里不使用 Selinux。
  • 尝试使用 telnet 连接到 127.0.0.1 返回“连接被拒绝”
  • 我以 root 身份运行命令

答案1

如果您的主机是 NFS 客户端,则它可能使用源端口 874 进行 NFS 挂载。我怀疑,由于该连接不是来自用户空间,因此您迄今为止使用的工具可能无法看到它。

请考虑以下操作之一:

  • 调整sysctlssunrpc.min_resvportsunrpc.max_resvport(默认 665 和 1023)以更改 NFS 客户端使用的源端口范围
  • 使用此范围之外的监听端口
  • 使用noresvportNFS 挂载上的选项来使用非特权范围(可能存在安全隐患)

相关内容