네트워크 보안 위협과 방어
암호화와 인증서가 통신의 기밀성과 무결성을 보호한다면, 이 절에서는 네트워크와 애플리케이션을 노리는 대표 공격과 방어 전략을 살펴보겠습니다. 보안 방어는 보통 한 장비나 한 헤더로 끝나지 않고, 예방, 탐지, 완화, 복구를 계층별로 조합해야 합니다.
중간자 공격(MITM)
MITM(Man-In-The-Middle)은 통신하는 두 당사자 사이에 공격자가 끼어들어 트래픽을 도청하거나 변조하려는 공격입니다. 같은 Wi-Fi, 악성 프록시, DNS/ARP 조작, 위조 인증서 설치 같은 경로로 시도될 수 있습니다.
HTTPS(TLS)는 MITM의 도청·변조 성공 가능성을 크게 낮추지만, 핵심은 단순 암호화가 아니라 서버 인증, 키 교환 무결성, 전송 데이터 보호입니다. 클라이언트가 인증서 체인과 호스트 이름을 검증하지 않거나, 사용자가 인증서 경고를 무시하거나, 기기에 악성 루트 인증서가 설치되면 보호가 약해질 수 있습니다. HSTS는 HTTPS 강제를 통해 downgrade/SSL stripping 위험을 줄이는 데 도움이 됩니다.
DDoS 공격과 계층별 방어
DDoS(Distributed Denial of Service)는 여러 출처에서 대량의 트래픽이나 비싼 요청을 보내 서버, 네트워크, 애플리케이션의 가용성을 떨어뜨리는 공격입니다. 공격 대상에 따라 L3/L4 대역폭·상태 고갈형과 L7 애플리케이션 고비용 요청형으로 나눠 볼 수 있고, 방어는 ISP/클라우드 스크러빙, Anycast/CDN, L3/L4 필터링, SYN 보호, 큐잉, L7 rate limit/WAF를 조합합니다.
| 방어 전략 | 대상 계층 | 동작 방식 | 주의점 |
|---|---|---|---|
| CDN/Anti-DDoS | L3-L7 | 엣지에서 흡수·필터링·캐시 | 원본 IP 노출과 우회 경로 차단 필요 |
| Anycast | L3 | 같은 IP를 여러 지역에서 광고해 분산 | 라우팅 정책과 용량 계획이 중요 |
| Rate Limiting | L7 | 사용자·IP·토큰별 요청량 제한 | 프록시·NAT·분산 공격에 취약할 수 있음 |
| SYN Cookies | L4 | 연결 상태를 늦게 만들며 SYN flood 완화 | 모든 TCP 공격을 해결하지는 않음 |
| Ingress Filtering | L3 | 스푸핑된 출발지 주소를 네트워크 경계에서 차단 | 운영자 간 협력이 필요 |
| WAF/Bot 관리 | L7 | HTTP 패턴, 평판, 챌린지로 필터링 | 오탐·우회·정상 사용자 영향 관리 필요 |
| Blackhole Routing | L3 | 특정 목적지 트래픽을 폐기 | 서비스도 함께 중단될 수 있는 최후 수단 |
DNS amplification 같은 반사 공격은 공격자가 출발지 IP를 피해자로 위조하고, 공개된 재귀 DNS(open resolver)가 큰 DNS 응답을 피해자에게 보내게 만드는 방식입니다. 증폭률은 쿼리 타입, EDNS0, DNSSEC, 응답 크기, 서버 설정에 따라 달라집니다. 이런 공격은 서비스 앞단의 흡수 능력뿐 아니라, 네트워크 운영자의 스푸핑 차단과 open resolver 관리가 같이 필요합니다.
방화벽과 ACL
방화벽(Firewall)은 네트워크 트래픽을 규칙에 따라 허용하거나 차단합니다. ACL은 보통 “어떤 출발지/목적지/포트/프로토콜을 허용할지”를 명시하는 규칙 목록이고, stateful firewall은 연결 상태까지 추적합니다.
방화벽은 불필요한 노출면을 줄이는 기본 방어선이지만, 허용된 포트 안에서 발생하는 SQL Injection, XSS, 인증 우회 같은 애플리케이션 취약점까지 자동으로 해결하지는 못합니다. 암호화된 트래픽 내부를 보려면 TLS 복호화 프록시, 내부 인증서 배포, 개인정보·성능 검토가 필요합니다. 그래서 네트워크 방화벽, 보안 그룹, 세그먼테이션, WAF, 애플리케이션 보안 점검을 함께 봐야 합니다.
WAF와 보안 관측
WAF(Web Application Firewall)는 HTTP 계층에서 동작하며 요청의 URL, 헤더, 쿠키, 본문 패턴을 분석해 웹 공격을 탐지하거나 차단합니다. 일반 방화벽이 IP와 포트 중심이라면, WAF는 HTTP 대화의 내용을 다룹니다. 다만 정상 요청처럼 보이는 비즈니스 로직 남용, 인증·인가 오류, 우회 인코딩, API 스키마 미반영, 오탐과 미탐은 애플리케이션 설계와 운영 튜닝으로 함께 다뤄야 합니다.
| 보안 도구 | 계층 | 역할 | 한계 |
|---|---|---|---|
| IDS | L3-L7 | 침입 징후 탐지와 알림 | 직접 차단하지 않는 구성이 많음 |
| IPS | L3-L7 | 탐지 후 인라인 차단 | 오탐이면 정상 트래픽 차단 가능 |
| WAF | L7 | 웹 공격 패턴 탐지·차단 | 비즈니스 로직 취약점은 별도 설계 필요 |
| SIEM | 전 계층 | 로그 상관분석과 경보 | 로그 품질과 룰 튜닝에 성능이 좌우됨 |
| EDR | 엔드포인트 | 단말 행위 기반 탐지·대응 | 네트워크 앞단의 대량 트래픽 흡수와는 다름 |
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_key):
bucket = self.buckets[client_key]
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
# 단일 인스턴스 예시: 초당 10개 요청, 버스트 최대 20개
limiter = RateLimiter(max_tokens=20, refill_rate=10)
for i in range(25):
key = "user:42"
if limiter.allow_request(key):
print(f"요청 {i + 1}: 허용")
else:
print(f"요청 {i + 1}: 제한")위 코드는 알고리즘 이해용입니다. 운영 환경에서는 여러 서버가 동시에 요청을 받으므로 Redis 같은 공유 저장소, 엣지 rate limit, 사용자 ID·IP·토큰 조합 키, 프록시 헤더 신뢰 정책, 모니터링을 함께 설계해야 합니다.
다음 장에서는 네트워크 이론을 코드로 직접 구현해 보는 소켓 프로그래밍을 다루겠습니다.