问题:
一些应用程序绑定到一个特定端口突然不能启动由于端口冲突。
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 �C
环境:
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 �C
另一个命令是“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 �Ci [port]可能证明与 NFS
服务相关或者无关。服务停止或服务重启可能协助识别基于服务使用端口。
* SystemTap 可以用来查询内核进一步在这个级别。
本文出自 “滴水穿石” 博客,谢绝转载!