Linux 中是否有一個介面可以取得目前連線的 IP 及其狀態?我知道ss
和netstat
,但我想使用/proc/
或其他一些已經擁有它們的“官方”內核介面(如果存在)。如果它不存在,我從哪裡開始獲取此資訊?基本上,我需要一個包含此資訊的介面,以便我可以以程式設計方式檢索它。
答案1
此外ss
,netstat
我目前不知道我會推薦任何其他工具。
有關如何取得此資訊:
如果您這樣做man netstat
,您可以在 參考資料 部分看到FILES
netstat 用於收集其資訊的一些列出的檔案。
其中,有/proc/net/tcp
和/proc/net/udp
。
如果您cat /proc/net/tcp
可以看到有關係統上 tcp 連線的各種資訊。
範例輸出將是
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11190 1 0000000000000 000 100 0 0 10 0
1: 8700A8C0:91FC 0F02000A:15B3 01 00000000:00000000 02:00000AF6 00000000 1000 0 5565254 2 00000000000 00000 46 4 13 10 -1
rem_address
這是您要尋找的 IP。我對此了解不多,但我認為可以為st
您提供有關當前狀態的資訊。0A
應該是LISTEN
,01
意味著ESTABLISHED
。
解碼local_address
orrem_address
相當容易,8700A8C0:8F76
例如:
Format: hex(rev_ip):hex(port)
87 -> 135
00 -> 0
A8 -> 168
C0 -> 192
:8F76 -> 36726
=> 192.168.0.135, Port 36726
有關該目錄的更多資訊/proc/net
是這裡。
有關所提供數據的更多資訊是這裡。
相關的 SO 線程也是這裡。
答案2
如果你運行strace lsof -i 2>&1 | grep open
你會得到一些關於如何lsof -i
工作的線索:
open("/proc/1/fdinfo/7", O_RDONLY) = 5
open("/proc/net/ax25", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/proc/net/ipx", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/proc/net/raw", O_RDONLY) = 5
open("/proc/net/netlink", O_RDONLY) = 5
open("/proc/net/packet", O_RDONLY) = 5
open("/proc/net/unix", O_RDONLY) = 5
請注意,我的系統上不存在一些文件。其中一些文件記錄在 中man proc
,但它們的輸出看起來並不難理解。
之後,lsof -i
按升序逐字遍歷整個進程表,尋找開啟的描述符:
open("/proc/2/stat", O_RDONLY) = 4
openat(AT_FDCWD, "/proc/2/fd", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/proc/3/stat", O_RDONLY) = 4
openat(AT_FDCWD, "/proc/3/fd", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/proc/5/stat", O_RDONLY) = 4
openat(AT_FDCWD, "/proc/5/fd", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/proc/7/stat", O_RDONLY) = 4
openat(AT_FDCWD, "/proc/7/fd", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/proc/8/stat", O_RDONLY) = 4
[...]
openat(AT_FDCWD, "/proc/101/fd", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/proc/112/stat", O_RDONLY) = 4
openat(AT_FDCWD, "/proc/112/fd", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/proc/143/stat", O_RDONLY) = 4
openat(AT_FDCWD, "/proc/143/fd", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/proc/143/fdinfo/3", O_RDONLY) = 5
open("/proc/143/fdinfo/4", O_RDONLY) = 5
open("/proc/143/fdinfo/5", O_RDONLY) = 5
open("/proc/143/fdinfo/11", O_RDONLY) = 5
open("/proc/143/fdinfo/12", O_RDONLY) = 5
open("/proc/143/fdinfo/13", O_RDONLY) = 5
答案3
另一種選擇是,如果您正在使用iptables
並已ip_conntrack
編譯到核心中或作為模組加載,那麼您可以從較新的用戶空間介面工具取得iptables
所有連接狀態的視圖/proc/net/ip_conntrack
conntrack
$ sudo cat /proc/net/ip_conntrack
icmp 1 23 src=10.1.1.14 dst=10.1.1.1 type=8 code=0 id=10017 src=10.1.1.1 dst=10.1.1.14 type=0 code=0 id=10017 mark=0 use=2
unknown 2 597 src=10.1.1.10 dst=224.0.0.1 [UNREPLIED] src=224.0.0.1 dst=10.1.1.10 mark=0 use=2
udp 17 17 src=10.1.1.181 dst=10.1.1.255 sport=17500 dport=17500 [UNREPLIED] src=10.1.1.255 dst=10.1.1.181 sport=17500 dport=17500 mark=0 use=2
tcp 6 431999 ESTABLISHED src=10.1.1.14 dst=10.1.1.2 sport=22 dport=49218 src=10.1.1.2 dst=10.1.1.14 sport=49218 dport=22 [ASSURED] mark=0 use=2
icmp 1 28 src=10.1.1.14 dst=8.8.8.8 type=8 code=0 id=13601 src=8.8.8.8 dst=10.1.1.14 type=0 code=0 id=13601 mark=0 use=2
這還包括透過您的電腦路由的連接的訊息,而不僅僅是本地連接。