Call of Duty 서버를 DDoS 공격으로부터 방어하기
Call of Duty 서버에 실제로 필요한 포트는 무엇인지, 게임과 쿼리와 RCON이 왜 같은 포트에 놓이는지, getstatus 반사 공격과 RCON 공격은 어떻게 제한하는지, 그리고 어느 공격 규모부터 서버 앞단 네트워크의 필터링만이 통하는지 정리했습니다.
Call of Duty 서버를 DDoS 공격으로부터 방어하는 일은 고전 타이틀에서는 반갑도록 구체적인 작업입니다. UDP 포트 하나, server.cfg의 Dvar 몇 개, 그리고 엔진이 2003년부터 지니고 있는 증폭 경로 하나가 전부입니다. 반면 저녁에 한 판이 진행되는 도중 모든 플레이어를 동시에 잃는 서버는 하드웨어 문제인 경우가 드뭅니다. 대개는 공격이 진행 중이고, 그것도 서버가 가득 찬 바로 그때 벌어집니다.
이 글은 먼저 이 내용이 어떤 타이틀에 적용되는지 밝히고, 그다음 추가 비용 없이 직접 조치할 수 있는 것을 보여 주고, 이어서 그 조치가 기술적으로 어디에서 한계에 이르는지, 마지막으로 서버 앞단 네트워크에서 무엇이 이뤄져야 하는지 설명합니다. 명령은 Debian 12, Debian 13, Ubuntu 22.04 LTS, Ubuntu 24.04 LTS를 기준으로 root를 전제로 적었으니, 일반 사용자라면 앞에 sudo를 붙이세요.
공격이 지금 진행 중이라면: 지금은 server.cfg를 건드리지 마시고 서버를 재시작하지도 마세요. 먼저 “로그 기록” 절의 측정값부터 확보하세요. 공격이 끝나면 그 값은 사라집니다.
어떤 Call of Duty 타이틀에서 서버를 DDoS로부터 방어할 수 있나요
Call of Duty 서버를 DDoS로부터 방어하는 것은 자체 전용 서버를 허용하는 타이틀에서만 가능합니다. Call of Duty(2003) 원작, Call of Duty United Offensive, Call of Duty 2, Call of Duty 4 Modern Warfare, Call of Duty World at War가 여기에 해당하고, 여기에 커뮤니티 플랫폼 Plutonium(World at War, Black Ops, Black Ops II, Modern Warfare 3), IW4x(Modern Warfare 2), CoD4X(Call of Duty 4)가 더해집니다. 이 타이틀은 모두 같은 구조를 지닙니다. server.cfg 하나, 열린 UDP 포트 하나, 그리고 공개 서버 목록의 항목 하나입니다.
현대 시리즈에는 이 글이 명시적으로 적용되지 않습니다. Warzone, Modern Warfare(2019), Black Ops Cold War, Vanguard, Modern Warfare II, Modern Warfare III, Black Ops 6에는 임대할 수 있는 전용 서버가 없습니다. 대전은 Activision의 매치메이킹 인프라에서 진행되며, server.cfg도 서버 브라우저도 없고, 여러분이 열거나 보호할 수 있는 포트도 없습니다. Activision이 이 타이틀에 대해 공개하는 포트 목록(그중 TCP 3074와 27014부터 27050까지, 그리고 UDP 3074, 3478, 27000부터 27031까지)은 클라이언트와 플랫폼 포트를 설명하는 것이지 서버 포트가 아닙니다. Warzone에서 접속이 끊긴다면 자기 회선의 문제이거나 Activision 쪽의 문제이며, 서버를 임대해서 해결되는 문제가 아닙니다.
왜 하필 Call of Duty 서버가 공격받나요
Call of Duty 서버에는 손쉬운 표적으로 만드는 네 가지 특성이 겹쳐 있습니다. 첫째, 목록에 오른 서버는 모두 자기 주소를 스스로 공개합니다. 서버 목록의 항목에는 IP 주소와 포트가 평문으로 담겨 있고, 그러지 않으면 아무도 들어올 수 없습니다. 둘째, 모든 트래픽이 UDP로 흐르고, UDP에는 요구할 수 있는 연결 수립 절차가 없으며 출발지 주소는 위조할 수 있습니다. 셋째, 엔진은 누구의 상태 조회에든 응답하고, 조회하는 쪽은 게임을 실행할 필요조차 없습니다. 넷째, 원격 제어 RCON이 게임 자체와 같은 포트에 놓여 있습니다.
여기에 사회적인 부분이 더해집니다. 차단된 플레이어, 클랜 사이의 경쟁, 몇 년째 서로 아는 커뮤니티 안의 갈등입니다. 공격을 시작하는 쪽은 실력도 이렇다 할 비용도 들이지 않습니다. 이른바 booter와 stresser는 월 몇 유로짜리 구독으로 팔리고, 게임 서버를 이용한 증폭 공격은 거기서 기본 상품에 속합니다. DDoS 공격이 구체적으로 무엇인지는 DDoS 공격이란 무엇인가? 글에서 설명합니다.
실제로 문제가 되는 포트
고전 Call of Duty 서버는 정확히 하나의 UDP 포트, 곧 28960을 차지합니다. 이 하나의 포트에서 세 가지가 동시에 돌아갑니다. 게임 트래픽, 서버 목록의 상태 조회, 그리고 원격 제어 RCON입니다. 별도의 쿼리 포트도, 별도의 RCON 포트도 없습니다. 전용 서버의 시작 줄은 모든 타이틀에서 같고, 실행 파일 이름만 다릅니다.
+set dedicated 2 +set net_ip 0.0.0.0 +set net_port 28960 +set sv_maxclients 32 +exec server.cfg +map_rotate
| 타이틀 또는 플랫폼 | 용도 | 포트 | 프로토콜 |
|---|---|---|---|
| Call of Duty, United Offensive, Call of Duty 2, Call of Duty 4, World at War | 게임, 쿼리, RCON 공용 | 28960 | UDP |
| 같은 머신의 추가 인스턴스 | 게임, 쿼리, RCON 공용 | 28961부터 28970까지 | UDP |
| Plutonium T4(World at War) | 게임, 쿼리, RCON 공용 | 28960 | UDP |
| Plutonium T5(Black Ops) | 게임, 쿼리, RCON 공용 | 28960 | UDP |
| Plutonium T6(Black Ops II) | 게임, 쿼리, RCON 공용 | 4976 | UDP |
| Plutonium IW5(Modern Warfare 3) | 게임, 쿼리, RCON 공용 | 27016 | UDP |
| IW4x(Modern Warfare 2) | 게임, 쿼리, RCON 공용 | 28960 | UDP |
| t7x(Black Ops III) | 게임, 쿼리, RCON 공용 | 27017 | UDP |
| Call of Duty 4 마스터 서버(아웃바운드) | 목록 등록과 인증 | 20810과 20800 | UDP |
| Call of Duty 2 마스터 서버(아웃바운드) | 목록 등록과 인증 | 20710과 20700 | UDP |
| Call of Duty 1 마스터 서버(아웃바운드) | 목록 등록과 인증 | 20510과 20500 | UDP |
| IW4MAdmin | 관리용 웹 인터페이스 | 1624 | TCP |
| SSH | 서버 접속 | 22 | TCP |
마스터 서버 포트는 여러분의 방화벽 허용 규칙에 들어갈 것이 아닙니다. 20810과 20800은 상대 쪽의 목적지 포트이고, 여러분 머신에서 대기하는 포트가 아닙니다. 여러분의 서버가 목록에 먼저 말을 거는 쪽입니다. 그럼에도 많은 포트 개방 안내서가 이 포트를 인바운드로 열라고 권합니다. 그것은 아무런 대가 없이 공격 표면만 넓히는 일입니다.
Call of Duty에서 흔히 보는 규모
두 번째 표가 더 중요합니다. 아직 스스로 감당할 수 있는지 판단하려는 분께는 특히 그렇습니다. 가득 찬 서버의 평상시 부하를 공격에서 다루게 되는 숫자와 나란히 놓았습니다.
| 항목 | 값 |
|---|---|
플레이어당 송신 속도(sv_maxRate의 일반적인 값) |
초당 25,000 바이트 |
| 슬롯 32개가 모두 찼을 때의 송신 부하 | 초당 약 800 킬로바이트, 곧 약 6.4 Mbit/s |
| 일반적인 게임 서버의 회선 | 1 Gbit/s, 곧 초당 125 메가바이트 |
| 패킷 크기 64 바이트일 때 1 Gbit/s의 패킷 전송률 | 초당 약 149만 개 |
회선 위에서 getstatus 요청의 크기 |
41 바이트(IP 헤더 20 바이트, UDP 헤더 8 바이트, 페이로드 13 바이트) |
| CISA 경고 TA14-017A 기준 Quake 네트워크 프로토콜의 증폭 계수 | 63.9 |
그 값으로 계산한 getstatus 요청의 응답 크기 |
약 2,600 바이트 |
CoD4X에 내장된 getstatus 상한 |
20초당 응답 20개 |
CoD4X에 내장된 getinfo 상한 |
100초당 응답 100개 |
| KernelHost에서 걸러 낸 게임 서버 대상 UDP 플러드 | 112.2 Gbit/s 이상 |
| KernelHost에서 걸러 낸 음성 서버 대상 공격 | 초당 4,150만 패킷 이상과 함께 473.4 Gbit/s 이상 |
게임, 쿼리, RCON이 같은 포트에 놓인 이유
이것이 Call of Duty에서 결정적인 특이점입니다. 모든 고전 Call of Duty 타이틀이 올라서 있는 id Tech 3 엔진에는 게임, 조회, 원격 제어를 위한 별도의 포트가 없습니다. 모든 것이 하나의 UDP 포트에서 이른바 연결 없는 패킷으로 흐릅니다. 연결 없는 패킷은 0xFF 네 바이트로 시작하고 그다음에 명령 이름을 평문으로 담는 UDP 패킷입니다. getstatus, getinfo, getchallenge, connect 또는 rcon이 그것입니다.
실제 결과는 불편합니다. 게임까지 함께 막지 않고서는 방화벽으로 RCON을 게임에서 떼어 낼 수 없습니다. 포트 28960에 걸린 규칙은 언제나 전부에 적용됩니다. 쿼리 플러드와 RCON 공격만 골라내려면 포트 번호만 보지 말고 패킷 내용을 들여다봐야 합니다. 바로 그래서 포트 기반 방화벽 규칙은 쿼리 포트가 분리된 게임보다 Call of Duty에서 더 이르게 한계에 이릅니다.
Call of Duty의 getstatus 반사 공격이란 무엇인가요?
getstatus 반사 공격은 공격자가 출발지 주소를 위조한 작은 상태 조회를 여러 게임 서버에 보내, 그 서버의 훨씬 큰 응답이 실제 피해자에게 쏟아지도록 만드는 증폭 공격입니다. 이때 게임 서버는 표적이 아니라 증폭기입니다. 이 경로는 id Tech 3 엔진에서 십 년이 넘게 문서로 확인되어 있고, Quake 3와 그 나머지 파생작과 마찬가지로 Call of Duty에도 해당합니다.
여러분은 두 방향에서 이중으로 맞습니다. 공격받는 쪽으로서는 getstatus 요청의 홍수를 받고, 이것이 CPU 시간과 송신 대역폭을 소모하며, 플레이어는 이를 랙 스파이크로 느낍니다. 원치 않은 증폭기로서는 남의 피해자에게 응답을 보내게 되고, 어뷰즈 신고는 여러분에게 옵니다. 둘 다 같은 포트에서 같은 패킷으로 일어나고, 둘 다 사용률 그래프에서는 처음에 무해하게 보입니다.
getstatus 패킷의 모습
요청은 0xFF 네 바이트와 getstatus라는 단어로 이뤄지고, 합해서 페이로드 13 바이트입니다. IP 헤더와 UDP 헤더를 더하면 회선 위에서 41 바이트입니다. Call of Duty 포럼에서 수년째 돌아다니는 방화벽 규칙의 길이 검사가 바로 이 값을 겨냥합니다.
iptables -A INPUT -p udp -m length --length 41:45 -m recent --set --name getstatus_cod
iptables -A INPUT -p udp -m string --algo bm --string "getstatus" -m recent --update --seconds 1 --hitcount 20 --name getstatus_cod -j DROP
응답은 비교할 수 없이 큽니다. statusResponse는 서버 설정 전체를 문자열로 담고 여기에 접속한 플레이어마다 한 줄을 더하므로, 서버가 가득 차면 수 킬로바이트가 됩니다. CISA는 UDP 증폭 공격 개요(TA14-017A)에서 Quake 네트워크 프로토콜의 증폭 계수를 63.9로 제시하고, 악용되는 명령으로 서버 정보 교환을 명시합니다. 이로써 위조된 요청 1 Mbit/s가 피해자에게는 약 64 Mbit/s가 됩니다. 비교하면 DNS는 같은 개요에서 28에서 54 사이이고, NTP는 556.9입니다.
내장된 제동 장치: sv_queryIgnoreTime과 sv_queryIgnoreMegs
Call of Duty 4에는 서버 버전 1.7부터 내장 쿼리 제동 장치가 있습니다. 상태 조회를 보낸 주소를 모두 기억해 두고, 같은 주소에서 오는 이후 조회를 설정한 시간만큼 무시합니다. Dvar 네 개가 이를 제어하며, 기본값은 다음과 같습니다.
sv_queryIgnoreMegs 1
sv_queryIgnoreTime 2000
sv_queryBounceIgnoreTime 12000
sv_queryIgnoreDebug 0
sv_queryIgnoreMegs는 무시 목록이 차지할 수 있는 메모리 양을 정합니다. 1 메가바이트는 약 65,000개 주소를 담고, 그 뒤로 1 메가바이트마다 약 87,000개가 더 들어갑니다. 값 0은 제동 장치를 완전히 끄며, 많은 서버가 정확히 그 상태입니다. 설정이 오래된 예시 파일에서 왔기 때문입니다. sv_queryIgnoreTime은 밀리초 단위의 차단 시간입니다. sv_queryBounceIgnoreTime은 응답이 “ICMP Port Unreachable”로 되돌아올 때, 곧 여러분의 서버가 남의 피해자를 향한 증폭기로 악용되고 있을 때 작동합니다. sv_queryIgnoreDebug 1은 적용 내역을 로그에 기록하므로, 무슨 일이 벌어지고 있는지 비로소 보이게 해 줍니다.
CoD4X를 쓴다면 서버 코드에 고정 상한이 추가로 있습니다. getstatus 응답은 20초당 최대 20개, getinfo 응답은 100초당 최대 100개, RCON 오류 메시지는 100 밀리초당 최대 한 개입니다. 소스 코드의 주석은 의도를 분명히 밝힙니다. 서버가 넘치도록 얻어맞는 것은 감수하되, 그러면서 송신 대역폭을 낭비하지는 말자는 것입니다. 우선순위를 옳게 잡은 것이지만, 서버 앞단의 필터링을 대신하지는 못합니다.
Call of Duty에서 RCON이 역사적으로 문제인 이유
RCON은 서버의 원격 제어이고, Call of Duty에서는 게임 포트에 실린 암호화되지 않은 UDP 패킷입니다. RCON 명령은 회선 위에서 이렇게 보입니다. 0xFF 네 바이트, 그다음 rcon이라는 단어, 그다음 평문 비밀번호, 그다음 실제 명령입니다. 암호화도, 세션도, 사용자 계정도, 두 번째 인증 수단도 없습니다. 여기서 세 가지 문제가 따라오고, 모두 실제로 일어나는 문제입니다.
- 엿보기. 경로의 어느 지점에서든 트래픽을 볼 수 있는 사람은 여러분의 RCON 비밀번호를 평문으로 함께 읽습니다. 이는 여러분과 서버 사이의 모든 네트워크에, 그리고 비밀번호를 건네는 모든 도구에 해당합니다.
- 추측. 잠글 수 있는 로그인도, 열 번 실패 뒤의 계정 차단도 없습니다. 공격자는 원하는 속도로 비밀번호를 하나씩 시도합니다. 원본 서버는 이를 전혀 제동하지 않고, CoD4X는 오류 메시지 응답만 100 밀리초당 한 개로 제동하며 시도를 “Bad rcon”으로 기록합니다.
- 반사. RCON 오류 메시지도 위조된 패킷에 대한 응답입니다. 위조된 RCON 패킷으로 여러분의 서버를 때리는 사람은 서버를 작은 증폭기로 쓰는 것이고, 여러분의 서버는 덤으로 자기 로그를 가득 채웁니다.
실제 결론은 이렇습니다. RCON이 정말 필요할 때만 rcon_password를 설정하세요. 필요하다면 길고 무작위로 정하세요. CoD4X는 최소 여덟 자를 요구하지만, 이는 하한선이고 권고 사항이 아닙니다. 평소 관리는 열린 네트워크의 RCON이 아니라 SSH와 서버 콘솔로 하세요. 그리고 자체적으로 RCON을 통해 말을 거는 IW4MAdmin 같은 관리 도구를 운영한다면, 그 웹 인터페이스가 놓인 포트 1624는 열린 네트워크에 두지 마세요.
돈을 쓰기 전에 직접 할 수 있는 일
이 절이 가장 길고, 의도한 바입니다. 설정이 깔끔한 Call of Duty 서버는 어디에 놓여 있든 작거나 중간 규모의 공격을 자체 힘으로 견뎌 냅니다.
1. 현황 파악: 서버에서 무엇이 대기하고 있나요?
규칙을 한 줄이라도 쓰기 전에 서버가 외부에 무엇을 내주고 있는지 확인하세요. 추측하지 말고 직접 확인합니다.
ss -lntup
여기서 중요한 것은 로컬 주소 열입니다. 0.0.0.0:28960과 [::]:28960은 “인터넷 전체에서 접근할 수 있음”을 뜻하고, 127.0.0.1:3306은 “로컬에서만 접근할 수 있음”을 뜻하므로 방화벽 규칙이 필요하지 않습니다. 게임 외에도 IW4MAdmin, Fast Download용 웹 서버, 통계용 데이터베이스, 잊고 방치한 두 번째 게임 인스턴스가 함께 나타나는 일이 잦습니다. 공격자의 시선은 외부에서 실행하는 포트 스캔이 보여 줍니다.
nmap -Pn -sU -p 28960-28970,4976,27016 YOUR.SERVER.IP.ADDRESS
nmap -Pn -p- --min-rate 1000 YOUR.SERVER.IP.ADDRESS
2. 게임이 실제로 필요한 것만 열어 두기
Call of Duty 서버 하나에는 외부로 단 하나의 허용 규칙이면 충분하고, 나머지는 제한하거나 애초에 공개하지 않습니다. UFW에서는 다음과 같이 하며, 스스로 접속이 막히지 않도록 반드시 이 순서를 지키세요.
ufw allow 22/tcp comment 'SSH'
ufw allow 28960/udp comment 'Call of Duty'
ufw allow from 203.0.113.10 to any port 1624 proto tcp comment 'IW4MAdmin'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose
203.0.113.10은 본인 주소로 바꾸세요. Plutonium T6에서는 28960/udp 대신 4976/udp가, Plutonium IW5에서는 27016/udp가 들어갑니다. 여러 인스턴스를 운영한다면 실제로 쓰는 구간만 허용하세요. 예를 들어 28960부터 28970까지를 통째로 열지 말고 28960:28962/udp만 허용합니다. 아무것도 대기하지 않는 포트는 침입 경로가 되지는 않지만, 공격을 받으면 그래도 커널에 일거리를 만듭니다. 복구 방법까지 포함한 전체 안내는 스스로 접속이 막히지 않게 UFW 방화벽 설정하기에 있습니다.
3. server.cfg에서 쿼리 제동 장치 켜기
다음 네 줄은 Call of Duty 4 서버의 어느 server.cfg에나 들어가야 하고, 메모리 몇 메가바이트 외에는 아무 비용도 들지 않습니다.
set sv_queryIgnoreMegs "4"
set sv_queryIgnoreTime "2000"
set sv_queryBounceIgnoreTime "12000"
set sv_queryIgnoreDebug "0"
4 메가바이트는 약 326,000개 주소를 담으므로 본격적인 플러드에도 충분합니다. sv_queryIgnoreTime을 기본값 2000 밀리초보다 올릴 때는 조심하세요. 서버 목록과 모든 서버 브라우저가 같은 방식으로 여러분의 서버를 조회하므로, 차단 시간을 너무 높이면 목록에서 사라집니다. 제동 장치가 실제로 작동하는지 알고 싶으면 sv_queryIgnoreDebug를 잠시 1로 두고, 그다음 다시 0으로 되돌려 로그가 디스크를 채우지 않게 하세요.
4. 방화벽에서 쿼리 플러드 골라내기
엔진의 제동 장치는 패킷이 게임 프로세스에 닿은 뒤에야 작동합니다. 방화벽 규칙은 더 이른 단계에서 판단하고 비용도 덜 듭니다. 다음 두 줄은 출발지 주소별로 getstatus를 제한합니다.
iptables -A INPUT -p udp --dport 28960 -m length --length 41:45 -m recent --set --name cod_query --rsource
iptables -A INPUT -p udp --dport 28960 -m string --algo bm --string "getstatus" -m recent --update --seconds 2 --hitcount 4 --name cod_query --rsource -j DROP
첫 번째 줄은 상태 조회에 흔한 길이의 패킷을 보낸 출발지 주소를 모두 기억합니다. 두 번째 줄은 같은 주소가 2초 안에 넷을 넘겨 보내는 순간부터 이후의 getstatus 요청을 모두 폐기합니다. 2초에 네 번이면 어느 서버 브라우저에나 충분합니다. 포럼에는 초당 20회로 잡은 변형도 돌아다니는데, 훨씬 넉넉한 값이라서 정교한 반사 공격보다는 엉성한 봇에 더 잘 듣습니다.
iptables 규칙만 쓰면 재시작 후에 사라지므로 Debian과 Ubuntu에서는 다음과 같이 저장합니다.
apt-get install -y iptables-persistent
netfilter-persistent save
UFW를 쓴다면 이런 규칙은 /etc/ufw/before.rules에 들어가야 합니다. 그러지 않으면 다음 ufw reload에서 사라집니다. 그다음 iptables -L INPUT -n -v로 매칭 카운터가 올라가는지 확인하세요. 0에 머물러 있으면 규칙에 도달하지 못하는 것입니다.
5. RCON을 끄거나 좁게 운용하기
가장 안전한 RCON 접속은 존재하지 않는 접속입니다. 빈 rcon_password는 모든 RCON 패킷을 거부합니다.
set rcon_password ""
여기에는 한 가지 세부 사항이 있습니다. 서버는 그래도 응답하는데, 오류 메시지로 응답하므로 작은 증폭기로 남습니다. 그것까지 막고 싶고 RCON도 고정된 주소에서만 필요하다면, 그 전에 패킷을 폐기하세요.
iptables -A INPUT -p udp --dport 28960 ! -s 203.0.113.10 -m string --algo bm --string "rcon " -j DROP
이 규칙에는 알아 두어야 할 부작용이 있습니다. rcon이라는 문자열은 이론적으로 접속한 플레이어의 채팅 패킷에도 나타날 수 있고, 그러면 그 패킷도 함께 폐기됩니다. 실제로는 감수할 만합니다. 부작용을 원하지 않는다면 규칙을 빼고, 비어 있거나 아주 긴 비밀번호만으로 운용하세요.
6. 접속 플러드와 슬롯 고갈 막기
접속 플러드는 회선이 아니라 게임 로직을 노립니다. 공격자는 getchallenge와 connect 패킷을 빠르게 연달아 보내 모든 슬롯이 반쯤 완성된 연결로 채워지게 만듭니다. 그러면 게임 안에 아무도 없는데도 실제 플레이어에게는 “Server is full”이 뜹니다. 여기에는 다음 설정이 듣습니다.
set sv_maxclients "32"
set sv_reconnectLimit "3"
set sv_floodProtect "1"
set sv_connectTimeout "30"
set sv_timeout "120"
sv_reconnectLimit은 같은 플레이어가 연달아 몇 번까지 다시 접속할 수 있는지 제한합니다. sv_floodProtect는 서버가 플레이어별로 처리하는 클라이언트 명령의 수를 제한해, 한 클라이언트가 명령으로 서버를 느려지게 하는 것을 막습니다. sv_connectTimeout과 sv_timeout은 반쯤 완성된 연결과 응답 없는 연결이 각각 얼마나 오래 슬롯을 붙잡을지 정합니다. 여기에 오래된 예시 파일의 넉넉한 값을 그대로 두면 공격자에게 슬롯 고갈을 쉽게 만들어 주는 셈입니다.
CoD4X에서는 sv_authorizemode가 더해집니다. 값 1은 정품을 가진 플레이어만 들이고, 0은 정품이 없는 플레이어만, -1은 둘 다 들입니다. 1을 설정하면 일회용 클라이언트를 상당 부분 차단하지만, 원본을 갖지 않은 실제 플레이어도 잃습니다. 가장 강한 수단은 g_password로 설정하는 서버 비밀번호이며, 정규 접속 경로를 쓰는 모든 것에 듣습니다. 그리고 한 가지는 분명히 해 두어야 합니다. 비밀번호는 여러분의 게임 로직을 지켜 줄 뿐 회선을 지켜 주지 않습니다. 서버를 플러딩하는 공격자는 애초에 접속할 생각이 없습니다. 그 패킷은 거부되지만 그래도 이미 도착해 있고, 바로 그것이 핵심입니다.
7. 서버 목록의 항목과 여러분의 주소
여기서는 희망적 사고보다 솔직함이 낫습니다. 여러분의 IP 주소는 비밀로 유지할 수 없습니다. 한 번이라도 접속했던 플레이어는 모두 알고 있고, 목록 항목은 포트까지 함께 어차피 공개합니다. server.cfg에 마스터 서버를 설정하지 않으면(해당 Dvar는 sv_master1, sv_master2 등입니다) 항목을 끌 수 있습니다. 다만 그러면 새 플레이어를 향한 노출을 전부 잃고, 가장 게으른 공격자에게만 듣습니다.
목록의 위치에 관해 한마디 덧붙이면, Activision의 원래 마스터 서버(codmaster.activision.com의 20510, cod2master.activision.com의 20710, cod4master.activision.com의 20810)는 옛 타이틀에 대해 더 이상 아무것도 응답하지 않습니다. 오늘 목록에 오르려는 사람은 커뮤니티 목록을 씁니다. CoD4X는 자체 목록을 운영하며 이를 위해 sv_authtoken에 토큰을 요구하고, Plutonium은 자체 서버 목록을 함께 제공합니다. 사정 자체는 달라지지 않습니다. 거기에도 주소가 똑같이 평문으로 올라갑니다.
그래도 두 가지 습관은 듣습니다. 원시 IP 주소를 어디에도 스스로 공개하지 마세요. Discord 채널에도, 클랜 홈페이지에도 올리지 않는 것입니다. 그리고 플레이어를 호스트 이름으로 접속시켜, 만일의 경우에 모든 참조가 깨지지 않으면서 주소를 바꿀 수 있게 하세요. 여기서 고전적인 실수는 옛 주소를 가리키는 A 레코드를 잊고 방치하는 것입니다. 그것은 어떤 변경도 무의미하게 만듭니다.
8. 웹 인터페이스, 데이터베이스, Fast Download를 열린 네트워크에서 빼기
대부분의 Call of Duty 서버에서는 게임 외에도 더 많은 것이 돌아갑니다. 포트 1624의 웹 인터페이스를 가진 IW4MAdmin, 맵의 Fast Download를 담당하는 웹 서버, 때로는 통계용 데이터베이스입니다. 이들 각각이 별개의 공격 표면이고, 그중 어느 것도 제한 없이 열린 네트워크에 둘 것이 아닙니다.
1624를 본인 주소로 제한하거나, SSH 포워딩으로 인터페이스에 접근한 다음 로컬에서 http://127.0.0.1:1624을 여세요.
ssh -N -L 1624:127.0.0.1:1624 root@YOUR.SERVER.IP.ADDRESS
데이터베이스는 127.0.0.1에 바인딩하세요. 어떤 경우에도 열린 네트워크에 둘 것이 아닙니다. 그리고 Fast Download는 게임 프로세스가 아니라 별도의 웹 서버에 두세요. 부하를 받는 웹 서버는 그러지 않으면 게임이 시뮬레이션에 쓸 CPU 시간을 정확히 그만큼 빼앗습니다.
9. 만일의 경우에 데이터를 갖도록 로그 기록하기
가장 중요하면서 거의 아무도 미리 하지 않는 단계가 있습니다. 모든 것이 정상으로 돌아가는 동안에 기준값을 만들어 두는 것입니다. 평상시 값이 없으면 사건이 끝난 뒤에 초당 40,000 패킷이 많았던 것인지 그냥 금요일 저녁이었던 것인지 말할 수 없습니다. apt-get install -y vnstat sysstat로 측정이 상시 돌아갑니다. 사건이 진행되는 동안에는 네 개의 명령으로 충분합니다.
sar -n DEV 1 10
ip -s link show eth0
dmesg -T | tail -50
tcpdump -ni eth0 udp port 28960 -c 200 -q
Call of Duty에는 결정적인 질문에 답해 주는 다섯 번째 명령이 있습니다. 이 캡처는 연결 없는 패킷만, 곧 정확히 getstatus, getinfo, getchallenge, connect, rcon만 보여 줍니다.
tcpdump -ni eth0 'udp port 28960 and udp[8:4] = 0xffffffff' -c 200 -A
거기에 계속 새로 바뀌는 주소에서 getstatus가 수백 번 찍히면 쿼리 플러드입니다. rcon이 찍히면 누군가 여러분의 비밀번호를 추측하려는 것입니다. getchallenge와 connect만 찍히면 접속 플러드입니다. tcpdump에는 한 가지 원칙이 있습니다. 항상 -c로 개수를 제한하세요. 과부하 상태에서의 캡처는 이미 과부하인 서버에 부담을 더 얹습니다. 측정값을 해석하는 방법은 DDoS 공격 알아내기에 있습니다.
이 조치들이 한계에 이르는 지점
이제 어떤 설정 파일로도 해결할 수 없는 부분입니다. 지금까지의 모든 조치는 여러분의 서버, 즉 회선의 끝에서 동작합니다. 방화벽 규칙은 이미 케이블을 지나온 패킷을 두고 판단합니다. 그 패킷을 폐기할 수는 있지만, 보내지 않은 것으로 만들 수는 없습니다.
한번 계산해 보겠습니다. 슬롯 32개가 가득 찬 서버는 송신으로 약 6.4 Mbit/s를 만들고, 이는 기가비트 회선의 1퍼센트에도 못 미칩니다. 같은 회선은 누군가 초당 125 메가바이트를 보내는 순간 꽉 차고, 월 10유로에 주문할 수 있는 공격이 바로 그것을 겨냥합니다. 그 뒤에 놓인 iptables 규칙이 훌륭한지는 그때부터 아무 상관이 없습니다. 플레이어의 패킷이 그 앞에서 이미 통과하지 못하기 때문입니다.
두 번째 수치는 패킷 전송률이고, Call of Duty에서는 대역폭보다 이쪽이 규칙적으로 먼저 터집니다. 64 바이트짜리 작은 패킷이라면 1 Gbit/s 회선에 초당 약 149만 개가 들어갑니다. 일반적인 서버 커널은 CPU와 네트워크 카드에 따라 그중 수십만 개를 처리한 뒤 폐기를 시작합니다. getstatus 요청은 41 바이트로 그보다도 작습니다. 회선을 3분의 1도 채우지 못하는 공격이 그래도 서버를 멈춰 세우는데, CPU 시간 전부가 폐기에 들어가기 때문입니다. 운영자는 이것을 “사용률은 전혀 높지 않았는데 그래도 전부 죽었다”로 경험합니다.
Call of Duty에는 계산을 더 악화시키는 특이점이 있습니다. 게임, 쿼리, RCON이 같은 포트에 놓여 있으므로 비상시에 28960을 닫을 수 없습니다. 그것은 서버를 끄는 것과 같습니다. 그리고 엔진이 모든 상태 조회에 요청 크기의 몇 배로 응답하므로, 공격자는 같은 효과를 내기 위해 다른 게임보다 자기 대역폭을 덜 씁니다.
실제로 어떤 규모가 나오는지 가늠해 보면, KernelHost 서버에서는 음성 서버를 향한 초당 4,150만 패킷 이상과 함께 473.4 Gbit/s 이상의 공격, 그리고 게임 서버를 향한 112.2 Gbit/s 이상의 UDP 플러드가 걸러졌습니다. 이에 대한 로컬 설정은 없습니다. 볼류메트릭 공격은 서버 앞단 네트워크에서 끝나야 합니다.
KernelHost가 이에 맞서 제공하는 것
모든 서버에 포함된 상시 방어
KernelHost의 DDoS 방어는 두 단계로 구성되어 있고 상시 동작합니다. 여러분이 무엇을 켜거나 주문하거나 설정할 필요가 없습니다.
- 1단계: 글로벌 스크러빙 네트워크의 17 Tbps 방어 용량. 볼류메트릭 공격은 발생지에 가까운 곳에서 정화되어 데이터센터에 닿기 전에 걸러집니다.
- 2단계: 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링. 서버 바로 앞에서 프로토콜별 패턴을 찾아내 패킷 하나하나를 폐기합니다.
두 가지 특성이 결정적입니다. 이 방어는 상시 동작하므로 공격에 반응해서 비로소 시작될 필요가 없습니다. 그래서 초반에 서버가 사라지는 몇 분이 존재하지 않습니다. 그리고 null-routing을 쓰지 않습니다. 여러분의 IP 주소는 네트워크에 그대로 남고, 폐기되는 것은 악성 패킷뿐입니다. IP 주소를 네트워크에서 빼 버리면 여러분에게는 공격이 성공한 것과 같은 결과가 됩니다. 어떤 게임과 프로토콜이 포함되는지는 실시간 게임 서버 DDoS 방어에 정리되어 있습니다.
계속 공격받는 프로젝트를 위한 Advanced DDoS Protection
어떤 클랜과 커뮤니티는 어쩌다 한두 번이 아니라, 표적이 되어 몇 주에 걸쳐 공격받습니다. 이런 경우를 위해 Advanced DDoS Protection이 월 50.00 EUR부터, PrePaid 방식으로, 최소 이용 기간 없이 제공됩니다. 차이는 용량이 더 커지는 데 있지 않고 통제권에 있습니다.
- 전용 방어 IP: 프랑크푸르트 코어에서 발급되며, 서버는 자체 네트워크에서 이 IP로 전환됩니다. 여러분 쪽에서 손볼 것은 없습니다.
- 포트와 프로토콜별로 직접 관리하는 방어 규칙: 고객 포털에서 티켓을 쓰지 않고도 UDP 28960에 무엇을 허용할지 설정하고, 인스턴스가 여러 개라면 포트별로 따로 설정할 수 있습니다.
- 변경은 실시간으로 반영: 공격이 진행되는 중에도 값을 조정할 수 있습니다.
- 게임에 맞춘 방어 프로필: 임의의 TCP 또는 UDP 포트에서 개조된 애플리케이션과 자체 애플리케이션도 같은 방식으로 다룹니다. Plutonium과 CoD4X에는 이것이 중요한 지점인데, 그 포트가 기본값과 다를 수 있기 때문입니다.
Advanced DDoS Protection은 KernelHost에 놓인 서버를 위한 것입니다. Call of Duty 서버가 현재 다른 곳에서 돌아가고 거기서 정기적으로 네트워크에서 빠진다면, 상황을 바꾸는 길은 KernelHost로의 이전입니다.
두 단계 비교
| 항목 | 포함된 DDoS 상시 방어 | Advanced DDoS Protection |
|---|---|---|
| 요금 | 모든 서버 상품에 추가 요금 없이 포함 | 월 50.00 EUR부터, PrePaid |
| 필터링 용량 | 17 Tbps 글로벌 스크러빙과 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링 | 동일한 2단계 필터링 |
| IP 주소 | 서버의 IP 주소 | 추가로 받는 전용 방어 IP |
| 규칙 세트 | 자동 프로필, 설정 불필요 | 고객 포털에서 포트와 프로토콜별 자체 규칙 |
| 변경 | 자동으로 함께 적용 | 실시간 반영, 공격 중에도 가능 |
| 게임 프로필 | 주요 게임에 최적화된 프로필 | 게임에 맞춘 프로필, Plutonium과 CoD4X, 자체 포트도 가능 |
| null-routing | 없음 | 없음 |
| 이용 기간 | 서버 상품에 연동 | PrePaid, 최소 이용 기간 없음, 해지 통보 기간 없음, 설치비 없음 |
대부분의 Call of Duty 서버에는 깔끔한 server.cfg와 함께 포함된 상시 방어면 충분합니다. Advanced DDoS Protection은 누군가 이 일을 개인적으로 받아들였을 때의 답입니다.
자주 나오는 실수와 해결 방법
“IP 주소를 바꿨는데 두 시간 뒤에 다시 오프라인이 되었습니다”: 공격자는 새 주소를 옛 주소와 같은 출처에서 얻었습니다. 보통 목록 항목, 상태를 표시하는 Discord 봇, 또는 오래된 DNS 항목입니다. 주소 변경은 시간을 벌어 주는 것이고 해결책이 아닙니다.
“저는 피해자인데도 업체가 어뷰즈 신고를 보냅니다”: 그렇다면 여러분의 서버는 표적이 아니라 증폭기입니다. 누군가 위조된 getstatus 요청을 보내고, 여러분의 서버가 남의 피해자에게 고분고분 응답하고 있습니다. 먼저 sv_queryIgnoreMegs가 0인지 확인하고, 쿼리 Dvar 네 개와 4번 절의 방화벽 규칙을 설정하세요.
“서버가 목록에는 가득 찬 것으로 나오는데 실제로는 비어 있습니다”: 접속 플러드이고, 회선이 아니라 게임 로직을 때립니다. 여기에는 sv_reconnectLimit, sv_connectTimeout과 sv_timeout의 짧은 값, 그리고 경우에 따라 서버 비밀번호가 듣습니다.
“공격 중에 서버가 서버 목록에서 사라집니다”: 그것은 원인이 아니라 결과입니다. 서버 목록은 같은 상태 조회로 여러분의 서버가 살아 있는지 확인합니다. 응답이 통과하지 못하거나 여러분 자신의 제동 장치에 폐기되면 서버는 오프라인으로 간주됩니다. 방화벽을 의심하기 전에 sv_queryIgnoreTime이 너무 높게 잡혀 있지 않은지 확인하세요.
“iptables 규칙이 적용되지 않습니다”: 흔한 원인이 세 가지입니다. 규칙이 UFW 체인 뒤에 있어 전혀 도달하지 못하거나, 마지막 재시작 이후 사라졌거나(이때는 netfilter-persistent save 또는 /etc/ufw/before.rules 항목이 도움이 됩니다), 공격이 볼류메트릭이어서 규칙은 이미 꽉 찬 회선에서 제대로 동작하고 있는 경우입니다. iptables -L INPUT -n -v로 매칭 카운터가 올라가는지 확인하세요.
“서버는 돌아가는데 모든 플레이어에게 랙 스파이크가 있습니다”: CPU 부하가 아니라 인터페이스의 패킷 전송률을 먼저 보세요. sar -n DEV 1 10이 평범한데도 버벅인다면 대개 모드, 과하게 잡은 sv_maxRate, 또는 단순히 한 판에 봇이 너무 많은 것이 원인입니다.
“기존 업체가 제 IP 주소를 차단했습니다”: 그것이 null-routing입니다. 업체는 그렇게 자기 네트워크를 지키지만, 여러분에게 남는 결과는 공격이 성공한 것과 똑같고, 보통 그 뒤로 몇 시간 더 이어집니다. 확실하지 않으면 필터링을 하는지 null-routing을 하는지 물어보세요. 그 답이 어떤 하드웨어 사양보다 여러분의 가용성을 더 크게 좌우합니다.
“tcpdump에 이상한 것이 보이지 않습니다”: 트래픽이 이미 앞단 네트워크에서 걸러지고 있으면 서버에는 아무것도 도착하지 않는 것이 당연합니다. 필터링이 작동하고 있을 때의 정상적인 모습입니다. 반대로 회선이 포화되면 측정에 쓰려던 SSH 세션조차 닿지 않을 수 있습니다. 그럴 때는 게스트 시스템의 네트워크와 무관하게 동작하는 고객 포털의 VNC 콘솔을 이용하세요.
핵심 요약
- 고전 Call of Duty 서버에는 열린 포트가 정확히 하나, 28960 UDP가 필요합니다. Plutonium T6에서는 4976 UDP, Plutonium IW5에서는 27016 UDP입니다.
- Call of Duty에서는 게임, 상태 조회, RCON이 같은 포트에 놓입니다. 포트 규칙으로는 RCON을 게임에서 떼어 낼 수 없고, 그러려면 패킷 내용을 들여다보는 규칙이 필요합니다.
- getstatus 반사 공격이 이 게임에 전형적인 증폭 경로입니다. 요청은 41 바이트이고, CISA 경고 TA14-017A 기준 Quake 네트워크 프로토콜의 계수가 63.9이므로 응답은 약 2,600 바이트입니다.
- 쿼리 제동 장치를 켜세요.
sv_queryIgnoreMegs 4,sv_queryIgnoreTime 2000,sv_queryBounceIgnoreTime 12000입니다. 많은 서버에서 이 값이 0으로 되어 있어 꺼진 상태입니다. rcon_password는 RCON이 정말 필요할 때만 설정하세요. 비밀번호는 암호화되지 않은 채 UDP로 흐르고, 계정 차단이 없으므로 원하는 만큼 추측할 수 있습니다.- 마스터 서버 포트 20810과 20800은 아웃바운드 목적지 포트이므로 인바운드 허용 규칙에 들어갈 것이 아닙니다.
- 대략 1 Gbit/s를 넘거나 초당 수십만 패킷에 이르면, 여러분의 설정이 아니라 서버 앞단 네트워크만이 결과를 결정합니다.
서버가 이미 KernelHost에 있다면 필터링은 여러분이 아무것도 하지 않아도 동작하고 있습니다. 그래도 이상한 점이 보이면 지원 티켓을 열어 주세요. 해당 IP 주소의 필터 규칙을 다시 맞춰 드립니다. 공격이 진행 중일 때는 WhatsApp 긴급 채팅 +43 650 8209883으로도 연락하실 수 있습니다.
자주 묻는 질문
Call of Duty 서버에 필요한 포트는 무엇인가요?
이 글이 Warzone이나 Modern Warfare, Black Ops 6에도 적용되나요?
Call of Duty의 getstatus 반사 공격이란 무엇인가요?
제 서버가 제3자를 향한 공격의 증폭기로 악용되고 있습니다. 어떻게 해야 하나요?
Call of Duty에서 rcon_password가 위험한 이유는 무엇인가요?
Call of Duty 서버가 지금 오프라인입니다. DDoS 공격인지 어떻게 알 수 있나요?
iptables나 UFW로 DDoS 공격에 맞설 수 있나요?
KernelHost의 서버는 공격 중에 오프라인이 되나요?
DDoS 방어에 추가 요금이 드나요? Advanced DDoS Protection은 언제 필요한가요?
2026 KernelHost GmbH. 모든 권리를 보유합니다. 본 가이드는 저작권법의 보호를 받습니다. 전체든 일부든, 또는 수정된 형태이든 저희의 서면 동의 없이 다른 웹사이트에 게시할 수 없습니다. 출처를 밝히고 링크를 덧붙인 인용은 언제든지 환영합니다.

