获取通过 TCP/UDP 侦听的本地 IP 地址和端口列表:

获取通过 TCP/UDP 侦听的本地 IP 地址和端口列表:

给定一个进程 ID(使用套接字),我想获取套接字端点上的 IP。

例如,当创建新的 SSH 会话时,每个会话都会分叉 sshd 恶魔进程。我想获取该会话的 IP 端点。

我发现这个逻辑有效:
1. 列出所有 TCP 套接字,“cat /proc/net/tcp”
2. 列出输入进程和 grep“socket”的所有文件描述符:“ls -la /proc/PID/fd | grep socket”
3. 合并结果

输出#1:

root@L137B-DV3:/home/ilan# cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
...
  18: 519A0A0A:E0D1 3C890A0A:C006 01 00000000:00000000 00:00000000 00000000     0        0 10494 1 ffff88003c44f640 20 4 30 10 -1
  19: 519A0A0A:9930 3C890A0A:C004 01 00000000:00000000 00:00000000 00000000     0        0 10496 1 ffff88003c44ee80 20 4 32 10 -1
  20: 519A0A0A:01BD 59890A0A:C1FA 01 00000000:00000000 02:0004F47D 00000000     0        0 76451 2 ffff88003b39d740 21 4 30 10 -1

输出#2

root@L137B-DV3:/home/ilan# ls -la /proc/4038/fd/ | grep socket
lrwx------ 1 root root 64 Jun  4 13:40 30 -> socket:[6347]
lrwx------ 1 root root 64 Jun  4 13:40 32 -> socket:[76483]
lrwx------ 1 root root 64 Jun  4 13:40 35 -> socket:[6357]
lrwx------ 1 root root 64 Jun  4 13:40 36 -> socket:[76451]
lrwx------ 1 root root 64 Jun  4 13:40 6 -> socket:[76453]

我们看到inode 76451是合并结果,套接字ip地址是localhost:519A0A0A和remote:59890A0A。

我的问题是:
1.是否可以“cat /proc/net/tcp”具体的过程 ?我尝试了 cat /proc/PID/net/tcp - 它返回与 cat /proc/net/tcp 相同的结果。
2. 有没有更有效的方法来检索IP?

答案1

您可以列出 PID 的打开文件lsof:

lsof -p <PID>

但您可能更喜欢在 ssh 进程上使用命令名称过滤:

# filters on both ssh and sshd command (client/server)
lsof -i -na -c /sshd?/ -sTCP:ESTABLISHED

当然,将两者结合起来:

lsof -p <PID> -i -na -sTCP:ESTABLISHED

答案2

获取通过 TCP/UDP 侦听的本地 IP 地址和端口列表:

netstat -planu | awk '/^udp / {print $4}'

通过 /proc 文件系统获取相同的信息:

for h in $(awk 'NR>1{print $2}' /proc/net/tcp); do
printf "%s:%d\n" $(printf "%d." $(echo ${h%:*}|sed 's/../0x& /g'|tr ' ' '\n'|tac)|sed 's/\.$/\n/') 0x${h#*:}; done

其次是

ip_addr=$(echo 0F01A8C0 | sed -e 's/\(..\)\(..\)\(..\)\(..\)/echo $((0x\4)).$(echo $((0x\3))).$(echo $((0x\2))).$(echo $((0x\1)))/e')

然后在awk中

 awk 'NR>1{split($2, addr, ":"); for(i=0;i<4;i++){
printf("%d.",strtonum("0x" substr(addr[1],2*i+1,2)))}; print ":" strtonum("0x" addr[2]);}' /proc/net/udp

只需要将点分小数反转即可。

echo 0F01A8C0 | awk '{str = sprintf("0x%s", $0); ip = strtonum(str); \
printf ("%d.%d.%d.%d\t",rshift(and(ip,0x000000ff),00),
                        rshift(and(ip,0x0000ff00),08),
                        rshift(and(ip,0x00ff0000),16),
                        rshift(and(ip,0xff000000),24))}'

最终的:

 awk 'NR>1 {
    split($2, a, ":");
   patsplit(a[1],h,/.{2}/);
   for(i=4;i>0;i--){
     h[i]=strtonum("0x" h[i]);
   };
   printf("%d.%d.%d.%d:%d\n",h[4],h[3],h[2],h[1],strtonum("0x" a[2]));
 }' /proc/net/udp

来源:https://wiki.christophchamp.com/index.php?title=Unix_sockets

相关内容