icon

안동민 개발노트

10장 : HTTPS와 네트워크 보안

네트워크 보안 위협과 방어


암호화와 인증서가 통신의 기밀성과 무결성을 보호한다면, 이 절에서는 네트워크 자체를 위협하는 공격과 그 방어 전략을 살펴보겠습니다.


중간자 공격 (MITM)

MITM(Man-In-The-Middle) 공격은 통신하는 두 당사자 사이에 공격자가 끼어들어, 트래픽을 도청하거나 변조하는 공격입니다.

MITM 공격 시나리오
정상 통신
  Alice ──────────────────→ Bob
         "안녕하세요"

MITM 공격
  Alice ─────→ 공격자(Eve) ─────→ Bob
         "안녕하세요"   "안녕하세요"
                        (도청 완료)
  또는
  Alice ─────→ 공격자(Eve) ─────→ Bob
         "100만원 송금"   "1000만원 송금"
                          (변조!)
MITM 공격 유형별 동작
1. ARP 스푸핑 (LAN)
   공격자: "게이트웨이 MAC은 나야" (거짓 ARP 응답)
   → 피해자의 트래픽이 공격자를 경유

2. 가짜 Wi-Fi AP
   공격자: "무료 와이파이" SSID로 AP 생성
   → 연결한 사용자의 모든 트래픽 중계/도청

3. DNS 스푸핑
   공격자: bank.com → 가짜 서버 IP로 DNS 응답 조작
   → 피해자가 가짜 사이트에 로그인 정보 입력

4. SSL 스트리핑
   공격자: HTTPS → HTTP로 다운그레이드
   → 피해자는 HTTP로 통신 중인지 모름

   피해자 ←─ HTTP ─→ 공격자 ←─ HTTPS ─→ 실제 서버

HTTPS(TLS)는 MITM에 대한 가장 효과적인 방어입니다.

TLS가 MITM을 방어하는 원리
공격자가 중간에서 가로채려 해도

  1. 인증서 검증: 공격자가 bank.com의 인증서를 위조할 수 없음
     → CA의 개인키 없이는 유효한 인증서 서명 불가
     → 브라우저가 즉시 경고 표시

  2. 암호화: 데이터를 가로채도 복호화 불가
     → 세션 키를 모르면 평문을 얻을 수 없음

  3. HSTS: HTTP → HTTPS 리디렉션을 강제
     → SSL 스트리핑 방지
     → Strict-Transport-Security 헤더

하지만 방어가 무력화되는 경우
  * 사용자가 인증서 경고를 무시하고 진행
  * 기업 환경에서 내부 루트 CA 설치 (SSL 검사 프록시)
  * 피해자 기기에 악성 루트 인증서 설치됨

DDoS 공격과 방어 전략

DDoS(Distributed Denial of Service)는 대량의 트래픽을 한꺼번에 보내 서버나 네트워크를 마비시키는 공격입니다.

DDoS 공격 계층별 분류
OSI 계층       공격 유형               특징
──────────────────────────────────────────────────────
L3/L4          볼류메트릭              대역폭 자체를 고갈
(네트워크/     ┌ UDP Flood            대량의 UDP 패킷
 전송)         ├ ICMP Flood           대량의 Ping
               └ DNS Amplification    증폭 공격

L4             프로토콜                연결 자원 고갈
(전송)         ┌ SYN Flood            반개방 연결 누적
               └ ACK Flood            상태 테이블 소모

L7             애플리케이션            서버 연산 자원 고갈
(애플리케이션) ┌ HTTP Flood           대량의 정상적 요청
               ├ Slowloris            연결을 천천히 유지
               └ API 남용             복잡한 쿼리 반복
DNS Amplification 공격 원리
공격자 ── 출발지 IP를 피해자 IP로 위조 ──→ DNS 서버
  작은 질의 (60 bytes)                    ↓
  "ANY google.com?"                   큰 응답 (4000 bytes)

                              피해자 서버 ←────────────
                              (응답의 홍수!)
                              증폭 비율: ~60배
                              1 Gbps 공격 → 60 Gbps 피해

Memcached Amplification: 증폭 비율 ~50,000배!
NTP Amplification: 증폭 비율 ~550배
방어 전략대상 계층동작 방식예시
CDN/AntiDDoSL3-L7트래픽 분산, 엣지 필터링Cloudflare, AWS Shield
Rate LimitingL7IP당 요청 수 제한Nginx limit_req
SYN 쿠키L4상태 없이 SYN 검증Linux tcp_syncookies
AnycastL3트래픽을 전 세계에 분산DNS, CDN
블랙홀 라우팅L3공격 IP를 null route로 폐기최후의 수단
지리 차단L3특정 국가/지역 IP 차단서비스 대상 외 지역
CAPTCHAL7봇 vs 사람 구분로그인, 검색

방화벽과 ACL

방화벽(Firewall)은 네트워크 트래픽을 규칙에 기반하여 허용하거나 차단하는 보안 장치입니다.

방화벽 유형 비교
패킷 필터 방화벽
  ┌──────────────────────────────────┐
  │ 규칙: 출발지IP → 목적지IP:포트   │
  │ ALLOW 10.0.0.0/8 → ANY:80        │
  │ ALLOW 10.0.0.0/8 → ANY:443       │
  │ DENY  ANY → ANY:22               │
  │ DENY  ANY → ANY                  │ ← 기본 거부
  └──────────────────────────────────┘
  * 각 패킷을 독립적으로 판단
  * 단순하고 빠름, 하지만 연결 상태 모름

상태 기반 방화벽 (Stateful)
  ┌────────────────────────────────────┐
  │ 연결 상태 테이블                   │
  │ SRC:10.0.0.5:54321 → DST:80        │
  │   상태: ESTABLISHED                │
  │   → 이 연결의 응답 패킷은 자동 허용│
  └────────────────────────────────────┘
  * 연결의 맥락을 추적
  * "내부에서 시작한 연결의 응답만 허용"

차세대 방화벽 (NGFW)
  * 패킷 내용(L7)까지 분석
  * 애플리케이션 식별 (YouTube, Slack 등)
  * IDS/IPS 통합
  * SSL 복호화/검사
AWS 보안 그룹 vs NACL
                      ┌───────────────────┐
                      │      VPC          │
                      │  ┌─── NACL ───┐   │
                      │  │            │   │
                      │  │  ┌───────┐ │   │
                      │  │  │ 보안  │ │   │
                      │  │  │ 그룹  │ │   │
                      │  │  │ ┌───┐ │ │   │
                      │  │  │ │EC2│ │ │   │
                      │  │  │ └───┘ │ │   │
                      │  │  └───────┘ │   │
                      │  └────────────┘   │
                      └───────────────────┘

항목          보안 그룹          NACL
─────────────────────────────────────────
적용 대상     인스턴스(ENI)      서브넷
상태          Stateful          Stateless
규칙          허용만 가능        허용/거부 가능
순서          모든 규칙 평가     번호 순서대로
기본          모든 아웃바운드 허용 모든 트래픽 허용

WAF

WAF(Web Application Firewall)는 HTTP 계층에서 동작하는 방화벽입니다. 일반 방화벽이 IP와 포트 수준에서 필터링한다면, WAF는 HTTP 요청의 내용을 분석합니다.

WAF가 탐지하는 공격 패턴
SQL Injection
  요청: GET /users?id=1 OR 1=1--
  WAF: "OR 1=1" 패턴 탐지 → 차단!

XSS (Cross-Site Scripting)
  요청: POST /comment body: <script>alert(1)</script>
  WAF: "<script>" 태그 탐지 → 차단!

Path Traversal
  요청: GET /files/../../../etc/passwd
  WAF: "../" 패턴 탐지 → 차단!

Command Injection
  요청: GET /ping?host=8.8.8.8;rm -rf /
  WAF: ";" + 시스템 명령 패턴 → 차단!
다층 방어 (Defense in Depth)
인터넷


┌──────────────┐
│ CDN/DDoS 방어│  L3-L4: 볼류메트릭 공격 흡수
└──────┬───────┘

┌──────────────┐
│     WAF      │  L7: SQL Injection, XSS 차단
└──────┬───────┘

┌──────────────┐
│   방화벽     │  L3-L4: IP/포트 기반 필터링
└──────┬───────┘

┌──────────────┐
│ 로드 밸런서  │  트래픽 분산, 헬스 체크
└──────┬───────┘

┌──────────────┐
│ 애플리케이션 │  입력 검증, 인증/인가
│ (코드 수준)  │  Parameterized Query, CSP
└──────┬───────┘

┌──────────────┐
│ 데이터베이스 │  최소 권한, 암호화
└──────────────┘

어느 한 계층이 뚫려도 다음 계층이 방어
→ "단일 방어점(Single Point of Failure)" 방지
보안 도구계층역할대표 제품
IDSL3-L7침입 탐지 (알림만)Snort, Suricata
IPSL3-L7침입 탐지 + 차단Snort inline
WAFL7웹 공격 차단AWS WAF, ModSecurity
SIEM전 계층로그 분석, 이상 탐지Splunk, ELK Stack
EDR엔드포인트기기 수준 위협 탐지CrowdStrike
rate_limiter.py
import time
from collections import defaultdict

class RateLimiter:
    """토큰 버킷 알고리즘 기반 Rate Limiter"""
    def __init__(self, max_tokens, refill_rate):
        self.max_tokens = max_tokens
        self.refill_rate = refill_rate  # 초당 충전 토큰 수
        self.buckets = defaultdict(lambda: {
            'tokens': max_tokens,
            'last_refill': time.time()
        })

    def allow_request(self, client_ip):
        bucket = self.buckets[client_ip]
        now = time.time()
        elapsed = now - bucket['last_refill']
        bucket['tokens'] = min(
            self.max_tokens,
            bucket['tokens'] + elapsed * self.refill_rate
        )
        bucket['last_refill'] = now

        if bucket['tokens'] >= 1:
            bucket['tokens'] -= 1
            return True  # 요청 허용
        return False  # 429 Too Many Requests

# 사용: 초당 10개 요청, 버스트 최대 20개
limiter = RateLimiter(max_tokens=20, refill_rate=10)

# 요청 처리
for i in range(25):
    ip = "192.168.1.100"
    if limiter.allow_request(ip):
        print(f"요청 {i+1}: 허용")
    else:
        print(f"요청 {i+1}: 차단 (Rate Limit 초과)")

다음 장에서는 네트워크 이론을 코드로 직접 구현해 보는 소켓 프로그래밍을 다루겠습니다.

목차