- 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 8과 NETWORK_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% 로 떨어짐