📚 네트워크 · 패킷 분석 › 02. 포트 · 프로토콜 분석 — 51편
이전 글: 50. 웹 요청 하나의 전체 경로 — 01 시리즈 종합 · 다음 글: 52. TCP 기반 서비스와 UDP 기반 서비스
참고(리눅스 시스템 기초): IP / TCP / UDP / Port — 포트의 기본 개념은 이 글에서 다룸
"이 포트에서 어떤 서비스와 프로토콜이 통신하는가?"
방화벽 로그 한 줄에는 보통 출발지 IP·목적지 IP·프로토콜과 함께 출발지 포트·목적지 포트가 남습니다. 관제 요원은 이 두 포트를 보고 다음을 빠르게 판단해야 합니다.
포트 번호 체계를 모르면 51514 → 22 와 22 → 51514 가 같은 연결의 요청·응답이라는 것도 헷갈리고, 응답 패킷을 "누군가 51514번 포트로 접속을 시도했다"고 잘못 읽게 됩니다. 이번 글은 포트의 번호 구간(범위) 과 임시 포트(ephemeral port) 를 관제 관점에서 정리합니다. 포트·소켓의 기본 정의는 리눅스 시리즈 IP / TCP / UDP / Port, Socket 이해에서 다뤘으므로 반복하지 않습니다.

그림 1. 포트 번호 범위 — 폭은 개수에 비례하지 않습니다
TCP와 UDP 헤더의 포트 필드는 16비트이므로 포트 번호는 0~65535 입니다. 번호의 등록·관리는 IANA(Internet Assigned Numbers Authority)가 담당하며, 다음 세 구간으로 나눕니다.
| 구간 | 범위 | IANA 명칭 | 의미 |
|---|---|---|---|
| Well-known | 0 ~ 1023 | System Ports | 대표 서비스용으로 할당 (22 SSH, 53 DNS, 80 HTTP, 443 HTTPS 등) |
| Registered | 1024 ~ 49151 | User Ports | 특정 애플리케이션이 등록해 사용 (3306 MySQL, 3389 RDP 등) |
| Dynamic / Private | 49152 ~ 65535 | Dynamic Ports | 할당하지 않음. 클라이언트 임시 포트 등 자유 사용 |
주의할 점은 이 구간이 "등록 관례"일 뿐 강제 규칙이 아니라는 것입니다. 관리자는 SSH를 2222번에, 웹을 8080번에 얼마든지 열 수 있습니다. 이 문제는 다음 글 02. 서비스와 포트 매핑에서 다룹니다.
| 구분 | 서버(수신) 포트 | 클라이언트 임시(ephemeral) 포트 |
|---|---|---|
| 결정 주체 | 서비스 설정 파일 (예: sshd_config의 Port) | 운영체제가 연결마다 자동 선택 |
| 번호 특징 | 고정, 주로 Well-known / Registered | 매번 바뀜, 높은 번호 대역 |
| 수명 | 서비스가 떠 있는 동안 계속 LISTEN | 연결이 끝나면 반환 |
| 로그에서의 위치 | 요청의 목적지 포트 | 요청의 출발지 포트 |
임시 포트 범위는 IANA 권고(49152~65535)와 실제 운영체제 기본값이 다를 수 있습니다.
| 운영체제 | 확인 방법 | 일반적인 기본값 |
|---|---|---|
| Linux | /proc/sys/net/ipv4/ip_local_port_range | 32768 60999 (배포판·설정에 따라 다름) |
| Windows (Vista 이후) | netsh int ipv4 show dynamicport tcp | 시작 49152, 개수 16384 |
즉 Linux 클라이언트는 IANA 기준으로 Registered 구간인 32768번대 포트를 출발지로 쓰는 것이 정상입니다. "49152 미만 출발지 포트 = 이상"으로 판단하면 오탐이 생깁니다.
하나의 연결(흐름)은 출발지 IP, 출발지 포트, 목적지 IP, 목적지 포트, 프로토콜의 5개 값으로 구분합니다. 같은 PC가 같은 웹서버에 탭 3개로 접속해도 출발지 포트가 달라 서로 다른 연결로 기록됩니다. 방화벽 세션 테이블, NetFlow, IDS 이벤트가 모두 이 단위로 통신을 묶습니다.
아래 주제는 리눅스 시스템 기초 시리즈에 이미 정리되어 있어, 이 시리즈에서는 별도 글을 쓰지 않고 링크로 대신합니다.
| 주제 | 포트 | 대신하는 기존 글 |
|---|---|---|
| SSH 구조 | 22/TCP | SSH 구조 이해 |
| SSH 인증·설정 | 22/TCP | 12. SSH 인증 방식, 13. SSH 보안 설정 |
| SSH 공격·키 보안 | 22/TCP | 14. SSH Brute Force 공격 이해, 15. SSH Key 인증 보안 |
| Listening Port 점검 | 전체 | 37. Listening Port 보안 점검 |
| Syslog | 514/UDP·TCP 등 | 08. Syslog의 Facility와 Severity, 36. 원격 Syslog와 중앙 로그 서버 |
클라이언트가 웹서버에 접속할 때 포트가 정해지는 흐름은 다음과 같습니다.
[클라이언트 192.168.10.30] [웹서버 192.168.10.20]
nginx가 0.0.0.0:80 LISTEN
① 애플리케이션이 connect(192.168.10.20:80) 호출
↓
② 커널이 ip_local_port_range 안에서
사용 가능한 임시 포트 선택 (예: 40522)
↓
③ 요청: 192.168.10.30:40522 → 192.168.10.20:80 (dport = 80)
↓
④ 응답: 192.168.10.20:80 → 192.168.10.30:40522 (sport = 80)
↓
⑤ 연결 종료 후 40522번은 반환 → 다음 연결은 다른 번호
핵심은 요청과 응답에서 출발지·목적지 포트가 뒤바뀐다는 점입니다. 로그를 볼 때는 "낮고 고정된 쪽 포트 = 서비스", "높고 매번 바뀌는 쪽 포트 = 클라이언트"로 먼저 방향을 잡습니다.
Linux에서 1024 미만 포트를 LISTEN하려면 기본적으로 root 권한(정확히는 CAP_NET_BIND_SERVICE capability)이 필요합니다. 이 기준값은 net.ipv4.ip_unprivileged_port_start(기본 1024)로 조정할 수 있습니다. 따라서 일반 사용자 권한으로 실행된 프로그램이 1024 이상 포트를 여는 것은 흔하며, 반대로 이 값을 바꾸지 않은 서버에서 알 수 없는 프로세스가 1024 미만 포트를 LISTEN하고 있다면 root 권한(또는 해당 capability)을 가진 상태로 실행되었다고 볼 수 있습니다.
실습 환경: 본인 소유 Linux VM (Rocky Linux 또는 Ubuntu). 인터페이스 이름은 ens33을 예시로 사용합니다(환경마다 다름).
cat /proc/sys/net/ipv4/ip_local_port_range
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.ip_unprivileged_port_start
/etc/services는 포트 번호와 서비스 이름을 대응시킨 로컬 참조 파일입니다(Rocky·Ubuntu 모두 기본 존재).
grep -wE '22/tcp|53/udp|443/tcp' /etc/services
getent services ssh
getent services 443/tcp
연결이 너무 빨리 끝나면 관찰이 어려우므로, bash의 /dev/tcp 기능으로 연결을 잠시 열어 둔 채 확인합니다.
exec 3<>/dev/tcp/example.com/80 # 80번 포트로 TCP 연결을 열어 둠
ss -tn state established '( dport = :80 )' # 출발지(Local) 임시 포트 확인
exec 3>&- # 연결 닫기
같은 명령을 두 번 반복하면 Local 쪽 포트 번호가 매번 달라지는 것을 볼 수 있습니다.
SSH로 VM에 접속해 있다면 서버 쪽에서 다음처럼 보면 방향이 명확합니다.
ss -tn state established '( sport = :22 )'
📷 [실습 화면 삽입]
ip_local_port_range값과ss -tn에서 Local/Peer 포트가 보이는 화면
sudo ss -tulnp
LISTEN 포트 점검의 전체 절차는 37. Listening Port 보안 점검을 참고합니다.
형식 예시(값은 환경마다 다름):
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999
$ ss -tn state established '( sport = :22 )'
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 0 192.168.10.20:22 192.168.10.1:51514
| 확인 항목 | 읽는 법 |
|---|---|
Local :22 | 이 VM이 SSH 서버 역할 (서비스 포트) |
Peer :51514 | 접속한 클라이언트가 고른 임시 포트 (Windows 호스트라면 49152 이상이 일반적) |
ip_local_port_range | 이 VM이 클라이언트가 될 때 출발지 포트로 쓸 범위 |
ss 출력에서 서버 포트와 임시 포트를 구분할 수 있다/etc/services에서 번호와 이름의 대응을 찾을 수 있다📷 [실습 화면 삽입]
/dev/tcp연결을 연 상태에서ss -tn에 출발지 임시 포트가 보이는 화면(두 번 반복 비교)
방화벽이나 커널 로그에서는 포트가 SPT(출발지), DPT(목적지)로 표기되는 경우가 많습니다. Linux netfilter LOG 대상의 출력 형식은 다음과 같습니다.
형식 예시(값은 환경마다 다름):
IN=ens33 OUT= SRC=203.0.113.50 DST=192.168.10.20 LEN=60 ... PROTO=TCP SPT=44120 DPT=3389 WINDOW=64240 SYN
위 한 줄은 "외부 203.0.113.50이 임시 포트 44120에서 이 서버의 3389번(RDP) 포트로 연결을 시도했다"로 읽습니다.
| 관찰 | 정상일 수 있는 경우 | 의심해야 하는 경우 |
|---|---|---|
| 출발지 포트 32768~60999 | Linux 클라이언트의 일반 연결 | — |
| 출발지 포트 1024 미만 | DHCP(68→67), NTP(123↔123) 등 고정 출발지 포트를 쓰는 프로토콜 | 일반 TCP 클라이언트 연결인데 낮은 포트를 출발지로 사용 (직접 조작된 패킷 가능성) |
| 출발지·목적지 포트 0 | — | 포트 0은 정상 통신에 쓰이지 않음. 비정상 패킷·조작 트래픽 의심 |
| 목적지 포트가 임시 포트 대역 | 응답 패킷, FTP 데이터 채널 등 동적 포트 사용 서비스 | 외부에서 내부 고번호 포트로 SYN이 계속 들어옴 (백도어 포트 탐색 가능성) |
| 한 출발지 → 다수 목적지 포트 | 취약점 점검 등 승인된 작업 | 포트 스캔 (05. 네트워크 스캔 · 공격 징후 분석 시리즈에서 다룸) |
방향 판단은 TCP 플래그와 함께 보는 것이 가장 확실합니다. SYN만 있는 첫 패킷의 목적지 포트가 서비스 포트입니다(플래그 해석은 08. TCP 3-Way Handshake 참고). 필드 단위 패킷 해석은 03. Wireshark 패킷 분석 시리즈에서 다룹니다.
| 로그·장비 | 포트 관련 흔적 | 활용 |
|---|---|---|
| 방화벽 | 5-tuple, 허용/차단 결과 | 허용되지 않은 목적지 포트 접근 시도 |
| IDS/IPS | 5-tuple + 탐지 룰 | 룰이 특정 포트 기준인지 확인 필요 (06. 방화벽 · IDS/IPS 분석 시리즈에서 다룸) |
서버 ss / EDR | 포트 ↔ 프로세스 연결 | 어떤 프로그램이 그 포트를 쓰는지 확인 (lspm-16) |
| NetFlow 등 흐름 기록 | 흐름별 포트·바이트 수 | 비정상 포트로의 대량 전송 |
한계와 오탐 주의
/proc/sys/net/ipv4/ip_local_port_range에서 확인하며, IANA 권고 범위와 다를 수 있습니다.