Linux netstat 명령어로 네트워크 포트 및 세션 분석하기

CompTIABeginner
지금 연습하기

소개

이 실습에서는 Linux 시스템에서 네트워크 활동을 분석하기 위해 netstat 명령어를 사용하는 방법을 배웁니다. 네트워크 포트, 소켓, 활성 연결과 같은 기본 개념을 탐색하여 서비스가 네트워크를 통해 어떻게 통신하는지에 대한 통찰력을 얻을 것입니다.

먼저 모든 활성 소켓을 나열한 다음, 결과를 필터링하여 수신 대기 중인 TCP 및 UDP 포트에 집중하고 이를 실행 중인 서비스에 매핑합니다. 이러한 개념을 실제로 확인하기 위해 웹사이트를 탐색하여 새 연결을 생성한 다음, netstat을 사용하여 새로 생성된 ESTABLISHED 세션과 해당 임시 포트를 식별합니다.

netstat -a 명령어로 모든 활성 및 수신 대기 소켓 나열하기

이 단계에서는 netstat 명령어를 사용하여 시스템의 네트워크 활동을 탐색하기 시작합니다. 이 명령어는 네트워크 관리자와 개발자에게 필수적인 도구로, 네트워크 연결, 라우팅 테이블 및 인터페이스 통계에 대한 통찰력을 제공합니다. -a 옵션으로 시작할 것입니다. 이 옵션은 netstat에게 원격 시스템과의 연결 및 새 수신 연결을 "수신 대기" 중인 포트를 포함한 모든 활성 소켓을 표시하도록 지시합니다.

먼저 기본 작업 디렉토리에 있는지 확인하십시오. 이 실습의 모든 명령어는 터미널에서 실행됩니다.

이제 모든 소켓을 나열해 보겠습니다. 터미널에서 다음 명령어를 입력하고 Enter를 누르십시오.

netstat -a

많은 양의 출력이 표시될 것입니다. 걱정하지 마십시오. 이 내용을 분석할 것입니다. 출력은 TCP, UDP 및 UNIX 도메인 소켓을 포함한 모든 유형의 소켓을 보여줍니다.

출력 구조를 살펴보겠습니다. 다음과 유사해야 합니다 (시스템의 정확한 세부 정보는 다를 수 있습니다).

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
tcp        0      0 localhost:6010          0.0.0.0:*               LISTEN
tcp        0     52 labex-vm:ssh            192.168.0.10:54321      ESTABLISHED
tcp6       0      0 [::]:http-alt           [::]:*                  LISTEN
udp        0      0 0.0.0.0:bootpc          0.0.0.0:*
...
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  2      [ ]         DGRAM                    23456    /run/systemd/notify
unix  2      [ ACC ]     STREAM     LISTENING     34567    /tmp/.X11-unix/X0
...

다음은 인터넷 연결에 대한 가장 중요한 열의 분석입니다.

  • Proto: 소켓에서 사용되는 프로토콜입니다. 예를 들어 tcp (TCPv4 용), tcp6 (TCPv6 용) 또는 udp가 있습니다.
  • Local Address: 시스템의 IP 주소와 이 연결에 사용되는 포트 번호입니다. 포트는 콜론 (:) 뒤의 숫자입니다. 0.0.0.0 또는 [::] 주소는 해당 포트가 시스템의 사용 가능한 모든 네트워크 인터페이스에서 수신 대기 중임을 의미합니다.
  • Foreign Address: 원격 시스템의 IP 주소와 포트 번호입니다. 상태가 LISTEN인 경우 일반적으로 0.0.0.0:* 또는 [::]:*로 표시되며, 이는 모든 주소로부터의 연결을 기다리고 있음을 나타냅니다.
  • State: TCP 연결에 매우 중요합니다.
    • LISTEN: 애플리케이션이 지정된 Local Address 포트에서 수신 연결을 기다리고 있습니다. 이것은 서버 측 상태입니다.
    • ESTABLISHED: 연결이 활성 상태이며 로컬 및 원격 주소 간에 데이터를 전송할 수 있습니다.
    • TIME_WAIT 또는 CLOSE_WAIT와 같은 다른 상태는 TCP 연결을 닫는 프로세스와 관련이 있습니다.

잠시 시간을 내어 출력을 스크롤하고 LISTEN 상태의 항목을 식별하십시오. 이는 네트워크 연결을 수락할 준비가 된 시스템의 서비스를 나타냅니다. 이것은 전송 계층 (계층 4) 이 작동하는 것을 직접 보여줍니다.

sudo netstat -tulnp 명령어로 수신 대기 중인 TCP/UDP 포트 필터링하기

이전 단계에서 netstat -a 명령어는 모든 소켓에 대한 완전하지만 긴 목록을 제공했습니다. 이 정보를 더 유용하게 만들기 위해 필터링해야 합니다. 이 단계에서는 netstat의 특정 옵션을 사용하여 수신 대기 중인 TCP 및 UDP 포트만 표시하고, 가장 중요하게는 어떤 프로그램이 이를 사용하고 있는지 식별하는 방법을 배웁니다.

포트와 연결된 프로그램 이름을 보려면 프로세스가 시스템 또는 다른 사용자에 의해 소유될 수 있으므로 관리자 권한이 필요한 경우가 많습니다. 이것이 sudo 명령어를 사용하는 이유입니다. LabEx 환경에서는 암호 없이 sudo를 사용할 수 있습니다.

더 집중된 netstat 명령어를 실행해 보겠습니다. 터미널에서 다음을 입력하십시오.

sudo netstat -tulnp

이 옵션들은 자주 함께 사용되므로 각각을 분석해 보겠습니다.

  • t: TCP 연결을 표시합니다.
  • u: UDP 연결을 표시합니다.
  • l: listening (수신 대기) 소켓만 표시합니다. 이것은 어떤 서비스가 연결을 기다리고 있는지 확인하기 위한 주요 필터입니다.
  • n: numerical (숫자) 주소를 표시합니다. 이렇게 하면 netstat이 IP 주소와 포트 번호를 호스트 이름 및 서비스 이름으로 확인하려고 시도하는 것을 방지합니다 (예: ssh 대신 22를 표시). 이렇게 하면 명령이 훨씬 빠르게 실행됩니다.
  • p: 소켓이 속한 프로그램의 process ID (PID) 와 이름을 표시합니다. 모든 프로세스를 보려면 sudo가 필요합니다.

Enter를 누른 후 출력은 훨씬 짧고 더 유익해질 것입니다. 다음과 유사하게 표시될 것입니다.

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      779/systemd-resolve
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3422/sshd
udp        0      0 127.0.0.53:53           0.0.0.0:*                           779/systemd-resolve

마지막에 새로운 열인 PID/Program name에 주목하십시오. 이것이 핵심 정보입니다. 이제 수신 대기 중인 포트를 해당 포트를 연 정확한 애플리케이션에 직접 매핑할 수 있습니다. 예를 들어 위의 출력에서 포트 22(SSH 의 표준 포트) 가 프로세스 ID 3422sshd 프로그램에 의해 사용되고 있음을 알 수 있습니다.

이 명령어는 시스템 관리자에게 매우 강력합니다. 실행 중이고 네트워크에 노출된 서비스를 신속하게 확인할 수 있으며, 이는 문제 해결 및 보안 감사 모두에 필수적입니다.

수신 대기 중인 포트와 실행 중인 서비스 매핑하기

이 단계에서는 실행 중인 애플리케이션과 수신 대기 중인 네트워크 포트 간의 연결에 대한 이해를 공고히 할 것입니다. netstat으로 기존 서비스를 나열하는 방법을 보았습니다. 이제 간단한 웹 서비스를 시작하고 netstat 출력에 나타나는 것을 실시간으로 관찰하여 이 관계를 시연할 것입니다.

Python 의 내장 http.server 모듈을 사용하여 웹 서버를 신속하게 실행할 것입니다. 이는 개발 및 테스트에 편리한 도구입니다.

  1. 먼저 웹 서버를 시작해 보겠습니다. 웹 서비스에 대한 일반적인 대체 포트인 8080 포트에서 수신 대기하도록 지시할 것입니다. 터미널에서 다음 명령어를 실행하십시오. 터미널이 서버를 적극적으로 실행 중이므로 "멈춘" 것처럼 보일 것입니다.

    python3 -m http.server 8080
    

    서버가 시작되었음을 나타내는 출력이 표시되어야 합니다.

    Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
    
  2. 이 터미널은 이제 웹 서버 프로세스에 의해 점유되었습니다. 다른 명령어를 실행하려면 새 터미널이 필요합니다. LabEx 환경에서는 터미널 창의 "더하기" 아이콘을 클릭하거나 메뉴 (File -> New Tab) 를 사용하여 새 터미널 탭을 열 수 있습니다.

  3. 터미널 탭에서 netstat 명령어를 다시 실행하여 수신 대기 중인 포트 목록을 확인하십시오.

    sudo netstat -tulnp
    
  4. 출력을 주의 깊게 검토하십시오. 이제 포트 8080에 대한 새 항목이 표시됩니다.

    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      779/systemd-resolve
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3422/sshd
    tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      12345/python3
    udp        0      0 127.0.0.53:53           0.0.0.0:*                           779/systemd-resolve
    ...
    

    보시다시피 시스템은 이제 python3 프로그램 (예: 12345와 같은 특정 PID 포함) 이 포트 8080에서 LISTEN 상태임을 보고합니다. 서비스를 성공적으로 시작하고 네트워크 연결을 수신 대기 중임을 확인했습니다.

  5. 이제 서비스를 중지해 보겠습니다. 첫 번째 터미널 탭 (Python 서버를 실행 중인 탭) 으로 돌아가 Ctrl+C를 누르십시오. 이렇게 하면 서버 프로세스가 중단되고 종료됩니다.

  6. 두 번째 터미널 탭으로 돌아가 마지막으로 netstat 명령어를 실행하십시오.

    sudo netstat -tulnp
    

    포트 8080에 대한 줄이 사라지며, 애플리케이션이 종료되면 더 이상 해당 포트에서 수신 대기하지 않음을 증명합니다.

웹사이트를 방문하여 새 연결 생성하기

이 단계에서는 서버 측 수신 대기 포트에서 클라이언트 측 활성 연결로 초점을 전환합니다. 지금까지 다른 서비스가 연결되기를 기다리는 서비스를 관찰했습니다. 이제 자신의 컴퓨터에서 원격 서버로 연결을 시작하고 연결이 형성되는 것을 관찰할 것입니다. 명령줄 도구 curl을 사용하여 웹사이트 방문을 시뮬레이션할 것입니다.

이 순간적인 이벤트를 관찰하기 위해 watch 명령어를 사용할 것입니다. 이 명령어는 다른 명령어를 반복적으로 실행하여 netstat 출력의 변경 사항을 거의 실시간으로 볼 수 있게 해줍니다.

  1. 먼저 모니터링 창을 설정해 보겠습니다. 터미널에서 다음 명령어를 실행하십시오. 이 명령어는 2 초마다 netstat -antp를 실행하고 결과를 표시하며 화면을 지속적으로 새로 고칩니다.

    watch netstat -antp
    
    • a: 모든 소켓을 표시합니다.
    • n: 숫자 주소를 표시합니다.
    • t: TCP 연결만 표시합니다.
    • p: PID/프로그램 이름을 표시합니다.

    이제 터미널은 자동으로 업데이트되는 netstat 출력으로 채워질 것입니다. 이 터미널을 열어 두고 보이게 하십시오.

  2. 이제 연결을 생성하는 명령을 실행하기 위해 새 터미널 탭을 열어야 합니다. 터미널의 탭 표시줄에서 "더하기" 아이콘을 클릭하십시오.

  3. 터미널 탭에서 curl을 사용하여 LabEx 웹사이트의 홈페이지를 가져올 것입니다. > 기호는 HTML 출력을 /dev/null로 리디렉션하여 화면을 어지럽히지 않도록 합니다.

    curl https://www.labex.io > /dev/null
    
  4. Enter를 누르자마자 첫 번째 터미널 탭( watch를 실행 중인 탭) 으로 빠르게 전환하십시오. 몇 초 동안 새 연결이 나타나는 것을 볼 수 있습니다. 다음과 유사하게 표시될 것입니다.

    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    ...
    tcp        0      0 172.17.0.2:45678        104.21.5.141:443        ESTABLISHED 13579/curl
    ...
    
    • StateESTABLISHED로 표시되어 활성 연결을 나타냅니다.
    • Foreign Addresslabex.io 서버의 IP 주소와 포트 443(HTTPS 의 표준) 을 보여줍니다.
    • PID/Program name 열은 curl이 이 연결을 시작한 프로그램임을 명확하게 식별합니다.
    • Local Address는 높은 번호의 임의 포트 (예: 예제의 45678) 를 사용합니다. 이것은 다음 단계에서 논의할 **임시 포트 (ephemeral port)**입니다.
  5. curl 명령이 다운로드를 완료하면 (매우 빠름), 연결이 완전히 사라지기 전에 연결 상태가 TIME_WAIT 또는 FIN_WAIT로 변경되는 것을 볼 수 있습니다.

  6. 이제 watch 명령을 중지할 수 있습니다. 첫 번째 터미널 탭으로 이동하여 Ctrl+C를 누르십시오. 두 번째 터미널 탭을 닫을 수도 있습니다.

ESTABLISHED 세션 및 임시 포트 식별하기

이 마지막 단계에서는 지속적이고 활성 상태인 연결을 검사하여 이해를 통합할 것입니다. 이를 통해 네트워크 "세션"을 명확하게 식별하고 시스템이 클라이언트 측 통신에 임시 또는 "임시 (ephemeral)" 포트를 사용하는 방법을 볼 수 있습니다.

netstat 출력의 ESTABLISHED 연결은 두 애플리케이션이 데이터를 교환할 준비가 된 활성 세션 (OSI 계층 5) 을 나타냅니다. 이전 단계에서 curl 세션은 매우 짧았습니다. 세션을 더 쉽게 연구하기 위해 SSH 를 사용하여 열린 상태로 유지되는 세션을 만들 것입니다.

먼저 중요한 개념인 **임시 포트 (ephemeral ports)**를 정의해 보겠습니다. 컴퓨터 (클라이언트) 가 잘 알려진 포트 (SSH 의 경우 포트 22 또는 HTTPS 의 경우 443과 같은) 로 서버에 연결할 때 운영 체제는 대화의 해당 측을 위한 포트를 할당해야 합니다. 높은 번호의 범위 (일반적으로 32768 이상) 에서 임시로 사용되지 않는 포트를 선택합니다. 이를 임시 포트라고 합니다. 이 메커니즘을 통해 단일 컴퓨터는 동일한 서버 포트에 대해 여러 개의 별도 연결을 가질 수 있습니다. 예를 들어, 동일한 웹사이트에 대해 여러 브라우저 탭을 열어 둘 수 있습니다.

  1. 안정적이고 관찰 가능한 세션을 만들기 위해 실험실 컴퓨터에서 자체로 SSH 를 수행할 것입니다. 터미널에서 다음 명령어를 실행하십시오.

    ssh localhost
    

    처음 이 작업을 수행할 때 호스트의 진위 여부에 대한 메시지가 표시될 수 있습니다. 이는 정상입니다.

    The authenticity of host 'localhost (127.0.0.1)' can't be established.
    ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
    Are you sure you want to continue connecting (yes/no/[fingerprint])?
    

    yes를 입력하고 Enter를 눌러 계속하십시오.

    비밀번호를 입력하라는 프롬프트가 표시됩니다. 비밀번호를 입력할 필요 없이 그대로 두십시오.

  2. "더하기" 아이콘을 클릭하여 새 터미널 탭을 엽니다. 활성 SSH 세션을 방해하지 않고 netstat을 실행하려면 이 새 터미널이 필요합니다.

  3. 새 터미널에서 netstat을 다시 실행하지만, 이번에는 grep 명령어를 사용하여 출력을 필터링하고 ESTABLISHED를 포함하는 줄만 표시합니다. 이렇게 하면 활성 세션을 훨씬 쉽게 찾을 수 있습니다.

    netstat -antp | grep ESTABLISHED
    
  4. 출력에는 현재 활성 상태인 모든 TCP 연결이 표시됩니다. sudo를 사용하지 않았기 때문에 예상대로 모든 프로세스를 식별할 수 없다는 경고가 표시될 수 있습니다. 실험실 환경에 대한 원래 SSH 연결과 방금 localhost에 대해 생성한 새 연결이 표시되어야 합니다.

    (Not all processes could be identified, non-owned process info
     will not be shown, you would to be root to see it all.)
    tcp        0      0 172.16.50.192:22        47.251.66.143:36882     ESTABLISHED -
    tcp        0      0 127.0.0.1:46280         127.0.0.1:22            ESTABLISHED 5449/ssh
    tcp        0      0 127.0.0.1:22            127.0.0.1:46280         ESTABLISHED -
    

    127.0.0.1 주소로 식별되는 새 localhost 연결을 분석해 보겠습니다.

    • 연결의 서버 측은 포트 22 에서 수신 대기 중인 SSH 서버 (sshd) 인 127.0.0.1:22입니다. 127.0.0.1:46280에서 설정된 연결이 있습니다. sshd 프로세스가 root 사용자에 의해 소유되고 sudo를 사용하지 않았기 때문에 프로그램 정보는 -입니다.
    • 클라이언트 측은 127.0.0.1:22에 연결된 127.0.0.1:46280입니다. 프로그램은 5449/ssh로 명확하게 식별됩니다.
    • 포트 46280임시 포트입니다. 시스템이 이 특정 SSH 세션의 클라이언트 끝을 위해 무작위로 선택했습니다. 다른 ssh localhost 연결을 열면 다른 임시 포트를 사용합니다.
  5. 마무리하려면 세션을 닫으십시오. ssh localhost를 실행한 터미널 탭으로 전환하고 exit를 입력한 다음 Enter를 누르십시오.

    exit
    

    이렇게 하면 연결이 종료됩니다. 다른 터미널에서 netstat -antp | grep ESTABLISHED를 다시 실행하면 localhost 세션이 사라진 것을 볼 수 있습니다.

요약

이 실습에서는 Linux 시스템에서 네트워크 활동을 분석하기 위해 netstat 명령어를 사용하는 방법을 배웠습니다. netstat -a를 사용하여 TCP, UDP 및 UNIX 도메인 소켓을 포함한 모든 활성 및 수신 대기 소켓을 나열하는 것으로 시작했습니다. 그런 다음 -t, -u, -l, -n, -p와 같은 플래그를 적용하여 수신 대기 중인 TCP 및 UDP 포트를 구체적으로 필터링하고, 숫자 주소를 표시하고, 각 포트와 관련된 프로세스 ID 및 이름을 식별하여 이 출력을 개선했습니다.

이를 바탕으로 명령 출력 해석을 연습하여 수신 대기 포트와 해당 서비스를 매핑했습니다. 연결을 실제로 관찰하기 위해 웹사이트에 연결하여 새 네트워크 세션을 시작했습니다. 이를 통해 ESTABLISHED 상태의 연결을 식별하고 네트워크 통신의 클라이언트 측에 할당되는 임시 포트인 임시 포트의 역할을 이해할 수 있었습니다.