Translated message

A translation of this page exists in English.

RHEL에서 netstat 프로세스의 PID / Program Name을 표시하지 않는 이유는 무엇인가요?

Solution Verified - Updated -

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