ss 명령어: 리눅스 포트와 프로세스 확인, netstat 비교

공정위 광고 문구 Ver 3.1
공정위 광고 문구 Ver 3.2(모바일 전용)
테스트 환경Debian 계열Debian 12iproute2 6.1.0일반 사용자 계정2026-11-04 확인
네트워크 명령어ss위치/usr/bin/ss

리눅스 서버에서 어떤 포트가 열려 있고 누가 접속해 있는지는 ss 명령어로 확인합니다. ss는 netstat을 대신하는 iproute2의 소켓 조회 도구입니다. Debian 12 서버에서 ss로 수신 대기(LISTEN) 중인 포트와 접속을 조회한 결과, 일반 계정에서는 -p를 붙여도 다른 계정이 띄운 프로그램의 이름이 Process 칸에 나오지 않는 것을 확인했습니다.

아래 출력은 영어 locale로 실행한 결과입니다. 서버와 상대의 주소는 예시 주소로 표기했습니다.

1️⃣ ss 명령어 기본 사용법과 출력 칸

옵션 없이 ss를 실행하면 수신 대기 중인 포트는 빠지고 접속이 맺어진 소켓만 나옵니다. 테스트 서버에서는 맨 앞 줄들이 모두 서버 안 프로그램끼리 사용하는 유닉스 소켓(u_str, u_dgr)이었습니다.

ss | head -n 5
Netid State Recv-Q Send-Q                              Local Address:Port       Peer Address:Port    Process
u_str ESTAB 0      0                                               * 1013903               * 1013904
u_dgr ESTAB 0      0                                               * 1013960               * 13394
u_str ESTAB 0      0                                               * 1013907               * 1013908
u_str ESTAB 0      0                                               * 46066198              * 46066199

그래서 TCP 접속만 보려면 -t를 붙입니다. 유닉스 소켓이 빠지고, 포트 자리에는 번호 대신 ssh와 https 같은 서비스 이름이 뜹니다.

ss -t
State Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
ESTAB 0      0       203.0.113.10:ssh   198.51.100.7:51114
ESTAB 0      0       203.0.113.10:26676   192.0.2.15:https
ESTAB 0      0       203.0.113.10:29714   192.0.2.16:https

-n을 함께 붙이면 서비스 이름으로 바꾸지 않고 포트 번호가 그대로 나옵니다.

ss -tn
State Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
ESTAB 0      0       203.0.113.10:22    198.51.100.7:51114
ESTAB 0      0       203.0.113.10:26676   192.0.2.15:443
ESTAB 0      0       203.0.113.10:29714   192.0.2.16:443

Recv-Q와 Send-Q는 같은 칸이라도 소켓 상태에 따라 의미하는 값이 다릅니다. 접속 중인 소켓에서 Recv-Q는 받았지만 프로그램이 아직 읽지 않은 바이트 수이고, Send-Q는 보냈지만 상대가 아직 받았다고 확인하지 않은 바이트 수입니다.

수신 대기 소켓에서는 Recv-Q가 대기열에 쌓인 접속 수, Send-Q가 대기열 최대 크기를 의미합니다. 두 칸의 뜻은 net-tools의 netstat(8) man 페이지 설명입니다.

2️⃣ 리눅스 포트 확인(-tln, -uln, -tulpn)

옵션 없는 출력에는 접속을 기다리는 포트가 나오지 않으므로, 열린 포트를 확인할 때는 수신 대기 소켓만 고르는 -l을 붙입니다. [ss -tln]은 수신 대기 중인 TCP 포트를 번호로 출력합니다.

ss -tln
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      128          0.0.0.0:22        0.0.0.0:*
LISTEN 0      511          0.0.0.0:80        0.0.0.0:*
LISTEN 0      511          0.0.0.0:443       0.0.0.0:*
LISTEN 0      511        127.0.0.1:8080      0.0.0.0:*
LISTEN 0      128             [::]:22           [::]:*
LISTEN 0      511             [::]:80           [::]:*
LISTEN 0      511             [::]:443          [::]:*

Local Address가 0.0.0.0이면 서버의 모든 IPv4 주소로 들어오는 접속을 받고, 127.0.0.1이면 서버 안에서만 접속할 수 있습니다. [::]는 IPv6의 모든 주소를 의미하므로, 22번과 80번, 443번 포트는 IPv4와 IPv6 양쪽에서 열려 있습니다.

-n을 빼면 포트 번호가 서비스 이름으로 바뀝니다. 8080번은 http-alt로 나옵니다.

ss -tl
State  Recv-Q Send-Q Local Address:Port     Peer Address:PortProcess
LISTEN 0      128          0.0.0.0:ssh           0.0.0.0:*
LISTEN 0      511          0.0.0.0:http          0.0.0.0:*
LISTEN 0      511          0.0.0.0:https         0.0.0.0:*
LISTEN 0      511        127.0.0.1:http-alt      0.0.0.0:*
LISTEN 0      128             [::]:ssh              [::]:*
LISTEN 0      511             [::]:http             [::]:*
LISTEN 0      511             [::]:https            [::]:*

UDP는 접속을 맺지 않는 방식이라 수신 대기 소켓에도 LISTEN 상태가 없습니다. [ss -uln] 출력의 상태 칸은 모두 UNCONN이었습니다. 68번(bootpc)은 DHCP 클라이언트, 123번(ntp)은 시간 동기화 포트입니다.

ss -uln
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
UNCONN 0      0            0.0.0.0:68        0.0.0.0:*
UNCONN 0      0       203.0.113.10:123       0.0.0.0:*
UNCONN 0      0          127.0.0.1:123       0.0.0.0:*
UNCONN 0      0            0.0.0.0:123       0.0.0.0:*
UNCONN 0      0              [::1]:123          [::]:*
UNCONN 0      0               [::]:123          [::]:*

TCP와 UDP를 한 번에 보려면 [ss -tulpn]처럼 옵션을 모아 붙입니다. 종류가 둘 이상이면 맨 앞에 Netid 칸이 붙습니다.

ss -tulpn
Netid State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
udp   UNCONN 0      0            0.0.0.0:68        0.0.0.0:*
udp   UNCONN 0      0       203.0.113.10:123       0.0.0.0:*
udp   UNCONN 0      0          127.0.0.1:123       0.0.0.0:*
udp   UNCONN 0      0            0.0.0.0:123       0.0.0.0:*
udp   UNCONN 0      0              [::1]:123          [::]:*
udp   UNCONN 0      0               [::]:123          [::]:*
tcp   LISTEN 0      128          0.0.0.0:22        0.0.0.0:*
tcp   LISTEN 0      511          0.0.0.0:80        0.0.0.0:*
tcp   LISTEN 0      511          0.0.0.0:443       0.0.0.0:*
tcp   LISTEN 0      511        127.0.0.1:8080      0.0.0.0:*
tcp   LISTEN 0      128             [::]:22           [::]:*
tcp   LISTEN 0      511             [::]:80           [::]:*
tcp   LISTEN 0      511             [::]:443          [::]:*

3️⃣ ss 명령어 프로세스 확인(-p)

-p는 소켓을 사용하는 프로그램을 Process 칸에 출력하는 옵션입니다. 그런데 테스트 서버의 일반 계정에서 [ss -tlnp]를 실행해 보니 아래처럼 Process 칸이 비어, 옵션이 적용되지 않은 것처럼 보였습니다.

ss -tlnp
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      128          0.0.0.0:22        0.0.0.0:*
LISTEN 0      511          0.0.0.0:80        0.0.0.0:*
LISTEN 0      511          0.0.0.0:443       0.0.0.0:*
LISTEN 0      511        127.0.0.1:8080      0.0.0.0:*
LISTEN 0      128             [::]:22           [::]:*
LISTEN 0      511             [::]:80           [::]:*
LISTEN 0      511             [::]:443          [::]:*

ss는 프로세스마다 /proc 아래 fd 폴더를 읽어 소켓을 사용하는 프로세스를 찾습니다. 다른 계정이 띄운 프로세스의 fd 폴더는 일반 계정이 열 수 없으므로, 그 프로그램의 이름은 칸에 들어가지 않습니다. root가 띄운 1번 프로세스의 폴더를 일반 계정에서 열면 권한 오류가 납니다.

ls /proc/1/fd
ls: cannot open directory '/proc/1/fd': Permission denied

내 계정으로 띄운 프로그램은 일반 계정에서도 Process 칸에 나옵니다. python3의 간이 웹 서버를 127.0.0.1의 8000번 포트로 띄워 확인했습니다.

python3 -m http.server 8000 --bind 127.0.0.1 &

띄운 뒤에는 [sport = :8000]을 붙여 8000번 포트의 줄만 조회합니다.

ss -tlnp sport = :8000
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      5          127.0.0.1:8000      0.0.0.0:*    users:(("python3",pid=343015,fd=3))

users 뒤 괄호에는 프로그램 이름과 pid, 파일 디스크립터 번호(fd)가 차례로 들어갑니다.

확인을 마친 간이 웹 서버는 [kill %1]로 끕니다. 끈 뒤에 [ss -tln sport = :8000]을 다시 실행하면 머리줄만 남고 8000번 줄은 나오지 않습니다.

root 계정에서 실행하면 모든 프로세스의 정보를 읽을 수 있어 Process 칸이 채워집니다. 한 포트에서 여러 프로세스가 함께 수신 대기 중이면 그 수만큼 users 괄호 안 항목이 이어집니다. 아래 root 출력의 프로그램 이름과 pid는 예시 값입니다.

ss -tlnp sport = :443
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      511          0.0.0.0:443       0.0.0.0:*    users:(("app",pid=2101,fd=6),("app",pid=2100,fd=6))
LISTEN 0      511             [::]:443          [::]:*    users:(("app",pid=2101,fd=7),("app",pid=2100,fd=7))

포트 번호로 프로그램을 찾을 때는 lsof 명령어의 [lsof -i :443] 꼴도 사용할 수 있습니다.

계정에 따라 Process 칸이 어떻게 달라지는지는 아래 다이어그램에서 계정을 바꿔 가며 비교할 수 있습니다.

🧭 ss -p와 계정: Process 칸이 차는 조건
설명 다이어그램
👤 계정
$# ss -tlnp
수신 대기 소켓프로세스 정보Process 칸
0.0.0.0:22LISTEN
➜
/proc/812/fd소유: root
➜
다른 계정 프로세스: 못 읽음root: 모든 프로세스 읽음Process 칸 빈칸users:(("sshd",pid=812,fd=3))
127.0.0.1:8080LISTEN
➜
/proc/2100/fd소유: root
➜
다른 계정 프로세스: 못 읽음root: 모든 프로세스 읽음Process 칸 빈칸users:(("app",pid=2100,fd=3))
127.0.0.1:8000LISTEN
➜
/proc/343015/fd소유: user
➜
내 계정 프로세스: 읽음root: 모든 프로세스 읽음users:(("python3",pid=343015,fd=3))
일반 계정은 다른 계정이 띄운 프로세스의 /proc 정보를 읽지 못해 그 줄의 Process 칸이 비고, 내 계정으로 띄운 python3 줄만 채워집니다.
root는 모든 프로세스의 정보를 읽을 수 있어, 수신 대기 소켓마다 프로그램 이름과 pid가 Process 칸에 출력됩니다.

4️⃣ ss 상태와 포트 필터 옵션

  • ↪️ state, dport, sport

열린 포트를 확인한 뒤에도 지금 그 포트로 누가 접속해 있는지는 따로 골라야 합니다. ss는 옵션 뒤에 필터 조건을 붙여 원하는 줄만 남깁니다.

state 뒤에 상태 이름을 적으면 그 상태의 소켓만 남습니다. [ss -tn state established]의 출력은 State 칸 없이 Recv-Q 칸부터 시작합니다.

ss -tn state established
Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
0      0       203.0.113.10:22    198.51.100.7:51114
0      0       203.0.113.10:26676   192.0.2.15:443
0      0       203.0.113.10:29714   192.0.2.16:443

포트는 dport(상대 쪽 포트)와 sport(내 쪽 포트)로 거릅니다. 서버에서 바깥 https 서버로 나간 접속은 [dport = :443]으로 고릅니다.

ss -tn dport = :443
State Recv-Q Send-Q Local Address:Port  Peer Address:PortProcess
ESTAB 0      0       203.0.113.10:26676   192.0.2.15:443
ESTAB 0      0       203.0.113.10:29714   192.0.2.16:443

sport를 -l과 함께 사용하면 그 포트가 수신 대기 중인지만 확인할 수 있습니다.

ss -tln sport = :22
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      128          0.0.0.0:22        0.0.0.0:*
LISTEN 0      128             [::]:22           [::]:*

조건 여러 개는 괄호와 or로 묶고, 셸이 괄호를 먼저 읽지 않게 작은따옴표로 감쌉니다. 아래는 man 페이지 예시를 따라 ssh 접속만 고른 결과입니다.

ss -tn state established '( dport = :ssh or sport = :ssh )'
Recv-Q Send-Q Local Address:Port Peer Address:Port Process
0      0       203.0.113.10:22   198.51.100.7:51114

TIME-WAIT는 접속이 끊긴 뒤 잠시 남아 있는 상태입니다. 기본 출력에는 나오지 않으므로 [state time-wait]로 따로 골라야 보입니다.

ss -tn state time-wait
Recv-Q Send-Q Local Address:Port  Peer Address:PortProcess
0      0          127.0.0.1:28750    127.0.0.1:80
0      0          127.0.0.1:57698    127.0.0.1:8080
0      0              [::1]:31936        [::1]:80

상태 이름을 잘못 적으면 [wrong state name] 오류 한 줄만 남기고 명령이 바로 끝납니다. 아래는 일부러 foo를 넣은 결과입니다. 사용할 수 있는 이름은 [ss -h] 출력의 TCP-STATES 줄에서 확인할 수 있습니다.

ss -tn state foo
ss: wrong state name: foo

📌 주요 옵션: 이 글에서 실행한 결과

옵션하는 일이 글에서 본 결과
-tTCP 소켓만 출력유닉스 소켓이 빠지고, 포트 자리에 ssh와 https 같은 서비스 이름이 나옴
-n서비스 이름으로 바꾸지 않고 포트 번호로 출력ss -tn에서 ssh가 22, https가 443으로 나옴
-l수신 대기(LISTEN) 소켓만 출력ss -tln에 22번, 80번, 443번 같은 수신 대기 포트가 나옴
-uUDP 소켓만 출력ss -uln의 상태 칸이 모두 UNCONN
-p소켓을 사용하는 프로그램을 Process 칸에 출력일반 계정에서는 내 계정이 띄운 python3만 이름과 pid가 나오고, 다른 계정의 프로그램은 빈칸
-s소켓 목록 대신 종류별 개수를 요약TCP 줄의 estab 9가 state established 출력에서 머리줄을 뺀 9줄과 같음
-4IPv4 소켓만 출력ss -t4ln에서 [::]로 시작하는 줄이 빠짐
-6IPv6 소켓만 출력ss -t6ln에서 0.0.0.0과 127.0.0.1로 시작하는 줄이 빠짐
-H머리줄 없이 소켓 줄만 출력ss -H -tln | wc -l의 줄 수에 머리줄이 세어지지 않음
state 상태그 상태의 소켓만 남김state established 출력은 State 칸 없이 Recv-Q부터 시작, 없는 이름은 [wrong state name: foo]
dport = :포트상대 쪽 포트로 거름dport = :443에 바깥 https 서버로 나간 접속 두 줄
sport = :포트내 쪽 포트로 거름-l과 함께 쓴 sport = :22에 IPv4와 IPv6의 22번 수신 대기 두 줄
src 주소그 주소의 소켓만 남김ss -tln src 127.0.0.1에 서버 안에서만 접속을 받는 127.0.0.1 쪽 포트만 나옴

📎 그 밖의 옵션: 공식 매뉴얼 기준

옵션하는 일
-a, --all수신 대기 소켓과 접속 중인 소켓을 함께 출력
-r, --resolve주소와 포트 번호를 이름으로 풀어 출력
-e, --extended소켓마다 uid, inode 같은 자세한 정보를 출력
-o, --optionsTCP 재전송, keepalive 같은 타이머 정보를 출력
-m, --memory소켓이 사용하는 메모리를 출력
-i, --infoTCP 내부 정보(rtt, cwnd 등)를 출력
-x, --unix유닉스 도메인 소켓만 출력
-w, --rawRAW 소켓만 출력
-f 종류unix, inet, inet6, link, netlink 같은 소켓 종류로 고름
-Q, --no-queuesRecv-Q와 Send-Q 칸을 빼고 출력
-K, --kill필터에 맞는 소켓을 강제로 닫음, 커널이 지원하지 않는 소켓은 건너뜀
-E, --events닫히는 소켓을 계속 출력
-V, --version버전 정보를 출력

🔲 ss 명령어 시뮬레이터

아래 시뮬레이터에서 지금까지 나온 옵션과 필터를 직접 입력하고, [netstat -tln]과 출력을 비교할 수 있습니다.

ss 명령어 시뮬레이터iproute2 6.1.0
[root@server work]#
브라우저 안에서만 동작하는 일반 계정(user) 화면이며, ↑↓ 로 앞에서 쓴 명령을 다시 불러옵니다.

5️⃣ ss 소켓 요약(-s)

-s는 소켓 목록 대신 종류별 개수를 요약해 출력합니다. man 페이지에 따르면 목록을 하나씩 세지 않고 여러 통계 자료에서 숫자를 모읍니다.

ss -s
Total: 340
TCP:   48 (estab 9, closed 15, orphaned 0, timewait 13)

Transport Total     IP        IPv6
RAW       0         0         0
UDP       8         4         4
TCP       33        25        8
INET      41        29        12
FRAG      0         0         0

TCP 줄의 estab는 지금 맺어진 접속 수입니다. 그래서 같은 시점에 [state established]로 출력한 줄 수와 맞춰 볼 수 있습니다.

ss -tn state established | wc -l
10

출력 10줄에서 머리줄 하나를 빼면 9줄로, -s의 estab 9와 같았습니다. timewait 13은 [state time-wait]로 골라야 보이던 TIME-WAIT 소켓 수입니다.

6️⃣ ss 명령어와 netstat 비교

netstat이 들어 있는 net-tools 패키지의 man 페이지는 netstat을 거의 쓰이지 않게 된 프로그램(mostly obsolete)으로 적고, 대신 ss를 사용하도록 안내합니다. 다만 netstat 출력 꼴에 맞춰 짠 스크립트는 ss로 바꾸면 칸 순서와 주소 표기가 달라 그대로 읽지 못합니다.

같은 서버에서 수신 대기 중인 TCP 포트를 두 명령으로 출력해 보니, netstat은 상태가 맨 끝에 오고 IPv6 주소를 :::22처럼 적었습니다.

netstat -tln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::80                   :::*                    LISTEN
tcp6       0      0 :::443                  :::*                    LISTEN

ss에서는 상태가 맨 앞에 오고, IPv6 주소를 [::]:22처럼 대괄호로 감쌉니다.

ss -tln
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      128          0.0.0.0:22        0.0.0.0:*
LISTEN 0      511          0.0.0.0:80        0.0.0.0:*
LISTEN 0      511          0.0.0.0:443       0.0.0.0:*
LISTEN 0      511        127.0.0.1:8080      0.0.0.0:*
LISTEN 0      128             [::]:22           [::]:*
LISTEN 0      511             [::]:80           [::]:*
LISTEN 0      511             [::]:443          [::]:*

자주 사용하는 netstat 옵션을 ss와 ip 명령으로 옮기면 아래와 같습니다.

netstat대신할 명령 / 보는 것
netstat -tlnss -tln수신 대기 중인 TCP 포트를 번호로
netstat -tulpnss -tulpn수신 대기 중인 TCP·UDP 포트와 프로그램
netstat -tanss -tan모든 TCP 소켓을 번호로
netstat -rip route라우팅 표
netstat -iip -s link네트워크 인터페이스 통계
netstat -r, netstat -i를 대신하는 ip 명령은 net-tools의 netstat(8) man 페이지 NOTES에 적혀 있습니다.

🔢 FAQ & 추천 콘텐츠

-4를 붙이면 IPv4 소켓만, -6을 붙이면 IPv6 소켓만 남습니다. [ss -t4ln]에서는 [::]로 시작하는 줄이 빠지고, [ss -t6ln]에서는 0.0.0.0과 127.0.0.1로 시작하는 줄이 빠졌습니다.

src 뒤에 주소를 적으면 그 주소의 수신 대기 소켓만 남습니다. [ss -tln src 127.0.0.1]은 서버 바깥에서 접속할 수 없는 127.0.0.1 쪽 포트만 출력했습니다.

-H를 붙이면 머리줄 없이 소켓 줄만 나옵니다. [ss -H -tln | wc -l]처럼 줄 수를 셀 때 머리줄 한 줄이 함께 세어지지 않습니다.

🧭 네트워크 명령어 추천 콘텐츠 글 13 · 참조 3
🗂️ 네트워크 명령어
📄 ip 명령어 📄 netstat · ifconfig 명령어 📄 nmtui 명령어 📄 ss 명령어
📄 SSH 명령어 📄 rsync 명령어 📄 wget 명령어 📄 rz · sz 명령어
📄 host 명령어 📄 nslookup 명령어
📄 iptables 명령어 📄 firewall-cmd 명령어 📄 certbot 명령어

ℹ️ 제휴 안내
본 사이트의 콘텐츠에는 제휴 링크가 포함되어 있습니다. 방문자가 이 링크를 통해 상품 또는 서비스를 구매하면 본 사이트는 판매처로부터 수수료를 지급받습니다. 이 과정에서 구매자가 지불하는 금액(이벤트 할인 시 금액이 내려갑니다↓)은 오르지 않습니다. 게시된 가격·할인·재고 정보는 작성 시점 기준이며 실제와 다를 수 있으므로, 구매 전 판매처에서 최종 확인하시기 바랍니다. 상품 선정과 평가는 자체 기준에 따라 작성되며, 수수료 지급 여부가 소개 순서나 평가 내용에 영향을 주지 않습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

인간임을 증명하세요: 6   +   3   =