(5/6) DDoS 방어와 완화 — 탐지부터 스크러빙까지
- DDoS 완전정복 — 개념과 공격 지형도
- 볼류메트릭·반사증폭 공격 — 대역폭을 말려버리는 방법
- 프로토콜·상태 고갈 공격 — 연결 테이블을 터뜨리기
- 애플리케이션 계층(L7) 공격 — 정상 요청처럼 굴며 서버를 태우기
- DDoS 방어와 완화 — 탐지부터 스크러빙까지 ← 지금 글
- 내 사이트 DDoS 내성 테스트 — 합법적으로, 제대로
Summary
앞선 네 편에서 DDoS가 무엇인지, 대역을 채우는 볼류메트릭 공격, TCP·UDP를 노리는 프로토콜 공격, 그리고 정상 요청처럼 굴며 서버를 태우는 L7 공격까지 훑어봤습니다. 이번 편에서는 그 모든 공격을 어떻게 탐지하고 흡수하고 걸러내는지를 정리하려고 해요. 방어는 하나의 마법 스위치가 아니라 여러 계층에 얇은 방벽을 겹쳐 쌓는 일에 가깝습니다. 그리고 이렇게 쌓은 방벽이 진짜로 버티는지는 마지막 편(6편)에서 직접 두들겨 검증해볼 거예요.
💡 이 글에서 다루는 것
- 방어의 큰 그림: 탐지 · 흡수 · 완화의 3단 구조
- 평소 트래픽을 아는 것에서 시작하는 탐지와 오탐 함정
- 네트워크·프로토콜·애플리케이션 계층별 완화 기법
- 스크러빙 센터와 클라우드 실드의 동작 방식
- 사전·공격 중·사후로 나눈 실전 대응 플레이북
1. 방어의 큰 그림 — 탐지 · 흡수 · 완화
DDoS 방어를 처음 고민할 때 흔히 “공격을 완벽하게 차단한다”는 목표를 세우게 되는데요. 현실에서는 그게 잘 통하지 않아요. 초당 수백 기가비트가 밀려드는 트래픽을 서버 앞단에서 0으로 만드는 스위치 같은 건 없습니다. 그래서 방어는 세 가지 동작을 겹쳐서 생각하는 편이 실용적이에요.
- 탐지(Detect) — 지금 들어오는 게 정상인지 공격인지 판단합니다. 평소를 알아야 이상을 압니다.
- 흡수(Absorb) — 용량을 키워서 웬만한 규모는 버텨냅니다. Anycast, CDN, 넉넉한 대역폭이 여기 속해요.
- 완화(Mitigate) — 공격 트래픽만 골라 걸러내고, 정상 사용자는 통과시킵니다. 스크러빙이 이 단계예요.
중요한 건 이 세 동작이 계층마다 다르게 적용된다는 점입니다. 볼류메트릭 공격은 네트워크 상류에서 흡수·완화해야 하고, L7 공격은 애플리케이션 앞단에서 골라내야 해요. 아래 계층에서 못 막은 걸 위 계층에서 또 걸러내는, 이른바 심층방어(defense in depth) 구조로 가는 게 정석입니다.
2. 탐지 — 평소를 알아야 이상을 안다
탐지의 출발점은 언제나 베이스라인이에요. 우리 서비스가 평소 어떤 트래픽 패턴을 갖는지 모르면, 무엇이 비정상인지도 알 수 없습니다. 평일 낮 초당 요청 수, 국가별 분포, 프로토콜 비율, 평균 패킷 크기 같은 걸 꾸준히 기록해 두는 게 먼저예요.
베이스라인이 있으면 이상 탐지(anomaly detection)가 가능해집니다. 주요 신호를 몇 가지 꼽아 볼게요.
- rate 급증 — 초당 요청·연결·패킷 수가 평소 대비 몇 배로 튀는 경우
- 트래픽 지표 변화 — NetFlow·sFlow로 본 대역폭, 신규 연결 비율, SYN 대비 완료 핸드셰이크 비율
- 분포 왜곡 — 특정 URI·특정 국가·특정 User-Agent로 트래픽이 쏠리는 패턴
- 에러율 상승 — 5xx 응답이나 타임아웃이 동반 상승하는 경우
다만 급증이 곧 공격은 아니라는 점을 늘 조심해야 합니다. 뉴스에 소개되거나 세일이 시작되면 정상 사용자가 한꺼번에 몰리는 flash crowd가 생기는데, 지표만 보면 공격과 구별이 잘 안 돼요. 그래서 요청의 정당성(로그인 세션, 결제 전환, 자연스러운 페이지 이동 흐름)까지 함께 봐야 오탐을 줄일 수 있습니다.
⚠️ 탐지 임계값을 너무 빡빡하게 잡으면 정상 급증을 공격으로 오인해 진짜 손님을 막게 됩니다. 완화 조치는 단계적으로(관찰 → 챌린지 → 차단) 올리는 편이 안전해요.
3. 네트워크 계층 완화
네트워크 계층에서는 트래픽이 서버에 도달하기 전, 더 상류에서 처리하는 게 핵심입니다.
BCP38 / uRPF — 스푸핑 차단. 반사·증폭 공격은 대부분 출발지 IP를 위조(spoofing)한 패킷에서 시작해요. 공격자가 피해자의 IP를 출발지로 속여 DNS·NTP 서버에 요청을 던지면, 응답이 피해자에게 쏟아지죠. BCP38(RFC 2827)은 각 네트워크 경계에서 “여기서 나갈 수 없는 출발지 주소를 가진 패킷”을 걸러내자는 원칙입니다. 라우터의 uRPF(unicast Reverse Path Forwarding)가 이를 구현하는 대표적인 방법이에요. 근원에서 스푸핑을 막기 때문에 반사공격의 뿌리 대책으로 불립니다. 다만 우리 혼자 지켜서 되는 게 아니라 전 세계 네트워크가 함께 해야 효과가 커진다는 한계가 있어요.
RTBH — 블랙홀 라우팅. Remote Triggered Black Hole은 공격 대상 IP로 향하는 트래픽을 아예 버리도록 상류에 알리는 기법입니다. BGP로 특정 목적지를 null 경로로 광고해서, 그 IP로 가는 모든 걸 폐기해요. 대역이 완전히 막히는 최악을 피하는 최후의 수단이지만, 문제는 공격 대상 서비스도 함께 죽는다는 점입니다. 공격자의 목표를 대신 달성해 주는 셈이라 정말 급할 때만 씁니다.
Anycast — 공격 분산. 같은 IP를 여러 지역의 서버가 동시에 광고하면, 트래픽은 각자에게 가장 가까운 노드로 흩어집니다. 공격 트래픽도 여러 지점으로 분산되니, 한 곳이 감당할 부담이 줄어들어요. 대형 CDN과 DNS가 Anycast를 쓰는 이유입니다.
대역폭·용량 확보. 결국 볼류메트릭 공격은 용량 싸움이기도 해요. 상류 통신사와의 광대역, 여러 업스트림 연결, 넉넉한 여유 대역이 흡수 능력을 좌우합니다.
4. 프로토콜 계층 완화
프로토콜 공격은 연결 상태 테이블이나 핸드셰이크의 약점을 노립니다. SYN 플러드가 대표적이죠.
SYN cookies. 일반적인 TCP는 SYN을 받으면 half-open 연결 상태를 메모리에 잡아 두고 ACK를 기다립니다. SYN 플러드는 이 반쯤 열린 연결을 대량으로 만들어 상태 테이블을 고갈시켜요. SYN cookie는 상태를 저장하지 않고, 연결 정보를 암호학적으로 인코딩한 초기 시퀀스 번호를 SYN-ACK에 담아 보냅니다. 클라이언트가 그 값을 정확히 돌려주면 그때 연결을 만들죠. 덕분에 위조된 SYN에 메모리를 낭비하지 않아요.
리눅스에서 SYN cookie는 커널 파라미터로 켭니다. 개념을 확인하는 수준에서 한두 줄만 볼게요.
# SYN 플러드 시 SYN cookie 활성화 (방어용 커널 설정)
sysctl -w net.ipv4.tcp_syncookies=1
# half-open 백로그 큐를 넉넉히
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
위 설정은 SYN cookie를 켜고 백로그 큐를 늘려서, 정상 연결이 밀려나지 않게 여유를 두는 정도예요. 운영 환경마다 적정값이 다르니 부하 테스트로 확인하는 걸 권합니다.
연결 rate limit과 상태 테이블 튜닝. 방화벽에서 출발지별 신규 연결 속도를 제한하고, 연결 추적(conntrack) 테이블 크기와 타임아웃을 조정하면 상태 고갈을 늦출 수 있어요. 다만 값을 너무 크게 잡으면 메모리를 그만큼 쓰니, 하드웨어 여력과 함께 봐야 합니다.
5. 애플리케이션 계층 완화
L7 공격은 정상 HTTP 요청처럼 생겼기 때문에 네트워크 지표만으로는 걸러내기 어려워요. 애플리케이션 앞단에서 요청의 의도를 봐야 하죠.
WAF(웹 애플리케이션 방화벽) 는 요청 패턴·서명·행위 규칙으로 악성 요청을 식별합니다. 특정 URI에 대한 비정상적인 반복, 이상한 헤더 조합 같은 걸 규칙으로 잡아내요.
rate limiting 은 가장 기본적이면서 효과적인 방어입니다. nginx의 limit_req로 출발지별 요청 속도에 상한을 두는 최소 예시를 볼게요.
# 출발지 IP별 초당 10요청, 순간 버스트 20까지 허용
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
server {
location /login/ {
limit_req zone=perip burst=20 nodelay;
}
}
위 설정은 로그인 같은 민감한 경로에 요청 속도 상한을 걸어, 한 출발지가 과도하게 두드리는 걸 완화합니다. burst로 정상적인 순간 몰림은 허용하고요.
JS 챌린지 / CAPTCHA 는 자동화된 봇을 걸러내는 데 유용해요. 브라우저만 통과할 수 있는 자바스크립트 연산을 요구하거나, 사람만 풀 수 있는 문제를 냅니다. 다만 정상 사용자 경험을 해칠 수 있어 의심 트래픽에만 선별 적용하는 게 좋습니다.
캐싱과 CDN 은 원본 서버를 보호하는 든든한 방패예요. 정적 자원과 캐시 가능한 응답을 CDN 엣지에서 처리하면, 원본까지 도달하는 요청 자체가 크게 줄어듭니다. 봇 관리 기능을 함께 쓰면 알려진 악성 봇을 엣지에서 미리 차단할 수도 있고요.
6. 스크러빙 센터와 클라우드 실드
규모가 큰 공격은 결국 전문 인프라로 트래픽을 우회시켜 걸러내는 게 현실적입니다. 이때 등장하는 게 스크러빙 센터(scrubbing center)예요. 들어오는 트래픽을 대용량 정제 설비로 흘려 보내 공격 패킷은 버리고 깨끗한 트래픽만 원본으로 돌려보냅니다.
트래픽을 스크러빙 센터로 보내는 방식은 크게 둘이에요. BGP 우회 는 우리 네트워크 대역을 스크러빙 사업자가 대신 광고해 트래픽을 그쪽으로 끌어오는 방식이고, DNS 우회 는 도메인이 사업자의 프록시 IP를 가리키게 해 웹 트래픽을 통과시키는 방식입니다. 전자는 네트워크 전체를, 후자는 주로 웹 서비스를 보호해요.
운영 형태로는 두 가지가 있습니다.
| 방식 | 특징 |
|---|---|
| Always-on | 상시 경유, 지연 낮고 즉시 대응 |
| On-demand | 감지 시에만 우회, 평소 경로 유지 |
Cloudflare, AWS Shield, Akamai 같은 서비스가 이런 스크러빙과 클라우드 실드를 제공합니다. always-on은 전환 지연 없이 바로 걸러내는 대신 상시 경유 비용이 들고, on-demand는 평소엔 직접 경로를 쓰다가 공격 시에만 우회해 전환에 약간의 시간이 걸리는 트레이드오프가 있어요. 서비스 특성과 예산에 맞춰 고르면 됩니다.
7. 실전 대응 플레이북
기술만큼 중요한 게 사람과 절차예요. 공격은 늘 준비가 덜 됐을 때 옵니다. 그래서 미리 짜둔 룬북이 큰 차이를 만들어요. 시점별로 체크리스트를 정리해 봤습니다.
사전 준비
- 비상 연락체계 정리(내부 담당자·업스트림 통신사·스크러빙 사업자)
- 완화 절차 룬북 문서화, 실제로 한 번 리허설
- 업스트림·클라우드 실드와 사전 계약 및 우회 설정 검증
- 베이스라인 지표와 알림 임계값 세팅
공격 중
- 트래픽 분석으로 공격 유형(볼류메트릭·프로토콜·L7) 판별
- 계층에 맞는 완화 적용(상류 흡수 → 프로토콜 방어 → L7 필터)
- 정상 사용자 영향 모니터링, 오탐 시 조치 단계 조정
- 상황 로그 기록, 관계자에게 상태 공유
사후
- 회고(무엇이 통했고 무엇이 늦었나)
- 용량·임계값 재점검, 룬북 갱신
- 반복 공격 대비 규칙·차단 목록 정리
핵심은 공격 중에 처음 고민하지 않는 겁니다. 누구에게 전화하고, 어떤 스위치를 어떤 순서로 올릴지가 문서에 있어야 손이 떨리지 않아요.
8. 겹겹이 쌓는 심층방어
DDoS 방어에서 하나만 남긴다면, “완벽 차단이 아니라 회복탄력성”이라는 관점이에요. 어떤 단일 장비도, 어떤 서비스도 모든 공격을 혼자 막지 못합니다. 대신 네트워크 계층의 흡수와 필터, 프로토콜 계층의 SYN cookie와 rate limit, 애플리케이션 계층의 WAF와 챌린지, 그리고 그 바깥의 스크러빙 센터를 겹겹이 쌓아 두면, 한 겹이 뚫려도 다음 겹이 버텨 줍니다. 공격을 이해할수록 어느 계층에 어떤 방벽을 둘지 정확히 고를 수 있고, 그게 이 시리즈를 관통하는 이야기예요. 서비스가 잠깐 흔들려도 다시 일어서는 힘, 그게 우리가 진짜로 만들려는 것입니다.
마치며
여기까지 공격을 이해하고, 그 위에 계층별 방어를 겹겹이 쌓아봤어요. 그런데 방벽은 세워만 두고 한 번도 두들겨보지 않으면, 진짜 공격이 왔을 때 정말 버틸지는 아무도 모릅니다.
일단 오늘은 여기까지…..
다음 글에서는 이렇게 세운 방어가 실제로 버티는지, 내 사이트에서 합법적으로 두들겨 검증하는 방법을 정리해볼게요.
← 이전 글: (4/6) 애플리케이션 계층(L7) 공격 — 정상 요청처럼 굴며 서버를 태우기 | 다음 글 →: (6/6) 내 사이트 DDoS 내성 테스트 — 합법적으로, 제대로
참고: Cloudflare Learning — How to prevent DDoS attacks · RFC 2827 — Network Ingress Filtering (BCP38) · CISA — DDoS Quick Guide