TECH 으로 돌아가기
TECH HACKER NEWS 오늘 7분 읽기 28 READS

월핵을 원천 차단하는 방법 - CS2 서버가 '보이는 적만' 알려주는 Fog of War 기술

월핵을 원천 차단하는 방법 - CS2 서버가 '보이는 적만' 알려주는 Fog of War 기술

벽 너머 적이 보이는 치트, 왜 근본적으로 못 막았나

FPS 게임을 해본 사람이라면 '월핵(wallhack)'이라는 말을 들어봤을 거예요. 벽 뒤에 숨은 적의 위치가 훤히 보이는 부정행위죠. CS2(카운터 스트라이크 2)를 위한 CS2FOW라는 오픈소스 프로젝트가 공개됐는데, 이게 월핵을 잡아내는 게 아니라 아예 '작동할 수 없게' 만드는 접근이라 흥미로워요. 오늘은 이 발상이 왜 똑똑한지 차근차근 풀어볼게요.

먼저 월핵이 왜 가능한지부터 알아야 해요. 대부분의 온라인 FPS는 반응 속도를 위해 서버가 모든 플레이어의 위치를 각 클라이언트(내 컴퓨터의 게임)에 미리 다 보내줘요. 내 컴퓨터는 그중에서 실제로 내 시야에 들어오는 것만 화면에 그리고, 벽에 가려진 적은 그냥 안 그릴 뿐이에요. 문제는 '안 그린다'뿐이지 그 적의 좌표 정보는 이미 내 컴퓨터 메모리 안에 들어와 있다는 거예요. 치트 프로그램은 이 메모리를 몰래 읽어서 벽에 가려진 적까지 화면에 표시해버리는 거죠.

그러니까 근본 원인은 '보여줄 필요도 없는 정보를 서버가 미리 다 넘겨준다'는 데 있어요. 정보가 이미 손 안에 있으니, 그걸 안 보이게 감추는 건 결국 눈 가리고 아웅일 수밖에 없는 거예요.

'보이는 적만 보낸다'는 서버 사이드 오클루전 컬링

CS2FOW가 하는 일이 바로 이 근본 원인을 건드리는 거예요. 서버 쪽에서 각 플레이어가 실제로 볼 수 있는 적이 누구인지를 계산해서, 안 보이는 적의 정보는 아예 그 플레이어에게 보내지 않는 거죠. 정보가 오지 않으니 치트가 읽을 것도 없어요. 이걸 서버 사이드 오클루전 컬링(server-side occlusion culling)이라고 불러요.

오클루전 컬링이 뭐냐면, 원래 그래픽스에서 '다른 물체에 가려서 안 보이는 건 그리지 말자'며 성능을 아끼는 최적화 기법이에요. CS2FOW는 이 개념을 성능이 아니라 보안 목적으로 서버에서 돌리는 거예요. 서버가 A라는 플레이어의 눈 위치에서 B라는 적을 향해 가상의 광선(ray)을 쏴보고, 중간에 벽이 가로막으면 'A는 지금 B를 못 봐'라고 판단해서 B의 위치 전송을 끊는 식이죠. 게임 맵에는 어디까지가 보이는 영역인지 미리 계산해둔 PVS(Potentially Visible Set, 잠재적 가시 집합)라는 데이터도 있어서 이런 판단을 빠르게 도와줘요. 게다가 이건 서버 쪽 로직이라 플레이어들이 게임 클라이언트를 고칠 필요도 없어요.

여기서 진짜 어려운 문제: 늦게 보이면 안 된다

말은 간단한데, 실제로는 아주 미묘한 균형을 잡아야 해요. 문제는 네트워크 지연이에요. 적이 벽 뒤에서 튀어나오는 순간, 서버가 그제야 '이제 보이네' 하고 정보를 보내면, 그 정보가 내 컴퓨터에 도착할 때까지 시간이 걸려서 적이 화면에 '뿅' 하고 늦게 나타나요. 이러면 이미 총 맞은 뒤에 적이 보이는 황당한 상황이 벌어지죠.

그래서 실제 구현에서는 '곧 보일 것 같은 적'을 살짝 미리 드러내주는(reveal) 타이밍 조절이 필요해요. 너무 일찍 드러내면 치트에게 정보를 주는 셈이고, 너무 늦게 드러내면 게임이 답답해져요. 이 '얼마나 미리 보여줄까'의 절묘한 지점을 찾는 게 이 기술의 진짜 핵심 난이도예요. 정보 은닉의 강도와 게임의 손맛 사이에서 줄타기를 하는 거죠.

업계에서는 이미 검증된 방향

이 발상을 대중적으로 성공시킨 대표 사례가 라이엇의 발로란트(Valorant)예요. 발로란트는 출시 때부터 'Fog of War'라는 이름으로 정확히 이 방식을 내세웠어요. 서버가 각 플레이어의 시야를 계산해서 안 보이는 적 정보는 클라이언트에 아예 안 보내는 구조요. 덕분에 발로란트는 월핵 치트가 상대적으로 무력화된 편이에요.

반면 카운터 스트라이크는 전통적으로 VAC라는 클라이언트 측 탐지 방식에 많이 의존해 왔어요. 이건 치트 프로그램을 사후에 잡아내 밴하는 방식이라, 새로운 치트가 나오면 잡을 때까지 시차가 생기는 태생적 한계가 있죠. CS2FOW는 커뮤니티가 운영하는 CS2 서버에서, 발로란트식 '원천 차단' 철학을 직접 구현해보려는 시도라는 점에서 의미가 있어요.

한국 개발자에게 주는 시사점

게임 서버를 만드는 분들에게는 '신뢰할 수 없는 클라이언트'를 다루는 정석적인 교훈이 담겨 있어요. 보안의 기본 원칙 중 하나가 '클라이언트를 절대 믿지 마라'인데, 이건 게임뿐 아니라 모든 서버 개발에 통하는 이야기예요. 정보를 보내놓고 화면에서만 가리는 건 보안이 아니고, 애초에 필요 없는 정보는 보내지 않는 게 진짜 방어라는 거죠.

동시에 이 사례는 '보안과 사용자 경험은 종종 상충한다'는 현실도 잘 보여줘요. 정보를 완벽히 감추면 게임이 버벅이고, 부드럽게 하려면 정보를 조금 흘려야 하는 트레이드오프. 실무에서 실시간 멀티플레이어나 대전형 서비스를 설계할 때, 지연 시간과 정보 노출 사이의 이 균형 감각은 그대로 응용할 수 있는 값진 관점이에요.

한 줄 정리: 최고의 치트 방어는 치트를 잡는 게 아니라, 치트가 훔칠 정보 자체를 애초에 주지 않는 거예요.

여러분은 실시간 서비스를 만들 때, 클라이언트에 데이터를 얼마나 미리 내려주는 편이세요? 반응성과 보안 사이에서 어떻게 선을 긋고 계신지 궁금해요.


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://github.com/karola3vax/CS2FOW
SHARE
처리 중...