1P by GN⁺ | ★ favorite | 댓글 1개
  • Counter-Strike의 오래된 No user logon 끊김은 CS2에서도 재현되며, 게임 시작 직후 서버에 너무 빨리 접속하면 Steam ID 검증이 시작되지 않을 수 있음
  • 핵심은 CS2.exe 시작 중 levelload 루프가 Steam3 검증을 끝내기 전에 조기 종료되고, 서버가 검증되지 않은 Steam ID로 접속을 처리한다는 점임
  • Esportal 로그에서는 정상 사용자도 STEAM USERID validated가 접속 후 약 1분 20초 뒤 기록됐고, 실패 사용자는 2~3분 뒤 STEAMAUTH failure code 8NETWORK_DISCONNECT_STEAM_LOGON으로 끊김
  • 게임 재설치, 파일 검증, Steam 재시작, PC 재부팅, WiFi 비활성화는 근본 원인을 고치지 못하며, CS2를 먼저 띄운 뒤 메인 메뉴에서 5~10초 기다려야 함
  • Esportal은 2024년 1월 10일 CS2.exe가 완전히 초기화되기 전에 steam://connect/<IP>:<Port>를 실행하던 동작을 고쳤고, 이후 관련 티켓 비중이 0%로 떨어짐

오래 반복된 No user logon 현상

  • Counter-Strike의 No user logon 끊김은 플레이 중 무작위로 발생하는 문제로 알려져 있으며, 2008년부터 2023년까지 여러 포럼과 Valve 공식 지원 포럼에 반복적으로 보고됨
  • No user logon과 일부 글에서 보이는 No steam logon은 기술적으로 같은 근본 원인의 다른 이름일 가능성이 있음
  • 인터넷에 널리 퍼진 해결책들은 근본 원인을 고치지 못함
    • 게임 재설치
    • 게임 파일 검증
    • Steam 재시작
    • 컴퓨터 재부팅
    • WiFi 비활성화
  • CS2는 2023년 9월 27일 CS:GO를 대체했고, 일반 사용자는 CS:GO를 더 이상 플레이할 수 없게 됨
  • Valve의 HackerOne 버그 바운티 범위에는 cs2.exe가 포함되지 않았고, CS2 Limited Test 보고도 범위 밖으로 표시돼 있었음

Esportal에서 갑자기 늘어난 보고

  • Esportal은 과거 CS:GO에서도 이 문제를 겪었고, 기록상 첫 발생은 2019-11-15 19:15:32 CET, 마지막 CS:GO 발생은 CS2로 대체되기 전날인 2023-09-26 21:38:01 CET였음
  • CS2 초기에는 문제가 사라진 것처럼 보였지만, 2024년 1월 첫째 주에 사용자 보고가 증가함
    • 2024-01-03: 일일 티켓 중 6%
    • 2024-01-05~06: 18%
    • 2024-01-07: 23%
    • 2024-01-08: 10%
    • 2024-01-09: 9%
  • 보고 시간대는 주로 13~17시 CET에 몰렸고, 이는 Valve가 있는 Washington 기준 04~08시에 해당함
  • 이전에는 보고가 하루 전체에 고르게 분포했지만, 새로 관측된 문제는 특정 시간대에 집중됨
  • Esportal 외부 플레이어들도 같은 문제를 겪고 있어, 특정 플랫폼만의 문제는 아니었음

증상: 늦어지는 Steam 검증과 사라지는 스킨

  • 관측된 No user logon 오류는 플레이어가 게임 서버에 접속한 뒤 2~3분 후 발생했고, 이 시간 간격은 꽤 일정했음
  • 동료는 “게임에 들어간 뒤 몇 분 동안 CS2에서 스킨이 보이지 않는다”고 말했고, Esportal 외부 플레이어들도 스킨 누락을 보고함
  • 스킨은 Steam ID 소유권과 연결되므로, 개인 스킨이 보이기 전까지는 플레이어가 Steam을 통해 제대로 인증되지 않았을 가능성이 있음
  • 정상 사용자 로그에서는 접속 후 약 1분 20초STEAM USERID validated가 기록됨
16:39:55: "Alice<1><>" connected
16:41:14: "Alice<1><>" STEAM USERID validated
17:17:32: "Alice<1><CT>" disconnected (reason "NETWORK_DISCONNECT_DISCONNECT_BY_USER")
  • 2024년 1월 3일 이전의 오래된 로그에서는 Steam 검증이 접속 후 2~3초 안에 끝났음
  • Washington 야간 시간대에는 직접 재현이 가능했고, Washington 주간에는 재현되지 않았음

NETWORK_DISCONNECT_STEAM_LOGON과 failure code 8

  • 실패 사용자 로그에서는 STEAMAUTH: Client Bob received failure code 8 직후 NETWORK_DISCONNECT_STEAM_LOGON으로 연결이 끊김
16:40:13: "Bob<6><>" connected
16:43:02: STEAMAUTH: Client Bob received failure code 8
16:43:02: "Bob<6><TERRORIST>" disconnected (reason "NETWORK_DISCONNECT_STEAM_LOGON")
  • NETWORK_DISCONNECT_STEAM_LOGON은 사용자가 보는 No user logon 메시지의 내부 식별자로 추정됨
  • libengine2.so에서 STEAMAUTH: Client %s received failure code %d 문자열을 찾고, CS:GO 유출 소스의 sv_steamauth.cpp와 역공학 결과를 함께 비교함
  • CS2의 관련 함수는 eAuthSessionResponse 값에 따라 클라이언트를 끊음
    • 1: k_EAuthSessionResponseUserNotConnectedToSteam
    • 7: k_EAuthSessionResponseAuthTicketInvalidAlreadyUsed
    • 8: k_EAuthSessionResponseAuthTicketInvalid
  • failure code 8은 Steam3 검증 실패 시 보이는 k_EAuthSessionResponseAuthTicketInvalid에 해당하는 것으로 보임

Steam3 검증 흐름

  • 게임 클라이언트 CS2.exe는 게임 서버에 접속할 때 자신의 Steam ID를 전달함
  • 게임 서버는 그 Steam ID가 유효한지, 게임을 소유했는지 확인하기 위해 Steam3 서버에 묻는 구조임
  • 검증 응답을 기다리는 동안 플레이어는 서버에서 계속 플레이할 수 있지만, 개인 스킨은 보이지 않을 수 있음
  • Steam3 서버가 “yes”를 반환하면 게임 서버는 해당 정보를 신뢰하고 스킨 같은 개인 정보를 적용할 수 있음
  • Steam3 서버가 “no”를 반환하면 게임 서버는 클라이언트를 NETWORK_DISCONNECT_STEAM_LOGON으로 끊음
  • Washington 야간 시간대에 Steam3 응답이 느려지는 상황에서는 검증 완료까지 약 1분 20초가 걸렸음

CS2.exe 신뢰 검증과 Steam 클라이언트

  • Steam ID가 유효하다는 것만으로는 해당 CS2.exe 인스턴스가 같은 머신에서 로그인된 Steam 계정의 게임인지 증명되지 않음
  • CS2.exe는 같은 머신의 Steam.exe와 연결해, 자신이 보낸 Steam ID가 현재 로그인된 Steam 계정과 일치하는지 확인받아야 함
  • Steam.exe가 일치 여부를 확인하면 Steam3 서버에 해당 Steam ID가 CS2에 대해 유효하다는 정보를 임시로 저장함
  • Steam3가 “no”를 반환할 수 있는 후보 중 실제 문제와 가까운 것은 다음 두 가지로 좁혀짐
    • CS2.exe 인스턴스가 신뢰되지 않음
    • Steam3 서버가 해당 CS2.exe 인스턴스에 대한 Steam ID 정보를 아직 모름

클라이언트 쪽 단서: NETWORK_DISCONNECT_LOOPSHUTDOWN

  • 실패 로그에는 NETWORK_DISCONNECT_STEAM_LOGON 전에 NETWORK_DISCONNECT_LOOPSHUTDOWN 이 먼저 나타남
16:40:03: "Bob<6><>" connected
16:40:08: "Bob<6><Unassigned>" disconnected (reason "NETWORK_DISCONNECT_LOOPSHUTDOWN")
16:40:13: "Bob<6><>" connected
16:43:02: STEAMAUTH: Client Bob received failure code 8
16:43:02: "Bob<6><TERRORIST>" disconnected (reason "NETWORK_DISCONNECT_STEAM_LOGON")
  • NETWORK_DISCONNECT_LOOPSHUTDOWN 뒤에는 게임이 5초 후 자동으로 다시 연결을 시도함
  • 이 첫 번째 끊김은 게임 서버가 아니라 CS2.exe 자체가 시작한 끊김임
  • 따라서 근본 원인은 게임 서버가 아니라 게임 클라이언트 쪽에 있었음

Source 2의 levelload 루프와 초기화 순서

  • Source 2 엔진은 한 번에 하나의 활성 루프를 실행하며, 루프는 특정 목표가 완료될 때까지 백그라운드 작업과 사용자 입력 처리를 반복함
  • CS2.exe 시작 후 최종적으로 실행되는 루프는 실제 메뉴 상호작용과 게임플레이를 담당하는 game 루프
  • 콘솔 출력에서는 game 루프로 전환되기 직전에 Steam 인증 상태가 OK로 표시됨
[SteamNetSockets] AuthStatus (steamid:<redacted>):  OK  (OK)
[Client] CL:  CLoopModeLevelLoad::MaybeSwitchToGameLoop switching to "game" loopmode with addons ()
[EngineServiceManager] SwitchToLoop game requested:  id [1] addons []
  • levelload는 CS2 시작 시 실행되는 초기화 루프이며, 실제 맵이 아니더라도 인트로 영상과 메인 메뉴 같은 초기 화면을 로드하는 것으로 보임
  • levelload의 마지막 작업 중 하나가 CS2.exe에서 Steam.exe를 거쳐 Steam3 검증을 시작하는 것임

버그의 직접 원인

  • CS2는 levelload 루프가 성공적으로 끝난 뒤에야 완전히 초기화된 상태로 볼 수 있음
  • levelload 초기화가 끝나기 전에 조기 종료되면 Steam3 검증이 시작되지 않음
  • 이 상태의 CS2.exe 인스턴스는 깨진 상태가 되며, 단순히 CS2를 다시 시작하기 전까지 복구되지 않음
  • 버그 흐름은 다음과 같음
    • CS2.exe 시작
    • levelload 루프 시작
    • Steam3 검증을 시작하기 전에 levelload가 조기 종료
    • game 루프가 게임 서버에 검증되지 않은 Steam ID로 접속
    • 게임 서버가 Steam3에 확인
    • 최대 약 2분 50초 뒤 실패 응답을 받고 No user logon으로 끊음
  • 이 문제는 CS2 예시와 이름을 기준으로 다루지만, CS:GO와 Counter-Strike: Source에도 동등한 버그가 있으며 기술 이름과 방식만 다름

버그를 유발하는 접속 방식

  • 문제는 CS2 시작 방식에 따른 경쟁 조건(race condition)
  • 버그를 거의 확실하게 유발하는 방법은 CS2가 열려 있지 않은 상태에서 바로 게임 서버에 접속하는 것임
  • 위험한 접속 방식은 다음과 같음
    • 게임 외부 서버 브라우저에서 CS2가 실행되지 않았거나 막 시작된 상태로 서버 접속
    • Steam 친구 목록에서 CS2가 실행되지 않았거나 막 시작된 상태로 친구에게 접속
    • steam://connect/127.0.0.1:27015 같은 Steam 브라우저 프로토콜로 외부에서 직접 접속
  • CS2를 시작한 뒤 완전히 초기화되기 전에 위 동작을 하면 발생 가능성이 더 높아짐
  • 원인 비중은 “Counter-Strike 시작 방식 90%, 컴퓨터 속도 3%, 사용자 속도 3%, 달의 상태 3%, 실제 사용자 설정 문제 1%”라는 비유로 정리됨

실제 해결 방법

  • 하지 말아야 할 조치
    • 게임 재설치
    • 게임 파일 검증
    • Steam 재시작
    • 컴퓨터 재부팅
    • WiFi 비활성화
    • CS2가 시작되기 전 외부에서 게임 서버에 접속
  • 대신 CS2를 먼저 실행하고, 게임 서버에 접속하기 전에 충분히 기다려야 함
  • 기준은 게임 콘솔이 보일 때까지 기다리거나, 인트로 영상이 보인 뒤 5~10초 기다리는 것임
  • 확실히 확인하려면 CS2를 시작한 뒤 게임 콘솔에서 status를 입력하고 다음 줄을 확인하면 됨
[EngineServiceManager] @ Current  :  game

Esportal의 수정 결과

  • 실패 사용자 Bob이 첫 시도 후 9분 뒤 검증에 성공한 이유는 CS2를 다시 시작했고, 그때는 운 나쁘게 버그가 발생하지 않았기 때문임
  • 한 번 Steam ID가 검증되면, 같은 게임 인스턴스에서는 Steam 클라이언트를 닫지 않는 한 나중에 실패하지 않음
  • Esportal은 2024년 1월 10일까지 CS2.exe 프로세스가 생기자마자 완전 초기화 전에도 steam://connect/<IP>:<Port>로 매치메이킹 서버에 접속시키고 있었음
  • 해당 동작을 고쳐 모든 Esportal 플레이어에게 배포하자 관련 사용자 티켓이 멈춤
  • 일일 티켓 중 No user logon 비중은 2024-01-07에 23% 까지 올랐지만, 2024-01-10부터 2024-01-12까지 0% 로 떨어짐

댓글과 토론

Hacker News 의견들
  • 다이어그램의 흐름은 Steam이 Session Tickets라고 부르는 방식에 가깝고, 실제로는 좀 더 미묘함
    게임 클라이언트가 Steam 서버에 세션 티켓을 요청한 뒤, 게임 서버에는 자신이 특정 Steam ID임을 증명하는 티켓을 전달함
    이후 게임 서버는 Steam의 Web API에 온라인으로 확인해서 티켓이 여러 번 쓰였거나 변조되지 않았는지 검증해야 함
    CS2 클라이언트가 세션 티켓을 얻는 과정의 지연 응답을 제대로 처리하지 못하는 것처럼 들림
    흐름은 여기 자세히 나와 있음: https://partner.steamgames.com/doc/features/auth#3
    글의 다이어그램처럼 동작한다면 공격자가 피해자의 Steam ID로 서버 참가를 경합할 수 있어 꽤 우려스러움

    • 맞음, 대체로 세션 티켓일 가능성이 높고 글에서는 그 부분이 명확히 표현되지 않은 듯함
      문제는 게임이 실제로 세션 티켓을 만들기 전, 또는 느린 Steam 서버 응답을 기다리는 동안 중단되고, 티켓 없이 게임 서버에 접속하는 데 있어 보임
    • 맞음, 기술적으로는 이 흐름이 정확하고 문제 설명에는 크게 중요하지 않다고 봤지만 더 명확하게 언급했어야 했다고 봄
  • 글은 훌륭하지만, 추적 과정과 결론이 완전히 맞물리지는 않음
    “Counter-Strike가 시작되는 방식: 책임 비중 90%”라고 하면서도, 전 세계 플레이어가 Esportal 밖에서도 같은 문제를 겪고 워싱턴 한밤중 점검 때문이라고 확인했다는 부분은 동시에 참이기 어려움
    책임이 90%가 실행 방식이라면 문제가 점검 시간대에 분포하지는 않았을 것임
    핵심은 “게임 루프가 시작되기 직전에 Steam ID 검증이 시작된다”와 “levelload 초기화가 끝나지 않으면 Steam3 검증이 마지막 단계라서 시작되지 않는다”는 부분으로 보임
    즉 점검 시간대에 steam3 서버가 매우 느려지면 이 과정이 길어지고, 그 사이 게임을 시작해 루프를 끊을 가능성이 커짐
    그래서 “Counter-Strike가 시작되는 방식”도 맞지만, “달의 상태: 책임 비중 3%” 같은 표현은 사실상 점검 시간대를 가리키는 셈이라 조금 어긋남
    조언도 “CET 13~17시에는 Valve 점검 시간대라 몇 분 더 기다려라”가 포함되면 좋겠음
    어쨌든 이 문제를 겪어봤고, “조금 기다려 로딩이 끝나게 하라”는 해결책은 지금까지 들은 것 중 가장 실용적이고 합리적임

    • 설명이나 결론의 세부에는 빈틈이 있지만, 이 해석도 완전히 맞는지는 확신하기 어려움
      CS:GO에서도 점검 시간대와 무관하게 같은 문제가 있었고, CS2에서는 점검 시간대에만 관찰됐음
      결국 CS:GO와 CS2의 버그 성격이 달랐을 수도 있지만, CS:GO가 CS2로 대체되어 더는 증명할 방법이 없음
  • 예전에 Steam이 없던 시절, 친구가 접속한 서버를 보고 바로 들어갈 수 있도록 활성 플레이어와 점수 목록을 보여주는 도구를 만든 적이 있음
    그 도구를 만들다가 테스트하던 서버에 잘못된 패킷을 보냈더니 서버가 내려갔음
    Delphi로 작성한 소스 코드가 아직 있는데, 10년 된 버그들이 남아 있다면 이게 아직도 서버를 죽일 수 있을지 궁금함

    • 한번 해볼 수 있음? :D
  • 진짜 버그는 인증 완료가 비 LAN 멀티플레이어 시작의 필수 조건이 아니라는 점임

    • 또는 세션 티켓 검증 흐름이 게임 서버와 Valve의 인증 서버 사이 연결에 의존한다는 점도 문제임. 그 인증 서버가 때때로 매우 느린 듯함
      더 빠르고 견고한 방식은 Steam 클라이언트가 Valve에서 몇 시간짜리 서명 토큰을 받아 보관하고, 게임 서버에 접속할 때마다 그 토큰을 보내는 것일 수 있음
      게임 서버는 Valve가 발급하고 서버 콘텐츠에 함께 배포되는 공개 인증서로 로컬에서 검증하면 됨
  • 몇몇 문단은 “모자 위에 모자를 얹는” 느낌임
    이미 밈스러운 문단 위에 빈정거림을 더 쌓아서, 은근할 때 더 잘 먹히는 요소가 과하게 느껴짐
    다른 사람들이 말했듯이 핵심으로 더 빨리 들어가는 편이 좋음

  • 아주 재미있게 읽었음. 게임 클라이언트가 갑자기 크래시 나는 이유도 같은 방식으로 조사할 수 있을지 궁금함
    실행 파일 무결성 검사가 실행 중에도 돌아가는지, 그중 하나가 실행 중 실패하면 다른 연결 해제 메시지가 뜨는지도 궁금함
    GTA V 로딩 시간이 너무 길었던 문제를 분석한 글처럼 보상받을 만해 보임: https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...

    • 어떤 갑작스러운 크래시를 말하는 건지 궁금함
      크래시는 이론상 조사할 수 있지만, Valve는 크래시 보고서를 디스크에 저장하지 않고 서버로 보냄
      디버거를 붙인 상태로 실시간으로 잡지 못하면 분석이 더 어렵고, VAC 때문에 까다롭지만 불가능하지는 않음. VAC를 끄면 됨
  • 글 첫머리에 문제 해결을 검색해 들어온 사람들을 위한 요약을 둔 건 배려심 있어 보임
    그런데 바로 이어서 “하지 말아야 할 것”을 말하고, 실제로 할 수 있는 조치는 킬로미터급 글 중간의 한 문장에 숨겨둔 셈임
    우회 방법을 요약에 넣는 편이 좋겠음

    • 거의 잔인한 농담 같음. 요약: 이건 하지 말고, 대신 전체 글을 읽으세요!
    • “킬로미터급 글”은 계산 단위로는 Page Down 약 25번, 자유 단위로는 CTRL+F 정도임
    • 맞는 말이라 더 나은 요약으로 수정했음
  • Strunk and White식 글쓰기 취향이 머리에 박혀 있어서 하는 말이니, 원하면 무시해도 됨
    피드백을 원한다면 글을 훨씬 더 직접적이고 간결하게 강하게 편집하는 걸 권함
    긴 글을 쓸 수는 있지만, 몇 분 지나자 부가 설명과 일화가 쌓이면서 핵심 흐름을 꽤 빨리 놓쳤음
    여기에 Inception 참조 이미지까지 들어가니 정보 전달 글이라기보다 서로 관련 없는 내용이 모이는 느낌이 커짐
    무엇을 말하려는지 생각하고, 그것을 말한 뒤, 다시 돌아가 정말 그것만 말했는지 확인하면 됨
    나머지는 글쓰기가 아니라 타자 연습에 가까움. 말할 게 3~4개라면 그냥 그것만 말하면 됨

  • 글은 훌륭했지만 몇 가지 질문이 남음
    levelloadloop는 게임 실행 시에만 실행되고, 서버 참가와 맵 로딩 때는 실행되지 않는가?
    문제가 Steam 인증 프로세스가 시작되기 전에 루프가 종료되는 것이라면, 점검 때문에 느려지는 현상은 왜 중요해지는가?

    • 1번은 맞음, 게임 실행 때만 실행됨
      이 루프 이름은 Portal 같은 싱글플레이어 게임과 관련 있어 보이고, 그런 게임에서는 레벨을 끊김 없이 바꾸기 때문에 이런 이름이 훨씬 자연스러움
      2번은 설명에 빈틈이 있는 게 맞고 답은 모름
      다만 이 방법이 문제를 고치는 것은 확실함. 결론의 세부가 불완전할 가능성이 높지만, 지금은 더 깊게 파고들 필요를 느끼지 않음
  • Valve의 보상 프로그램 문구에는 “Steam 플랫폼과 Valve가 개발·배급한 현재 게임”이 포함된다고 되어 있음
    또 2023년 6월 14일 오전 10시 PDT부터 CS:GO 신규 보고는 범위 밖이고, CS2 Limited Test 보고도 현재 범위 밖이라고 되어 있음
    Valve가 보안에 약한 건 맞지만, 전체 HackerOne 설명을 넓게 읽으면 개인적으로는 범위 안으로 보겠음
    “Scope” 탭에서 csgo.exe를 제외하도록 업데이트하지 않았으니, 그 탭만으로는 신뢰하기 어렵다는 뜻임
    그래도 Valve는 제발 그 부분을 업데이트해야 함

    • Valve가 이게 범위 안인지 묻는 단순 요청에도 답하지 않으니 알 수는 없음
      그래도 결론에는 동의하고, 말이 됨