如果他们没有收听,如何列出绑定的Linux套接字

Ger*_*zty 5 sockets linux networking bind

在Linux环境中是否有一种方法如果它们没有监听,如何检查绑定套接字?

如果一个套接字被创建,绑定和监听,而不是它列出netstat -l,可见/proc/net/<L4 type>,等等.这没关系.

但是,如果套接字仅创建并绑定到特定的TCP/UDP/SCTP端口和IP,则在上述位置不可见./proc/<PID>/fd/使用socket:[inode]符号可以看到fd ,但它不能与任何其他表/列表AFAIK相关联.问题是,绑定套接字会阻止同一网络命名空间中的其他进程在同一IP /端口上绑定/侦听.它导致了Errno 98: Address already in use.

那么,是否可以列出(或确定所有者进程)绑定,但不是监听/连接套接字?

编辑:

我们来看看这个Golang TCP示例.你可以运行它go run TCP_bind.go.如果运行两次,则第二次运行失败.

您如何判断流程绑定到哪个端口?或者反过来,当你不能在你的应用程序中使用它时,你怎么能找到谁保留端口55555?

o90*_*000 0

在 Linux 下,您可以使用审核系统来记录某些事件,其中包括系统调用。我们可以利用它来找出哪个进程调用了bind(2)

假设Ubuntu:

sudo apt install auditd
sudo auditctl -a exit,always -F arch=b64 -S bind -k BIND
Run Code Online (Sandbox Code Playgroud)

我已经使用以下 Python 代码进行了测试,相当于您的 Go 代码:

import socket
s = socket.socket()
s.bind(('127.0.0.1', 55555))
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式搜索审核日志ausearch -i -k BIND

----
type=CONFIG_CHANGE msg=audit(04/18/2017 21:29:52.730:19) : auid=ovi ses=1 op="add_rule" key=BIND list=exit res=yes
----
type=CONFIG_CHANGE msg=audit(04/18/2017 21:29:58.062:20) : auid=ovi ses=1 op="add_rule" key=BIND list=exit res=yes
----
type=PROCTITLE msg=audit(04/18/2017 21:31:09.189:33) : proctitle=python
type=SOCKADDR msg=audit(04/18/2017 21:31:09.189:33) : saddr=inet host:127.0.0.1 serv:55555
type=SYSCALL msg=audit(04/18/2017 21:31:09.189:33) : arch=x86_64 syscall=bind success=yes exit=0 a0=0x3 a1=0x7fff11c66440 a2=0x10 a3=0x373 items=0 ppid=28677 pid=28693 auid=o9000 uid=o9000 gid=o9000 euid=o9000 suid=o9000 fsuid=o9000 egid=o9000 sgid=o9000
fsgid=o9000 tty=pts1 ses=4 comm=python exe=/usr/bin/python2.7 key=BIND
Run Code Online (Sandbox Code Playgroud)

我们确实可以看到一个从 pid 28693 调用 host:127.0.0.1 serv:55555 的绑定。

必须在启动有问题的程序之前启用审核。

实际日志存储在/var/log/audit/audit.log. 您可能需要设置auditd来轮换它,这样它就不会无限期地增长。

上述命令的解释(基于doc):

  • auditctl -a:审核系统调用...
  • exit,always:在系统调用退出时始终对其进行审核(因为我们想知道是否bind(2)成功)
  • -F arch=b64:审核 64 位程序(必须为 32 位创建单独的规则!)
  • -S bind:审计bind系统调用
  • -k BINDBIND:为日志中的事件添加标签
  • ausearch:搜索审核日志...
  • -i:将结构转换为人类可读的符号(解码IP地址和端口号)
  • -k BIND:仅显示标记为“BIND”的事件。