TCP/UDP 포트 번호 체계와 소켓 포트 고갈(Port Exhaustion) 완벽 가이드
Layer 4 포트 다중화의 원리, IANA 3대 포트 분류, TCP 4-Tuple 연결 메커니즘, 마이크로서비스 TIME_WAIT 누수 및 에페머럴 포트 고갈 방어 전략을 해설합니다.
네트워크 포트 번호 안내
서버 전송 없이 100% 브라우저 로컬에서 안전하게 직접 테스트하고 검증해보세요.
TCP/IP 네트워크에서 포트 다중화(Port Multiplexing)가 필요한 이유
OSI 7계층 및 TCP/IP 모델에서 IP 주소(Layer 3)는 인터넷상의 물리적 또는 논리적 호스트 장비 자체를 식별합니다. 하지만 현대의 서버나 개인용 컴퓨터는 하나의 기기 안에서 웹 서버(Nginx), 데이터베이스(PostgreSQL), SSH 데몬 등 수십 개의 서로 다른 네트워크 프로그램(프로세스)을 동시에 실행합니다.
수신된 패킷이 장비 안의 어떤 프로그램으로 전달되어야 하는지 구분하기 위해 전송 계층(Layer 4)에 도입된 주소 체계가 바로 포트 번호(Port Number)입니다. 포트는 16비트 부호 없는 정수(0~65535)로 표현되며, IP 주소와 포트 번호가 결합하여 고유한 네트워크 통신 종단점인 소켓(Socket)을 형성합니다.
공식 IANA 3대 포트 분류 체계
국제인터넷주소관리기구(IANA)는 65,536개의 포트 번호를 용도에 따라 3개 영역으로 엄격히 분류하여 관리합니다:
- 잘 알려진 포트 (Well-Known Ports, 0 ~ 1023): 표준 인터넷 기본 통신 규약에 사전 할당된 포트입니다 (HTTP 80, HTTPS 443, SSH 22, DNS 53, SMTP 25). 리눅스/유닉스 시스템에서는 보안상 루트(
root) 권한이나CAP_NET_BIND_SERVICE권한이 있는 프로세스만 1024 미만 포트에 바인딩할 수 있습니다. - 등록된 포트 (Registered Ports, 1024 ~ 49151): 벤더나 오픈소스 소프트웨어가 IANA에 등록하여 사용하는 포트입니다 (PostgreSQL 5432, MySQL 3306, Redis 6379, MongoDB 27017).
- 동적/임시 사설 포트 (Dynamic/Ephemeral Ports, 49152 ~ 65535): 클라이언트가 외부 서버로 나가는 아웃바운드 연결을 열 때 운영체제 커널이 임시로 할당하는 포트입니다.
TCP 4-Tuple과 대규모 동시 접속 확장성의 원리
개발자들의 흔한 오해 중 하나는 "웹 서버의 포트가 443번 하나뿐이므로 최대 65,535개의 클라이언트만 접속할 수 있다"는 생각입니다. 실제 TCP 연결은 단일 포트가 아니라 4-Tuple(4개 요소의 조합)에 의해 고유하게 정의됩니다:
{ 출발지 IP, 출발지 포트, 목적지 IP, 목적지 포트 }
서버의 목적지 IP와 목적지 포트(예: 203.0.113.1:443)가 동일하더라도, 접속하는 전 세계 수많은 클라이언트의 출발지 IP와 클라이언트가 임의로 연 출발지 포트 번호의 조합은 각각 모두 고유합니다. 따라서 메모리와 파일 디스크립터(File Descriptor) 한도만 충분하다면 단일 443 포트 서버에서도 수십만~수백만 개의 동시 TCP 소켓 세션을 유지할 수 있습니다.
마이크로서비스의 복병: 에페머럴 포트 고갈과 TIME_WAIT 소켓 누수
서버 측의 인바운드와 달리, 다른 API 서버를 빈번하게 호출하는 클라이언트 측 백엔드에서는 에페머럴 포트 고갈(Ephemeral Port Exhaustion) 장애가 자주 발생합니다:
마이크로서비스가 연결 풀링(HTTP Keep-Alive) 없이 단발성 HTTP 요청을 초당 수천 건씩 쏘아 보낼 때마다 로컬 OS의 임시 포트를 하나씩 소모합니다. 요청이 끝난 후 소켓을 닫아도, 지연 도착 패킷과의 충돌을 방지하기 위해 TCP 상태 머신은 해당 소켓을 1~2분간 TIME_WAIT 상태로 유지합니다.
이로 인해 리눅스 기본 범위(약 28,000개)의 임시 포트가 순식간에 고갈되어 EADDRNOTAVAIL: Cannot assign requested address 에러가 발생하며 서버 간 통신이 전면 마비됩니다. 이를 해결하기 위해 HTTP 클라이언트에 반드시 커넥션 풀을 적용해야 합니다.
# 리눅스 커널의 임시 포트 범위 확인
cat /proc/sys/net/ipv4/ip_local_port_range
# 출력 예: 32768 60999 (사용 가능한 임시 포트 총 28,232개)
# 현재 시스템의 TIME_WAIT 소켓 개수 모니터링
ss -tan state time-wait | wc -l
# 소켓 재사용 활성화 (커널 튜닝 sysctl.conf)
net.ipv4.tcp_tw_reuse = 1포트 보안 및 바인딩 권장 원칙
0.0.0.0대신127.0.0.1에 바인딩: Redis나 DB 등 내부 통신용 서비스는 절대 외부 공인망(0.0.0.0)에 열지 말고localhost나 사설 VPC IP에만 바인딩해야 합니다.- 방화벽 Default-Deny 원칙: 80, 443 외의 모든 포트는 인바운드를 기본 차단합니다.
- 포트 번호 사전 확인: 표준 포트와 충돌을 방지하기 위해 DevUtils의 Port Numbers 검색 도구를 통해 예약된 서비스 대역을 사전에 확인하세요.
네트워크 포트 번호 안내
주요 TCP/UDP 포트 번호 및 서비스 명칭 검색 참조 도구.