Terraria 서버를 DDoS 공격으로부터 방어하기

게시일 읽는 시간 38분

Terraria가 왜 TCP만 사용하는지, 서버에 실제로 필요한 포트는 무엇인지, serverconfig.txt와 TShock, 7878의 REST API는 어떻게 보호하는지, 그리고 어느 공격 규모부터 서버 앞단 네트워크의 필터링만이 통하는지 정리했습니다.

Terraria 서버를 DDoS 공격으로부터 방어하는 일은 특수한 경우에 속합니다. Terraria는 TCP만 사용합니다. 게임 트래픽은 정확히 하나의 포트, 7777 TCP로 흐르고, 게임은 UDP 포트를 아예 열지 않습니다. 인터넷에 돌아다니는 게임 서버 보호 조언은 거의 전부 UDP 게임을 전제로 쓰였기 때문에, 여기서는 헛돌거나 엉뚱한 곳을 겨냥합니다.

이 글은 먼저 추가 비용 없이 직접 지킬 수 있는 것을 보여 주고, 그다음 그 조치가 기술적으로 어디에서 한계에 이르는지, 마지막으로 서버 앞단 네트워크에서 무엇이 이뤄져야 하는지 설명합니다. 모든 내용은 Debian 12, Debian 13, Ubuntu 22.04 LTS 또는 Ubuntu 24.04 LTS에서 운영하는 Terraria 전용 서버(바닐라, TShock 또는 tModLoader)를 기준으로 합니다. 명령은 root 기준으로 적었으니, 일반 사용자라면 앞에 sudo를 붙이세요. 공격이 지금 진행 중이라면, 먼저 설정을 바꾸지도 말고 서버를 재시작하지도 마시고 “로그 기록” 절의 측정값부터 확보하세요. 공격이 끝나면 그 값은 사라집니다.

왜 하필 Terraria 서버가 DDoS 공격을 받나요

Terraria 서버는 주소가 필연적으로 공개되기 때문에 손쉬운 표적입니다. 바닐라 Terraria에는 내장 서버 브라우저가 없습니다. 플레이어는 “Multiplayer”와 “Join via IP”를 거쳐, 곧 누군가 미리 알려 둔 주소로 접속합니다. 새 플레이어를 원하는 운영자는 terraria-servers.com, tserverweb.com, topg.org 같은 목록 사이트에 서버를 등록하거나 Discord로 주소를 알립니다. 이 경로들은 모두 플레이어에게 주는 것과 똑같은 것을 공격자에게도 줍니다. 곧 IP 주소와 포트를 평문으로 넘깁니다.

하드웨어와 월드, 모드 목록에 바뀐 것이 없는데도 Terraria 서버가 계속 오프라인이 된다면, 공격이 가장 그럴듯한 설명입니다. 여기에 프로젝트의 전형적인 구도가 겹칩니다. 정해진 플레이 시간, 경쟁 서버, 차단된 플레이어, 커뮤니티 내부의 갈등입니다. 공격을 의뢰하는 쪽은 실력도 이렇다 할 비용도 들이지 않습니다. Terraria 서버용 booter는 월 몇 유로짜리 구독으로 팔립니다. DDoS 공격이 기술적으로 무엇이고 어떻게 구성되는지는 DDoS 공격이란 무엇인가? 글에서 설명합니다.

Terraria는 UDP가 아니라 TCP로 동작합니다

이것이 사실상 다른 모든 게임 서버와 갈라지는 가장 중요한 차이입니다. Terraria 전용 서버는 TCP 리스너로 연결을 받아들이고(게임 엔진에서는 Terraria.Net.Sockets.TcpSocket 클래스입니다) UDP 소켓은 열지 않습니다. 여기서 여러분의 방어 전체를 결정하는 네 가지 결과가 나옵니다.

  • 완전히 수립된 TCP 연결은 위조할 수 없습니다. 공격자가 연결 수립 절차를 끝내려면 서버의 SYN-ACK를 받아야 합니다. 그러니 실제로 접속해 있는 쪽은 진짜 주소에서 온 것입니다. Terraria에서 IP 차단과 연결 수 상한이 UDP 게임보다 훨씬 잘 듣는 이유가 여기 있습니다.
  • 반면 SYN 플러드는 얼마든지 위조할 수 있습니다. 연결 수립 절차를 끝내지 않기 때문입니다. 이 종류에는 IP 차단이 듣지 않고, SYN 쿠키와 앞단의 필터링만이 통합니다.
  • 포트 7777로 받아들인 TCP 연결은 커널뿐 아니라 게임 프로세스의 자원까지 차지합니다. 그래서 슬롯 고갈이 가장 적은 대역폭으로 가장 큰 효과를 내는 공격이 됩니다.
  • 그래도 UDP 플러드는 여러분의 서버를 때립니다. 패킷은 회선을 채우기 위해 받아들여질 필요가 없습니다. Terraria가 UDP를 쓰지 않는다는 사실은 회선을 지켜 주지 않고, 게임 프로세스가 직접 그 패킷을 처리하는 일만 막아 줍니다.

예외가 하나 있습니다. 전용 서버를 -steam과 -lobby friends 또는 -lobby private로 실행하면 연결이 Steam 네트워크를 거치고, 따라서 27000부터 27100까지의 UDP 포트를 씁니다. 이는 다른 운영 방식이며, IP 주소로 접속하는 고전적인 서버가 아닙니다.

실제로 문제가 되는 포트

Terraria 서버가 열린 네트워크에 필요한 포트는 정확히 하나, 7777 TCP입니다. 이 표의 나머지는 애초에 인터넷에 있을 것이 아니거나, 본인 주소에만 열려야 하는 것들입니다.

용도 포트 프로토콜 설정 위치 열린 네트워크에 열어야 하나요
Terraria 게임 트래픽 7777 TCP serverconfig.txt의 port=7777 예, 유일하게
UDP를 통한 Terraria 없음 없음 게임이 UDP 소켓을 열지 않음 아니요
쿼리 포트, 상태 포트 없음 없음 바닐라 Terraria에는 자체 조회 프로토콜이 없음 아니요
RCON 없음 없음 Terraria에는 RCON이 없고, 원격 제어는 TShock으로만 가능 아니요
TShock REST API 7878 TCP tshock/config.json의 RestApiPort 아니요
tModLoader 서버 7777 TCP 같은 serverconfig.txt 예, 유일하게
Steam 방식(-steam -lobby) 27000부터 27100까지 UDP Steam 운영 방식에서만 아니요
Pterodactyl Wings 8080 TCP 패널 데몬 아니요, 본인 주소만
Pterodactyl SFTP 2022 TCP 패널 SFTP 아니요, 본인 주소만
SSH 22 TCP /etc/ssh/sshd_config 본인 주소만

Terraria에 쿼리 포트도 RCON도 없다는 점은 보안에는 좋은 소식입니다. Counter-Strike, Rust, ARK에서 반사 공격에 자주 악용되는 두 엔드포인트가 여기에는 아예 없습니다. 대신 공격 표면이 그만큼 더 포트 7777에 몰리고, TShock을 쓰는 운영자는 포트 7878로 두 번째 표면을 들이게 됩니다.

돈을 쓰기 전에 직접 할 수 있는 일

이 절이 가장 길고, 의도한 바입니다. 설정이 깔끔한 Terraria 서버는 어디에 놓여 있든 작거나 중간 규모의 공격을 자체 힘으로 견뎌 냅니다.

1. 현황 파악: 서버에서 무엇이 대기하고 있나요?

규칙을 한 줄이라도 쓰기 전에 서버가 외부에 무엇을 내주고 있는지 확인하세요. 추측하지 말고 직접 확인합니다.

ss -lntup

여기서 중요한 것은 로컬 주소 열입니다. 0.0.0.0:7777은 “인터넷 전체에서 접근할 수 있음”을 뜻하고, 127.0.0.1:7878은 “로컬에서만 접근할 수 있음”을 뜻하므로 방화벽 규칙이 필요하지 않습니다. 이 목록에 Terraria 프로세스의 UDP 항목이 나타난다면 서버가 Steam 방식으로 돌고 있는 것입니다. 공격자의 시선은 외부에서 실행하는 포트 스캔이 보여 줍니다.

nmap -Pn -p- --min-rate 1000 YOUR.SERVER.IP.ADDRESS

2. 7777 TCP만 열어 두고 나머지는 모두 닫기

Terraria에는 외부로 여는 규칙 하나면 충분합니다. UDP 규칙은 필요하지 않고, 7777에 대한 UDP 규칙은 그냥 틀린 설정입니다. 아무것도 대기하지 않는 포트로 트래픽을 통과시키기 때문입니다. UFW에서는 다음과 같이 하며, 스스로 접속이 막히지 않도록 반드시 이 순서를 지키세요.

ufw allow 22/tcp comment 'SSH'
ufw allow 7777/tcp comment 'Terraria'
ufw allow from 203.0.113.10 to any port 7878 proto tcp comment 'TShock REST'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

203.0.113.10은 본인 주소로 바꾸세요. 복구 방법까지 포함한 전체 안내는 스스로 접속이 막히지 않게 UFW 방화벽 설정하기에 있습니다. 패널을 운영한다면 8080과 2022도 본인 주소로만 제한하세요.

3. serverconfig.txt: 비밀번호, maxplayers, secure 제대로 설정하기

Terraria 서버의 핵심 설정 파일은 serverconfig.txt이고 시작할 때 -config serverconfig.txt로 넘깁니다. 보안에 결정적인 지시어는 네 개입니다.

port=7777
maxplayers=16
password=ALongRandomPassword
secure=1
upnp=0
banlist=banlist.txt

password=는 정상 경로를 타는 접속 플러드에 맞서는 가장 효과적인 무료 조치입니다. 이유는 프로토콜에 있습니다. 클라이언트가 먼저 버전 식별자(예를 들어 Terraria279)를 담은 메시지 1을 보내고, 비밀번호가 설정되어 있으면 서버가 메시지 37로 답하며, 클라이언트는 메시지 38로 올바르게 답해야 하고, 그 뒤에야 서버가 메시지 3으로 플레이어 슬롯을 포함한 허가를 보냅니다. 따라서 올바른 비밀번호가 없는 공격자는 접속에서 값비싼 부분인 월드 전송까지 결코 도달하지 못합니다.

maxplayers는 1부터 255까지의 값을 받고 기본값은 16입니다(1.4.0.1 이전에는 8이었습니다). 255라는 상한은 임의로 정한 숫자가 아닙니다. Terraria는 플레이어를 단일 바이트로 지정합니다. 정말 필요한 것보다 maxplayers를 높게 잡지 마세요. 슬롯 하나하나가 공격자가 차지할 수 있는 자원입니다. secure=1은 내장 치트 검사를 켜고(명령줄에서는 -secure), upnp=0은 서버가 제멋대로 라우터에서 포트를 여는 일을 막습니다.

4. TShock 보호하기: 7878의 REST API와 로그인 플러드

TShock은 Terraria에서 가장 널리 쓰이는 서버 확장이고, REST API라는 완전한 두 번째 공격 표면을 함께 들여옵니다. 이 API는 기본값으로 7878 TCP에 있고, serverconfig.txt가 아니라 tshock/config.json에서 설정합니다. 출고 상태에서는 꺼져 있으며("RestApiEnabled": false), 필요하지 않은 동안에는 바로 그 상태로 두어야 합니다.

필요하다면 다음 값들이 중요합니다.

"RestApiEnabled": true,
"RestApiPort": 7878,
"EnableTokenEndpointAuthentication": true,
"LogRest": true,
"RESTMaximumRequestsPerInterval": 5,
"RESTRequestBucketDecreaseIntervalMinutes": 1

여기서 두 가지가 중요합니다. 첫째, EnableTokenEndpointAuthentication이 false로 있는 동안 /status 엔드포인트는 토큰 없이도 서버 이름, 포트, 접속자 수, 플레이어 이름을 내줍니다. 상태 페이지와 Discord 봇에는 편리하지만, 언제 공격이 값어치를 하는지 알고 싶은 공격자에게는 공짜 정찰입니다. 둘째, /v2/token/create 엔드포인트는 사용자 이름과 비밀번호로 접근 토큰을 만들어 주며, 포트 7878이 열려 있는 순간 외부에서 닿을 수 있습니다. 관리자 계정을 겨냥한 비밀번호 추측 공격이자, 덤으로 연산 시간을 소모하는 부담입니다. RESTMaximumRequestsPerInterval과 RESTRequestBucketDecreaseIntervalMinutes로 이뤄진 버킷이 이를 늦춰 주기는 하지만 방화벽 규칙을 대신하지는 못합니다.

게임 접속 자체에는 다른 TShock 값들이 적용됩니다. MaximumLoginAttempts는 3으로 설정되어 있고 세 번 실패한 플레이어를 내보냅니다. RequireLogin(기본값 false)은 모든 플레이어에게 계정을 요구합니다. EnableIPBans(기본값 true)와 KickProxyUsers(기본값 true)는 TCP 게임에서 특히 잘 듣습니다. 수립된 연결의 출발지 주소는 위조될 수 없기 때문입니다. 공격으로 신고되는 일이 잦은 그리핑에는 TileKillThreshold(60), TilePlaceThreshold(20), TileLiquidThreshold(15), ProjectileThreshold(50) 임계값이 듣고, 모두 초당 동작 횟수입니다.

5. 출발지 주소별 연결 수 제한과 SYN 쿠키 확인

Terraria가 TCP로 동작하므로, 서버에서 가장 효과적인 규칙은 출발지 주소별 동시 연결 수 상한입니다. 진짜 플레이어에게 필요한 연결은 정확히 하나입니다.

iptables -I INPUT -p tcp --dport 7777 --syn -m connlimit --connlimit-above 3 --connlimit-mask 32 -j DROP
iptables -I INPUT -p tcp --dport 7777 --syn -m hashlimit --hashlimit-name terraria_syn --hashlimit-mode srcip --hashlimit-above 10/min --hashlimit-burst 20 -j DROP

첫 번째 규칙은 한 주소가 동시에 세 개를 넘겨 열자마자 새 연결을 폐기합니다. 두 번째 규칙은 같은 출발지의 연결 시도 속도를 1분에 열 번으로, 여유는 20으로 제한합니다. 두 숫자는 모두 출발점일 뿐이고 정답이 아닙니다. 공용 회선(셰어하우스, 학교 네트워크, 이동통신 사업자) 뒤에서는 같은 주소로 여러 명이 정상 접속합니다. 먼저 평상시 운영에서 한 주는 측정하세요.

iptables 규칙만 쓰면 재시작 후에 사라지므로 Debian과 Ubuntu에서는 다음과 같이 저장합니다.

apt-get install -y iptables-persistent
netfilter-persistent save

UFW를 쓴다면 이런 규칙은 /etc/ufw/before.rules에 들어가야 합니다. 그러지 않으면 다음 ufw reload에서 사라집니다. 연결 수립 절차를 끝내지 않는 위조된 SYN 패킷에는 이 규칙들이 아니라 커널 자체가 대응합니다. 다음 세 값을 확인하세요.

sysctl net.ipv4.tcp_syncookies net.ipv4.tcp_max_syn_backlog net.core.somaxconn

net.ipv4.tcp_syncookies는 1이어야 하고, Debian과 Ubuntu에서는 보통 이미 그렇게 되어 있습니다. SYN 쿠키는 절반만 열린 연결의 대기열을 두지 않고 클라이언트의 응답에서 상태를 되살립니다. 그래서 회선이 가득 차지 않는 한 SYN 플러드는 헛돌게 됩니다. net.core.somaxconn은 Linux 5.4부터 4096이고 그 이전에는 128이었습니다. 이 값이 작으면 커널이 완전히 수립된 연결을 게임 프로세스가 받아들이기도 전에 폐기합니다.

6. 슬롯 고갈 막기: 포트 스캔이 서버를 채우는 이유

슬롯 고갈은 Terraria 서버에 통하는 가장 값싼 공격입니다. 공격자는 서버의 플레이어 슬롯 수만큼 포트 7777로 TCP 연결을 열고 그대로 유지합니다. 대역폭은 거의 들지 않는데 서버는 꽉 찹니다. 진짜 플레이어는 “Server is full”을 보고 더 들어오지 못하는데, 회선에는 눈에 띄는 일이 전혀 없습니다. Terraria 운영자가 공격받는 줄도 모르는 경우가 많은 이유가 바로 이것입니다.

원인은 세는 방식에 있습니다. 연결은 클라이언트가 버전 식별자를 보내기도 전에 받아들여집니다. 예전에는 이런 유령 연결이 TCP 세션이 만료될 때까지 자리를 차지했습니다. 1.4.5 계열에서 이 문제가 완화되어, 곧바로 다시 끊는 클라이언트에게는 더 이상 슬롯을 예약하지 않습니다. 다만 1.4.5.7과 1.4.5.8의 초기 배포판에서는 TCP 연결이 열리고 연결 수립 절차가 끝나지 않으면 전용 서버가 처리되지 않은 ObjectDisposedException으로 중단되었습니다. nc -z 한 번이나 모니터링의 접속 확인 한 번으로도 충분했습니다. 이 오류는 몇 주 안에 조용히 수정되었지만, 오래된 컨테이너 이미지에는 아직 남아 있는 경우가 있습니다. 그러니 서버 버전을 최신으로 유지하세요. 여기서 이것은 흔한 상투어가 아니라 구체적인 가용성 문제입니다.

설정 두 가지가 추가로 도움이 됩니다. TShock을 쓴다면 MaxSlots를 원하는 플레이어 수로 정하고 serverconfig.txt의 maxplayers는 두 자리 더 높게 두세요. 그러면 게임 프로세스가 남은 마지막 틈으로 들여보내는 대신 TShock이 초과 연결을 깔끔한 메시지로 거절합니다. 그리고 앞 절의 연결 수 상한이야말로 한 주소가 모든 슬롯을 한꺼번에 차지하는 것을 막는 규칙입니다.

7. UPnP 끄기와 주소를 스스로 공개하지 않기

Terraria 서버는 기본값으로 UPnP를 통해 라우터에서 자기 포트를 열려고 시도합니다. 임대한 서버에서는 아무 효과가 없고, 가정 네트워크에서는 나중에 존재조차 잊게 되는 포트를 열어 놓습니다. serverconfig.txt의 upnp=0이나 명령줄의 -noupnp로 끄세요.

그리고 여기서는 희망적 사고보다 솔직함이 낫습니다. 여러분의 IP 주소는 비밀로 유지할 수 없습니다. 한 번이라도 접속한 플레이어는 그 주소를 알고 있고, 목록 사이트의 항목은 어차피 주소를 공개합니다. 효과가 있는 것은 두 가지 습관입니다. 날것의 IP 주소를 직접 어디에도 공개하지 말고, 플레이어는 호스트 이름으로 연결하게 하세요. Terraria 클라이언트는 호스트 이름을 해석하므로, 만일의 경우에 모든 안내가 깨지지 않게 두고도 주소를 바꿀 수 있습니다. 그리고 오래된 DNS 항목은 치우세요. 이전 주소를 가리키는 A 레코드를 방치하면 어떤 변경도 무의미해집니다.

8. 상태 조회를 그대로 넘기지 말고 캐시하기

Terraria에는 조회 프로토콜이 없으므로 상태 페이지, Discord 봇, 목록 사이트는 두 가지 방법 가운데 하나로 서버 상태를 알아냅니다. 7777로 실제 TCP 연결을 열고 클라이언트인 척하거나, TShock REST API에 질의합니다. 둘 다 서버에 일을 시키고, 둘 다 조회하는 쪽의 수에 비례해 늘어납니다.

대응 방법에는 비용이 들지 않습니다. 방문자 쪽에서 조회하게 두지 마세요. 하나의 서비스가 일정한 간격으로(30초나 60초면 충분합니다) 상태를 가져오게 하고, 그 결과를 캐시에 담아 모든 방문자에게 캐시된 상태를 내주세요. 그러면 방문자가 많은 상태 페이지도 방문자 한 명당 한 번이 아니라 간격당 한 번만 조회합니다. 이 용도로 REST API를 쓴다면 포트 7878을 그 서비스 하나의 주소로만 제한하세요.

9. 만일의 경우에 데이터를 갖도록 로그 기록하기

가장 중요하면서 거의 아무도 미리 하지 않는 단계가 있습니다. 모든 것이 정상으로 돌아가는 동안에 기준값을 만들어 두는 것입니다. 평상시 값이 없으면 사건이 끝난 뒤에 초당 40,000 패킷이 많았던 것인지 그냥 토요일 저녁이었던 것인지 말할 수 없습니다. apt-get install -y vnstat sysstat로 측정이 상시 돌아갑니다. 사건이 진행되는 동안에는 다섯 개의 명령으로 충분합니다.

sar -n DEV 1 10
ss -s
ss -tn state syn-recv | wc -l
ip -s link show eth0
tcpdump -ni eth0 tcp port 7777 -c 200 -q

세 번째 명령이 Terraria에 특화된 것입니다. 절반만 열린 연결의 수를 셉니다. 두 자리 수는 정상이고, 네 자리나 다섯 자리는 SYN 플러드입니다. ss -s는 그 옆에서 TCP 연결의 총수를 보여 주는데, 게임 안에 아무도 없는데 이 숫자가 maxplayers와 비슷하다면 슬롯 고갈을 보고 있는 것입니다. tcpdump에는 한 가지 원칙이 있습니다. 항상 -c로 개수를 제한하세요. 과부하 상태에서의 캡처는 이미 과부하인 서버에 부담을 더 얹습니다. 측정값을 해석하는 방법은 DDoS 공격 알아내기에 있습니다.

이 조치들이 한계에 이르는 지점

이제 어떤 설정 파일로도 해결할 수 없는 부분입니다. 지금까지의 모든 조치는 여러분의 서버, 즉 회선의 끝에서 동작합니다. 방화벽 규칙은 이미 케이블을 지나온 패킷을 두고 판단합니다. 그 패킷을 폐기할 수는 있지만, 보내지 않은 것으로 만들 수는 없습니다.

한번 계산해 보겠습니다. 일반적인 게임 서버는 1 Gbit/s 회선에 물려 있고, 이는 초당 125 메가바이트이며, 누군가 그보다 많이 보내는 순간 회선은 꽉 찹니다. 이 정도 규모의 게임 서버 프로젝트를 겨냥한 공격은 보통 5 Gbit/s에서 50 Gbit/s 사이, 곧 여러분 회선의 5배에서 50배입니다. 그 뒤에 있는 connlimit 규칙이 훌륭한지는 그때부터 아무 상관이 없습니다. 플레이어의 패킷이 그 앞에서 이미 통과하지 못하기 때문입니다. CPU 사용률은 정상으로 보이는 Terraria 서버 랙 스파이크가 바로 이렇게 생깁니다.

두 번째 수치는 패킷 전송률이고, 대역폭보다 먼저 터지는 일이 잦습니다. 64 바이트짜리 작은 패킷이라면 1 Gbit/s 회선에 초당 약 149만 개가 들어갑니다. 일반적인 서버 커널은 CPU와 네트워크 카드에 따라 그중 수십만 개를 처리한 뒤 폐기를 시작합니다. SYN 플러드에서는 한계가 더 낮습니다. SYN 패킷 하나하나가 상태 판단을 일으키기 때문입니다. 초당 수만 개의 SYN 패킷만으로도 표준 리눅스의 연결 수용이 마비되고, 그것도 회선이 가득 차기 훨씬 전입니다. 운영자는 이것을 “사용률은 전혀 높지 않았는데 그래도 전부 죽었다”로 경험합니다.

그리고 세 번째 지점이 Terraria에서 가장 많이 간과됩니다. 공격자는 여러분의 프로토콜에 맞춰 주지 않습니다. UDP 포트에 아무것도 대기하지 않는데도 여러분의 주소로 UDP 플러드와 반사 트래픽을 보냅니다. 서버는 그 패킷을 올바르게 폐기하지만, 그 패킷은 이미 회선을 차지했고, 단 하나의 패킷도 게임 프로세스에 닿지 않은 채로 Terraria 서버는 오프라인이 됩니다. 실제로 어떤 규모가 나타나는지 가늠해 보자면, KernelHost 서버에서는 초당 4,150만 패킷과 함께 473.4 Gbit/s를 넘긴 공격과, 게임 서버를 겨냥한 112.2 Gbit/s 이상의 UDP 플러드가 걸러졌습니다. 여기에 맞는 로컬 설정은 없습니다. 볼류메트릭 공격은 서버 앞단 네트워크에서 끝나야 합니다.

KernelHost가 이에 맞서 제공하는 것

모든 서버에 포함된 상시 방어

KernelHost의 DDoS 방어는 두 단계로 구성되어 있고 상시 동작하므로, 여러분이 무엇을 켜거나 주문하거나 설정할 필요가 없습니다.

  • 1단계: 글로벌 스크러빙 네트워크의 17 Tbps 방어 용량. 볼류메트릭 공격은 발생지에 가까운 곳에서 정화되어 데이터센터에 닿기 전에 걸러집니다.
  • 2단계: 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링. 서버 바로 앞에서 프로토콜별 패턴을 찾아내 패킷 하나하나를 폐기합니다. Terraria에서는 구체적으로 이런 뜻입니다. 7777 TCP를 겨냥한 SYN 플러드와 연결 플러드가 여러분의 네트워크 카드가 아니라 여기서 끝납니다.

두 가지 특성이 결정적입니다. 이 방어는 상시 동작하므로 공격에 반응해서 비로소 시작될 필요가 없습니다. 그래서 초반에 서버가 사라지는 몇 분이 존재하지 않습니다. 그리고 null-routing을 쓰지 않습니다. 여러분의 IP 주소는 네트워크에 그대로 남고, 폐기되는 것은 악성 패킷뿐입니다. IP 주소를 네트워크에서 빼 버리면 여러분에게는 공격이 성공한 것과 같은 결과가 됩니다. 위치는 프랑크푸르트암마인입니다. 어떤 게임과 프로토콜이 포함되는지는 실시간 게임 서버 DDoS 방어에 정리되어 있습니다.

계속 공격받는 프로젝트를 위한 Advanced DDoS Protection

어떤 프로젝트는 어쩌다 한두 번이 아니라, 표적이 되어 몇 주에 걸쳐 공격받습니다. 이런 경우를 위해 Advanced DDoS Protection이 월 50.00 EUR부터, PrePaid 방식으로, 최소 이용 기간과 설치비 없이 제공됩니다. 차이는 용량이 더 커지는 데 있지 않고 통제권에 있습니다.

  • 전용 방어 IP: 프랑크푸르트 코어에서 발급되며, 서버는 자체 네트워크에서 이 IP로 전환됩니다. 여러분 쪽에서 손볼 것은 없습니다.
  • 포트와 프로토콜별로 직접 관리하는 방어 규칙: 고객 포털에서 7777 TCP에 무엇을 허용할지 설정하고, 티켓을 쓰지 않고도 나머지는 모두 닫을 수 있습니다.
  • 변경은 실시간으로 반영: 공격이 진행되는 중에도 값을 조정할 수 있습니다. 예를 들어 출발지 주소별 허용 연결 속도를 더 좁게 당길 수 있습니다.
  • 애플리케이션에 맞춘 방어 프로필: Terraria 같은 TCP 게임에도, 임의의 TCP 또는 UDP 포트에서 돌아가는 자체 애플리케이션이나 개조된 애플리케이션에도 맞는 프로필이 있습니다.

두 단계 비교

항목 포함된 DDoS 상시 방어 Advanced DDoS Protection
요금 모든 서버 상품에 추가 요금 없이 포함 월 50.00 EUR부터, PrePaid
필터링 용량 17 Tbps 글로벌 스크러빙과 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링 동일한 2단계 필터링
IP 주소 서버의 IP 주소 추가로 받는 전용 방어 IP
규칙 세트 자동 프로필, 설정 불필요 고객 포털에서 포트와 프로토콜별 자체 규칙
변경 자동으로 함께 적용 실시간 반영, 공격 중에도 가능
Terraria용 프로필 TCP 게임 서버용 자동 프로필 7777 TCP를 위한 자체 규칙 세트, tModLoader와 TShock에도 적용
null-routing 없음 없음
이용 기간 서버 상품에 연동 PrePaid, 최소 이용 기간 없음, 해지 통보 기간 없음, 설치비 없음

대부분의 Terraria 프로젝트에는 깔끔한 서버 설정과 포함된 상시 방어면 충분합니다. Advanced DDoS Protection은 누군가 이 일을 개인적으로 받아들였을 때의 답입니다. 지금 서버를 다른 곳에서 운영하는 분은 이 방어를 나중에 덧붙일 수 없고, KernelHost로 옮겨야 받을 수 있습니다. 필터링은 네트워크의 일부이고 서버에 얹는 부가 기능이 아니기 때문입니다.

자주 나오는 실수와 해결 방법

“서버가 꽉 찼는데 안에는 아무도 없습니다”: 슬롯 고갈입니다. ss -tn dst :7777 | wc -l로 실제로 열려 있는 연결이 몇 개인지 확인하고, 플레이어 목록(서버 콘솔에서 playing)과 비교하세요. 숫자가 맞지 않으면 외부 연결이 슬롯을 차지하고 있는 것입니다. 대응책은 출발지 주소별 연결 수 상한, 서버 비밀번호, 최신 서버 버전입니다.

“7777 UDP를 열었는데 아무것도 달라지지 않습니다”: 맞습니다. 7777 UDP에는 아무것도 대기하지 않습니다. Terraria는 TCP만 사용합니다. UDP 개방이 직접 해를 끼치지는 않지만, 불필요한 구멍이고 다른 게임의 안내를 그대로 복사했다는 확실한 신호입니다.

“iptables 규칙이 적용되지 않습니다”: 흔한 원인이 세 가지입니다. 규칙이 UFW 체인 뒤에 있어 전혀 도달하지 못하거나, 마지막 재시작 이후 사라졌거나(이때는 netfilter-persistent save 또는 /etc/ufw/before.rules 항목이 도움이 됩니다), 공격이 볼류메트릭이어서 규칙은 이미 꽉 찬 회선에서 제대로 동작하고 있는 경우입니다. iptables -L INPUT -n -v로 매칭 카운터가 올라가는지 확인하세요. 0에 머물러 있으면 규칙에 도달하지 못하는 것입니다.

“공격이 없는데도 플레이어가 튕깁니다”: connlimit 한도를 너무 좁게 당기면 공용 회선 뒤의 플레이어가 걸립니다. TCP에서는 UDP 게임보다 이런 일이 빨리 생깁니다. 끊김 뒤의 재접속이 곧바로 새 연결을 만드는데 이전 연결은 아직 TIME_WAIT에 남아 있기 때문입니다. 값을 단계적으로 올리고 매칭 카운터를 지켜보세요.

“서버가 버벅이는데 회선은 조용합니다”: 공격보다는 모드나 플러그인인 경우가 더 많습니다. tModLoader에서는 모드를 하나 더할 때마다 같은 프로세스에서 연산 시간이 들고, 엔티티가 많은 월드는 패킷 하나 더 도착하지 않아도 코어 하나를 꽉 채웁니다. sar -n DEV 1 10이 이상 없이 나온다면 DDoS 공격이 아니었습니다.

“기존 업체가 제 IP 주소를 차단했습니다”: 그것이 null-routing입니다. 업체는 그렇게 자기 네트워크를 지키지만, 여러분에게 남는 결과는 공격이 성공한 것과 똑같고, 보통 그 뒤로 몇 시간 더 이어집니다. 확실하지 않으면 필터링을 하는지 null-routing을 하는지 물어보세요. 그 답이 어떤 하드웨어 사양보다 여러분의 가용성을 더 크게 좌우합니다.

“tcpdump에 이상한 것이 보이지 않습니다”: 트래픽이 이미 앞단 네트워크에서 걸러지고 있으면 서버에는 아무것도 도착하지 않는 것이 당연합니다. 필터링이 작동하고 있을 때의 정상적인 모습입니다. 반대로 회선이 포화되면 측정에 쓰려던 SSH 세션조차 닿지 않을 수 있습니다. 그럴 때는 게스트 시스템의 네트워크와 무관하게 동작하는 고객 포털의 VNC 콘솔을 이용하세요.

핵심 요약

  • Terraria 서버에 필요한 열린 포트는 정확히 하나, 7777 TCP입니다. 게임은 UDP 소켓을 열지 않고, 조회 프로토콜도 RCON도 없습니다.
  • 7878 TCP의 TShock REST API가 두 번째 공격 표면입니다. RestApiEnabled를 false로 두거나, 포트를 본인 주소로만 제한하세요.
  • serverconfig.txt의 서버 비밀번호가 가장 효과적인 무료 조치입니다. 메시지 37에 올바르게 답하지 못하는 공격자는 월드 전송까지 도달하지 못하기 때문입니다.
  • Terraria에서 가장 값싼 공격은 슬롯 고갈입니다. 7777로 받아들여진 TCP 연결은 이렇다 할 대역폭 없이도 자리 하나를 차지합니다. 여기에는 출발지 주소별 상한, 비밀번호, 최신 서버 버전이 듣습니다.
  • Terraria는 TCP를 쓰므로 수립된 연결의 출발지 주소는 위조할 수 없습니다. 그래서 IP 차단이 UDP 게임보다 잘 듣습니다. 위조된 SYN 플러드에는 SYN 쿠키와 앞단의 필터링만이 통합니다.
  • UDP 플러드는 Terraria가 UDP를 쓰지 않아도 서버를 마비시킵니다. 게임 프로세스가 무엇을 보기도 전에 회선을 채우기 때문입니다.
  • 대략 업링크 대역폭 규모부터는 서버 앞단 네트워크만이 결과를 결정합니다. KernelHost에서는 이 필터링이 2단계로, 상시 동작하며, 모든 서버 상품에 추가 요금 없이 포함되어 있습니다.

프로젝트가 이미 KernelHost에 있다면 필터링은 여러분이 아무것도 하지 않아도 동작하고 있습니다. 그래도 이상한 점이 보이면 지원 티켓을 열어 해당 IP 주소의 필터 규칙을 다시 맞춰 달라고 알려 주세요. 공격이 진행 중일 때는 WhatsApp 긴급 채팅 +43 650 8209883으로도 연락하실 수 있습니다.

자주 묻는 질문

Terraria 서버에는 어떤 포트와 어떤 프로토콜이 필요한가요?
Terraria 서버에 필요한 포트는 정확히 하나, 7777 TCP입니다. 이것이 기본값이고 serverconfig.txt의 port=7777에 들어 있습니다. 게임은 UDP 포트를 열지 않고, 자체 쿼리 포트도 RCON도 없습니다. TShock을 쓰면 7878 TCP의 REST API가 더해지는데, 출고 상태에서는 꺼져 있습니다. 7777에 대한 UDP 개방은 불필요하고, 다른 게임의 안내를 그대로 복사했다는 확실한 신호입니다. tModLoader는 바닐라 서버와 같은 포트를 씁니다.
Terraria가 UDP가 아니라 TCP를 쓴다는 점이 왜 중요한가요?
효과적인 대응책이 뒤바뀌기 때문입니다. 완전히 수립된 TCP 연결은 위조할 수 없습니다. 공격자가 서버의 SYN-ACK를 받아야 하기 때문입니다. 그래서 Terraria에서는 IP 차단과 출발지 주소별 연결 수 상한이 UDP 게임보다 훨씬 잘 듣습니다. 반면 SYN 플러드는 연결 수립 절차를 끝내지 않으므로 얼마든지 위조할 수 있습니다. 여기에는 커널의 SYN 쿠키와 서버 앞단 네트워크의 필터링만이 통합니다.
아무도 플레이하지 않는데 Terraria 서버가 Server is full이라고 합니다. 무엇인가요?
슬롯 고갈이고, Terraria 서버에 통하는 가장 값싼 공격입니다. 공격자는 서버의 플레이어 슬롯 수만큼 포트 7777로 TCP 연결을 열고 그대로 유지합니다. 대역폭은 거의 들지 않는데 모든 자리가 찹니다. ss -tn dst :7777 | wc -l로 열려 있는 연결의 수를 확인하고, 서버 콘솔에서 playing 명령의 결과와 비교하세요. 대응책은 출발지 주소별 연결 수 상한, 서버 비밀번호, 최신 서버 버전입니다.
서버 비밀번호가 공격에 도움이 되나요?
접속 플러드에는 도움이 되고 볼류메트릭 공격에는 도움이 되지 않습니다. 이유는 프로토콜에 있습니다. 클라이언트가 먼저 버전 식별자를 담은 메시지 1을 보내고, 비밀번호가 설정되어 있으면 서버가 메시지 37로 답하며, 클라이언트는 메시지 38로 올바르게 답해야 하고, 그 뒤에야 메시지 3으로 플레이어 슬롯을 포함한 허가가 따라옵니다. 올바른 비밀번호가 없는 공격자는 접속에서 값비싼 부분인 월드 전송까지 도달하지 못합니다. 설정은 serverconfig.txt의 password= 또는 명령줄의 -password로 합니다.
7878 포트의 TShock REST API는 어떻게 보호하나요?
가장 안전한 방법은 아예 켜지 않는 것입니다. tshock/config.json의 RestApiEnabled는 출고 상태에서 false입니다. 필요하다면 EnableTokenEndpointAuthentication을 true로 설정하세요. 그러지 않으면 /status 엔드포인트가 토큰 없이도 서버 이름, 포트, 접속자 수, 플레이어 이름을 내줍니다. LogRest를 켜고, RESTMaximumRequestsPerInterval은 5로, 간격은 1분으로 두고, 방화벽에서 포트 7878을 본인 주소로만 제한하세요.
maxplayers에는 몇 명을 적어야 하나요?
정말 필요한 만큼만 적으세요. 슬롯 하나하나가 공격자가 차지할 수 있는 자원입니다. maxplayers는 1부터 255까지의 값을 받고 기본값은 16이며, 1.4.0.1 이전에는 8이었습니다. 255라는 상한은 Terraria가 플레이어를 단일 바이트로 지정하기 때문에 생깁니다. TShock을 쓴다면 MaxSlots를 원하는 플레이어 수로 정하고 serverconfig.txt의 maxplayers는 두 자리 더 높게 두세요. 그러면 TShock이 초과 연결을 깔끔한 메시지로 거절합니다.
iptables나 UFW로 DDoS 공격에 맞설 수 있나요?
작은 공격과 연결 플러드에는 맞설 수 있지만 볼류메트릭 공격에는 그렇지 못합니다. 서버의 방화벽 규칙은 이미 회선을 지나온 패킷을 두고 판단합니다. 회선이 포화되면 규칙 세트가 얼마나 훌륭한지와 무관하게 플레이어의 패킷이 그 앞에서 이미 통과하지 못합니다. 그래도 Terraria에서는 7777 TCP에 connlimit 규칙을 두는 것이 값어치를 합니다. 슬롯 고갈을 효과적으로 막아 주기 때문입니다. 볼류메트릭 공격은 서버 앞단 네트워크에서 끝나야 합니다.
어느 규모부터 Terraria 서버가 혼자 버티지 못하나요?
일반적인 게임 서버는 1 Gbit/s에 물려 있고, 이는 초당 125 메가바이트입니다. 이 정도 규모의 프로젝트를 겨냥한 공격은 보통 5 Gbit/s에서 50 Gbit/s 사이입니다. 패킷 전송률도 그만큼 중요합니다. 64 바이트 패킷이라면 1 Gbit/s에 초당 약 149만 개가 들어가고, 일반적인 서버 커널은 그중 수십만 개만 처리합니다. SYN 플러드에서는 한계가 더 낮습니다. SYN 패킷 하나하나가 상태 판단을 일으키기 때문입니다. 그래서 대역폭을 다 쓰지 않은 공격으로도 여러분을 마비시킬 수 있습니다.
Terraria는 UDP를 전혀 쓰지 않는데 왜 UDP 공격에 맞나요?
공격자가 여러분의 프로토콜에 맞춰 주지 않기 때문입니다. UDP 서비스가 대기하지 않는데도 여러분의 IP 주소로 UDP 플러드와 반사 트래픽을 보냅니다. 서버는 그 패킷을 올바르게 폐기하지만, 그 패킷은 이미 회선을 차지했고, 단 하나의 패킷도 게임 프로세스에 닿지 않은 채 Terraria 서버는 오프라인이 됩니다. Terraria가 UDP를 쓰지 않는다는 사실은 애플리케이션만 지켜 주고 회선은 지켜 주지 못합니다. 여기에는 서버 앞단 네트워크의 필터링만이 통합니다.
KernelHost의 서버는 공격 중에 오프라인이 되나요?
아니요. null-routing을 쓰지 않습니다. 여러분의 IP 주소는 네트워크에 그대로 남고, 폐기되는 것은 악성 패킷뿐입니다. 방어는 두 단계입니다. 글로벌 스크러빙 네트워크의 17 Tbps 방어 용량과 프랑크푸르트암마인의 3.2 Tbps Arbor 실시간 필터링입니다. 이 방어는 상시 동작하며 공격에 먼저 반응할 필요가 없습니다. Terraria에서는 구체적으로 7777 TCP를 겨냥한 SYN 플러드와 연결 플러드가 여러분의 네트워크 카드가 아니라 그곳에서 끝난다는 뜻입니다.
KernelHost의 DDoS 방어는 추가 요금이 드나요?
아니요. 2단계 상시 방어는 모든 서버 상품에 추가 요금 없이 포함되어 있고 서버 제공 시점부터 동작합니다. 주문하거나 켜거나 설정하실 필요가 없습니다. 지금 Terraria 서버를 다른 곳에서 운영하는 분은 이 방어를 나중에 덧붙일 수 없습니다. 필터링은 네트워크의 일부이고 서버에 얹는 부가 기능이 아니기 때문입니다. 이 경우 권하는 방법은 KernelHost로 옮기는 것입니다.
Advanced DDoS Protection은 언제 추가로 필요한가요?
프로젝트가 어쩌다 한두 번이 아니라 표적이 되어 몇 주에 걸쳐 공격받고, 필터링을 직접 조정하려 할 때입니다. 전용 방어 IP를 받고, 고객 포털에서 포트와 프로토콜별 방어 규칙을 직접 관리합니다. 7777 TCP에 무엇을 허용할지 설정하고 나머지는 모두 닫을 수 있습니다. 변경은 실시간으로 반영되므로 공격이 진행되는 중에도 조정할 수 있습니다. 요금은 월 50.00 EUR부터, PrePaid, 최소 이용 기간 없음, 설치비 없음입니다.

Terraria Terraria DDoS 방어 TShock tModLoader 게임 서버 보호 포트 7777 포트 7878 Advanced DDoS Protection