DDoS 공격이란 무엇인가: 기술, 계층, 방어
DDoS 공격이 기술적으로 어떻게 진행되는지, 유한한 네 가지 자원 가운데 무엇을 점유하는지, 여러분 자신의 측정값으로 어떻게 알아내는지, 그리고 서버에서의 방어가 어디에서 끝나는지 정리했습니다. 운영 중에 실제로 걸러 낸 공격 사례를 함께 실었습니다.
DDoS 공격은 인위적으로 만들어 낸 과부하로 서비스를 이용할 수 없게 만들려는 시도이며, 아주 많은 서로 다른 출발지에서 동시에 수행됩니다. 약어는 Distributed Denial of Service를 뜻하고, 곧 분산된 방식으로 일으킨 서비스 거부입니다. 이때 공격받는 것은 서버의 콘텐츠도 아니고 소프트웨어의 보안 취약점도 아니며, 유한한 자원입니다. 회선의 대역폭, 네트워크 카드의 패킷 전송률, 커널 상태 테이블의 한 자리, 또는 애플리케이션이 요청 하나에 들이는 연산 시간입니다. 이 네 가지 자원 가운데 하나가 점유되면 실제 사용자는 더 이상 들어오지 못하며, 그것도 누군가 시스템에 침입하지 않은 상태에서 그렇게 됩니다.
이 글은 이 주제로 들어가는 입구입니다. 공격이 벌어지는 세 계층, 요청 1 바이트가 응답 51,000 바이트로 바뀌는 증폭 계수, 공격 용량이 어디에서 나오고 시장에서 얼마에 거래되는지, 여러분 자신의 측정값으로 공격을 어떻게 알아내는지, 서버 자체에서 무엇이 아직 도움이 되고 그 한계선이 정확히 어디에 있는지를 설명합니다. 모든 수치에는 출처를 적어 두었으니 직접 확인하실 수 있습니다. 지금 서비스가 멈춰 있다면 “공격을 받았을 때 해야 할 일” 절을 먼저 읽고, 설정을 손대는 대신 측정부터 하세요.
DDoS 공격의 기술적 정체
모든 DDoS 공격은 비대칭성으로 먹고삽니다. 패킷 하나를 보내는 비용이 공격자에게는 그 패킷을 처리하는 목표 쪽 비용보다 적어야 합니다. 나머지는 이 비대칭성이 어느 지점에서 가장 큰지의 문제일 뿐입니다. 그 지점은 정확히 네 곳이고, 각각 계산으로 구할 수 있는 확실한 상한이 있습니다.
회선의 대역폭. 1 Gbit/s 회선은 초당 125 메가바이트를 나르고, 그 이상은 나르지 못합니다. 더 많이 보내면 손실이 생기고, 그 손실은 공격자의 패킷과 마찬가지로 여러분 사용자의 패킷에도 닥칩니다. 꽉 찬 회선은 골라내지 않기 때문입니다.
패킷 전송률. 허용되는 가장 작은 이더넷 패킷은 64 바이트이고, 프리앰블과 패킷 간격까지 합하면 회선에서 84 바이트를 차지합니다. 1 Gbit/s에는 그것이 초당 약 149만 개 들어갑니다. 일반적인 서버 커널은 CPU와 네트워크 카드에 따라 수십만 개를 처리한 뒤 폐기를 시작합니다. 그래서 패킷 전송률은 거의 항상 대역폭보다 먼저 닿는 한계입니다.
상태 테이블. 커널은 절반만 열린 TCP 연결과 패킷 흐름을 기억해 둡니다. 이 테이블은 초당 비트가 아니라 개수로 제한됩니다. 패킷마다 새로운 출발지 주소를 달고 오면 아주 적은 대역폭으로도 채울 수 있습니다.
애플리케이션의 연산 시간. 검색 요청 하나, 비밀번호 검증이 딸린 로그인 시도 하나, 또는 모드 목록 전체를 돌려주는 서버 조회 하나는 보내는 쪽보다 목표 쪽에 수천 배 많은 비용을 지웁니다. 여기서는 효과적인 공격에 10 Mbit/s조차 필요하지 않은 경우가 많습니다.
DoS와 DDoS: 측정할 수 있는 차이
개념의 토대는 RFC 4732 “Internet Denial-of-Service Considerations”가 제공하며, 2006년 11월에 나온 IETF의 정보성 문서입니다. 거기에는 이렇게 적혀 있습니다. “A Denial-of-Service (DoS) attack is an attack in which one or more machines target a victim and attempt to prevent the victim from doing useful work.” 곧 DoS 공격은 출발지의 개수가 아니라 효과로 정의됩니다. 분산된, 곧 DDoS가 되는 것은 그 출발지가 수없이 많고 서로 독립적일 때입니다.
실무에서 이 차이가 의미를 갖는 지점은 정확히 하나, 여러분의 차단 목록 길이입니다. 출발지가 하나인 DoS 공격은 규칙 한 줄로 끝냅니다. Cloudflare는 2025년 5월에 161개국 5,433개 자율 시스템의 서로 다른 출발지 주소 122,145개에서 들어온 공격을 기록했고, 초당 평균 26,855개, 최대 45,097개의 새 주소가 나타났습니다. 이런 것에 맞설 만큼 빠르게 자라는 차단 목록은 없고, 목록의 항목 하나하나가 이미 과부하인 장비에서 메모리와 검색 시간을 추가로 잡아먹습니다.
CISA, FBI, MS-ISAC의 공동 안내서 “Understanding and Responding to Distributed Denial-of-Service Attacks”는 공격을 정확히 세 가지 기법으로 나눕니다. 볼류메트릭, 프로토콜 기반, 애플리케이션 기반입니다. 이 삼분법은 존재하는 분류 가운데 가장 유용합니다. 여러분의 네 가지 자원 중 무엇이 공격받는지와 방어가 어디에 놓여야 하는지를 동시에 설명하기 때문입니다.
DDoS 공격의 세 계층
레이어 3과 레이어 4의 볼류메트릭 공격
볼류메트릭 공격은 목표 앞의 회선을 채우는 것 외에 아무것도 원하지 않습니다. 측정 단위는 초당 비트입니다. 수단은 보통 UDP 플러드입니다. UDP에는 요구할 수 있는 연결 수립 절차가 없고, 출발지 주소를 위조할 수 있기 때문입니다.
현재 공개적으로 기록된 가장 큰 사례입니다. Cloudflare는 2025년 말까지의 기간에 대해, 35초 동안 이어졌고 자동으로 막아 낸 31.4 Tbit/s 공격을 보고했습니다. 이는 1 Gbit/s 서버 회선 약 31,400개의 용량이 동시에, 30초를 훌쩍 넘겨 쏟아진 것과 같습니다. 같은 보고서에는 최대치보다 규모를 더 잘 실감하게 하는 두 번째 값이 있습니다. 2025년에 같은 사업자는 DDoS 공격 4,710만 건을 막아 냈고, 이는 전년 대비 121 퍼센트 증가이며 시간당 평균 5,376건입니다.
2025년 5월의 더 잘 기록된 사례는 이런 공격을 분해했을 때 어떤 모습인지 보여 줍니다. 최대 7.3 Tbit/s, 45초 동안 37.4 테라바이트로, 초당 평균 약 830 기가바이트입니다. 1 Gbit/s 회선이라면 같은 데이터양에 사흘 넘게 걸렸을 것입니다. 트래픽의 99.996 퍼센트가 순수한 UDP 플러드였고, 동시에 평균 21,925개, 최대 34,517개의 목표 포트에 퍼져 있었습니다. 모든 포트에 걸친 이런 분산은 전형적입니다. 공격자는 어느 포트가 중요한지 모르므로 전부 다 잡습니다.
프로토콜 공격: 회선이 아니라 테이블
프로토콜 공격은 커널이 상태를 기억해 두어야 한다는 점을 악용합니다. 표준 예시는 SYN 플러드입니다. 공격자가 SYN 비트를 세운 TCP 패킷을 위조된 출발지 주소로 보내면, 서버는 그 하나하나마다 절반만 열린 연결 대기열에 항목을 만들고, 한 번도 응답한 적 없는 주소로 SYN-ACK를 보낸 뒤 기다립니다. 여기서 측정 단위는 기가비트가 아니라 초당 패킷입니다.
이 대기열의 길이는 net.ipv4.tcp_max_syn_backlog에 들어 있고, 일반적인 서버에서는 네 자리 수준입니다. 자리가 1,024개인 대기열은 초당 149만 개의 SYN 패킷 앞에서 1 밀리초도 되지 않아 꽉 찹니다. 계산만으로 보면 1 Gbit/s로 충분하고, 테이블만이 목표라면 그 일부만으로도 충분합니다.
같은 계열에 2021년에야 기술된 방식이 있습니다. 상태를 유지하는 중간 장비를 이용한 TCP 반사 공격입니다. 논문 “Weaponizing Middleboxes for TCP Reflected Amplification”은 TCP 상태를 절반만 따라가는 방화벽과 검열 장비가 위조된 패킷 한 개에 여러 페이지 분량의 응답으로 반응한다는 것을 보여 줍니다. 이로써 그때까지 사실상 불가능하다고 여겨졌던 TCP의 증폭 악용이 처음으로 가능해졌습니다.
레이어 7의 애플리케이션 공격
애플리케이션 공격은 평범한 트래픽처럼 보입니다. 실제로 평범한 트래픽이고, 양만 잘못되어 있기 때문입니다. 측정 단위는 초당 요청입니다. 완전히 수립된 연결을 통해 들어오므로 연결 수립만 평가하는 모든 검사를 통과하며, 대역폭도 거의 필요하지 않습니다. 초당 HTTP 요청 10,000건은 요청 크기에 따라 50 Mbit/s도 되지 않지만, 그럼에도 데이터베이스를 무릎 꿇리기에 충분합니다.
이 분야의 기준은 HTTP/2 Rapid Reset이고, 2023년 10월 10일에 CVE-2023-44487로 공개되었습니다. 취약점은 HTTP/2의 다중화 기능에 있습니다. 공격자가 데이터 스트림을 열고 요청을 보낸 뒤 그 스트림을 곧바로 중단합니다. 서버는 이미 일을 시작했지만, 공격자는 곧바로 창에 빈자리를 다시 얻습니다. 이렇게 도달한 값은 초당 요청 2억 100만 건(Cloudflare), 3억 9,800만 건(Google), 1억 5,500만 건(Amazon)이었습니다. 비교하자면 그때까지 Cloudflare가 측정한 가장 큰 레이어 7 공격은 초당 7,100만 건이었습니다.
게임 서버에서는 레이어 7 계층이 곧 연결 수립 자체입니다. Minecraft 네트워크를 겨냥한 nullping, QuietException, 위조 핸드셰이크 플러드는 대역폭을 거의 쓰지 않으면서 프록시 묶음 전체를 멈춰 세웁니다. 패킷 하나하나가 프록시에 비싼 상태 판단을 강요하기 때문입니다. 이 패턴이 정확히 어떤 모습인지는 Minecraft DDoS 방어와 nullping 방어에 있습니다.
세 계층 비교
| 계층 | 공격받는 대상 | 측정 단위 | 전형적인 방식 | 방어가 놓여야 하는 곳 |
|---|---|---|---|---|
| 볼류메트릭(레이어 3과 4) | 회선의 대역폭 | Gbit/s와 Tbit/s | UDP 플러드, DNS와 NTP와 memcached와 CLDAP를 통한 증폭 공격 | 서버 앞단 네트워크에서만 |
| 프로토콜(레이어 3과 4) | 커널, 방화벽, 로드밸런서의 상태 테이블 | 초당 패킷 | SYN 플러드, ACK 플러드, 분할 패킷, 중간 장비를 통한 TCP 반사 공격 | 일부는 서버에서, 초당 수십만 패킷부터는 그 앞단에서 |
| 애플리케이션(레이어 7) | 연산 시간, 데이터베이스, 애플리케이션의 연결 수립 | 초당 요청 | HTTP 플러드, HTTP/2 Rapid Reset, 로그인 플러드, 쿼리 플러드, 슬롯 고갈 | 애플리케이션과 그 앞단 필터링, 둘을 함께 |
실제 공격은 이 분류를 지키지 않습니다. 현장에서 가장 곤란한 경우는 여러 계층이 겹친 공격입니다. 회선을 붙잡아 두는 볼류메트릭 성분에, 주의가 대역폭에 쏠린 순간을 노려 통과하는 레이어 7 성분이 함께 옵니다. 아래에서 보여 드리는, KernelHost에서 걸러 낸 공격 가운데 하나는 열두 가지가 넘는 주요 패턴이 동시에 들어온 것이었습니다.
증폭 공격: 1 바이트가 51,000 바이트가 되는 방식
증폭 공격은 공격자가 목표를 직접 쏘지 않고, 외부의 공개된 서비스가 자기 대신 쏘도록 만드는 공격입니다. 열려 있는 서비스에 작은 조회를 보내면서 출발지로 피해자의 IP 주소를 적어 넣습니다. 그 서비스는 규정대로 응답하지만, 그 응답은 피해자에게 가고 조회보다 몇 배 큽니다.
응답 크기와 조회 크기의 비율을 Bandwidth Amplification Factor, 줄여서 BAF라고 합니다. BAF가 50이면 자기 회선 1 Gbit/s를 가진 공격자가 목표로 50 Gbit/s를 돌린다는 뜻입니다. 이것이 동작하려면 두 가지가 함께 있어야 합니다. 질문보다 많이 응답하는 UDP 기반 프로토콜, 그리고 출발지 주소를 위조할 수 있는 조건입니다. 그래서 IP 스푸핑은 단순한 은폐 수단이 아니라 모든 증폭 공격의 전제입니다.
방어하는 쪽에게는 여기서 불편한 성질이 따라옵니다. 트래픽이 실제로 존재하는 정상적인 서버에서 옵니다. 실제 DNS 리졸버, 실제 시간 서버, 실제 게임 서버입니다. 그래서 출발지 주소 기준 차단 목록은 나라 절반을 막아 버리거나, 아니면 효과가 없습니다.
악용되는 프로토콜의 증폭 계수
다음 계수는 US-CERT, 곧 현재의 CISA가 낸 경보 TA14-017A “UDP-Based Amplification Attacks”에서 가져온 것이며, 이 문서는 2014년부터 계속 보강되고 있습니다. 업계 전체가 근거로 삼는 기준 문서입니다.
| 프로토콜 | 증폭 계수 | 악용되는 동작 |
|---|---|---|
| memcached(포트 11211) | 10,000에서 51,000 | 임시 저장된 콘텐츠 조회 |
| NTP(포트 123) | 556.9 | monlist 조회 |
| CharGEN(포트 19) | 358.8 | 문자 생성기 |
| WS-Discovery(포트 3702) | 10에서 500 | 네트워크 장치 검색 |
| QOTD(포트 17) | 140.3 | 명언 조회 |
| RIPv1(포트 520) | 131.24 | 잘못된 경로 조회 |
| CLDAP(포트 389) | 56에서 70 | 잘못된 디렉터리 조회 |
| Quake 프로토콜 | 63.9 | 서버 정보 |
| TFTP(포트 69) | 60 | 파일 요청 |
| LDAP(포트 389) | 46에서 55 | 잘못된 디렉터리 조회 |
| DNS(포트 53) | 28에서 54 | 응답이 큰 조회 |
| SSDP(포트 1900) | 30.8 | SEARCH 요청 |
| Portmap / RPCbind(포트 111) | 7에서 28 | 잘못된 요청 |
| Kad | 16.3 | 노드 목록 교환 |
| mDNS(포트 5353) | 2에서 10 | 유니캐스트 조회 |
| SNMPv2(포트 161) | 6.3 | GetBulk 요청 |
| Steam 프로토콜 | 5.5 | 서버 조회 |
| NetBIOS(포트 137) | 3.8 | 이름 해석 |
| BitTorrent | 3.8 | 파일 검색 |
이 표는 잘 관리된 방화벽마다 차단 포트 목록이 늘 비슷해 보이는 이유를 설명합니다. 여러분이 직접 할 수 있는 일은 많지 않지만 중요합니다. ss -lnup으로 이 표에 있는 서비스가 여러분의 서버에서 네트워크에 열려 있는지 확인하세요. 127.0.0.1에 바인딩되지 않은 memcached는 여러분의 서버를 제3자를 향한 무기로 만들고, 여러분 자신의 송신 대역폭을 소모하며, 한번 올라가면 빠져나오기 어려운 차단 목록에 여러분의 IP 주소를 올립니다.
게임 조회 프로토콜이 여기에 들어가는 이유
게임 서버는 이 표에 두 가지 역할로 들어 있습니다. 조회 포트가 작은 패킷 하나에 이름, 맵, 플레이어 수, 모드 목록 전체를 담아 응답하므로 증폭기입니다. 그리고 같은 조회가 연산 시간을 소모하고, 그것도 시뮬레이션을 떠받치는 바로 그 코어에서 소모하는 경우가 많으므로 피해자이기도 합니다.
Steam 프로토콜의 증폭 계수는 5.5로 낮고, 더 오래된 Quake 프로토콜은 63.9로 높습니다. 다만 효과는 계수만으로 결정되지 않고 개별 사례의 응답 크기에 달려 있습니다. 모드가 200개인 서버는 모드가 없는 서버보다 훨씬 큰 응답을 내놓습니다. Bohemia Interactive는 Arma 3에 대해 티켓 T83469에서 2015년부터, 위조된 조회 4 Mbit/s만 Steam 쿼리 포트에 들어와도 서버를 멈춰 세우기에 충분했다고 기록하고 있습니다. 초당 4 메가비트는 가정용 회선 하나가 내는 양보다도 적습니다.
여기서 모든 게임에 통하는 규칙이 나옵니다. 조회 포트는 제한하고, 차단하지 마세요. 차단하면 서버 목록에서 사라지고 새 플레이어가 서버를 찾지 못합니다. 게임별로 그 포트가 무엇이고 얼마나 좁게 운용해도 되는지는 아래의 게임별 글에 있습니다. 예를 들어 Arma 3, CS2와 Source 계열, Rust입니다.
memcached 사례: GitHub를 향한 1.35 Tbit/s
2018년 2월 28일 GitHub는 UTC 17시 21분부터 17시 26분까지 접속되지 않았고 17시 30분까지도 간헐적으로만 열렸습니다. 공격은 1.35 Tbit/s에 이르렀고 그때 초당 1억 2,690만 패킷이었으며, 1,000개가 넘는 서로 다른 자율 시스템과 수만 개의 개별 엔드포인트에서 들어왔습니다. 증폭에는 memcached가 쓰였고 계수는 최대 51,000이었습니다. 공격자의 1 바이트가 목표 방향으로 최대 51 킬로바이트를 만들어 냈습니다.
이 사례는 오늘까지도 가장 좋은 교재입니다. 세 가지를 한꺼번에 보여 주기 때문입니다. 첫째, 증폭이 봇넷 크기를 이깁니다. 공격자에게 필요한 것은 기기 10만 대가 아니라 열려 있는 memcached 인스턴스였고, 당시 전 세계에 9만 개가 넘게 네트워크에 놓여 있었습니다. 둘째, 초당 1억 2,690만 패킷은 1 Gbit/s 회선이 애초에 나를 수 있는 양의 약 85배입니다. 서버의 어떤 설정도 여기에는 영향을 주지 못합니다. 셋째, 방어는 트래픽을 필터 네트워크로 우회시켰기 때문에 성공했고, 그 덕분에 장애 시간이 아홉 시간이 아니라 9분에서 끝났습니다.
DDoS 공격의 용량이 어디에서 오는가
탈취된 기기로 이뤄진 봇넷
봇넷은 악성 소프트웨어로 탈취한 남의 기기를 묶어 공격자가 중앙에서 원격 제어하는 집합입니다. 소유자는 보통 아무것도 눈치채지 못합니다. 기기가 구입 목적대로 계속 동작하기 때문입니다. 주로 공격받는 것은 늘 네트워크에 붙어 있고, 업데이트가 드물며, 기본 비밀번호를 쓰는 기기입니다. 라우터, 감시 카메라, 네트워크 녹화기, TV 박스입니다.
기준이 되는 것은 2016년 9월 말에 소스 코드가 공개된 Mirai입니다. 논문 “Understanding the Mirai Botnet”(USENIX Security 2017)은 이 네트워크를 일곱 달 동안 추적하며 최고치를 감염 기기 60만 대 이상으로 제시합니다. 2016년 9월 Brian Krebs의 사이트를 향한 공격은 620 Gbit/s에 이르렀고 기기 17만 5,000대 이상에서 들어왔습니다. 2016년 10월 21일 DNS 사업자 Dyn을 향한 공격, 곧 Twitter와 Spotify와 Reddit을 동시에 접속 불가로 만든 그 공격에서는 공격에 참여한 IP 주소가 약 10만 7,000개로 집계되었습니다.
9년이 지난 지금 규모는 다릅니다. Cloudflare는 31.4 Tbit/s의 기록적 공격을 감염 기기 100만에서 400만 대로 추정되는 봇넷의 소행으로 봅니다. 대부분 Android TV 박스입니다. 2025년 12월의 공격 물결에서는 초대형 볼류메트릭 공격 902건이 집계되었고, 하루 평균 53건이었으며, 최고치는 초당 90억 패킷, 24 Tbit/s, 초당 요청 2억 500만 건이었습니다. 봇넷 규모는 10년 사이에 5배로, 도달한 대역폭은 50배로 커졌습니다.
booter 및 stresser 서비스와 공격 한 건의 값
봇넷과 의뢰자 사이에는 공격 용량을 구독 형태로 판매하는 서비스가 있습니다. 이런 서비스들은 “booter”, “stresser” 또는 “IP stresser”라는 이름으로 나타나며, 이용 약관에서는 자기 시스템의 부하 시험에 쓰는 도구라고 주장합니다. 그러면서 입력된 목표가 이용자의 것인지는 한 번도 확인하지 않고, 바로 그 점이 도구와 판매되는 공격을 가르는 차이입니다.
조작은 입력란 세 개짜리 웹 화면입니다. 목표, 포트, 시간입니다. 결제 절차도 있고 고객 지원도 있고 리셀러 프로그램도 있습니다. 입문 상품은 월 10에서 20 유로 수준이고, 대역폭이 더 크고 공격 시간이 더 긴 상품은 월 수백 유로 수준입니다. 이로써 작은 프로젝트까지 피해를 보는 이유에 답이 나옵니다. 게임 서버의 토요일 저녁을 날려 버리는 공격 한 건은 의뢰자에게 영화표 두 장보다 적은 비용이 들고 기술 지식은 전혀 필요하지 않습니다.
다른 한편에는 지속적인 단속 압력이 있습니다. 2026년 4월 국제 작전 PowerOFF의 집중 단속 주간에 21개국 당국이 그러한 서비스의 도메인 53개를 인수하고, 4명을 체포하고, 25건의 압수 수색을 집행했습니다. 그 과정에서 수사관들은 300만 개가 넘는 이용자 계정의 데이터에 접근했고, 신원이 확인된 이용자 7만 5,000명 이상에게 통지가 발송되었습니다. 2024년 12월 같은 작전에서는 플랫폼 27개가 폐쇄되었습니다. 그러니 그런 서비스에 돈을 낸 사람은 언젠가 압수되는 데이터베이스에 결제 흔적을 남깁니다.
DDoS 공격을 알아내는 방법
사용자가 알려 주는 것과 그것이 이미 말해 주는 것
첫 정보는 거의 항상 사용자에게서 옵니다. 그리고 그 정보는 들리는 것보다 쓸 만합니다. 네 가지 신고에는 분명한 뜻이 있습니다.
- “전부 동시에 튕겼습니다.” 모든 사용자에게서 동시에 끊김이 일어나면 개별 연결이 아니라 회선이나 서비스 프로세스를 가리킵니다. 부하 문제는 사용자를 차례대로 건드립니다.
- “핑이 20에서 400으로 튀었다가 돌아옵니다.” 연결은 계속 유지되는데 지연이 흔들리는 것은 과부하인 프로세스가 아니라 목표 앞의 대기열이 넘친 패턴입니다.
- “서버 목록에는 오프라인으로 나오는데 저는 접속됩니다.” 이것은 쿼리 플러드를 가리키는 손짓입니다. 조회 포트는 더 이상 응답하지 않고 게임 포트는 아직 응답합니다.
- “휴대폰 회선으로는 들어가는데 집 회선으로는 안 됩니다.” 접속 네트워크에 따라 동작이 다르다면 여러분의 서버가 아니라 그곳으로 가는 경로 하나가 포화되었음을 시사합니다.
서버에서 볼 네 가지 측정값
그다음에는 측정하고, 순서는 이렇습니다. 패킷 전송률, 대역폭, 연결 상태, 폐기 카운터입니다. CPU 사용률 표시는 마지막입니다. 네트워크 공격에서는 그 값이 평범하게 남아 있는 경우가 많기 때문입니다.
sar -n DEV 1 10
ip -s link show eth0
ss -s
ss -tn state syn-recv | wc -l
nstat -az TcpExtListenDrops TcpExtListenOverflows TcpExtTCPReqQFullDrop UdpRcvbufErrors UdpInErrors UdpNoPorts
cat /proc/sys/net/netfilter/nf_conntrack_count /proc/sys/net/netfilter/nf_conntrack_max
sar -n DEV 1 10은 10초에 걸쳐 인터페이스별 초당 패킷과 바이트를 알려 줍니다. 결정적인 것은 비율입니다. 바이트는 적은데 패킷이 많으면 작은 패킷이고, 곧 프로토콜 공격입니다. 바이트는 아주 많은데 패킷이 적으면 큰 패킷이고, 곧 증폭 공격입니다. ip -s link show는 dropped와 overrun 열에서 커널이 이미 폐기하고 있는지 보여 줍니다. ss -tn state syn-recv는 절반만 열린 연결을 셉니다. 세 자리 값은 정상이고 다섯 자리 값은 SYN 플러드입니다. 그리고 nstat은 공격이 끝난 뒤에도 남는 카운터를 알려 줍니다.
가장 중요하면서 거의 아무도 미리 하지 않는 단계가 있습니다. 모든 것이 정상으로 돌아가는 동안에 기준값을 만들어 두는 것입니다. 평상시 값이 없으면 초당 40,000 패킷이 많은 것인지 그냥 토요일 저녁인지 말할 수 없습니다. apt-get install -y vnstat sysstat로 측정이 상시 돌아갑니다. 해석에 관한 자세한 안내는 DDoS 공격 알아내기에 있습니다.
확실하게 판별되는 로그 줄
커널 로그와 웹 서버 로그의 네 가지 메시지는 사실상 증거가 됩니다. dmesg -T | tail -50이 앞의 세 가지를 보여 줍니다.
kernel: TCP: request_sock_TCP: Possible SYN flooding on port 443. Sending cookies. Check SNMP counters.
kernel: nf_conntrack: nf_conntrack: table full, dropping packet
kernel: net_ratelimit: 2247 callbacks suppressed
nginx: [alert] 1123#1123: 768 worker_connections are not enough
첫 줄은 절반만 열린 연결 대기열이 넘쳐 커널이 SYN 쿠키로 전환했다는 뜻입니다. 거기에 대신 Dropping request가 적혀 있으면 net.ipv4.tcp_syncookies가 0으로 설정되어 있고, 서버는 정상 요청까지 포함해 요청을 폐기합니다. 두 번째 줄은 연결 추적이 가득 찼다는 뜻이고, 그 순간부터 서버는 정상 트래픽도 폐기합니다. 세 번째 줄은 부수 효과입니다. 커널이 그러지 않으면 로그를 남기는 일에만 매달리게 되므로 메시지를 억제합니다. 네 번째 줄은 문제를 애플리케이션으로 옮깁니다.
웹 서버의 접근 로그에서는 두 가지가 말해 줍니다. 상태 코드 499의 비율이 갑자기 오르면 클라이언트가 응답이 끝나기 전에 연결을 닫는다는 뜻이고, 일만 유발하고 읽지는 않으려는 레이어 7 공격이 하는 일이 바로 그것입니다. 그리고 거의 모든 요청에서 리퍼러 필드가 비어 있다면, 검색 엔진과 소셜 네트워크의 리퍼러를 함께 들고 오는 실제 방문자 급증과 공격을 구별해 줍니다.
되짚어 보기: 공격인가, 급증인가, 자기 실수인가
| 관찰 | 유력한 원인 | 다음 측정 단계 |
|---|---|---|
| 수신 패킷 전송률은 높고 CPU 부하는 낮음 | 볼류메트릭 또는 프로토콜 공격 | 바이트를 패킷으로 나눠 패킷 크기 계산 |
| CPU 부하는 높고 패킷 전송률은 평범 | 레이어 7 공격 또는 애플리케이션의 자기 실수 | 접근 로그에서 반복되는 URL과 상태 코드 499 확인 |
127.0.0.1로는 서비스가 빠르게 응답하는데 외부에서는 응답하지 않음 |
애플리케이션이 아니라 네트워크가 문제 | 인터페이스의 폐기 카운터와 외부에서의 지연 확인 |
| 서비스를 재시작해도 부하가 곧바로 돌아옴 | 외부에서 오는 공격 | 연결이 아니라 출발지 주소를 셀 것 |
| 아주 적은 주소에서 아주 많은 연결 | 단일 출발지, 차단 가능 | 출발지 주소별 속도 제한 설정 |
| 아주 많은 주소에서 아주 적은 연결 | 분산 공격, 차단 불가 | 서버 앞단 필터링, 사업자 참여 |
| 송신이 수신보다 뚜렷하게 많음 | 실제 방문자 급증 또는 여러분의 서버가 제3자를 향해 증폭 중 | ss -lnup으로 열린 UDP 서비스 확인 |
| 재시작, 업데이트 또는 cron 실행 직후에 시작 | 자기 실수 | 변경을 되돌리고 다시 측정 |
서버 자체에서 도움이 되는 것
서버에서는 흔히 말하는 것보다 많은 것을 이룰 수 있고, 규모가 작게 유지되는 모든 것에 대해 그렇습니다. 엉성한 봇, 단일 출발지, 쿼리 플러드, 애플리케이션 공격입니다. 이를 위한 도구는 nftables, 연결 추적, SYN 쿠키, 그리고 출발지 주소별 속도 제한입니다. 아래의 모든 내용은 Debian 12, Debian 13, Ubuntu 22.04 LTS, Ubuntu 24.04 LTS에 적용되며 root 기준으로 적었습니다.
nftables: 일찍 폐기하고 계산은 적게
원칙은 이렇습니다. 폐기될 패킷은 가능한 한 이르고 가능한 한 값싸게 폐기되어야 합니다. 그 앞에서 실행되는 규칙마다 연산 시간 곱하기 패킷 전송률의 비용이 듭니다. /etc/nftables.conf에 넣는 다음 규칙 세트는 웹 서버 하나와 게임 서비스 하나를 통과시키고 나머지를 폐기하며, 새 TCP 연결에 출발지 주소별 속도 제한을 둡니다.
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
set adminips {
type ipv4_addr
flags interval
elements = { 203.0.113.10 }
}
set newconn {
type ipv4_addr
size 131072
flags dynamic,timeout
timeout 1m
}
chain input {
type filter hook input priority filter; policy drop;
iif lo accept
ct state established,related accept
ct state invalid counter drop
ip saddr @adminips tcp dport 22 accept
tcp dport { 80, 443 } ct state new add @newconn { ip saddr limit rate over 30/second burst 60 packets } counter drop
tcp dport { 80, 443 } accept
udp dport 25565 accept
icmp type echo-request limit rate 5/second accept
icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } accept
counter drop
}
chain forward { type filter hook forward priority filter; policy drop; }
chain output { type filter hook output priority filter; policy accept; }
}
불러오기 전에 adminips에 여러분 자신의 고정 주소를 넣으세요. 그러지 않으면 SSH에서 스스로 막힙니다. 검사와 활성화는 이렇게 합니다.
nft -c -f /etc/nftables.conf
systemctl enable --now nftables
nft list ruleset
nft list set inet filter newconn
효과를 가르는 것은 세 가지입니다. ct state established,related accept가 일부러 두 번째 규칙에 놓여 있는 것은 기존 연결이 규칙 세트 전체를 지나가지 않게 하기 위함입니다. ct state invalid counter drop은 잘못된 플래그 조합과 늦게 도착한 분할 패킷을 하나하나 기술하지 않고도 걸러 냅니다. 그리고 모든 drop 앞의 counter는 나중에 어느 규칙이 걸렸는지 알 수 있게 해 주는 이유입니다. 카운터가 0에 머물러 있으면 규칙에 도달하지 못하는 것이고, 그것은 효과 없는 규칙 세트와는 완전히 다른 진단입니다.
SYN 쿠키와 백로그의 한계
SYN 쿠키는 서버가 절반만 열린 연결을 기억해 두지 않고, 필요한 정보를 자기 응답 번호에 암호화해 넣는 방식입니다. 연결 수립의 세 번째 패킷이 돌아오면 거기서 상태를 다시 계산합니다. 그러면 대기열이 더 이상 넘치지 않습니다. 이런 연결에는 애초에 대기열이 없기 때문입니다.
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 8192
net.core.netdev_max_backlog = 16384
net.core.rmem_max = 16777216
이 값들은 /etc/sysctl.d/ 아래의 파일에 넣고 sysctl --system으로 적용합니다. 그러지 않으면 다음 재시작에서 사라집니다. Debian과 Ubuntu에서는 tcp_syncookies가 기본값 1이며, 그것이 맞습니다. 값 1은 “항상 쿠키”가 아니라 “대기열이 넘치는 순간부터 쿠키”를 뜻합니다.
그 대가는 실재하고 거의 언급되지 않습니다. 쿠키 하나에는 상대편의 TCP 옵션을 담을 자리가 없습니다. Linux는 net.ipv4.tcp_timestamps가 1일 때만 창 크기 확장과 선택적 확인 응답을 살려 냅니다. 그때는 그 정보가 타임스탬프에 함께 실려 가기 때문입니다. 타임스탬프가 없으면 그 정보는 사라지고, 연결은 남은 수명 내내 더 느리게 동작합니다. 게다가 최대 패킷 크기에는 3 비트만 쓸 수 있으므로 정확한 값 대신 여덟 단계의 대략적인 값만 남습니다. SYN 쿠키는 연결을 살려 내는 비상 운전이고, 평상시를 위한 설정이 아닙니다.
conntrack: 가장 먼저 가득 차는 테이블
커널의 연결 추적은 패킷 흐름마다 항목을 만들고, UDP에도 그렇게 합니다. UDP에 연결이라는 것이 없음에도 그렇습니다. 분산 공격에서 가장 먼저 바닥나는 자원이 바로 이 테이블이고, 아주 빠르게 바닥납니다. 초당 149만 패킷이 매번 새로운 출발지 주소로 들어오면 자리가 262,144개인 테이블은 0.2초도 되지 않아 가득 찹니다.
net.netfilter.nf_conntrack_max = 524288
net.netfilter.nf_conntrack_udp_timeout = 10
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 20
항목 하나는 약 300 바이트를 차지하므로 524,288개면 커널 메모리 약 150 메가바이트입니다. 해시 테이블 크기는 sysctl이 아니라 모듈 파라미터로 설정하며, 보통 상한의 4분의 1로 두고 /etc/modprobe.d/nf_conntrack.conf에 적습니다.
options nf_conntrack hashsize=131072
순수한 게임 서버나 음성 서버라면 게임 트래픽을 아예 추적하지 않게 하는 쪽이 더 깔끔한 해법입니다. 그러면 테이블을 완전히 아낄 수 있습니다.
nft add table ip raw
nft add chain ip raw prerouting '{ type filter hook prerouting priority raw; }'
nft add rule ip raw prerouting udp dport 25565 notrack
주의하세요. notrack과 상태를 쓰는 규칙은 함께 쓸 수 없습니다. 어떤 포트를 추적에서 빼면 그 포트에 대해서는 ct state가 들어간 규칙을 더 이상 쓸 수 없습니다. 그러지 않으면 허용이 동작하지 않아 서비스가 닫힙니다.
출발지 주소별 속도 제한
출발지 주소별 속도 제한은 서버에서 할 수 있는 가장 효과적인 단일 조치입니다. 공격자가 하는 일을 정확히 때리고, 사용자가 하는 일을 정확히 통과시키기 때문입니다. 차이는 큽니다. 정상적인 서버 브라우저는 1분에 몇 번 조회하고, 공격자는 1초에 수백 번 조회합니다. nftables에서는 위의 규칙 세트처럼 동적 집합으로 처리하고, 고전적인 iptables에서는 hashlimit으로 처리합니다.
iptables -I INPUT -p udp --dport 27015 -m hashlimit --hashlimit-name query --hashlimit-mode srcip --hashlimit-above 10/sec --hashlimit-burst 20 -j DROP
iptables -I INPUT -p udp --dport 27015 -m length --length 0:27 -j DROP
이런 규칙의 모든 숫자는 출발점일 뿐이고 정답이 아닙니다. 먼저 평상시 운영에서 한 주는 측정하세요. 그러지 않으면 자기 사용자를 내쫓게 되고, 그것도 가장 나쁜 순간에 그렇게 됩니다. 또한 iptables 규칙만 쓰면 재시작 후에 사라진다는 점(apt-get install -y iptables-persistent 다음에 netfilter-persistent save)과, UFW에서는 그런 규칙이 /etc/ufw/before.rules에 들어가야 한다는 점(그러지 않으면 다음 ufw reload에서 사라집니다)을 유념하세요. 상시 운영을 위한 전체 규칙 세트는 서버를 DDoS 공격으로부터 방어하기에 있습니다.
서버에서의 모든 필터링이 한계에 이르는 지점
이제 어떤 설정 파일로도 해결되지 않는 부분입니다. 지금까지의 모든 조치는 여러분의 서버, 곧 회선의 끝에서 동작합니다. 방화벽 규칙은 이미 케이블을 지나온 패킷을 두고 판단합니다. 그 패킷을 폐기할 수는 있지만 보내지 않은 것으로 만들 수는 없습니다. 그 앞의 회선이 꽉 차 있으면 사용자의 패킷은 그 앞에서 이미 도착하지 못하고, 여러분의 규칙 세트가 얼마나 훌륭한지와는 무관합니다.
| 회선 | 초당 실데이터 | 64 바이트일 때 초당 패킷 |
|---|---|---|
| 1 Gbit/s | 125 메가바이트 | 1,488,095 |
| 1 Gbit/s 2회선 | 250 메가바이트 | 2,976,190 |
| 10 Gbit/s | 1,250 메가바이트 | 14,880,952 |
| 25 Gbit/s | 3,125 메가바이트 | 37,202,381 |
| 100 Gbit/s | 12,500 메가바이트 | 148,809,523 |
이 표는 자체 방어로 충분한지에 대한 물음을 사례마다 답해 줍니다. 초당 1억 2,690만 패킷의 GitHub 공격은 패킷 전송률만 보면 100 Gbit/s 회선 하나에 간신히 들어가지만, 1.35 Tbit/s의 양이라면 그런 회선이 동시에 열네 개 필요합니다. 31.4 Tbit/s의 기록적 공격은 완전히 포화된 100 Gbit/s 회선 314개에 해당합니다. 게임 서버는 보통 1 Gbit/s나 1 Gbit/s 두 회선에 물려 있습니다. 그러므로 자체 방어의 한계는 초당 약 150만에서 300만 패킷이고, 실제로는 그보다 훨씬 아래입니다. 커널이 그 전에 포기하기 때문입니다.
두 번째, 더 불편한 한계가 하나 더 있습니다. 회선이 포화되는 순간, 측정에 쓰려던 SSH 세션조차 여러분에게 닿지 않을 수 있습니다. 그때 네트워크와 무관한 접근 수단, 예를 들어 고객 포털의 VNC 콘솔이 없으면 무슨 일이 벌어지는지 들여다볼 수조차 없습니다.
서버 앞단에서만 통하는 것: 네트워크 필터링과 스크러빙
효과적으로 필터링할 수 있는 것은 공격보다 큰 용량을 가진 쪽뿐입니다. 그러려면 많은 회선이 모이는 지점이 필요하고, 곧 머신 하나가 아니라 네트워크가 필요합니다. 거기에는 서로 보완하는 두 가지 방식이 있습니다.
네트워크에서의 실시간 필터링. 전체 트래픽이 상시로 필터 단계를 지나가며, 서버로 넘기기 전에 패킷 하나하나를 평가합니다. 장점은 전환이 없다는 것입니다. 방어가 효과를 내기 위해 공격을 먼저 알아낼 필요가 없습니다. 게임에서는 바로 이 점이 승부를 가릅니다. 전환 시간 2분은 한 라운드를 잃는 것이고, 35초 동안 이어지는 공격에 대한 전환 시간 2분은 아예 방어가 아닙니다.
스크러빙. 네트워크가 큰 볼류메트릭 공격을 알아내면 해당 트래픽을 필터 센터로 우회시켜 악성 성분을 걷어 낸 뒤 목표 방향으로 전달합니다. 이 우회의 뜻은 근접성입니다. 공격 트래픽이 데이터센터에 이르러서가 아니라 들어온 지점에서 끝납니다. 이를 위해 필터 규칙이 네트워크에 배포되며, 기술적으로는 RFC 8955의 Flow Specification에 기술되어 있습니다.
덧붙여, 위조된 출발지 주소에 대한 구조적 대책은 2000년부터 알려져 있고 RFC 2827, 곧 BCP 38에 들어 있습니다. 고객을 연결하는 쪽이 그 경계에서 해당 고객에게 속하지 않은 출발지 주소의 모든 패킷을 폐기하는 것입니다. RFC 3704는 이를 여러 회선에 연결된 네트워크까지 확장합니다. 모든 네트워크 사업자가 이를 적용하면 증폭 공격이라는 부류 전체가 사라집니다. 그렇게 되지 않은 이유는 일부가 적용하지 않는 것만으로도 충분하기 때문입니다.
그리고 알아 두어야 할 세 번째 방법이 있습니다. 방어라고 팔리는 일이 잦기 때문입니다. null-routing, 기술적으로는 RFC 5635의 Remote Triggered Black Hole Filtering입니다. 공격받는 IP 주소를 네트워크에서 도달 불가로 알려, 그 주소로 가는 모든 트래픽을 폐기합니다. 공격 트래픽도, 여러분 사용자의 트래픽도 함께입니다. 이는 사업자의 네트워크를 지켜 주지만, 여러분에게 남는 결과는 공격이 성공한 것과 똑같고, 보통 그 뒤로 몇 시간 더 이어집니다. 확실하지 않으면 필터링을 하는지 null-routing을 하는지 물어보세요. 그 답이 어떤 하드웨어 사양보다 여러분의 가용성을 더 크게 좌우합니다.
KernelHost가 이에 맞서 제공하는 것
모든 서버 상품에 포함된 상시 방어
KernelHost의 DDoS 방어는 두 단계로 구성되어 있고 상시 동작합니다. 여러분이 무엇을 켜거나 주문하거나 설정할 필요가 없습니다.
- 1단계: 글로벌 스크러빙 네트워크의 17 Tbps 방어 용량. 볼류메트릭 공격은 발생지에 가까운 곳에서 정화되어 데이터센터에 닿기 전에 걸러집니다.
- 2단계: 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링. 서버 바로 앞에서 프로토콜별 패턴을 찾아내 패킷 하나하나를 폐기합니다.
두 가지 특성이 결정적입니다. 이 방어는 상시 동작하며 서버 제공 시점부터 동작하므로, 공격 초반에 서비스가 사라지는 몇 분이 존재하지 않습니다. 그리고 null-routing을 쓰지 않습니다. 여러분의 IP 주소는 네트워크에 그대로 남고, 폐기되는 것은 악성 패킷뿐입니다. 어떤 게임과 프로토콜이 자체 필터 프로필을 갖는지는 실시간 게임 서버 DDoS 방어에 정리되어 있습니다.
계속 공격받는 프로젝트를 위한 Advanced DDoS Protection
어떤 프로젝트는 어쩌다 한두 번이 아니라, 표적이 되어 몇 주에 걸쳐 공격받습니다. 매일 저녁 같은 시각에, 패턴을 바꿔 가며 들어옵니다. 이런 경우를 위해 Advanced DDoS Protection이 월 50.00 EUR부터, PrePaid 방식으로, 최소 이용 기간과 설치비 없이 제공됩니다. 차이는 용량이 더 커지는 데 있지 않고 통제권에 있습니다.
- 전용 방어 IP: 프랑크푸르트 코어에서 발급되며, 서버는 자체 네트워크에서 이 IP로 전환됩니다. 여러분 쪽에서 손볼 것은 없습니다.
- 포트와 프로토콜별로 직접 관리하는 방어 규칙: 고객 포털에서 게임 포트에 무엇을 허용할지와 조회 포트에 무엇을 허용할지를 따로 설정하고, 그럼으로써 조회 프로토콜 절에서 설명한 비대칭성을 정확히 활용할 수 있습니다.
- 변경은 실시간으로 반영: 유지보수 시간을 기다리지 않고 공격이 진행되는 중에도 값을 조정할 수 있습니다.
- 서비스에 맞춘 방어 프로필: 개조된 애플리케이션과 자체 작성 애플리케이션도 임의의 TCP 또는 UDP 포트에서 같은 방식으로 다룹니다.
Advanced DDoS Protection은 KernelHost 고객을 대상으로 하며 KernelHost의 서버를 전제로 합니다. 프로젝트가 현재 다른 곳에서 돌아가고 거기서 정기적으로 공격을 받는다면, 답은 기존 주소를 원격으로 돌봐 주는 것이 아니라 이곳으로의 서버 이전입니다.
두 단계 비교
| 항목 | 포함된 DDoS 상시 방어 | Advanced DDoS Protection |
|---|---|---|
| 요금 | 모든 서버 상품에 추가 요금 없이 포함 | 월 50.00 EUR부터, PrePaid |
| 필터링 용량 | 17 Tbps 글로벌 스크러빙과 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링 | 동일한 2단계 필터링 |
| 동작 시작 | 서버 제공 시점 | 방어 IP 제공 시점 |
| IP 주소 | 서버의 IP 주소 | 추가로 받는 전용 방어 IP |
| 규칙 세트 | 자동 프로필, 설정 불필요 | 고객 포털에서 포트와 프로토콜별 자체 규칙 |
| 변경 | 자동으로 함께 적용 | 실시간 반영, 공격 중에도 가능 |
| null-routing | 없음 | 없음 |
| 이용 기간 | 서버 상품에 연동 | PrePaid, 최소 이용 기간 없음, 해지 통보 기간 없음, 설치비 없음 |
운영 중에 실제로 걸러 낸 공격 네 건
다음 네 건의 공격은 KernelHost 고객의 서버로 들어왔고 모두 실시간으로 완전히 걸러졌으며, 각각 장애 없이 지나갔습니다. 그림은 방어의 실시간 모니터링에서 가져왔습니다.
TeamSpeak 3 음성 서버, UDP 포트 9987. 여러 패턴이 동시에 들어온 복합 공격으로, 473.4 Gbit/s를 넘고 초당 4,150만 패킷을 넘었습니다. 1 Gbit/s 회선의 패킷 전송률로 약 28배입니다.

ARK 게임 서버, UDP 포트 7777. 복잡한 구조 없는 단순 UDP 플러드였지만 112.2 Gbit/s를 넘고 초당 870만 패킷을 넘었습니다. ARK 클러스터를 그 옆에서 직접 어떻게 지키는지는 ARK 서버를 DDoS 공격으로부터 방어하기에 있습니다.

모든 포트를 향한 공격, TCP와 UDP 포트 0-65535. 열두 가지가 넘는 주요 공격 패턴이 모든 포트를 향해 동시에 들어왔고, 합계 21.3 Gbit/s를 넘고 초당 390만 패킷을 넘었습니다. 이 사례는 2025년 5월 Cloudflare 사례에서 평균 21,925개의 목표 포트로도 나타난 그 분산을 보여 줍니다.

Minecraft와 OpenVPN, TCP 포트 25565와 UDP 포트 1194. 열여섯 가지가 넘는 주요 공격 패턴, 초당 400만 패킷 이상, 8.6 Gbit/s 이상이 결합된 공격입니다. 두 서비스는 서로 다른 프로토콜을 쓰는데도 내내 접속 가능한 상태로 남았습니다.

공격을 받았을 때 해야 할 일, 이 순서로
개별 단계보다 순서가 더 중요합니다. 가장 흔한 실수가 첫 5분 안에 벌어지기 때문입니다.
- 설정을 손대지 말고 측정하세요. 먼저
sar -n DEV 1 10,ip -s link show,ss -s,dmesg -T의 값을 파일로 확보하세요. 공격이 끝나면 그 값은 사라지고, 그것이 없으면 아무도 여러분을 도울 수 없습니다. - 재시작하지 마세요. 재시작은 모든 카운터, 모든 연결 상태, 모든 증거를 지우고, 부하는 몇 초 뒤에 다시 돌아옵니다.
- 어느 계층인지 확인하세요. 바이트를 패킷으로 나누면 평균 패킷 크기가 나옵니다. 100 바이트 미만이면 프로토콜 공격, 1,000 바이트 초과면 증폭 공격, 크기는 평범한데 CPU 부하가 높으면 레이어 7을 가리킵니다.
- 관리 포트를 닫으세요. 패널, 데이터베이스, RCON, 공개될 필요가 없는 모든 것은 여러분 자신의 주소로 제한해야 합니다. 그러면 공격 표면이 즉시 줄어들고 사용자에게는 위험이 없습니다.
- 속도 제한을 설정하세요. 조회 포트에는 좁게, 이용 포트에는 넉넉하게. 조회 포트를 차단하지는 마세요. 그러면 모든 서버 목록에서 사라집니다.
- 자기 주소를 성급하게 바꾸지 마세요. 주소 변경은 새 주소가 다시 공개되지 않는 동안에만 통하고, 잊고 방치한 옛 DNS 항목 하나가 그 변경을 무의미하게 만듭니다.
- 사업자를 숫자와 함께 참여시키세요. 시각, 목표 포트, 패킷 전송률, 대역폭, 평균 패킷 크기를 적어 티켓을 열어 주세요. 이 다섯 가지가 해당 주소의 필터 규칙이 얼마나 빨리 다시 맞춰지는지를 결정합니다.
- 끝난 뒤에는 기록하세요. 언제 시작했고 얼마나 이어졌고 어떤 패턴이었는지 남기세요. 같은 시각에 반복되는 공격은 그 프로젝트에 전용 방어 IP가 필요한지 판단하는 기준입니다.
심각하고 오래 이어지는 공격에 대한 자세한 절차는 심각한 DDoS 공격, 어떻게 대응하나요?에 있습니다.
법적 상황: DDoS 공격은 범죄입니다
오스트리아에서 DDoS 공격은 형법(StGB) 제126b조 “컴퓨터 시스템 기능의 방해”에 해당합니다. 기본 구성 요건은 6개월 이하의 자유형 또는 360일수 이하의 벌금형을 규정합니다. 방해가 상당한 기간 이어지면 2년 이하입니다. 그 목적으로 만들어진 것이 분명한 프로그램으로 많은 시스템을 공격하면 3년 이하입니다. 그리고 손해가 30만 유로를 넘는 경우, 핵심 기반 시설을 공격한 경우, 또는 범죄 단체의 구성원으로서 행한 경우에는 6개월 이상 5년 이하입니다. 이에 더해 형법 제126c조는 그 목적의 프로그램을 제작하고 유포하고 접근 가능하게 만드는 행위 자체를 이미 처벌합니다.
독일에서는 형법 제303b조 “컴퓨터 사보타주”가 적용됩니다. 3년 이하의 자유형 또는 벌금형, 데이터 처리가 사업체나 기업 또는 공공 기관에 쓰이는 경우 5년 이하, 그리고 영업적으로 행한 경우나 핵심 기반 시설을 침해한 경우처럼 특히 중대한 경우에는 6개월 이상 10년 이하입니다. 미수도 처벌되며, 예비 행위에 대해서는 제303b조 제5항이 제202c조를 준용합니다.
그래서 booter 및 stresser 서비스는 회색 지대가 아니라 범죄의 유료 부분입니다. 이때 세 가지가 자주 오해됩니다. 첫째, “자기 시스템의 부하 시험 전용”이라는 문구는 아무것도 합법으로 만들지 않습니다. 그 서비스들이 입력된 목표가 누구의 것인지 확인하지 않기 때문입니다. 둘째, 운영자만이 아니라 의뢰자도 처벌됩니다. Europol은 2026년 4월 집중 단속 주간 이후 바로 이 점을 분명히 하려고 신원이 확인된 이용자 7만 5,000명 이상에게 통지를 보냈습니다. 셋째, 그런 서비스를 통해 자기 서버에 부하 시험을 하는 것 역시 해법이 아닙니다. 공격 트래픽이 사업자의 네트워크를, 그럼으로써 다른 고객의 회선을 지나가기 때문이며, 어떤 호스팅 계약도 이를 금지합니다. 서비스의 부하 한계를 정말로 측정하려면 미리 알리고 사업자와 협의해서 하세요. 이 절은 법령의 현재 상태를 옮긴 것이고 법률 상담이 아닙니다.
여러분의 서비스에 맞는 안내서
이 글은 원리를 설명합니다. 어느 포트를 열어 두어야 하는지, 어떤 설정 지시어가 어떤 조회를 제한하는지, 그리고 각 게임에서 한계가 어디에 있는지는 개별 서비스를 다룬 글에, 각각 포트 사실 정리 표와 함께 들어 있습니다.
- 기초와 절차: DDoS 공격 알아내기, 서버를 DDoS 공격으로부터 방어하기, 심각한 DDoS 공격, 어떻게 대응하나요?, 실시간 필터링을 적용한 게임 DDoS 방어
- Minecraft와 음성: Minecraft와 nullping, Minecraft Bedrock, TeamSpeak 3, Hytale
- GTA 기반 롤플레이: FiveM, RedM, RAGE MP와 alt:V, SA-MP와 open.mp, MTA:SA
- 생존과 건설: Rust, ARK, DayZ, Palworld, Conan Exiles, Project Zomboid, Terraria, Unturned
- 전술과 슈팅: CS2와 Source, Arma 3, Call of Duty, Team Fortress 2, Left 4 Dead 2, Garry's Mod, Mordhau, Lineage 2
핵심 요약
- DDoS 공격은 유한한 네 가지 자원 가운데 하나를 점유합니다. 대역폭, 패킷 전송률, 커널의 상태 테이블, 또는 애플리케이션의 연산 시간입니다. 보안 취약점을 이용하지 않으므로 업데이트만으로는 막히지 않습니다.
- RFC 4732는 DoS 공격을 출발지의 개수가 아니라 효과로 정의합니다. 출발지가 수없이 많을 때 분산 공격이라고 부르며, 2025년 5월 Cloudflare 사례에서는 161개국의 주소 122,145개였습니다.
- CISA, FBI, MS-ISAC는 세 가지 기법을 구분합니다. Gbit/s로 재는 볼류메트릭, 초당 패킷으로 재는 프로토콜 기반, 초당 요청으로 재는 애플리케이션 기반입니다. 각각 다른 방어가 필요합니다.
- 증폭 공격은 열려 있는 UDP 서비스를 악용합니다. 계수는 Steam 프로토콜의 5.5부터 SSDP의 30.8, NTP의 556.9를 거쳐 memcached의 51,000까지이며, US-CERT TA14-017A에서 확인할 수 있습니다.
- 용량은 탈취된 기기로 이뤄진 봇넷에서 나옵니다. 2016년 Mirai의 60만 대부터, 31.4 Tbit/s의 기록적 공격 뒤에 있는 추정 100만에서 400만 대까지이고, 월 10 유로 수준부터 되팔립니다.
- 서버에서는
nftables, SYN 쿠키, 조정한 conntrack 상한, 출발지 주소별 속도 제한이 통합니다. 이 조치들은 초당 약 150만 패킷에서 끝납니다. 1 Gbit/s 회선이 그 이상을 나르지 못하기 때문입니다. - 그 한계를 넘어서면 서버 앞단 네트워크의 필터링만이 결과를 결정합니다. null-routing은 방어가 아니라 공격자가 원했던 결과입니다.
- KernelHost에서는 2단계 상시 방어가 모든 서버 상품에 추가 요금 없이 포함되어 서버 제공 시점부터 동작하고, null-routing을 쓰지 않습니다. 글로벌 스크러빙 네트워크의 17 Tbps 방어 용량과 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링입니다. Advanced DDoS Protection은 월 50.00 EUR부터 전용 방어 IP와 포트별로 직접 관리하는 규칙을 더해 줍니다.
- DDoS 공격은 오스트리아에서 형법 제126b조, 독일에서 형법 제303b조에 따라 처벌되며, 서비스 운영자만이 아니라 의뢰자도 마찬가지입니다.
프로젝트가 이미 KernelHost에 있다면 필터링은 여러분이 아무것도 하지 않아도 동작하고 있습니다. 그래도 이상한 점이 보이면 7번 단계의 다섯 가지 정보를 담아 지원 티켓을 열어 주세요. 해당 IP 주소의 필터 규칙을 다시 맞춰 드립니다. 공격이 진행 중일 때는 WhatsApp 긴급 채팅 +43 650 8209883으로도 연락하실 수 있습니다.
자주 묻는 질문
DDoS 공격이란 무엇인가요?
DoS와 DDoS의 차이는 무엇인가요?
DDoS 공격에는 어떤 종류가 있나요?
증폭 공격이란 무엇이고 증폭 계수는 얼마나 되나요?
DDoS 공격의 용량은 어디에서 오고 공격 한 건에 얼마가 드나요?
내 서버가 지금 공격받고 있는지 어떻게 알 수 있나요?
어떤 로그 줄이 DDoS 공격을 증명하나요?
서버의 방화벽만으로 DDoS 공격을 막을 수 있나요?
DDoS에 맞서 서버에서 정말로 도움이 되는 설정은 무엇인가요?
조회 포트를 그냥 차단하면 안 되는 이유는 무엇인가요?
null-routing이란 무엇이고 왜 방어가 아닌가요?
서버가 지금 공격을 받고 있다면 가장 먼저 무엇을 해야 하나요?
KernelHost의 서버는 공격 중에 꺼지나요?
KernelHost의 DDoS 방어는 얼마이고 Advanced DDoS Protection은 언제 필요한가요?
DDoS 공격은 처벌되나요?
2023-2026 KernelHost GmbH. 모든 권리를 보유합니다. 본 가이드는 저작권법의 보호를 받습니다. 전체든 일부든, 또는 수정된 형태이든 저희의 서면 동의 없이 다른 웹사이트에 게시할 수 없습니다. 출처를 밝히고 링크를 덧붙인 인용은 언제든지 환영합니다.

