Team Fortress 2: TF2 서버를 DDoS 공격으로부터 방어하기
Team Fortress 2 서버가 실제로 필요한 포트는 무엇인지, 서버 브라우저에서 떨어지지 않으면서 A2S 조회와 분할 패킷, RCON, 전송률을 어떻게 제한하는지, 그리고 어느 공격 규모부터 서버 앞단 네트워크의 필터링만이 통하는지 정리했습니다.
저녁 라운드 도중에 모든 플레이어를 동시에 잃고 그 뒤로 몇 분 동안 서버 브라우저에서 사라지는 Team Fortress 2 커뮤니티 서버는 하드웨어 문제인 경우가 드뭅니다. 대개는 27015/UDP를 노린 공격이 진행 중입니다. 이 글은 TF2 서버를 DDoS 공격으로부터 방어하는 방법을 보여 줍니다. 먼저 앞으로 십 분 안에 추가 비용 없이 직접 할 수 있는 것, 그다음 이 조치들이 물리적으로 끝나는 지점, 마지막으로 그 앞의 네트워크에서 무엇이 이뤄져야 하는지입니다.
모든 내용은 Debian 12, Debian 13, Ubuntu 22.04 LTS 또는 Ubuntu 24.04 LTS에서 SteamCMD로 설치한 Source 전용 서버(srcds_run -game tf)를 기준으로 합니다. 명령은 root 기준으로 적었으니, 일반 사용자라면 앞에 sudo를 붙이세요. 공격이 지금 진행 중이라면, 먼저 아무것도 바꾸지 말고 서버를 재시작하지도 마시고 9번 절의 측정값부터 확보하세요. 공격이 끝나면 그 값은 사라집니다.
Team Fortress 2 서버에 DDoS 방어가 필요한 이유
Team Fortress 2는 2011년부터 무료로 플레이할 수 있고, 바로 그 점이 공격의 경제성을 바꿉니다. 공격자는 버릴 수 있는 계정을 무한정 가질 수 있고, 어느 계정에도 돈을 낼 필요가 없으며, 차단을 당해도 잃을 것이 없습니다. 유료 게임에서 돈이 드는 일이 여기서는 1분이면 됩니다.
여기에 TF2를 다른 대부분의 게임과 구별해 주는 특성이 하나 더해집니다. 2016년 7월의 “Meet Your Match” 업데이트 이후로는 새 플레이어를 커뮤니티 서버에 자동으로 배분해 주던 Quickplay가 없습니다. 새 플레이어는 Casual 모드에서 Valve 서버로 갑니다. 커뮤니티 서버는 오직 서버 브라우저로만 찾을 수 있습니다. 이 목록에서 떨어진 서버는 프로세스가 아무 문제 없이 돌고 있어도 새 플레이어에게는 사실상 존재하지 않습니다. 그러니 여러분의 서버를 목록에서 밀어내기만 하는 공격도 이미 목적을 이룬 것입니다.
표적도 그에 맞습니다. 고정 플레이어가 있는 상시 운영 커뮤니티 서버(24시간 2Fort, Trade, Jailbreak, Surf, Dodgeball, Mann vs. Machine), ETF2L과 RGL, ozfortress의 리그 운영에서 경기 시간이 정해진 리그 서버, 그리고 방금 누군가를 차단한 운영자의 서버입니다. 계기가 기술적인 경우는 거의 없습니다. DDoS 공격이 대체 무엇인지는 DDoS 공격이란 무엇인가? 글에서 설명합니다.
TF2 서버에서 실제로 문제가 되는 포트
TF2 서버가 외부로 필요한 포트는 정확히 하나, 27015/UDP입니다. 나머지는 모두 끌 수 있거나, 제한해야 하거나, 어차피 아웃바운드로만 동작합니다. 이 표가 아래에 나오는 모든 방화벽 규칙의 바탕입니다.
| 포트 | 프로토콜 | 용도 | 외부에서 접근할 수 있어야 하나요 |
|---|---|---|---|
| 27015 | UDP | 게임 트래픽과 A2S 서버 조회가 같은 포트를 씀, -port로 지정 |
예, 반드시 |
| 27015 | TCP | RCON, rcon_password를 통한 서버 원격 제어 |
아니요, 본인 주소에서만 |
| 27020 | UDP | SourceTV(STV), tv_port로 지정하며 -nohltv로 끌 수 있음 |
실제로 중계할 때만 |
| 27005 | UDP | 플레이어가 아웃바운드로 쓰는 클라이언트 포트(+clientport) |
아니요, 서버에서는 개방이 필요하지 않음 |
| 26900 이상 | UDP | 서버 프로세스의 Steam 포트(-steamport), 인스턴스마다 번호가 올라감 |
아니요, Steam으로 아웃바운드만 |
| 80과 443 | TCP | 맵과 콘텐츠용 FastDL(sv_downloadurl), 같은 호스트에 있는 경우 |
다운로드가 그곳에 있을 때만 |
한 머신에서 여러 인스턴스를 운영하면 번호가 올라갑니다. 게임에는 27016, 27017 등이, SourceTV에는 27021과 27022가 쓰입니다. 설정 파일은 tf/cfg/server.cfg에 있고 맵이 바뀔 때마다 다시 읽힙니다.
공유 포트 27015가 가장 민감한 지점인 이유
TF2에서는 게임 트래픽과 서버 조회가 같은 UDP 포트를 함께 쓰고, 별도의 쿼리 포트는 없습니다. A2S_INFO 요청은 정확히 25 바이트입니다. FF FF FF FF 4 바이트, 0x54 1 바이트, 그리고 끝에 널 바이트가 붙은 20 바이트 문자열 “Source Engine Query”입니다. 서버 이름, 맵, 접속자 수, 태그를 담은 응답은 그보다 몇 배 큽니다. 미국 기관 CISA는 Alert TA14-017A에서 Steam 프로토콜의 증폭 계수를 5.5로 제시합니다.
UDP에는 연결 수립 절차가 없고 출발지 주소는 위조할 수 있으므로, 이것은 여러 해 동안 열려 있던 증폭 구멍이었습니다. 공격자는 피해자의 주소를 출발지로 삼아 남의 Source 서버에 조회를 보내고, 그 서버들은 응답을 피해자에게 보냈습니다. A2S_PLAYER와 A2S_RULES는 처음부터 미리 받아 온 챌린지를 요구했지만 A2S_INFO는 그러지 않았습니다. Valve는 2020년 12월에야 A2S_INFO에도 챌린지를 추가했습니다. 서버는 응답 대신 S2C_CHALLENGE를 돌려줄 수 있고, 조회하는 쪽은 그것을 되돌려 보내야 하며, 그로써 출발지 주소를 위조하지 않았음을 증명합니다.
이로써 반사 공격은 누그러들지만 문제가 끝나지는 않습니다. 조회 패킷은 여전히 여러분에게 도착하고, 응답을 받거나 폐기되기 전에 연산 시간을 소모합니다. 게다가 여러분의 서버를 직접 플러딩하는 공격자에게는 애초에 증폭이 필요하지 않습니다.
돈을 쓰기 전에 직접 할 수 있는 일
이 절이 가장 길고, 의도한 바입니다. 설정이 깔끔한 TF2 서버는 어디에 놓여 있든 작거나 중간 규모의 공격을 자체 힘으로 견뎌 냅니다.
1. 현황 파악: 무엇이 대기하고 있고, 시작 줄은 어떤가요?
규칙을 한 줄이라도 쓰기 전에 서버가 외부에 무엇을 내주고 있는지 확인하세요. 추측하지 말고 직접 확인합니다.
ss -lntup
127.0.0.1이나 ::1에 바인딩된 것은 개방이 필요하지 않습니다. 0.0.0.0이나 [::]에 있는 것은 인터넷에서 접근할 수 있고, 통계 플러그인이 함께 들여온 MySQL 데이터베이스와 FastDL 파일이 놓인 웹 서버도 여기에 해당합니다. 그 결과를 여러분의 시작 줄과 비교하세요.
./srcds_run -game tf -console \
-port 27015 -steamport 26901 -nohltv \
+maxplayers 24 +map ctf_2fort +sv_pure 1 \
+sv_setsteamaccount YOUR_GSLT_TOKEN
이 줄의 포트 하나하나가 의식적인 결정입니다. 기반을 어떻게 설치하는지는 SteamCMD로 게임 서버 설치하기에 있습니다.
2. TF2가 실제로 필요한 포트만 열어 두기
공개 TF2 서버가 외부로 필요한 개방은 정확히 하나이고, 여기에 본인 주소를 위한 RCON이 더해집니다. UFW에서는 다음과 같이 하며, 스스로 접속이 막히지 않도록 반드시 이 순서를 지키세요.
ufw allow 22/tcp comment 'SSH'
ufw allow 27015/udp comment 'TF2 게임과 A2S'
ufw allow from 203.0.113.10 to any port 27015 proto tcp comment 'RCON'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose
203.0.113.10은 본인 주소로 바꾸세요. SourceTV는 여기에 일부러 넣지 않았습니다. 중계하지 않는다면 -nohltv로 실행해 27020/UDP를 애초에 차지하지 않습니다. 이것만으로 TF2 서버가 외부에 내보이는 UDP 표면이 절반으로 줄어듭니다. 리그 경기를 중계한다면 ufw allow 27020/udp가 더해지고, 그때는 tv_password를 설정해야 합니다.
복구 방법까지 포함한 전체 안내는 스스로 접속이 막히지 않게 UFW 방화벽 설정하기에 있습니다. 그래도 막혔다면, KernelHost의 KVM 루트 서버와 Dedicated Server는 고객 포털의 VNC 콘솔로 접근할 수 있습니다. 이 콘솔은 게스트 시스템의 네트워크와 무관하게 동작합니다.
3. 서버 브라우저에서 떨어지지 않으면서 A2S 조회 제한하기
이 주제에서 가장 값비싼 실수가 여기 있습니다. 27015/UDP를 일괄 차단하거나 거칠게 속도 제한하면 자기 플레이어를 내쫓게 되고, 공격은 공격자가 원한 방식으로 끝납니다. 게임 트래픽과 조회가 같은 포트를 차지하므로, 경계는 포트가 아니라 패킷 종류 사이에 그어져야 합니다.
엔진은 이를 위해 콘솔 변수 세 개를 제공하며, 이들은 tf/cfg/server.cfg에 들어가야 합니다.
sv_max_queries_sec 3
sv_max_queries_sec_global 60
sv_max_queries_window 30
첫 번째는 출발지 주소별로 응답해 주는 조회 수를, 두 번째는 모든 주소를 합한 총수를, 세 번째는 평균을 내는 구간을 초 단위로 정합니다. 이 값들은 CPU가 무의미한 응답을 만들어 내는 일을 막아 줍니다. 기본값은 게임과 빌드에 따라 다르고, 서버 콘솔에서 find sv_max_queries를 실행하면 여러분의 서버가 아는 값이 나옵니다.
TF2에서 까다로운 것은 두 번째 값입니다. 이 값은 모든 주소를 합한 응답 수에 상한을 둡니다. 너무 낮게 설정하면 조회 플러드가 벌어지는 동안 서버가 목록 서비스의 요청에도 응답하지 않게 되고, 서버 브라우저에서, 곧 새 플레이어가 여러분을 찾는 유일한 경로에서 사라집니다. 넉넉하게 시작하고, 정상 조회가 통과하는 것을 측정할 수 있게 된 다음에 좁히세요.
한 단계 아래에서는 같은 트래픽을 깔끔하게 갈라낼 수 있습니다. Source 엔진의 연결 없는 패킷은 모두 비트가 모두 설정된 4 바이트(0xffffffff)로 시작하고, 이미 접속한 플레이어의 트래픽에는 이 머리말이 없습니다. 여기에 속도 제한을 걸면 게임 트래픽은 건드리지 않습니다.
table inet tf2 {
chain input {
type filter hook input priority -10; policy accept;
udp dport 27015 @th,64,32 0xffffffff \
meter a2sflood { ip saddr limit rate over 10/second burst 20 packets } drop
}
}
이 파일은 nft -f로 불러옵니다. 우선순위 -10은 규칙이 UFW의 필터 체인보다 먼저 적용되게 하고, @th,64,32는 UDP 헤더 뒤의 첫 4 바이트를 읽습니다.
4. 로그에 NET_GetLong으로 나타나는 분할 패킷 플러드 막기
이 공격은 Source 엔진의 특성이고, TF2가 오늘날까지 옛 엔진 분기에서 돌기 때문에 특히 TF2를 때립니다. 엔진은 평범한 연결 없는 패킷 외에 분할된 패킷도 다룹니다. 이 패킷은 FF FF FF FF 대신 FE FF FF FF로 시작하며, 더 큰 메시지가 여러 조각으로 이어진다고 알립니다. 서버는 조각을 임시로 저장하고 나머지를 기다려야 합니다.
바로 이 점이 악용됩니다. 공격자는 예고만 되어 있고 끝내 완성되지 않는 조각 패킷을 위조된 출발지 주소로 대량 보냅니다. CPU 부하가 올라가고 게임이 버벅이며, 서버 로그에는 NET_GetLong이 담긴 줄이 쌓입니다. 여기에는 컴퓨터 한 대로도 충분하고 대역폭은 거의 필요하지 않습니다. 회선은 거의 비어 있는데도 운영자가 이것을 DDoS 공격으로 신고하는 일이 잦습니다.
정상적인 TF2 클라이언트가 서버에 분할된 패킷을 보낼 이유는 거의 없으므로, 여기서는 좁은 제한도 받아들일 만합니다.
udp dport 27015 @th,64,32 0xfffffffe \
meter tf2split { ip saddr limit rate over 5/second burst 10 packets } drop
이 줄은 3번 절의 규칙과 같은 체인에 들어갑니다. 클라이언트 업로드가 정당하게 필요한 몇 안 되는 이유 가운데 하나는 sv_allowupload 0으로 아예 막아 버릴 수 있습니다(7번 절 참고).
5. RCON을 열린 네트워크에서 빼기
Source 엔진의 RCON 프로토콜은 비밀번호를 TCP로 평문 전송합니다. 여러분과 서버 사이의 경로를 엿볼 수 있는 사람은 그 뒤로 여러분의 RCON 비밀번호를 갖게 되고, RCON을 가진 사람은 맵을 바꾸고 모든 플레이어를 차단하고 서버를 멈출 수 있습니다. 이것은 DDoS 문제가 아니라 서버 탈취이지만, 공격으로 신고되는 일이 잦습니다.
rcon_password는 절대 비워 두지 말고 추측할 수 있는 값으로도 두지 마세요. openssl rand -base64 32로 만든 값이면 충분합니다. 여기에 로그인 시도를 막는 제동 장치가 따라붙어야 합니다.
rcon_password "A_RANDOM_VALUE_HERE"
sv_rcon_maxfailures 3
sv_rcon_minfailures 3
sv_rcon_minfailuretime 30
sv_rcon_banpenalty 1440
이 설정으로 서버는 30초 안에 세 번 실패한 주소를 24시간 동안 차단합니다. find sv_rcon은 여러분의 빌드가 아는 변수를 보여 줍니다. 그래도 더 효과적인 것은 2번 절의 방화벽 규칙입니다. 시도 자체가 애플리케이션까지 도달하지 못하게 막기 때문입니다. 접속 회선이 계속 바뀌는 환경이라면 SSH로 로컬 포워딩을 만들고 그다음에는 127.0.0.1로 RCON에 접속하세요.
ssh -N -L 27015:127.0.0.1:27015 root@YOUR.SERVER.IP.ADDRESS
6. 전송률에 상한을 두고 휴면 상태는 켜 둔 채로 두기
Team Fortress 2는 초당 66.67 틱으로 고정되어 동작합니다. 여기서 얼마만큼의 트래픽이 나오는지는 틱이 아니라 개별 클라이언트가 요청할 수 있는 양이 정합니다. 상한이 없으면 플레이어마다 자기 클라이언트가 요구하는 만큼 가져가고, 그 값은 여러분의 송신 대역폭으로 치릅니다.
sv_minrate 50000
sv_maxrate 100000
sv_mincmdrate 40
sv_maxcmdrate 66
sv_minupdaterate 40
sv_maxupdaterate 66
한번 계산해 보겠습니다. sv_maxrate 100000이면 플레이어마다 초당 100 킬로바이트를 받아 갈 수 있고, 24 슬롯이면 초당 2.4 메가바이트, 곧 아웃바운드로 약 19 Mbit/s입니다. sv_maxrate 0으로 두면 상한이 없습니다. 리그 서버는 의도해서 그렇게 하지만, 슬롯이 많은 공개 서버는 그러지 않는 것이 좋습니다. 틱레이트 제한을 푸는 플러그인은 플레이어별 패킷 전송률을 몇 배로 늘리고, 같은 계산도 그만큼 커집니다.
두 번째 지점은 자주 잘못 다뤄집니다. TF2는 아무도 접속하지 않으면 휴면 상태로 들어가고, 이 상태에서는 CPU를 거의 쓰지 않습니다. 많은 운영자가 서버를 “깨어 있는” 상태로 느끼게 하려고 이 기능을 끕니다. 인스턴스가 여러 개 있는 머신에서 그렇게 하면 CPU가 유휴 상태에서도 이미 다 쓰이고, 공격은 이미 꽉 찬 시스템을 때리게 됩니다. 기본값을 그대로 두세요.
sv_hibernate_when_empty 1
sv_hibernate_postgame_delay 5
tf_allow_server_hibernation 1
7. FastDL 분리하고 업로드 끄기
커뮤니티 서버는 자체 맵으로 살아가고, 바로 거기서 두 번째 공격 표면이 생깁니다. sv_downloadurl이 없으면 플레이어마다 게임의 네트워크 채널로 콘텐츠를 내려받습니다. 곧 경기를 계산하는 바로 그 포트와 그 프로세스를 거칩니다. 속도는 초당 몇 킬로바이트이고 파일도 하나씩 차례로 가므로, 200 메가바이트짜리 맵 모음이라면 플레이어 한 명당 몇 분씩 서버가 붙잡힙니다.
sv_allowdownload 1
sv_allowupload 0
net_maxfilesize 64
sv_downloadurl "https://fastdl.example.org/tf/"
net_maxfilesize는 기본값이 15이고 최대 64 메가바이트까지 올릴 수 있습니다. sv_allowupload 0은 클라이언트가 자기 파일(예를 들어 스프레이 그림)을 서버로 보내는 것을 막고, 그로써 4번 절의 분할된 패킷에 정당한 이유가 되는 몇 안 되는 경우 가운데 하나를 덜어 냅니다.
결정적인 것은 FastDL 호스트가 어디에 있는지입니다. 게임 서버와 같은 IP 주소에 있다면 443/TCP를 겨냥한 HTTP 플러드 하나로 회선이 차고, 그와 함께 27015/UDP도 숨이 막힙니다. 빠른 다운로드를 다른 호스트에 두거나 콘텐츠 네트워크 뒤에 두면, 파일을 겨냥한 공격이 게임까지 때리지 않습니다.
8. 투표 시스템, 접속 플러드, 플러그인 제한하기
모든 장애가 대역폭 때문은 아닙니다. TF2가 무료이기 때문에 게임 논리를 겨냥한 공격에는 계정 말고는 비용이 들지 않습니다. 모든 자리를 차지하는 접속 플러드, 음성과 채팅 스팸, 정상 플레이어를 내쫓는 투표 악용이 여기에 해당합니다. TF2의 기본값은 이 부분에서 이미 합리적인데, 자주 느슨하게 바뀝니다.
sv_allow_votes 1
sv_vote_issue_kick_allowed 0
sv_vote_allow_spectators 0
sv_vote_creation_timer 150
sv_vote_failure_timer 300
sv_vote_quorum_ratio 0.6
이것이 기본값입니다. 투표는 허용되고, 강제 퇴장 투표는 허용되지 않으며, 관전자는 투표에 참여하지 않고, 두 투표 사이에는 150초, 실패한 투표 뒤에는 300초의 간격이 있으며, 투표가 성립하려면 60퍼센트의 찬성이 필요합니다. sv_vote_issue_kick_allowed 1로 설정하는 분은 그로써 공개 서버에서 반드시 악용되는 도구를 열어 준다는 점을 알고 있어야 합니다.
그 이상의 기능은 TF2에서 SourceMod와 Metamod:Source에서 나옵니다. 둘 다 tf/addons/ 아래에 있고 콘솔에서 meta version과 sm version으로 자신을 알립니다. Counter-Strike 2와 달리 여기서는 기반이 충분히 성숙해 있어서, 차단 목록과 접속 검사, 채팅 제한용 플러그인이 일반적인 방법입니다. 여기에 두 가지 원칙이 있습니다. 플러그인은 모두 같은 프로세스 안의 코드이므로, 중단되는 플러그인은 서버까지 함께 끌고 내려갑니다. 그리고 자체 웹 서비스를 함께 들여오는 플러그인은 포트를 더 열고, 때로는 여러분이 지키려는 바로 그 주소를 공개합니다. 실제로 무엇이 돌고 있는지는 sm plugins list가 보여 줍니다.
엔진 쪽을 얼마나 진지하게 받아들여야 하는지는 2020년 4월이 보여 줍니다. TF2와 CS:GO의 옛 소스 코드가 유출된 뒤, Creators.TF와 Red Sun 같은 대형 커뮤니티 운영자들은 악용을 우려해 서버를 일시적으로 내렸습니다. 서버 바이너리를 최신으로 유지하고 확장은 엔진 버전에 맞게 맞춰 두세요.
9. 불이 나기 전에 측정하고 기록하기
가장 중요하면서 거의 아무도 미리 하지 않는 단계가 있습니다. 모든 것이 정상으로 돌아가는 동안에 기준값을 만들어 두는 것입니다. 평상시 값이 없으면 사건이 끝난 뒤에 초당 40,000 패킷이 많았던 것인지 그냥 금요일 저녁이었던 것인지 말할 수 없습니다. 사건이 진행되는 동안에는 네 개의 명령으로 충분합니다.
ip -s link show eth0
nstat -az | grep -i udp
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xffffffff"
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xfffffffe"
첫 번째 명령은 인터페이스별 패킷과 오류, 폐기된 패킷 수를 보여 줍니다. 10초 간격으로 두 번 실행하면 절대값이 아니라 비율을 얻습니다. 두 개의 캡처는 조회 플러드와 분할 패킷 플러드를 갈라내고, 그로써 3번과 4번 절의 두 규칙 가운데 어느 것이 실제로 필요한지에 답해 줍니다. 캡처는 항상 -c로 제한하세요. 과부하 상태에서의 캡처는 그 자체로 연산 시간을 소모합니다.
서버 안에서는 콘솔 명령 stats가 CPU 부하, 초당 킬로바이트 단위의 수신 및 송신 네트워크 부하, 서버 FPS, 접속자 수를 한 줄로 알려 줍니다. 접속자 수는 평범한데 서버 FPS가 틱 값보다 크게 떨어진다면, 서버는 게임이 아닌 다른 일을 하고 있는 것입니다. 이 값들을 어떻게 판단하는지는 서버에서 DDoS 공격 알아내기에 있습니다.
이 조치들이 한계에 이르는 지점: 대역폭과 패킷 전송률
이제 어떤 설정 파일로도 해결할 수 없는 부분입니다. 지금까지의 모든 조치는 여러분의 서버, 즉 회선의 끝에서 동작합니다. 방화벽 규칙은 이미 케이블을 지나온 패킷을 두고 판단합니다. 그 패킷을 폐기할 수는 있지만, 보내지 않은 것으로 만들 수는 없습니다.
꽉 찬 TF2 서버의 평상시 운영을 실제 공격과 나란히 놓으면 그 비율이 분명해집니다.
| 지표 | 24 슬롯, 66.67 틱의 꽉 찬 TF2 서버 | 공격 |
|---|---|---|
| 수신 패킷 | 초당 약 1,600개(플레이어 24명 곱하기 명령 66개) | 초당 수백만 개 |
| 수신 대역폭 | 2 Mbit/s에 크게 못 미침 | 커뮤니티 게임 서버 대상 보통 5 Gbit/s에서 50 Gbit/s |
| 송신 대역폭 | sv_maxrate 100000에서 약 19 Mbit/s |
문제가 되지 않음 |
| A2S 조회 | 목록 서비스별로 1분에 몇 번 | 초당 수천 번 |
| 물리적 상한 | 1 Gbit/s는 가장 작은 패킷을 초당 약 149만 개 나릅니다 | 10 Gbit/s는 약 1,488만 개를 나릅니다 |
일반적인 게임 서버는 1 Gbit/s에 물려 있고, 이는 초당 125 메가바이트이며, 누군가 그보다 많이 보내는 순간 회선은 꽉 찹니다. 두 번째 수치는 패킷 전송률이고, 대역폭보다 먼저 터지는 일이 대부분입니다. 패킷 하나하나가 네트워크 스택을 한 번 통과하는 비용을 치르며, 그 뒤에 폐기되더라도 마찬가지입니다. 그래서 회선을 3분의 1도 채우지 못하는 공격조차 서버를 마비시킵니다. 운영자는 이것을 “사용률은 전혀 높지 않았는데 그래도 전부 죽었다”로 경험합니다.
실제로 어떤 규모가 나타나는지 가늠해 보자면, KernelHost 서버에서는 초당 870만 패킷과 함께 112.2 Gbit/s를 넘긴 게임 서버 대상 UDP 플러드와, 초당 4,150만 패킷과 함께 473.4 Gbit/s를 넘긴 음성 서버 대상 멀티 벡터 공격이 실시간으로 걸러졌습니다. 473.4 Gbit/s는 1 Gbit/s 회선의 약 470배입니다. 여기에 맞는 로컬 설정은 없습니다.
널리 쓰이는 비상 수단 두 가지는 도움이 되지 않습니다. null-routing은 공격받는 IP 주소를 네트워크에서 빼내 공격을 끝내지만, 여러분의 서버도 함께 끝냅니다. 반응형 우회는 전환 시간 동안 정확히 경기가 결정되는 그 몇 분을 잡아먹습니다. 효과가 있는 것은 서버 앞단 네트워크에서 상시 동작하는 필터링뿐입니다.
KernelHost가 TF2 서버 공격에 맞서 제공하는 것
모든 서버 상품에 포함된 상시 방어
KernelHost의 DDoS 방어는 두 단계로 구성되어 있고 서버 제공 시점부터 상시 동작하므로, 여러분이 무엇을 주문하거나 켜거나 설정할 필요가 없습니다.
- 1단계: 글로벌 스크러빙 네트워크의 17 Tbps 방어 용량. 볼류메트릭 공격은 발생지에 가까운 곳에서 정화되어 데이터센터에 닿기 전에 걸러집니다.
- 2단계: 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링. 서버 바로 앞에서 프로토콜별 패턴을 찾아내 패킷 하나하나를 폐기합니다.
TF2 서버에는 두 가지 특성이 결정적입니다. 이 필터링은 상시 동작하므로 공격에 반응해서 비로소 시작될 필요가 없습니다. 그래서 플레이어가 튕기고 서버가 서버 브라우저에서 떨어지는 전환 시간이 존재하지 않습니다. 그리고 null-routing을 쓰지 않습니다. 여러분의 IP 주소는 네트워크에 그대로 남고, 폐기되는 것은 악성 패킷뿐입니다. 어떤 게임과 프로토콜이 포함되는지는 실시간 게임 서버 DDoS 방어에 정리되어 있습니다.
계속 공격받는 서버를 위한 Advanced DDoS Protection
어떤 프로젝트는 어쩌다 한두 번이 아니라 표적이 되어 몇 주에 걸쳐, 패턴을 바꿔 가며, 그리고 늘 정확히 경기 시간에 공격받습니다. 이런 경우를 위해 Advanced DDoS Protection이 월 50.00 EUR부터, PrePaid 방식으로, 최소 이용 기간 없이 제공됩니다. 차이는 용량이 더 커지는 데 있지 않고 통제권에 있습니다.
- 전용 방어 IP: 프랑크푸르트 코어에서 발급되며, 서버는 저희 네트워크에서 이 IP로 전환됩니다. 여러분 쪽에서 손볼 것은 없습니다.
- 포트와 프로토콜별로 직접 관리하는 방어 규칙: 고객 포털에서 27015/UDP에 무엇을 허용할지, 27020/UDP에는 무엇을, 27015/TCP에는 무엇을 허용할지 따로 설정하며, 그러려고 티켓을 쓸 필요가 없습니다.
- 변경은 실시간으로 반영: 경기가 끝날 때까지 기다리지 않고 공격이 진행되는 중에도 값을 조정할 수 있습니다.
- 게임에 맞춘 방어 프로필: Team Fortress 2와 나머지 Source 타이틀은 물론, 자체 애플리케이션을 위한 자유로운 TCP 및 UDP 프로필도 있습니다.
이 상품은 KernelHost에서 돌아가는 서버를 대상으로 합니다. TF2 서버가 지금 다른 곳에 있고 꾸준히 공격받는다면, 이 방어로 가는 길은 이전입니다.
두 단계 비교
| 항목 | 포함된 DDoS 상시 방어 | Advanced DDoS Protection |
|---|---|---|
| 요금 | 모든 서버 상품에 추가 요금 없이 포함 | 월 50.00 EUR부터, PrePaid |
| 활성화 | 서버 제공 시점부터 동작, 설정할 것 없음 | 주문하고 방어 IP를 받으면 서버가 전환됨 |
| 필터링 용량 | 17 Tbps 글로벌 스크러빙과 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링 | 동일한 2단계 필터링 |
| IP 주소 | 서버의 IP 주소 | 추가로 받는 전용 방어 IP |
| 규칙 세트 | 자동 프로필, 세부 조정은 티켓으로 | 고객 포털에서 포트와 프로토콜별 자체 규칙 |
| 변경 | 자동으로 함께 적용 | 실시간 반영, 공격 중에도 가능 |
| 게임 프로필 | Team Fortress 2를 포함한 주요 게임에 최적화된 프로필 | 포트별로 프로필 선택 가능, 개조된 서버도 가능 |
| null-routing | 없음 | 없음 |
| 이용 기간 | 서버 상품에 연동 | PrePaid, 최소 이용 기간 없음, 해지 통보 기간 없음, 설치비 없음 |
대부분의 TF2 커뮤니티 서버에는 깔끔한 서버 설정과 포함된 상시 방어면 충분합니다. Advanced DDoS Protection은 누군가 이 일을 개인적으로 받아들였을 때의 답입니다.
자주 나오는 실수와 해결 방법
“서버는 돌고 있는데 서버 브라우저에는 더 이상 없습니다”: 먼저 Game Server Login Token을 확인하세요. TF2 서버가 공개 목록에 오르려면 토큰이 필요하고, sv_setsteamaccount로 설정하며 앱 ID 440용으로 발급합니다. Steam은 30일 동안 쓰이지 않은 토큰을 회수합니다. 그래서 오랜 휴식 뒤에 사라진 서버는 새 토큰만 필요한 경우가 많고, 공격을 받는 것이 전혀 아닙니다. 그다음에야 너무 낮은 sv_max_queries_sec_global이나 27015/UDP를 겨냥한 지나치게 거친 방화벽 규칙을 따져 볼 차례입니다.
“CPU는 100퍼센트인데 회선은 거의 비어 있습니다”: 조회 플러드나 분할 패킷 플러드의 전형적인 모습입니다. 서버 로그에서 NET_GetLong이 담긴 줄을 살펴보고, 9번 절의 두 tcpdump 줄로 어떤 종류의 패킷이 도착하는지 측정하세요.
“nftables나 iptables 규칙이 적용되지 않습니다”: 흔한 원인이 세 가지입니다. 규칙이 UFW 체인 뒤에 있어 전혀 도달하지 못하거나(그래서 우선순위가 -10입니다), 마지막 재시작 이후 사라졌거나, 공격이 볼류메트릭이어서 규칙은 이미 꽉 찬 회선에서 제대로 동작하고 있는 경우입니다. nft list ruleset으로 카운터가 올라가는지 확인하세요. 0에 머물러 있으면 규칙에 도달하지 못하는 것입니다.
“IP 주소를 바꿨는데 다음 날 다시 오프라인이었습니다”: 공격자는 새 주소를 예전 주소와 같은 출처에서 찾아냅니다. 서버가 서버 브라우저에 다시 오르는 순간 스스로 주소를 공개하고, 오래된 DNS 항목과 Discord 상태 봇이 나머지를 합니다. 주소 변경은 몇 시간을 벌어 줄 뿐이고 해결책이 아닙니다.
“대역폭에는 이상이 없는데 서버가 반복적으로 중단됩니다”: 대개 DDoS 공격이 아니라 엔진 버전에 맞지 않는 플러그인이거나 오래된 서버 바이너리입니다. 여기서는 sm plugins list와 버전 상태 비교가 어떤 필터 규칙보다 빠릅니다.
“유휴 상태 뒤에 서버 반응이 느립니다”: 그것은 휴면 상태이고 오류가 아닙니다. 아무도 접속하지 않는 동안 CPU 부하를 거의 0으로 낮춰 주며, 바로 그 상태가 여유를 남겨 두고 싶은 상태입니다.
“서버에서 남의 관리 명령이 실행됩니다”: DDoS 공격이 아니라 탈취된 RCON 접근입니다. 비밀번호를 곧바로 새로 설정하고, 포트를 본인 주소로 제한하고, 비밀번호가 평문으로 회선을 지나간다는 점을 기억하세요.
“기존 업체가 제 IP 주소를 차단했습니다”: 그것이 null-routing입니다. 업체는 그렇게 자기 네트워크를 지키지만, 여러분에게 남는 결과는 공격이 성공한 것과 똑같고, 보통 그 뒤로 몇 시간 더 이어집니다. 확실하지 않으면 필터링을 하는지 null-routing을 하는지 물어보세요. 그 답이 어떤 하드웨어 사양보다 여러분의 가용성을 더 크게 좌우합니다.
핵심 요약
- TF2 서버가 외부로 필요한 것은 정확히 27015/UDP입니다. 27015/TCP의 RCON은 본인 주소로 제한해야 하고, 27020/UDP의 SourceTV는 중계하지 않는다면
-nohltv로 끕니다. - 게임 트래픽과 A2S 조회가 같은 포트를 함께 씁니다. 27015/UDP를 일괄 차단하거나 속도 제한하면 자기 플레이어를 내쫓게 됩니다. 경계는 패킷 종류 사이에 그어져야 하고, UDP 헤더 뒤의 첫 4 바이트로 구별할 수 있습니다.
- 머리말이
FE FF FF FF인 분할 패킷 플러드는 대역폭이 아니라 CPU 부하를 만들고 로그에NET_GetLong으로 남습니다. TF2에서는 이 패킷 종류를 좁게 제한해도 받아들일 만합니다. - “Meet Your Match” 이후로 새 플레이어는 서버 브라우저로만 커뮤니티 서버를 찾습니다. 여러분을 목록에서 밀어내는 조치는 모두 공격과 같은 효과를 냅니다.
- 24 슬롯이 꽉 찬 서버는 초당 약 1,600개의 수신 패킷을 처리합니다. 커뮤니티 게임 서버를 겨냥한 공격은 보통 5 Gbit/s에서 50 Gbit/s이고 초당 수백만 패킷에 이릅니다.
- 1 Gbit/s는 가장 작은 패킷을 초당 약 149만 개 나릅니다. 이 한계를 넘으면 서버의 어떤 규칙도 아니라 서버 앞단 네트워크만이 결과를 결정합니다.
- KernelHost에서는 2단계 상시 방어가 모든 서버 상품에 추가 요금 없이 포함되어 서버 제공 시점부터 동작하며, null-routing을 쓰지 않습니다. 포트별 규칙을 직접 조정하려면 Advanced DDoS Protection이 월 50.00 EUR부터 더해집니다.
서버가 이미 KernelHost에 있다면 필터링은 여러분이 아무것도 하지 않아도 동작하고 있습니다. 그래도 이상한 점이 보이면 지원 티켓을 열어 해당 IP 주소의 필터 규칙을 다시 맞춰 달라고 알려 주세요. 공격이 진행 중일 때는 WhatsApp 긴급 채팅 +43 650 8209883으로도 연락하실 수 있습니다. 이때 네 가지를 함께 알려 주세요. IP 주소, 포트, 여러분 시간대 기준의 발생 시각, 그리고 보이는 현상입니다. 이것만으로 되묻는 과정 한 번이 줄어들고, 경기가 진행되는 중에는 그 한 번이 중요합니다.
자주 묻는 질문
TF2 서버가 지금 오프라인입니다. DDoS 공격인지 어떻게 알 수 있나요?
Team Fortress 2 서버에는 어떤 포트를 열어 두어야 하나요?
포트 27015를 그냥 차단하거나 속도 제한해도 되나요?
서버 로그의 NET_GetLong 줄은 무엇을 뜻하나요?
서버는 돌고 있는데 서버 브라우저에 없습니다. 공격을 받는 중인가요?
지금 IP 주소를 빨리 바꾸면 도움이 되나요?
어느 규모부터 TF2 서버가 혼자 버티지 못하나요?
KernelHost의 서버는 공격 중에 오프라인이 되나요?
KernelHost의 DDoS 방어는 추가 요금이 드나요? Advanced DDoS Protection은 언제 필요한가요?
2026 KernelHost GmbH. 모든 권리를 보유합니다. 본 가이드는 저작권법의 보호를 받습니다. 전체든 일부든, 또는 수정된 형태이든 저희의 서면 동의 없이 다른 웹사이트에 게시할 수 없습니다. 출처를 밝히고 링크를 덧붙인 인용은 언제든지 환영합니다.

