问题:

一些应用程序绑定到一个特定端口突然不能启动由于端口冲突。

telnet 命令对 port 表明套接字是开放的,但没有过程可以被识别。

一个破折号(-)被列“PID /Program Name ”,如下所示:

[user@localhost ~]$ netstat -plnt | head -5

(No info could be read for "-p": geteuid()=500 but you should be root.)

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name

tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -

tcp 0 0 0.0.0.0:49234 0.0.0.0:* LISTEN -

tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN –

环境:

Red Hat Enterprise Linux

Network services

决议:

Run the netstat command as user 'root':

[root@localhost ~]# netstat -lnpt | head -5

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name

tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1334/rpcbind

tcp 0 0 0.0.0.0:49234 0.0.0.0:* LISTEN 1352/rpc.statd

tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1554/sshd

作为一个普通用户,使用 netstat 的选项“e”将显示 UID 和 Inode 的进程:

[user@localhost ~]$ netstat -plent | head -5

(No info could be read for "-p": geteuid()=500 but you should be root.)

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name

tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 0 11696 -

tcp 0 0 0.0.0.0:49234 0.0.0.0:* LISTEN 29 11895 -

tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 12767 –

另一个命令是“lsof”。这也需要 root 特权。语法是“lsof -:[port]”。如发现这个过

程监听端口 22,运行:

[root@localhost ~]# lsof -i:22

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

sshd 1554 root 3u IPv4 12767 0t0 TCP *:ssh (LISTEN)

sshd 1554 root 4u IPv6 12769 0t0 TCP *:ssh (LISTEN)

sshd 1872 root 3r IPv4 14156 0t0 TCP 10.0.0.13:ssh->example.redhat.com:41521

(ESTABLISHED)

sshd 1876 user 3u IPv4 14156 0t0 TCP 10.0.0.13:ssh->example.redhat.com:41521

(ESTABLISHED)

你可以用一个 SystemTap 脚本识别哪些内核线程对一个端口。

下面的脚本保存为 tcp_connections.stap

运行堵塞 tcp_connections。阻止端口,端口的端口号是你想调查

使连接或从给定的端口,看脚本的输出

#! /usr/bin/env stap

global port = -1

probe begin {

%( $# > 1 %?

log ("Usage:\n\tstap tcp_connections.stap [port-number]\n\n\n")

exit()

%)

%( $# == 1 %?

port = strtol (@1, 10)

if (port == 0)

{

printf ("Cannot convert %s to a number\n\n\n",@1)

port = -1

exit ()

}

if (port > -1) printf ("Looking for port %d\n",port)

%:

if ($# == 0)

{

port = 0

print ("Looking for all ports\n");

}

%)

if (port > -1) printf("%6s %16s %6s %6s %16s\n",

"UID", "CMD", "PID", "PORT", "IP_SOURCE")

}

probe kernel.function("tcp_accept").return?,

kernel.function("inet_csk_accept").return? {

sock = $return

if (sock != 0)

{

if ((port == 0) || (inet_get_local_port(sock) == port))

printf("%6d %16s %6d %6d %16s\n", uid(), execname(), pid(),

inet_get_local_port(sock), inet_get_ip_source(sock))

}

}

# tcp_connections ends here

根源:

作为非根用户执行的命令。因此,根用户运行的过程将显示为一个破折号。

另一种可能是,这是一个内核线程,这没有 PID,因为它运行在内核。

例如,NFSv4 调守护进程:

# rpcinfo -p localhost

program vers proto port

100000 2 tcp 111 portmapper

100000 2 udp 111 portmapper

100024 1 udp 687 status

100024 1 tcp 690 status

1073741824 1 tcp [PORT]

这表明 RPC 程序名 1073741824 上运行的 port [PORT]。lsof –i [port]可能证明与 NFS

服务相关或者无关。服务停止或服务重启可能协助识别基于服务使用端口。

* SystemTap 可以用来查询内核进一步在这个级别。