infra
Platform

모듈 맵

[Network] 3-Way Handshake 원리와 신뢰성 높은 포트 체계

0 / 35 완료

펼치기
0 / 35 완료0%

Networking · 05 / 35

[Network] 3-Way Handshake 원리와 신뢰성 높은 포트 체계

TCP 3-Way Handshake, UDP 특성, Well-known Port를 이해하고 nc로 통신을 테스트합니다

🚨INCIDENT ALERT
HIGH

서비스 포트를 열었다고 했지만 클라이언트는 여전히 연결하지 못합니다. TCP와 UDP의 동작 차이, 포트 번호의 의미를 모르면 같은 "포트"라는 단어 아래 다른 문제를 섞게 됩니다.

포트는 애플리케이션으로 들어가는 문입니다. 어떤 프로토콜의 어떤 문인지 먼저 구분해야 합니다.

TCP vs UDP와 포트 체계

네트워크에서 두 컴퓨터가 데이터를 주고받을 때, 단순히 IP 주소만으로는 어떤 애플리케이션이 받을지 알 수 없습니다. **포트(Port)**와 **전송 프로토콜(TCP/UDP)**이 이 문제를 해결합니다. 이 챕터에서는 TCP의 신뢰성 메커니즘인 3-Way Handshake, UDP의 빠른 통신 원리, 그리고 Well-known Port 체계를 이해하고 nc(netcat)으로 직접 통신을 실습합니다.


이번 챕터에서 배울 것
  • 1TCP 3-Way Handshake와 4-Way Teardown 연결 수립·종료 과정
  • 2TCP의 신뢰성 메커니즘: 순서 번호, ACK, 재전송, 흐름 제어
  • 3UDP의 특성과 TCP 대비 장단점 비교
  • 4DNS·NTP·스트리밍 등 UDP가 적합한 서비스 유형
  • 5Well-known Port 체계와 주요 서비스 포트 번호
  • 6nc(netcat)로 TCP/UDP 포트 통신 직접 실습
실습 환경 준비
netcat 설치 확인
nc -h 2>&1 | head -5
로컬 포트 LISTEN 상태 확인
ss -tlnp
nc로 임시 TCP 서버 열기 (터미널 A)
nc -l 9000

터미널 B에서 'nc localhost 9000'으로 접속하면 양방향 통신 실습 가능

💡개념

TCP — 신뢰성을 보장하는 연결 지향 프로토콜

마이크로서비스를 배포했는데 클러스터 내부에서는 헬스체크가 통과하지만 외부 모니터링은 타임아웃을 보고합니다. 방화벽도, 포트도, 프로세스도 문제없습니다. ss -tan 출력을 보면 SYN_RECV 상태로 쌓인 연결들이 보이는데, 이 상태가 무엇을 뜻하는지 해석조차 못 합니다. TCP의 연결 수립 과정을 이해하지 못하면 이 출력이 아무 의미 없는 숫자로만 보입니다.

TCP — 신뢰성을 보장하는 연결 지향 프로토콜

TCP란 무엇인가

**TCP(Transmission Control Protocol)**는 데이터를 순서대로, 빠짐없이, 오류 없이 전달하도록 설계된 전송 계층 프로토콜입니다. 이를 위해 연결 수립, 흐름 제어, 오류 감지 및 재전송 메커니즘을 갖추고 있습니다.

3-Way Handshake — 연결 수립

TCP 통신을 시작하기 전, 반드시 3단계 핸드셰이크로 연결을 수립합니다.

클라이언트                              서버
    │                                   │
    │ ──── SYN (seq=100) ───────────► │
    │      "연결하고 싶어"               │
    │                                   │
    │ ◄── SYN-ACK (seq=200, ack=101) ─ │
    │      "알겠어, 나도 연결 준비됐어"   │
    │                                   │
    │ ──── ACK (ack=201) ────────────► │
    │      "확인. 이제 통신 시작하자"     │
    │                                   │
    │ ═══════ 데이터 전송 가능 ══════════ │

각 단계의 의미:

  1. SYN: 클라이언트가 연결을 요청하며 초기 시퀀스 번호(ISN)를 전달
  2. SYN-ACK: 서버가 요청을 수락하고, 자신의 ISN을 전달하며 클라이언트의 SYN을 ACK
  3. ACK: 클라이언트가 서버의 SYN을 ACK하며 연결 수립 완료

연결 종료 — 4-Way Teardown

TCP 연결 종료는 4단계를 거칩니다:

클라이언트                              서버
    │ ──── FIN ──────────────────────► │  "더 보낼 데이터 없음"
    │ ◄─── ACK ───────────────────── │  "FIN 받았음"
    │ ◄─── FIN ───────────────────── │  "서버도 종료"
    │ ──── ACK ──────────────────────► │  "확인"

TCP의 신뢰성 메커니즘

TCP가 "빠짐없이, 순서대로" 데이터를 보장하는 것은 여러 메커니즘이 조합된 결과입니다. 각 기능이 담당하는 역할을 정리하면 TCP가 왜 느리지만 신뢰할 수 있는지 이해됩니다.

기능설명
순서 번호(Sequence Number)패킷에 번호를 붙여 순서 보장
확인 응답(ACK)받은 패킷을 확인하고, 미수신 시 재전송 요청
재전송일정 시간 내 ACK 없으면 자동 재전송
흐름 제어(Flow Control)수신 버퍼 크기(Window Size)에 맞춰 전송 속도 조절
혼잡 제어(Congestion Control)네트워크 혼잡 시 전송 속도 자동 감소

TCP를 사용하는 주요 프로토콜

HTTP/HTTPS  — TCP 80/443   (웹)
SSH         — TCP 22        (원격 접속)
FTP         — TCP 20/21     (파일 전송)
SMTP        — TCP 25/587    (이메일 발송)
MySQL       — TCP 3306      (데이터베이스)
PostgreSQL  — TCP 5432      (데이터베이스)
Redis       — TCP 6379      (캐시)

💡개념

UDP와 Well-known Port 체계

DNS 쿼리가 간헐적으로 실패합니다. 서버는 살아있고 포트 53도 열려 있는데 왜 안 되는지 이해가 안 됩니다. 원인은 UDP 패킷 유실이었습니다. TCP라면 자동으로 재전송했겠지만 DNS는 UDP를 씁니다. UDP가 왜 신뢰성을 포기하는지, 어떤 서비스가 UDP를 쓰는지 알면 이런 간헐적 실패의 원인을 훨씬 빠르게 좁힐 수 있습니다.

UDP와 Well-known Port 체계

UDP — 속도 우선, 신뢰성 포기

**UDP(User Datagram Protocol)**는 TCP의 연결 수립, 순서 보장, 재전송 메커니즘을 모두 제거하고 최소한의 기능만 가진 프로토콜입니다.

[UDP 통신 — 그냥 보냄]

클라이언트                        서버
    │                              │
    │ ──── 데이터 ───────────────► │
    │ ──── 데이터 ───────────────► │  (순서 보장 없음)
    │ ──── 데이터 ───────────────► │  (손실되어도 재전송 없음)
    │                              │

TCP vs UDP 비교

어떤 상황에서 TCP를 쓰고 어떤 상황에서 UDP를 쓸지는 각 프로토콜의 특성 차이에서 결정됩니다.

특성TCPUDP
연결 수립필요 (3-Way Handshake)불필요
순서 보장보장미보장
재전송자동 재전송없음
오류 검사헤더 + 데이터선택적 체크섬
속도상대적으로 느림빠름
오버헤드높음 (헤더 20~60바이트)낮음 (헤더 8바이트)
적합한 용도파일 전송, 웹, DBDNS, 스트리밍, 게임

UDP가 적합한 서비스

DNS (UDP 53)

클라이언트 → DNS 서버: "google.com이 뭐야?" (1패킷)
DNS 서버 → 클라이언트: "142.250.196.110" (1패킷)

요청과 응답이 각 1패킷으로 끝나는 단순한 질의응답 구조에서 TCP 연결 수립(3-Way Handshake)은 불필요한 오버헤드입니다. DNS는 UDP 53을 사용합니다.

NTP (UDP 123)

시간 동기화는 단발성 요청/응답이며, 일부 패킷 손실 시 재전송보다 다시 질의하는 것이 빠릅니다.

실시간 영상/음성 (RTP, UDP 기반)

1초에 30프레임을 전송하는 영상에서 한 프레임이 손실되어도 다음 프레임을 보여주는 것이 훨씬 자연스럽습니다. TCP 재전송으로 인한 지연은 화상통화를 불가능하게 만들 수 있습니다.

온라인 게임

캐릭터 위치 정보는 100ms마다 갱신됩니다. 오래된 위치 데이터를 재전송받는 것보다 최신 데이터를 새로 받는 것이 게임 경험에 유리합니다.

Well-known Port 체계

포트 번호는 0~65535 범위이며 세 구간으로 나뉩니다:

범위이름특징
0 ~ 1023Well-known Ports표준 서비스, root 권한 필요
1024 ~ 49151Registered Ports등록된 애플리케이션
49152 ~ 65535Dynamic/Ephemeral클라이언트 임시 포트

필수 암기 Well-known Ports

포트프로토콜서비스
20, 21TCPFTP (데이터, 제어)
22TCPSSH (보안 원격 접속)
23TCPTelnet (비암호화 원격)
25TCPSMTP (이메일 발송)
53UDP (+ TCP)DNS
67, 68UDPDHCP
80TCPHTTP
110TCPPOP3 (이메일 수신)
123UDPNTP (시간 동기화)
143TCPIMAP (이메일 수신)
443TCPHTTPS
587TCPSMTP Submission (이메일 발송, TLS)
3306TCPMySQL
5432TCPPostgreSQL
6379TCPRedis
8080TCPHTTP 대체 (개발/프록시)
27017TCPMongoDB

Ephemeral Port

클라이언트가 서버에 연결할 때, 운영체제가 자동으로 49152~65535 범위에서 임시 포트를 할당합니다.

클라이언트 IP:PORT          서버 IP:PORT
192.168.1.10:54321  ────►  93.184.216.34:443
              ↑
         임시 포트 (ephemeral)
         OS가 자동 할당
로컬 터미널
# 실습 디렉토리 준비
mkdir -p /tmp/networking/part1/exam_5 && cd /tmp/networking/part1/exam_5

# 현재 클라이언트 포트 범위 확인
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768   60999
🔍실행 후 확인할 것
  • 핵심 출력명령 결과에서 성공/실패를 가르는 값을 먼저 확인합니다
  • 대상 식별IP, 포트, 인터페이스, 프로세스명처럼 다음 조치를 결정하는 필드를 봅니다
  • 다음 분기결과가 기대와 다르면 어느 계층을 이어서 점검할지 정합니다

nc로 TCP 서버 열고 통신 테스트하기

목표

nc(netcat)로 간단한 TCP 서버를 열고 클라이언트로 접속하여, 실제 포트 통신이 어떻게 이루어지는지 체험합니다.

전제 조건

로컬 터미널
# nc 설치 확인
$ which nc
# 없으면:
$ sudo apt install netcat-openbsd    # Ubuntu/Debian
$ sudo yum install nmap-ncat         # CentOS/RHEL

단계별 실습

1단계: TCP 서버 열기 (터미널 1)

로컬 터미널
# 8080 포트에서 연결 대기
$ nc -l 8080

# 또는 다음 옵션과 함께:
$ nc -l -p 8080 -v
# Listening on 0.0.0.0 8080

이 명령어를 실행하면 터미널이 대기 상태로 멈춥니다. 연결이 들어오기를 기다리는 중입니다.

2단계: 클라이언트로 접속 (터미널 2)

새 터미널을 열어 접속합니다:

로컬 터미널
# 같은 서버에서 접속 (loopback)
$ nc 127.0.0.1 8080

# 또는 서버 IP로 원격 접속
$ nc 10.0.0.5 8080

3단계: 양방향 메시지 전송

터미널 2에서 입력하면 터미널 1에서 수신됩니다:

[터미널 2 - 클라이언트]           [터미널 1 - 서버]
$ nc 127.0.0.1 8080
Hello, Server!                  Hello, Server!    ← 수신
                    ←────────
                                Hi, Client!
Hi, Client!         ← 수신

4단계: 파일 전송 테스트

로컬 터미널
# 서버: 파일 수신 준비
$ nc -l 9000 > received_file.txt

# 클라이언트: 파일 전송
$ nc 127.0.0.1 9000 < /etc/hostname
# 전송 완료 후 Ctrl+D로 종료

# 서버 측에서 수신 확인
$ cat received_file.txt

5단계: 연결 종료

  • 클라이언트: Ctrl+D (EOF 전송) 또는 Ctrl+C
  • 서버: 클라이언트 연결 종료 후 자동 종료, 또는 Ctrl+C

확인 포인트

로컬 터미널
# 연결 중 상태 확인 (다른 터미널에서)
$ ss -tnp | grep 8080
# LISTEN  0  1  0.0.0.0:8080  0.0.0.0:*      서버 대기 중
# ESTAB   0  0  127.0.0.1:8080  127.0.0.1:54321   연결 수립됨

nc로 포트 개방 여부 확인하기

목표

nc를 클라이언트 모드로 사용하여 원격 서버의 특정 포트가 열려 있는지 확인합니다. 방화벽 정책 확인이나 서비스 응답 테스트에 활용됩니다.

단계별 실습

1단계: TCP 포트 개방 확인

로컬 터미널
# -z: 데이터 전송 없이 연결 시도만
# -v: 자세한 출력
# -w 3: 3초 타임아웃

# 포트가 열려 있는 경우
$ nc -zv google.com 443
# Connection to google.com 443 port [tcp/https] succeeded!

# 포트가 닫혀 있는 경우
$ nc -zv google.com 8888
# nc: connect to google.com port 8888 (tcp) failed: Connection refused

2단계: UDP 포트 확인

로컬 터미널
# -u: UDP 모드
$ nc -zvu 8.8.8.8 53
# Connection to 8.8.8.8 53 port [udp/domain] succeeded!

3단계: 여러 포트 범위 스캔

로컬 터미널
# 20~25 포트 순차 확인
$ nc -zv 192.168.1.1 20-25

# 출력:
# nc: connect to 192.168.1.1 port 20 failed: Connection refused
# nc: connect to 192.168.1.1 port 21 failed: Connection refused
# Connection to 192.168.1.1 port 22 (tcp) succeeded!  ← SSH 열림

4단계: 서비스 배너 확인

로컬 터미널
# SSH 서버 배너 확인 (연결 후 즉시 출력)
$ nc 10.0.0.5 22
# SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6

# HTTP 서버 직접 요청
$ echo -e "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n" | nc example.com 80
# HTTP/1.0 200 OK
# Content-Type: text/html
# ...

5단계: 방화벽 정책 테스트 시나리오

로컬 터미널
# 방화벽 규칙 추가 전 테스트
$ nc -zv app-server 3306
# nc: connect to app-server port 3306 failed: Connection refused

# 방화벽 규칙 추가 후 재테스트
$ nc -zv app-server 3306
# Connection to app-server port 3306 (tcp) succeeded!

nc vs telnet vs curl 비교

도구강점약점
ncTCP/UDP 모두 지원, 스크립팅 용이TLS 미지원
telnet단순, 배너 확인 용이UDP 미지원, 구식
curlHTTPS 지원, 다양한 프로토콜단순 포트 체크엔 과함

방화벽 ACL 요청서 작성 실습

목표

실제 운영 환경에서 방화벽 ACL(Access Control List) 정책을 요청할 때 필요한 정보를 올바르게 명시하는 방법을 익힙니다.

시나리오

애플리케이션 서버(10.0.1.20)가 다음 서비스에 접근해야 합니다:

  1. 데이터베이스 서버(10.0.2.10)의 MySQL(3306/TCP)
  2. 외부 DNS 서버(8.8.8.8)의 DNS(53/UDP)
  3. 외부 HTTPS API(api.partner.com의 443/TCP)

올바른 ACL 요청서 작성

잘못된 요청 (흔한 실수)

"10.0.1.20에서 10.0.2.10 포트 3306 허용해 주세요"
→ TCP인지 UDP인지 명시 안 됨!
→ 방화벽 담당자가 TCP만 추가하면 이후 문제 발생 가능

올바른 요청

방화벽 ACL 요청

출발지: 10.0.1.20/32
목적지: 10.0.2.10/32
포트:   3306
프로토콜: TCP
방향:   Outbound (10.0.1.20 → 10.0.2.10)
목적:   애플리케이션 서버 → MySQL DB 접근

---

출발지: 10.0.1.20/32
목적지: 8.8.8.8/32
포트:   53
프로토콜: UDP       ← DNS는 반드시 UDP!
방향:   Outbound
목적:   DNS 질의

---

출발지: 10.0.1.20/32
목적지: ANY (api.partner.com 해당 IP 대역)
포트:   443
프로토콜: TCP
방향:   Outbound
목적:   파트너 API 연동

프로토콜 확인 방법

로컬 터미널
# 서비스별 기본 프로토콜 확인
$ grep mysql /etc/services
# mysql  3306/tcp
# mysql  3306/udp (등록되어 있지만 실제로는 TCP만 사용)

$ grep domain /etc/services
# domain  53/tcp
# domain  53/udp   ← UDP가 기본

$ grep https /etc/services
# https  443/tcp

열린 포트와 프로토콜 확인

로컬 터미널
# 서버에서 열린 포트 확인 (TCP)
$ ss -tlnp
# State   Recv-Q  Send-Q  Local Address:Port
# LISTEN  0       128     0.0.0.0:22        TCP 22 (SSH)
# LISTEN  0       80      0.0.0.0:3306      TCP 3306 (MySQL)

# UDP 포트 확인
$ ss -ulnp
# State   Recv-Q  Send-Q  Local Address:Port
# UNCONN  0       0       0.0.0.0:53        UDP 53 (DNS)
# UNCONN  0       0       0.0.0.0:123       UDP 123 (NTP)

증상

로컬 터미널
# DNS 질의가 타임아웃
$ dig @10.0.0.53 myapp.internal.com
# ;; connection timed out; no servers could be reached

# 또는 특정 도구에서만 DNS 실패
# curl은 되는데 dig는 안 됨 (또는 반대)

원인: TCP 53을 사용했거나 방화벽에서 TCP 53만 허용

방화벽 ACL에 TCP 53만 허용되고 UDP 53이 차단된 경우, 또는 dignslookup 옵션에 TCP가 강제 지정된 경우 발생합니다.

로컬 터미널
# 잘못된 ACL 요청의 예:
출발지: 10.0.0.0/24
목적지: 10.0.0.53/32
포트: 53
프로토콜: TCP   ← UDP가 빠짐!

진단 방법

로컬 터미널
# UDP 53으로 직접 테스트
$ dig @10.0.0.53 myapp.internal.com
# 타임아웃

# TCP 53으로 테스트
$ dig @10.0.0.53 myapp.internal.com +tcp
# 응답 옴!
# → 방화벽에서 UDP 53만 차단됨, 반대로 TCP는 열림

# UDP로 nc 테스트
$ nc -zuv 10.0.0.53 53
# nc: connect to 10.0.0.53 port 53 (udp) failed: Connection refused
# → UDP 53 차단 확인

해결 방법

방화벽 ACL 수정

기존:
출발지: 10.0.0.0/24 → 10.0.0.53:53/TCP ALLOW

추가 필요:
출발지: 10.0.0.0/24 → 10.0.0.53:53/UDP ALLOW

임시 우회 (TCP 강제)

방화벽 수정 전 임시로 TCP DNS를 사용:

로컬 터미널
# dig에서 TCP 강제 지정
$ dig @10.0.0.53 myapp.internal.com +tcp

# /etc/resolv.conf에 options 추가
$ echo "options use-vc" | sudo tee -a /etc/resolv.conf
# use-vc: 모든 DNS 질의를 TCP로 전송

DNS에서 TCP를 사용하는 정당한 경우

상황이유
Zone Transfer (AXFR)대용량 Zone 데이터 전송
응답 크기 > 512바이트UDP 한계 초과 시 TCP로 재시도
DNSSEC 응답서명 데이터로 응답 크기 큼
DNS over TLS (DoT)TCP 853 사용
로컬 터미널
# Zone Transfer 테스트 (TCP 53 사용)
$ dig @ns1.example.com example.com AXFR

예방 방법

방화벽 ACL 요청 시 DNS 관련 규칙은 반드시 TCP/UDP 양쪽을 명시합니다:

포트 53, 프로토콜: TCP AND UDP 모두 허용

증상

로컬 터미널
# 서버에서 로컬 확인
$ nc -zv 127.0.0.1 8080
# Connection to 127.0.0.1 8080 port [tcp] succeeded!

# 외부에서 접속 시도 (다른 서버에서)
$ nc -zv 10.0.0.5 8080
# nc: connect to 10.0.0.5 port 8080 (tcp) failed: Connection refused

원인 1: 서비스가 Localhost에만 바인딩

로컬 터미널
# 바인딩 주소 확인
$ ss -tlnp | grep 8080
# LISTEN 0 128 127.0.0.1:8080 ...   ← 127.0.0.1만 바인딩!
#                ↑
#          외부 접속 불가

서비스 설정에서 0.0.0.0:8080 대신 127.0.0.1:8080으로 바인딩되어 있습니다.

해결: 서비스 설정에서 바인딩 주소를 0.0.0.0 또는 서버의 실제 IP로 변경:

로컬 터미널
# 예: Python HTTP 서버
$ python3 -m http.server 8080 --bind 0.0.0.0

# 예: 애플리케이션 설정 파일
# server.host=0.0.0.0  (또는 server.bind-address=0.0.0.0)

원인 2: 방화벽(firewalld/iptables)에서 포트 차단

위험 명령어

이 명령은 방화벽 정책을 변경해 현재 접속 중인 세션이나 운영 트래픽에 즉시 영향을 줄 수 있습니다. 적용 전 허용 대상 IP·포트와 롤백 명령을 확인하세요.

로컬 터미널
# firewalld 확인 (RHEL/CentOS)
$ sudo firewall-cmd --list-ports
# 22/tcp 80/tcp 443/tcp   ← 8080 없음!

# 포트 추가
$ sudo firewall-cmd --add-port=8080/tcp --permanent
$ sudo firewall-cmd --reload

# iptables 확인 (직접 확인 필요 시)
$ sudo iptables -L INPUT -n | grep 8080

원인 3: 클라우드 보안 그룹 미설정

AWS EC2, GCP VM 등에서는 OS 방화벽 외에 **보안 그룹(Security Group)**에서도 포트를 허용해야 합니다.

# AWS 콘솔 → EC2 → 보안 그룹 → 인바운드 규칙 추가
유형: 사용자 지정 TCP
포트 범위: 8080
소스: 0.0.0.0/0 (또는 특정 IP)

진단 순서

외부 접속 실패
    │
    ▼
서버에서 ss -tlnp | grep [포트]
    ├── 0.0.0.0:[포트] → 바인딩 OK → 방화벽 확인
    └── 127.0.0.1:[포트] → 바인딩 문제 → 서비스 설정 변경
    │
    ▼
OS 방화벽 확인
    ├── firewall-cmd --list-ports
    └── iptables -L INPUT -n
    │
    ▼
클라우드 보안 그룹 확인 (AWS/GCP/Azure)

💼
실무 맥락
현업 패턴

마이크로서비스 환경의 포트 관리

마이크로서비스 아키텍처에서는 서비스마다 포트를 할당하고 관리해야 합니다.

YAML
# docker-compose.yml에서 포트 매핑
services:
  auth-service:
    ports:
      - "3001:3001"   # HOST:CONTAINER TCP 기본

  catalog-service:
    ports:
      - "3002:3002"

  # 데이터베이스는 외부 노출 최소화
  postgres:
    ports:
      - "127.0.0.1:5432:5432"  # localhost에서만 접근 가능

포트 충돌 시 진단:

로컬 터미널
# 어떤 프로세스가 포트 사용 중인지 확인
$ ss -tlnp | grep :3001
$ lsof -i :3001

Kubernetes NetworkPolicy 작성 시

쿠버네티스 NetworkPolicy에서 포트와 프로토콜 명시:

YAML
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-mysql
spec:
  podSelector:
    matchLabels:
      app: web
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: mysql
      ports:
        - protocol: TCP    ← 프로토콜 명시 필수
          port: 3306
    - ports:               ← DNS는 UDP 필수!
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53

이 기술이 필요한 직군

직군활용 상황
백엔드 개발자서비스 포트 설계, 방화벽 ACL 요청, 로컬 개발 환경 구성
DevOps/SRE포트 충돌 진단, 방화벽 정책 검증, 서비스 헬스체크 구현
보안 엔지니어불필요한 포트 노출 감사, ACL 정책 리뷰
클라우드 엔지니어VPC 보안 그룹 설계, NLB/ALB 리스너 설정

알아두면 차별화되는 지식

QUIC과 HTTP/3 — UDP 443

HTTP/3은 TCP 대신 UDP 기반의 QUIC 프로토콜을 사용합니다. 기존 방화벽에서 TCP 443만 허용하면 HTTP/3이 작동하지 않아 HTTP/2로 폴백됩니다.

로컬 터미널
# QUIC(HTTP/3) 지원 여부 확인
$ curl -v --http3 https://cloudflare.com 2>&1 | grep "HTTP/"

SO_REUSEPORT — 포트 공유

여러 프로세스나 스레드가 동일 포트를 공유하는 기술:

로컬 터미널
# nginx 멀티 워커가 80 포트 공유하는 예
$ ss -tlnp | grep :80
# LISTEN  0  511  0.0.0.0:80  processes:(("nginx",pid=1234,...),("nginx",pid=1235,...))

TIME_WAIT 상태

TCP 연결 종료 후 약 2MSL(보통 60초) 동안 소켓이 TIME_WAIT 상태로 남습니다. 대량의 단기 연결을 처리하는 서버에서 포트 고갈이 발생할 수 있습니다:

로컬 터미널
# TIME_WAIT 연결 수 확인
$ ss -tan state time-wait | wc -l

# TIME_WAIT 빠른 재사용 설정
$ sudo sysctl net.ipv4.tcp_tw_reuse=1

핵심 명령어 요약

로컬 터미널
# nc 서버 모드 (포트 열기)
nc -l [포트]
nc -l -p [포트] -v

# nc 클라이언트 모드 (접속)
nc [IP] [포트]
nc -zv [IP] [포트]     # 포트 개방 확인 (데이터 전송 없음)
nc -zuv [IP] [포트]    # UDP 포트 확인

# 포트 현황 확인
ss -tlnp              # TCP LISTEN 포트 + 프로세스
ss -ulnp              # UDP LISTEN 포트 + 프로세스
ss -tnp               # 현재 TCP 연결 상태

# 서비스별 기본 포트 확인
grep [서비스명] /etc/services

체크리스트

방화벽 ACL 요청 전 확인 사항:

  • 포트 번호를 확인했는가?
  • 프로토콜이 TCP인지 UDP인지 명시했는가?
  • DNS(53)는 UDP와 TCP 모두 포함했는가?
  • 출발지/목적지 IP 또는 CIDR을 정확히 명시했는가?
  • 단방향인지 양방향인지 확인했는가?
  • ss -tlnp로 서비스가 올바른 주소에 바인딩되었는지 확인했는가?

지식 확인

퀴즈 — 5문제

Q1

TCP 3-Way Handshake의 올바른 순서는?

Q2

UDP가 TCP 대신 사용되기에 적합한 서비스는?

Q3

사내 DNS 서버(UDP 53)를 운영 중입니다. 특정 서버에서 nslookup은 되는데 외부 도메인 zone transfer가 실패합니다. 원인으로 가장 적절한 것은?

Q4

`nc -l 8080` 명령어의 역할은?

Q5

방화벽 정책을 요청할 때 프로토콜 명시가 중요한 이유는?

0 / 5 답변

🧪 실습으로 확인하기

포트는 열렸다는데 왜 안 되지? — ss/netstat/telnet으로 TCP 진단

초급

"포트 8080 열었는데요?"와 "왜 안 돼요?" 사이의 간극을 메우는 실습. ss로 바인딩 상태를 확인하고, telnet/nc으로 원격 연결을 테스트하고, iptables 방화벽을 진단하고, 바인딩 주소(0.0.0.0 vs 127.0.0.1)까지 수정하는 4단계 TCP 포트 진단 플로우를 완성한다.

35📋 4단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요

networking입문 · 30
[Network] DNS 질의 실패 극복 및 resolv.conf 수동 복구 가이드
Networking 트랙 계속
docker입문 · 30
[Docker] 백엔드 개발자에게 Docker와 컨테이너 가상화가 필수인 이유
Docker 트랙 시작점