Post

Network

Network

목차

Part 2: 네트워크

  1. 네트워크 기본 개념
  2. TCP/IP 프로토콜 스택
  3. Linux 네트워킹 아키텍처
  4. 가상 네트워크 디바이스
  5. 네트워크 네임스페이스
  6. iptables와 Netfilter
  7. 라우팅과 포워딩

1. 네트워크 기본 개념

1.1 OSI 7계층과 TCP/IP 모델

OSI 7계층 모델

OSI(Open Systems Interconnection) 모델은 네트워크 통신을 7개의 계층으로 추상화한 이론적 모델이다:

물리 계층 (Physical Layer)

  • 실제 하드웨어를 통한 비트 전송
  • 전압, 전파, 광신호 등
  • 예: 이더넷 케이블, 광섬유, 무선 신호

데이터 링크 계층 (Data Link Layer)

  • 인접한 노드 간 프레임 전송
  • MAC 주소 기반 통신
  • 에러 검출 및 복구
  • 예: Ethernet, Wi-Fi, ARP

네트워크 계층 (Network Layer)

  • 논리적 주소(IP) 기반 라우팅
  • 패킷 포워딩
  • 예: IP, ICMP, IGMP

전송 계층 (Transport Layer)

  • 종단 간 신뢰성 있는 데이터 전송
  • 포트 기반 프로세스 구분
  • 예: TCP, UDP

세션 계층 (Session Layer)

  • 세션 관리 (연결 설정, 유지, 종료)
  • 대화 제어

표현 계층 (Presentation Layer)

  • 데이터 형식 변환
  • 암호화/복호화
  • 압축/압축 해제

응용 계층 (Application Layer)

  • 사용자 애플리케이션 인터페이스
  • 예: HTTP, FTP, SMTP, DNS

TCP/IP 모델

실제 인터넷에서 사용되는 4계층 모델:

네트워크 접근 계층 (Network Access Layer)

  • OSI의 물리 + 데이터 링크 계층에 해당
  • Ethernet, Wi-Fi 등

인터넷 계층 (Internet Layer)

  • OSI의 네트워크 계층에 해당
  • IP, ICMP, ARP

전송 계층 (Transport Layer)

  • OSI의 전송 계층과 동일
  • TCP, UDP

응용 계층 (Application Layer)

  • OSI의 세션 + 표현 + 응용 계층을 통합
  • HTTP, DNS, SSH 등

1.2 IP 주소와 서브넷

IPv4 주소 체계

IPv4 주소는 32비트로 구성되며, 일반적으로 점-십진 표기법으로 표현된다:

  • 형식: 192.168.1.10
  • 4개의 옥텟(8비트)으로 구성
  • 각 옥텟은 0-255 범위

IP 주소 클래스

초기 IPv4는 클래스 기반으로 나뉘었다:

Class A

  • 범위: 1.0.0.0 ~ 126.255.255.255
  • 기본 서브넷 마스크: 255.0.0.0 (/8)
  • 대규모 네트워크용

Class B

  • 범위: 128.0.0.0 ~ 191.255.255.255
  • 기본 서브넷 마스크: 255.255.0.0 (/16)
  • 중규모 네트워크용

Class C

  • 범위: 192.0.0.0 ~ 223.255.255.255
  • 기본 서브넷 마스크: 255.255.255.0 (/24)
  • 소규모 네트워크용

Class D (멀티캐스트)

  • 범위: 224.0.0.0 ~ 239.255.255.255

Class E (예약)

  • 범위: 240.0.0.0 ~ 255.255.255.255

CIDR (Classless Inter-Domain Routing)

클래스 기반 주소의 비효율성을 해결하기 위해 도입:

  • 슬래시 표기법 사용: 192.168.1.0/24
  • /24는 네트워크 비트가 24개 (앞 3개 옥텟)
  • 호스트 비트는 8개 (마지막 옥텟)
  • 사용 가능한 호스트: 2^8 - 2 = 254개 (네트워크 주소와 브로드캐스트 주소 제외)

서브넷 마스크

네트워크 부분과 호스트 부분을 구분:

  • /24 = 255.255.255.0
  • /16 = 255.255.0.0
  • /8 = 255.0.0.0

예시 계산

192.168.1.0/24 네트워크:

  • 네트워크 주소: 192.168.1.0
  • 첫 번째 사용 가능 IP: 192.168.1.1
  • 마지막 사용 가능 IP: 192.168.1.254
  • 브로드캐스트 주소: 192.168.1.255
  • 총 호스트 수: 254개

사설 IP 주소 범위

인터넷에서 라우팅되지 않는 내부 네트워크용 주소:

  • Class A: 10.0.0.0/8 (10.0.0.0 ~ 10.255.255.255)
  • Class B: 172.16.0.0/12 (172.16.0.0 ~ 172.31.255.255)
  • Class C: 192.168.0.0/16 (192.168.0.0 ~ 192.168.255.255)

특수 IP 주소

  • 127.0.0.0/8: 루프백 주소 (localhost)
  • 0.0.0.0: 모든 인터페이스 또는 알 수 없는 주소
  • 169.254.0.0/16: APIPA (자동 사설 IP 주소)

1.3 MAC 주소와 ARP

MAC 주소 (Media Access Control Address)

MAC 주소는 네트워크 인터페이스 카드(NIC)의 물리적 주소이다:

  • 48비트 (6바이트) 주소
  • 16진수 표기: 00:1A:2B:3C:4D:5E
  • 전 세계적으로 고유 (이론상)
  • 앞 3바이트: 제조사 식별 (OUI)
  • 뒤 3바이트: 제조사가 할당한 고유 번호

ARP (Address Resolution Protocol)

ARP는 IP 주소를 MAC 주소로 변환하는 프로토콜이다.

ARP 작동 과정

  1. 호스트 A가 호스트 B(192.168.1.10)와 통신하려 함
  2. 호스트 A의 ARP 캐시 확인
  3. 캐시에 없으면 ARP Request를 브로드캐스트
    • “192.168.1.10의 MAC 주소가 무엇인가요?”
  4. 해당 IP를 가진 호스트 B가 ARP Reply로 응답
    • “제 MAC 주소는 00:1A:2B:3C:4D:5E이다”
  5. 호스트 A가 ARP 캐시에 저장
  6. 이후 통신에서는 캐시 사용 (일정 시간 후 만료)

ARP 캐시 확인

1
2
3
4
5
6
7
8
9
# ARP 캐시 테이블 확인
arp -n
ip neigh show

# 특정 항목 추가 (정적 ARP)
arp -s 192.168.1.10 00:1A:2B:3C:4D:5E

# ARP 캐시 삭제
arp -d 192.168.1.10

RARP와 기타 변형

  • RARP (Reverse ARP): MAC → IP 변환 (현재는 거의 사용 안 함)
  • Gratuitous ARP: 자신의 IP를 브로드캐스트 (IP 충돌 검사, ARP 캐시 업데이트)
  • Proxy ARP: 라우터가 다른 네트워크의 ARP 요청에 대신 응답

2. TCP/IP 프로토콜 스택

2.1 IP (Internet Protocol)

IP의 역할

IP는 패킷을 목적지까지 전달하는 네트워크 계층 프로토콜이다.

IP의 특징

  • 비연결성 (Connectionless): 연결 설정 없이 바로 전송
  • 비신뢰성 (Unreliable): 패킷 손실, 순서 뒤바뀜 등을 보장하지 않음
  • 최선형 전달 (Best Effort): 가능한 한 최선을 다해 전달하지만 보장은 없음

IPv4 헤더 구조

주요 필드:

  • Version: IP 버전 (4)
  • Header Length: 헤더 길이
  • TOS (Type of Service): QoS 정보
  • Total Length: 전체 패킷 크기
  • Identification, Flags, Fragment Offset: 단편화 관련
  • TTL (Time To Live): 라우터 홉 제한 (패킷 루프 방지)
  • Protocol: 상위 계층 프로토콜 (TCP=6, UDP=17, ICMP=1)
  • Header Checksum: 헤더 오류 검사
  • Source IP Address: 출발지 IP
  • Destination IP Address: 목적지 IP

TTL (Time To Live)

TTL은 패킷이 무한 루프를 방지하는 메커니즘이다:

  • 초기값 설정 (보통 64 또는 128)
  • 라우터를 거칠 때마다 1씩 감소
  • 0이 되면 패킷 폐기 및 ICMP Time Exceeded 메시지 전송
  • traceroute 명령이 이 원리를 활용

IP 단편화 (Fragmentation)

네트워크 경로의 MTU(Maximum Transmission Unit)가 다를 때:

  • 패킷을 작은 조각으로 분할
  • 목적지에서 재조립
  • 성능 저하 원인이므로 가능하면 피해야 함
  • Path MTU Discovery로 최적 크기 탐색

2.2 ICMP (Internet Control Message Protocol)

ICMP의 역할

ICMP는 네트워크 진단과 에러 보고를 위한 프로토콜이다.

주요 ICMP 메시지 타입

Echo Request/Reply (Type 8/0)

  • ping 명령에서 사용
  • 네트워크 연결성 테스트

Destination Unreachable (Type 3)

  • 패킷이 목적지에 도달할 수 없을 때
  • 다양한 코드:
    • Code 0: Network Unreachable
    • Code 1: Host Unreachable
    • Code 3: Port Unreachable
    • Code 4: Fragmentation Needed (PMTU Discovery)

Time Exceeded (Type 11)

  • TTL이 0이 되었을 때
  • traceroute가 이용

Redirect (Type 5)

  • 더 나은 라우트 알림

ICMP와 보안

ICMP는 진단 도구이지만 보안 위험도 있다:

  • Ping flood (DDoS 공격)
  • Smurf attack (ICMP 증폭 공격)
  • 정보 수집에 악용 가능

많은 방화벽이 ICMP를 제한하거나 차단한다.

2.3 TCP (Transmission Control Protocol)

TCP의 특징

TCP는 신뢰성 있는 연결 지향 프로토콜이다:

  • 연결 지향: 3-way handshake로 연결 설정
  • 신뢰성 보장: 패킷 손실 시 재전송
  • 순서 보장: 순서가 뒤바뀐 패킷 재정렬
  • 흐름 제어: 수신자 버퍼 오버플로 방지
  • 혼잡 제어: 네트워크 혼잡 완화

TCP 헤더 구조

주요 필드:

  • Source/Destination Port: 송신/수신 포트
  • Sequence Number: 바이트 스트림 상의 위치
  • Acknowledgment Number: 다음 수신할 바이트 번호
  • Flags: SYN, ACK, FIN, RST, PSH, URG
  • Window Size: 수신 윈도우 크기 (흐름 제어)
  • Checksum: 세그먼트 오류 검사

3-Way Handshake (연결 설정)

  1. SYN: 클라이언트 → 서버
    • “연결 요청, 내 초기 시퀀스 번호는 X이다”
  2. SYN-ACK: 서버 → 클라이언트
    • “연결 요청 확인, 내 초기 시퀀스 번호는 Y이다. X+1 수신 완료”
  3. ACK: 클라이언트 → 서버
    • “Y+1 수신 완료, 연결 완료”

4-Way Handshake (연결 종료)

  1. FIN: 클라이언트 → 서버
    • “데이터 전송을 완료”
  2. ACK: 서버 → 클라이언트
    • “확인 완료”
  3. FIN: 서버 → 클라이언트
    • “데이터 전송을 완료”
  4. ACK: 클라이언트 → 서버
    • “확인 완료”

TIME_WAIT 상태

연결 종료 후 일정 시간(2 * MSL) 동안 유지:

  • 지연된 패킷이 새 연결에 영향을 주지 않도록 방지
  • 일반적으로 60초 (Linux는 기본 60초)

TCP 재전송

패킷 손실 감지 및 재전송 메커니즘:

타임아웃 기반

  • ACK를 받지 못하면 RTO(Retransmission Timeout) 후 재전송
  • RTO는 RTT를 기반으로 동적 계산

빠른 재전송 (Fast Retransmit)

  • 중복 ACK 3개 수신 시 즉시 재전송
  • 타임아웃을 기다리지 않아 더 빠름

TCP 흐름 제어 (Flow Control)

수신자의 처리 속도에 맞춰 전송 속도 조절:

  • 슬라이딩 윈도우: 수신 버퍼 크기만큼만 전송
  • Window Size 필드: 수신 가능한 바이트 수 알림
  • Zero Window: 수신자가 버퍼가 가득 차면 0을 전송하여 일시 중단

TCP 혼잡 제어 (Congestion Control)

네트워크 혼잡을 감지하고 완화:

Slow Start

  • 연결 초기에는 작은 윈도우로 시작
  • ACK 수신마다 윈도우 크기 지수적 증가
  • 임계값(ssthresh)까지 빠르게 증가

Congestion Avoidance

  • 임계값 도달 후 선형적으로 증가
  • 패킷 손실 감지 시 윈도우 축소

Fast Recovery

  • 빠른 재전송 후 윈도우를 절반으로 줄임
  • Slow Start로 돌아가지 않음

주요 혼잡 제어 알고리즘

  • Reno: 전통적 알고리즘
  • CUBIC: Linux 기본값, 고속 네트워크 최적화
  • BBR: Google 개발, RTT 기반

2.4 UDP (User Datagram Protocol)

UDP의 특징

UDP는 단순하고 빠른 비연결 프로토콜이다:

  • 비연결성: 연결 설정 없이 바로 전송
  • 비신뢰성: 패킷 손실, 중복, 순서 뒤바뀜 가능
  • 오버헤드 최소: 헤더가 8바이트로 매우 작음
  • 실시간 전송: 지연이 적어 실시간 애플리케이션에 적합

UDP 헤더 구조

매우 간단한 구조:

  • Source Port: 송신 포트 (2바이트)
  • Destination Port: 수신 포트 (2바이트)
  • Length: 전체 데이터그램 길이 (2바이트)
  • Checksum: 오류 검사 (2바이트, 선택적)

UDP 사용 사례

DNS (Domain Name System)

  • 빠른 조회가 중요
  • 손실 시 재요청하면 됨

DHCP (Dynamic Host Configuration Protocol)

  • 클라이언트가 IP 주소 받을 때
  • 연결이 없는 상태에서도 통신 필요

스트리밍 (Video/Audio)

  • 약간의 패킷 손실은 허용 가능
  • 재전송보다 실시간성이 중요
  • RTP (Real-time Transport Protocol)

온라인 게임

  • 낮은 지연이 중요
  • 일부 패킷 손실 허용

VoIP (Voice over IP)

  • 실시간 음성 통신
  • 지연보다 품질 저하가 나음

TCP vs UDP 비교

특성TCPUDP
연결연결 지향비연결
신뢰성보장보장 안 함
순서보장보장 안 함
속도상대적으로 느림빠름
헤더 크기20바이트 이상8바이트
용도파일 전송, 웹, 이메일스트리밍, 게임, DNS

2.5 포트 번호

포트의 개념

포트는 하나의 호스트에서 여러 서비스를 구분하기 위한 논리적 주소이다:

  • 16비트 번호 (0-65535)
  • IP 주소 + 포트 = 소켓 (통신의 종단점)

포트 번호 분류

Well-Known Ports (0-1023)

  • 표준 서비스용으로 예약
  • root 권한 필요 (CAP_NET_BIND_SERVICE)
  • 주요 포트:
    • 20/21: FTP
    • 22: SSH
    • 23: Telnet
    • 25: SMTP
    • 53: DNS
    • 80: HTTP
    • 110: POP3
    • 143: IMAP
    • 443: HTTPS
    • 3306: MySQL
    • 5432: PostgreSQL

Registered Ports (1024-49151)

  • IANA에 등록된 애플리케이션용
  • 일반 사용자도 바인딩 가능
  • 주요 포트:
    • 3000: 많은 개발 서버
    • 5000: Flask 기본 포트
    • 6379: Redis
    • 8080: 대체 HTTP
    • 9090: Prometheus

Dynamic/Private Ports (49152-65535)

  • 클라이언트의 임시 포트 (ephemeral ports)
  • 운영체제가 자동 할당
  • 연결 종료 후 재사용

소켓 주소

통신 종단점은 IP + 포트로 표현:

  • 로컬 소켓: 192.168.1.10:8080
  • 원격 소켓: 203.0.113.5:443
  • 연결은 (로컬 IP, 로컬 포트, 원격 IP, 원격 포트) 4-tuple로 고유 식별

3. Linux 네트워킹 아키텍처

3.1 Linux 네트워크 스택 구조

Linux 네트워크 스택의 계층

Linux 커널의 네트워크 구현은 다음과 같이 계층화되어 있다:

하드웨어 레벨

  • 물리적 네트워크 인터페이스 카드 (NIC)
  • DMA를 통한 패킷 송수신

디바이스 드라이버

  • 하드웨어 추상화
  • 링크 계층 프로토콜 처리 (Ethernet, Wi-Fi 등)
  • sk_buff 구조체로 패킷 표현

네트워크 프로토콜 스택

  • IP 계층: 라우팅, 포워딩, 단편화
  • TCP/UDP 계층: 연결 관리, 포트 다중화
  • 소켓 계층: 애플리케이션 인터페이스

소켓 API

  • 시스템 콜 인터페이스
  • socket(), bind(), listen(), connect(), send(), recv() 등

패킷 수신 과정

  1. 하드웨어 인터럽트
    • NIC가 패킷 수신 시 인터럽트 발생
    • 드라이버의 인터럽트 핸들러 호출
  2. NAPI (New API)
    • 고속 네트워크를 위한 폴링 메커니즘
    • 인터럽트 빈도 감소
  3. sk_buff 생성
    • 패킷 데이터를 sk_buff 구조체에 저장
    • 메타데이터 포함 (프로토콜, 길이 등)
  4. 프로토콜 처리
    • IP 계층: 라우팅 결정, 헤더 검사
    • TCP/UDP: 포트 확인, 체크섬 검증
    • 소켓 버퍼로 전달
  5. 애플리케이션으로 전달
    • recv() 시스템 콜로 데이터 복사

패킷 송신 과정

  1. 애플리케이션 전송
    • send() 시스템 콜 호출
    • 데이터를 커널 버퍼로 복사
  2. 프로토콜 처리
    • TCP/UDP 헤더 추가
    • IP 헤더 추가
    • 라우팅 테이블 조회
  3. 큐잉
    • QDisc (Queueing Discipline)로 전달
    • 트래픽 셰이핑, 우선순위 적용
  4. 드라이버 전송
    • 네트워크 드라이버로 전달
    • DMA로 NIC 메모리로 복사
  5. 물리적 전송
    • NIC가 패킷을 네트워크로 전송

3.2 네트워크 인터페이스

네트워크 인터페이스의 개념

네트워크 인터페이스는 시스템과 네트워크를 연결하는 소프트웨어 객체이다:

  • 물리적 인터페이스: eth0, eth1, wlan0 등
  • 가상 인터페이스: lo, tun0, veth0 등

인터페이스 명명 규칙

전통적 명명 (Predictable Network Interface Names)

  • ethX: 이더넷 인터페이스
  • wlanX: 무선 인터페이스
  • lo: 루프백 인터페이스

systemd 명명 규칙 (현대적)

  • eno1: 온보드 이더넷
  • ens1: PCI Express 슬롯
  • enp0s3: PCI 버스 위치 기반
  • wlp3s0: 무선 PCI

인터페이스 관리

ifconfig (전통적 도구)

1
2
3
4
5
6
7
8
9
10
11
# 모든 인터페이스 확인
ifconfig -a

# 인터페이스 활성화
ifconfig eth0 up

# IP 주소 설정
ifconfig eth0 192.168.1.10 netmask 255.255.255.0

# 비활성화
ifconfig eth0 down

ip 명령 (현대적 도구)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 모든 인터페이스 확인
ip link show
ip addr show

# 인터페이스 활성화/비활성화
ip link set eth0 up
ip link set eth0 down

# IP 주소 추가
ip addr add 192.168.1.10/24 dev eth0

# IP 주소 삭제
ip addr del 192.168.1.10/24 dev eth0

# 라우트 확인
ip route show

# 기본 게이트웨이 추가
ip route add default via 192.168.1.1

네트워크 인터페이스 상태

  • UP: 인터페이스 활성화
  • DOWN: 인터페이스 비활성화
  • LOWER_UP: 물리적 연결 감지 (케이블 연결됨)
  • BROADCAST: 브로드캐스트 지원
  • MULTICAST: 멀티캐스트 지원
  • PROMISC: 프로미스큐어스 모드 (모든 패킷 수신)

3.3 라우팅 테이블

라우팅 테이블의 역할

라우팅 테이블은 패킷을 어디로 보낼지 결정하는 규칙 집합이다.

라우팅 테이블 확인

1
2
3
4
5
6
7
8
9
10
# route 명령 (전통적)
route -n

# ip route 명령 (현대적)
ip route show

# 출력 예시:
# default via 192.168.1.1 dev eth0 
# 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10 
# 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1

라우팅 테이블 항목 구성

각 라우팅 항목은 다음 정보를 포함:

  • Destination: 목적지 네트워크
  • Gateway: 다음 홉 라우터 (없으면 직접 전달)
  • Genmask: 서브넷 마스크
  • Flags: 라우트 속성
  • Metric: 우선순위 (낮을수록 우선)
  • Iface: 나가는 인터페이스

라우팅 결정 과정

  1. 목적지 IP와 가장 긴 매칭 (Longest Prefix Match)
  2. 여러 경로가 매칭되면 Metric이 낮은 것 선택
  3. 해당 인터페이스로 패킷 전송
  4. Gateway가 있으면 Gateway로, 없으면 직접 전달

라우트 추가/삭제

1
2
3
4
5
6
7
8
9
10
11
# 특정 네트워크로 가는 라우트 추가
ip route add 10.0.0.0/24 via 192.168.1.254 dev eth0

# 기본 게이트웨이 설정
ip route add default via 192.168.1.1

# 라우트 삭제
ip route del 10.0.0.0/24

# 특정 인터페이스로 직접 전달
ip route add 192.168.2.0/24 dev eth1

정책 기반 라우팅 (Policy-based Routing)

단순 목적지 주소 외에 다른 조건으로도 라우팅 가능:

  • 출발지 IP 주소
  • TOS (Type of Service)
  • 방화벽 마크
1
2
3
4
5
6
7
8
# 출발지 기반 라우팅 테이블 생성
ip route add default via 192.168.2.1 table 100

# 출발지 IP에 따라 라우팅 테이블 선택
ip rule add from 10.0.1.0/24 table 100

# 규칙 확인
ip rule show

3.4 소켓과 포트

소켓의 개념

소켓은 네트워크 통신의 종단점이다. 애플리케이션은 소켓을 통해 네트워크 I/O를 수행한다.

소켓 타입

Stream Socket (SOCK_STREAM)

  • TCP 기반
  • 연결 지향, 신뢰성 보장
  • 바이트 스트림

Datagram Socket (SOCK_DGRAM)

  • UDP 기반
  • 비연결, 메시지 경계 보존

Raw Socket (SOCK_RAW)

  • IP 계층 직접 접근
  • 커스텀 프로토콜 구현 가능
  • root 권한 필요

소켓 프로그래밍 흐름

서버 측

  1. socket() - 소켓 생성
  2. bind() - 로컬 주소/포트 바인딩
  3. listen() - 연결 대기 상태로 전환
  4. accept() - 클라이언트 연결 수락
  5. recv()/send() - 데이터 송수신
  6. close() - 소켓 종료

클라이언트 측

  1. socket() - 소켓 생성
  2. connect() - 서버에 연결
  3. send()/recv() - 데이터 송수신
  4. close() - 소켓 종료

소켓 상태 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 모든 소켓 확인
ss -tuln

# TCP 소켓만
ss -tln

# UDP 소켓만
ss -uln

# 프로세스 정보 포함
ss -tlnp

# netstat (구형 도구)
netstat -tuln

소켓 상태

TCP 소켓은 다양한 상태를 가진다:

  • LISTEN: 연결 대기 중
  • ESTABLISHED: 연결 확립됨
  • SYN_SENT: SYN 전송 후 ACK 대기
  • SYN_RECEIVED: SYN 수신 후 ACK 대기
  • FIN_WAIT1/2: 연결 종료 진행 중
  • TIME_WAIT: 연결 종료 후 대기
  • CLOSE_WAIT: 원격 종료 대기
  • CLOSED: 소켓 닫힘

포트 바인딩 이슈

Address already in use 에러

이미 사용 중인 포트에 바인딩 시도 시 발생:

1
2
3
4
5
6
# 해당 포트를 사용 중인 프로세스 확인
lsof -i :8080
ss -tlnp | grep :8080

# TIME_WAIT 상태의 소켓 때문일 수 있음
# SO_REUSEADDR 소켓 옵션으로 해결

권한 문제

1024 이하 포트는 root 권한 필요:

  • CAP_NET_BIND_SERVICE capability 필요
  • 또는 setcap으로 capability 부여
1
2
# 특정 바이너리에 capability 부여
sudo setcap 'cap_net_bind_service=+ep' /path/to/binary

4. 가상 네트워크 디바이스

4.1 루프백 인터페이스 (lo)

루프백의 개념

루프백 인터페이스는 자기 자신과 통신하기 위한 가상 인터페이스이다:

  • 항상 127.0.0.1 (IPv4) 또는 ::1 (IPv6)
  • 물리적 네트워크 카드 없이 동작
  • 로컬 프로세스 간 네트워크 통신에 사용

루프백의 용도

  • 로컬 서비스 테스트
  • 프로세스 간 TCP/IP 통신
  • localhost로 바인딩된 서비스 접근
  • 네트워크 프로그래밍 학습

특징

  • MTU가 매우 큼 (보통 65536 바이트)
  • 실제 네트워크를 거치지 않아 매우 빠름
  • 패킷이 NIC를 거치지 않고 커널 내부에서만 처리

4.2 TUN/TAP 디바이스

TUN/TAP의 개념

TUN과 TAP는 사용자 공간 프로그램이 네트워크 패킷을 직접 처리할 수 있게 하는 가상 인터페이스이다.

TUN vs TAP

TUN (Network TUNnel)

  • OSI 3계층 (Network Layer) 디바이스
  • IP 패킷 처리
  • VPN에서 주로 사용

TAP (Network TAP)

  • OSI 2계층 (Data Link Layer) 디바이스
  • Ethernet 프레임 처리
  • 브리지, 가상 머신 네트워킹에 사용

작동 원리

  1. 커널이 TUN/TAP 디바이스로 패킷 전송
  2. 사용자 공간 프로그램이 패킷 읽기
  3. 프로그램이 패킷 처리 (암호화, 터널링 등)
  4. 처리된 패킷을 다시 디바이스에 쓰기

사용 사례

VPN (Virtual Private Network)

  • OpenVPN, WireGuard 등
  • 암호화된 터널 생성

네트워크 에뮬레이션

  • 패킷 지연, 손실 시뮬레이션
  • 네트워크 조건 테스트

가상화

  • QEMU, VirtualBox 등
  • VM의 네트워크 인터페이스

4.3 veth pair (Virtual Ethernet)

veth pair의 개념

veth pair는 두 개의 가상 이더넷 인터페이스가 쌍으로 연결된 것이다. 마치 양쪽 끝에 네트워크 카드가 달린 가상 케이블과 같다.

특징

  • 한쪽 끝에서 전송한 패킷이 다른 쪽 끝에서 수신됨
  • 양방향 통신 가능
  • 서로 다른 네트워크 네임스페이스를 연결하는 데 사용
  • 컨테이너 네트워킹의 주요 컴포넌트

작동 원리

  • veth0과 veth1이 쌍으로 생성
  • veth0으로 전송된 패킷은 veth1에서 수신
  • veth1으로 전송된 패킷은 veth0에서 수신

생성 및 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# veth pair 생성
ip link add veth0 type veth peer name veth1

# 상태 확인
ip link show

# veth0을 기본 네임스페이스에, veth1을 다른 네임스페이스에 배치
ip netns add netns1
ip link set veth1 netns netns1

# IP 주소 할당
ip addr add 10.0.0.1/24 dev veth0
ip netns exec netns1 ip addr add 10.0.0.2/24 dev veth1

# 인터페이스 활성화
ip link set veth0 up
ip netns exec netns1 ip link set veth1 up

# 연결 테스트
ping 10.0.0.2

컨테이너에서의 사용

Docker 컨테이너가 생성될 때:

  1. veth pair 생성
  2. 한쪽 끝은 컨테이너의 네트워크 네임스페이스에 배치 (eth0으로 이름 변경)
  3. 다른 쪽 끝은 호스트의 브리지(docker0)에 연결
  4. 컨테이너는 veth를 통해 외부와 통신

4.4 Linux Bridge

Linux Bridge의 개념

Linux Bridge는 소프트웨어로 구현된 L2 스위치이다. 여러 네트워크 인터페이스를 연결하여 하나의 네트워크 세그먼트를 만든다.

작동 원리

  • 물리적 스위치처럼 MAC 주소 학습
  • MAC 주소 테이블 유지
  • 프레임을 적절한 포트로 포워딩
  • 브로드캐스트는 모든 포트로 전달

브리지 생성 및 관리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 브리지 생성
ip link add br0 type bridge

# 브리지 활성화
ip link set br0 up

# 인터페이스를 브리지에 추가
ip link set eth0 master br0
ip link set veth0 master br0

# 브리지에서 인터페이스 제거
ip link set eth0 nomaster

# 브리지 삭제
ip link delete br0

# 브리지 상태 확인
bridge link show
ip link show master br0

브리지 네트워크 설정

1
2
3
4
5
# 브리지에 IP 주소 할당
ip addr add 192.168.100.1/24 dev br0

# 브리지가 게이트웨이 역할
# 연결된 디바이스들은 192.168.100.0/24 네트워크에 속함

Docker와 브리지

Docker는 기본적으로 docker0 브리지를 생성:

1
2
3
4
5
6
7
8
# docker0 브리지 확인
ip link show docker0
brctl show docker0  # bridge-utils 패키지 필요

# 컨테이너가 시작되면:
# 1. veth pair 생성
# 2. 한쪽은 컨테이너 네임스페이스의 eth0
# 3. 다른 쪽은 docker0 브리지에 연결

브리지 vs NAT

브리지는 L2(링크 계층)에서 작동:

  • MAC 주소 기반 포워딩
  • 같은 서브넷에 있는 것처럼 동작
  • 브리지에 연결된 모든 디바이스가 같은 브로드캐스트 도메인

NAT는 L3(네트워크 계층)에서 작동:

  • IP 주소 변환
  • 다른 서브넷 간 통신

4.5 VLAN

VLAN의 개념

VLAN(Virtual LAN)은 물리적 네트워크를 논리적으로 분할하는 기술이다.

VLAN의 장점

  • 하나의 물리적 스위치로 여러 독립된 네트워크 구성
  • 브로드캐스트 도메인 분리
  • 보안 향상 (VLAN 간 격리)
  • 유연한 네트워크 관리

VLAN 태깅 (802.1Q)

Ethernet 프레임에 4바이트 VLAN 태그 추가:

  • 12비트 VLAN ID (1-4094)
  • VLAN 0: 우선순위만 표시
  • VLAN 1: 기본 VLAN

Linux에서 VLAN 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# VLAN 인터페이스 생성 (eth0.10 = eth0의 VLAN 10)
ip link add link eth0 name eth0.10 type vlan id 10

# IP 주소 할당
ip addr add 192.168.10.1/24 dev eth0.10

# 활성화
ip link set eth0.10 up

# 삭제
ip link delete eth0.10

# 확인
cat /proc/net/vlan/config

VLAN과 컨테이너

컨테이너를 서로 다른 VLAN에 배치하여 네트워크 격리:

  • 각 VLAN마다 별도의 브리지 생성
  • 컨테이너를 특정 브리지에 연결
  • VLAN 간 통신은 라우터를 통해서만 가능

5. 네트워크 네임스페이스

5.1 네트워크 네임스페이스의 개념

Network Namespace란?

네트워크 네임스페이스는 네트워크 스택 전체를 격리하는 Linux 커널 기능이다. 각 네트워크 네임스페이스는 독립된 네트워크 환경을 가진다:

  • 독립적인 네트워크 인터페이스
  • 독립적인 라우팅 테이블
  • 독립적인 iptables 규칙
  • 독립적인 네트워크 통계
  • 독립적인 소켓

왜 필요한가?

  • 컨테이너마다 독립된 네트워크 환경 제공
  • 네트워크 격리 및 보안
  • 테스트 환경 구축
  • VPN이나 특수 네트워크 설정 격리

5.2 네트워크 네임스페이스 관리

네임스페이스 생성 및 관리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 네트워크 네임스페이스 생성
ip netns add netns1

# 네임스페이스 목록 확인
ip netns list

# 네임스페이스 내에서 명령 실행
ip netns exec netns1 <command>

# 예: 네임스페이스의 인터페이스 확인
ip netns exec netns1 ip link show

# 네임스페이스 삭제
ip netns delete netns1

네임스페이스 간 통신 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# veth pair 생성
ip link add veth0 type veth peer name veth1

# veth1을 netns1로 이동
ip link set veth1 netns netns1

# 호스트 측 설정
ip addr add 10.0.0.1/24 dev veth0
ip link set veth0 up

# 네임스페이스 내부 설정
ip netns exec netns1 ip addr add 10.0.0.2/24 dev veth1
ip netns exec netns1 ip link set veth1 up
ip netns exec netns1 ip link set lo up

# 통신 테스트
ping 10.0.0.2
ip netns exec netns1 ping 10.0.0.1

5.3 네임스페이스 격리의 범위

격리되는 것

  • 네트워크 인터페이스 (lo, eth0 등)
  • IP 주소
  • 라우팅 테이블
  • iptables 규칙
  • ARP 테이블
  • /proc/net/* 내용
  • 소켓 및 네트워크 통계

격리되지 않는 것

  • 파일 시스템 (별도의 Mount Namespace 필요)
  • 프로세스 (별도의 PID Namespace 필요)
  • 사용자/그룹 (별도의 User Namespace 필요)
  • 호스트명 (별도의 UTS Namespace 필요)

5.4 컨테이너와 네트워크 네임스페이스

Docker의 네트워크 네임스페이스 사용

Docker 컨테이너가 시작될 때:

  1. 새로운 네트워크 네임스페이스 생성
  2. veth pair 생성
  3. 한쪽 끝을 컨테이너의 네임스페이스에 배치 (eth0으로 이름 변경)
  4. 다른 쪽 끝을 호스트의 docker0 브리지에 연결
  5. 컨테이너에 IP 주소 할당
  6. 기본 게이트웨이 설정

네임스페이스 확인

1
2
3
4
5
6
7
8
9
10
11
# 실행 중인 컨테이너의 네트워크 네임스페이스 찾기
docker inspect <container_id> | grep SandboxKey

# 또는
docker inspect -f '' <container_id>

# 네임스페이스로 진입
nsenter --net=/var/run/docker/netns/<namespace_id> <command>

# 예: 네임스페이스 내부의 인터페이스 확인
nsenter --net=/var/run/docker/netns/<namespace_id> ip addr show

호스트 네트워크 모드

컨테이너가 호스트의 네트워크 네임스페이스를 공유:

1
docker run --network host <image>

이 경우:

  • 네트워크 격리 없음
  • 컨테이너가 호스트의 모든 네트워크 인터페이스 접근
  • 포트 매핑 불필요
  • 성능은 좋지만 보안은 약함

6. iptables와 Netfilter

6.1 Netfilter 프레임워크

Netfilter란?

Netfilter는 Linux 커널 내부의 패킷 필터링 프레임워크이다. 네트워크 패킷을 가로채서 검사, 수정, 차단할 수 있다.

Netfilter Hooks

Netfilter는 패킷 처리 경로에 5개의 훅 포인트를 제공한다:

PREROUTING

  • 라우팅 결정 전
  • 패킷이 시스템에 도착한 직후
  • DNAT (Destination NAT)에 사용

INPUT

  • 로컬 프로세스로 전달되는 패킷
  • 방화벽 규칙 적용

FORWARD

  • 라우팅되어 다른 인터페이스로 전달되는 패킷
  • 라우터나 브리지 역할 시 사용

OUTPUT

  • 로컬 프로세스에서 생성된 패킷
  • 라우팅 결정 전

POSTROUTING

  • 라우팅 결정 후
  • 패킷이 시스템을 떠나기 직전
  • SNAT (Source NAT), Masquerade에 사용

6.2 iptables 기본

iptables의 개념

iptables는 Netfilter를 설정하는 사용자 공간 도구이다. 방화벽 규칙, NAT, 패킷 필터링 등을 설정한다.

iptables 구조

테이블 (Tables)

iptables는 여러 테이블을 가지며, 각 테이블은 특정 목적을 가진다:

filter 테이블 (기본)

  • 패킷 필터링 (허용/차단)
  • 체인: INPUT, OUTPUT, FORWARD

nat 테이블

  • 주소 변환 (NAT)
  • 체인: PREROUTING, OUTPUT, POSTROUTING

mangle 테이블

  • 패킷 헤더 수정
  • QoS, TTL 변경 등

raw 테이블

  • 연결 추적 제외
  • 성능 최적화

체인 (Chains)

각 테이블은 여러 체인을 가지며, 체인은 규칙들의 리스트이다:

  • 내장 체인: INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING
  • 사용자 정의 체인: 복잡한 규칙을 모듈화

규칙 (Rules)

각 규칙은 다음을 포함:

  • 매칭 조건: 출발지 IP, 목적지 IP, 프로토콜, 포트 등
  • 타겟 (Target): 패킷을 어떻게 처리할지
    • ACCEPT: 패킷 허용
    • DROP: 패킷 버림 (응답 없음)
    • REJECT: 패킷 거부 (ICMP 에러 응답)
    • LOG: 패킷 로깅
    • MASQUERADE: 동적 SNAT
    • DNAT: 목적지 주소 변환
    • SNAT: 출발지 주소 변환

6.3 iptables 사용법

기본 명령

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 규칙 목록 확인
iptables -L -n -v

# 특정 테이블의 규칙 확인
iptables -t nat -L -n -v

# 규칙 추가 (체인 끝에)
iptables -A INPUT -s 192.168.1.100 -j DROP

# 규칙 삽입 (특정 위치에)
iptables -I INPUT 1 -s 192.168.1.100 -j DROP

# 규칙 삭제
iptables -D INPUT -s 192.168.1.100 -j DROP

# 규칙 번호로 삭제
iptables -D INPUT 1

# 체인의 모든 규칙 삭제
iptables -F INPUT

# 모든 규칙 삭제
iptables -F

방화벽 규칙 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 특정 IP 차단
iptables -A INPUT -s 192.168.1.100 -j DROP

# 특정 포트 허용 (SSH)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 특정 포트 범위 허용
iptables -A INPUT -p tcp --dport 8000:9000 -j ACCEPT

# 확립된 연결 허용
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 로컬 루프백 허용
iptables -A INPUT -i lo -j ACCEPT

# 기본 정책 설정
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

NAT 규칙 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 출발지 NAT (SNAT) - 고정 IP
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.5

# Masquerade - 동적 IP
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# 목적지 NAT (DNAT) - 포트 포워딩
iptables -t nat -A PREROUTING -p tcp --dport 8080 \
  -j DNAT --to-destination 192.168.1.10:80

# 로드 밸런싱 (round-robin)
iptables -t nat -A PREROUTING -p tcp --dport 80 \
  -m statistic --mode nth --every 2 --packet 0 \
  -j DNAT --to-destination 192.168.1.10
iptables -t nat -A PREROUTING -p tcp --dport 80 \
  -m statistic --mode nth --every 2 --packet 1 \
  -j DNAT --to-destination 192.168.1.11

연결 추적 (Connection Tracking)

1
2
3
4
5
6
7
8
9
10
# NEW: 새로운 연결
# ESTABLISHED: 기존 연결의 일부
# RELATED: 관련 연결 (예: FTP 데이터 연결)
# INVALID: 추적할 수 없는 패킷

# 확립된 연결 허용
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 새 연결은 특정 포트만 허용
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

6.4 Docker와 iptables

Docker의 iptables 사용

Docker는 컨테이너 네트워킹을 위해 iptables를 광범위하게 사용한다:

컨테이너 격리

1
2
3
4
# Docker가 자동으로 추가하는 규칙 예시
iptables -t filter -N DOCKER
iptables -t filter -A FORWARD -j DOCKER
iptables -t filter -A DOCKER -i docker0 -o docker0 -j DROP

포트 매핑 (포트 포워딩)

1
2
3
4
5
# docker run -p 8080:80
# 호스트의 8080 포트를 컨테이너의 80 포트로 포워딩

iptables -t nat -A DOCKER -p tcp --dport 8080 \
  -j DNAT --to-destination 172.17.0.2:80

NAT (Masquerade)

1
2
3
# 컨테이너가 외부와 통신할 수 있도록 NAT 설정
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 \
  -o eth0 -j MASQUERADE

Docker 체인 확인

1
2
3
4
5
6
7
# Docker가 생성한 체인들
iptables -t nat -L -n | grep DOCKER
iptables -t filter -L -n | grep DOCKER

# DOCKER 체인
# DOCKER-ISOLATION 체인
# DOCKER-USER 체인 (사용자 정의 규칙용)

Docker와 iptables 충돌 방지

Docker가 iptables 규칙을 자동 관리하므로 주의 필요:

  • DOCKER-USER 체인에 사용자 규칙 추가 권장
  • Docker 재시작 시 규칙 초기화 가능
  • iptables-persistent 등으로 규칙 영구 저장

6.5 nftables (iptables의 후속)

nftables란?

nftables는 iptables를 대체하는 차세대 패킷 필터링 프레임워크이다:

  • 더 간결한 문법
  • 더 나은 성능
  • 통합된 인터페이스 (iptables, ip6tables, arptables, ebtables 통합)
  • 커널 5.0 이상에서 권장

기본 사용법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 규칙 확인
nft list ruleset

# 테이블 생성
nft add table inet filter

# 체인 생성
nft add chain inet filter input { type filter hook input priority 0 \; }

# 규칙 추가
nft add rule inet filter input tcp dport 22 accept

# 규칙 삭제
nft delete table inet filter

7. 라우팅과 포워딩

7.1 IP 포워딩

IP 포워딩이란?

IP 포워딩은 한 인터페이스로 수신한 패킷을 다른 인터페이스로 전달하는 기능이다. 리눅스 호스트를 라우터로 사용하려면 반드시 활성화해야 한다.

IP 포워딩 활성화

1
2
3
4
5
6
7
8
9
10
# 현재 설정 확인
cat /proc/sys/net/ipv4/ip_forward

# 임시로 활성화 (재부팅 시 초기화)
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1

# 영구 활성화
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

IPv6 포워딩

1
2
3
# IPv6 포워딩 활성화
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
sysctl -w net.ipv6.conf.all.forwarding=1

포워딩이 필요한 경우

  • 라우터 구성
  • NAT 게이트웨이
  • VPN 서버
  • Docker 호스트 (컨테이너 간 통신)
  • 브리지 네트워크

7.2 라우팅 결정 과정

라우팅 알고리즘

패킷의 목적지를 결정하는 과정:

  1. Longest Prefix Match
    • 목적지 IP와 가장 길게 매칭되는 라우트 선택
    • 예: 192.168.1.10은 192.168.1.0/24가 192.168.0.0/16보다 우선
  2. Metric 비교
    • 같은 prefix length면 metric이 낮은 것 선택
    • Metric: 경로의 비용 또는 우선순위
  3. 로컬 전달 vs 포워딩
    • 목적지가 로컬 인터페이스: INPUT 체인으로
    • 목적지가 다른 네트워크: FORWARD 체인으로

라우팅 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
# 라우팅 테이블
# default via 192.168.1.1 dev eth0
# 192.168.1.0/24 dev eth0 proto kernel scope link
# 10.0.0.0/8 via 192.168.1.254 dev eth0

# 목적지 192.168.1.50
# → 192.168.1.0/24 매칭, eth0로 직접 전달

# 목적지 10.20.30.40
# → 10.0.0.0/8 매칭, 192.168.1.254로 전달

# 목적지 8.8.8.8
# → default 매칭, 192.168.1.1로 전달

7.3 다중 라우팅 테이블

정책 기반 라우팅

Linux는 여러 라우팅 테이블을 지원하며, 규칙에 따라 테이블을 선택할 수 있다.

라우팅 테이블 확인

1
2
3
4
5
6
7
8
# 메인 라우팅 테이블
ip route show table main

# 특정 테이블 확인
ip route show table 100

# 모든 테이블 목록
cat /etc/iproute2/rt_tables

규칙 기반 라우팅 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 테이블 100 생성 및 라우트 추가
ip route add default via 192.168.2.1 table 100

# 출발지 IP 기반 규칙
ip rule add from 10.0.1.0/24 table 100

# 특정 인터페이스 기반
ip rule add iif eth1 table 100

# 방화벽 마크 기반
iptables -t mangle -A PREROUTING -s 10.0.1.0/24 -j MARK --set-mark 1
ip rule add fwmark 1 table 100

# 규칙 확인
ip rule show

사용 사례

  • 멀티-ISP 환경 (로드 밸런싱)
  • VPN 트래픽 분리
  • 특정 애플리케이션 트래픽 라우팅
  • 출발지 기반 정책 라우팅

7.4 컨테이너 라우팅

Docker 네트워크 라우팅

Docker 컨테이너의 라우팅 구조:

컨테이너 내부 라우팅

1
2
3
4
5
6
# 컨테이너 내부에서 확인
docker exec <container_id> ip route show

# 일반적인 구조:
# default via 172.17.0.1 dev eth0
# 172.17.0.0/16 dev eth0 scope link

호스트 라우팅

1
2
3
4
# 호스트에서 Docker 네트워크 라우팅
ip route show

# 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1

외부 통신 흐름

  1. 컨테이너(172.17.0.2) → 외부(8.8.8.8) 패킷 전송
  2. 컨테이너의 기본 게이트웨이(172.17.0.1 = docker0)로 전달
  3. 호스트의 라우팅 테이블 조회
  4. POSTROUTING에서 SNAT/Masquerade 적용
  5. 호스트의 eth0로 나가면서 출발지 IP가 호스트 IP로 변경

Kubernetes 네트워크 라우팅

Kubernetes는 더 복잡한 라우팅을 사용:

  • 각 노드는 Pod CIDR 블록 할당
  • CNI 플러그인이 라우팅 구성
  • 노드 간 라우팅 (Overlay 또는 라우팅 프로토콜)

This post is licensed under CC BY 4.0 by the author.