RHEL에서 netstat 프로세스의 PID / Program Name을 표시하지 않는 이유는 무엇인가요?
Environment
- Red Hat Enterprise Linux
- 네트워크 서비스
Issue
- 갑자기 특정 포트에 바인딩되는 일부 프로그램들이 포트예약 충돌때문에 시작할 수가 없습니다.
- 해당 포트에 대한 telnet 명령은 소켓이 열려있는 것을 보여 주지만 프로세스는 특정되지 않습니다.
- 다음과 같이 "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 -
Resolution
- 'root'사용자로 'netstat'명령을 실행하십시오.
[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
[root@localhost ~]#
- 일반적으로 사용자가 옵션 'e'에서 netstat를 사용하면 프로세스의 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-i : [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 스크립트를 사용할 수 있습니다.
- SystemTap 설정하기
- 다음 스크립트를 'tcp_connections.stap'로 저장합니다.
- 'stap tcp_connections.stap PORT'를 실행합니다. 여기서 PORT는 조사 할 포트 번호입니다.
- 지정된 포트에 연결하고 스크립트 출력을 확인합니다.
#!/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
Root Cause
- 명령이 root 사용자가 아닌 일반 사용자로 실행되었습니다. 따라서 root 사용자로 실행중인 프로세스는
-
으로 표시됩니다. - 커널 스레드 인 것도 생각할 수 있습니다. 커널 내부에서 실행하기 때문에 외부에서는 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]
-
이것은 포트 [PORT]에서 실행하는 RPC 프로그램 이름 1073741824을 보여줍니다.
lsof-i : [PORT]
는 NFS가 관련되어 있는지 여부를 확인합니다.service stop
또는service restart
포트를 사용하는 커널 기반의 서비스를 식별하는 데 도움이 될 수 있습니다. -
SystemTap을 사용하여이 수준에서 더 커널을 조사 할 수 있습니다.
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments