코드 한 줄도 안 고치고 끝난 게 정답이었다
폐쇄망에서 외부 데이터 시스템에 Kerberos로 접속하는데 인증이 자꾸 거절당하는 이슈가, 며칠째 끌려오고 있었다. 이틀간 코드를 읽고, 테스트 환경에서 재현하고, 보고 리포트를 세 번 다시 썼다. 그러고 결국 우리 코드는 한 줄도 수정하지 않았다. 남은 건 “이 문제를 서버 쪽과 클라이언트 쪽 중 누가 먼저 푸는가”를 다시 자른 리포트 한 장이었다. 디깅의 결과물이 코드가 아니라 분업의 재설계였던 셈이다.
이슈 맥락
접속 시 떨어지는 에러는 이거였다.
TTransportException: Bad status: 3 (Error validating the login)
문제는 내가 Kerberos 기반 인증 도메인에 거의 무지였다는 점이다. SASL이 뭔지, service name이 뭔지, DNS 역방향 조회 옵션이 뭔지 하나씩 물어가면서 따라갔다.
재현부터
첫 습관은 “우리 환경에서 재현되는가”다. 설정을 맞춰 돌려보니 우리 환경에서는 다른 에러가 났다. 에러 메시지를 단계별로 매핑해 보니, 우리는 인증 시작 이전 단계에서 막히고 상대는 서버까지 ticket이 도달한 뒤 검증에서 거절당하고 있었다. 처음 써둔 “테스트 환경 재현 완료”라는 결론을 철회했다. 비슷한 에러를 같은 원인으로 묶으면 단계 차이를 놓친다.
우리 쪽이 풀 수 있는 범위
그 후 원인 후보를 하나씩 소거했다. Kerberos 환경 변수 미설정, 사용자 계정 불일치에 의한 권한 거절, 클라이언트 간 요청 principal 차이, DNS 역방향 조회 옵션에 의한 principal 비틀림. 실측으로 확인할 수 있는 것과 없는 것이 섞여 있었다. 우리 쪽에서는 설정 패치로 정상 동작을 만들어냈다.
여기서 한 번 멈췄다. 우리 환경이 풀렸다고 상대 환경이 풀리는 건 아니다. 오히려 우리 환경이 풀린 게 “상대와 우리는 다른 단계에서 막힌다”는 관찰을 재확인해주는 신호였다. 우리가 만든 체크리스트 1·2·3번은 우리 테스트 환경을 상대 환경처럼 만드는 셋업이지, 상대가 적용해서 풀릴 항목이 아니었다. 진짜 원인은 4번 단계, 즉 서버 측 키 불일치, 계정 권한 거절, NTP 어긋남 같은 인프라 영역이었다.
이 지점에서 판단을 분리했다. 우리 코드의 개선 포인트는 다른 환경에서 같은 고생 안 하도록 따로 패치하되, 그걸 이번 건의 해결책으로 내밀지 않는다. 두 방향을 섞으면 상대는 우리 체크리스트를 받아 적용해도 같은 에러가 나고, 우리는 “체크리스트가 틀렸나”를 다시 분석해야 한다.
로그는 누가 먼저 읽나
리포트 초안을 정리하다가 한 번 더 멈췄다. 그때까지 흐름은 “상대에게 서버 로그 요청 → 우리가 받아서 분석 → 결론 공유”였다. 써놓고 보니 각자 잘할 수 있는 일이 뒤바뀐 구조였다.
서버 로그는 그쪽 인프라 담당자가 가장 빠르게 해석할 수 있는 자료다. 우리가 받아서 보는 구조에는 두 가지 비효율이 있었다. 하나, 로그 해석에 도메인 지식이 모자라 우리가 또 가설만 쌓게 된다. 둘, 설령 가설이 맞아도 조치는 상대가 하니 결국 그쪽이 한 번 더 읽어야 한다. 같은 로그를 두 번 읽는 셈.
순서를 다시 잡았다.
- 인프라 담당자가 서버 로그를 먼저 보고 자기 쪽에서 처리 가능한 항목(서버 키 불일치, 계정 권한, NTP 등)인지 판단
- 그중 “클라이언트가 이상하다” 싶은 경우만 공유
- 우리는 클라이언트 결함 부재를 증명
이 순서가 되면 우리 역할은 “완전한 원인 규명”이 아니라 “클라이언트 결함 부재 증명 + 참고 자료 제공”이다. 리포트를 다시 썼다. 분량은 오히려 줄었고, 상대가 받아 쓰기에 자연스러운 글이 됐다.
회신은 이렇게 나갔다. “테스트 환경에서 정상 동작 검증했고, 환경 셋업 점검 가이드 함께 드립니다. 점검 후에도 같은 에러면 서버 로그를 먼저 확인해주시고, 클라이언트 쪽이 같이 볼 부분이 있으면 그때 공유 부탁드립니다.” 디깅 이틀의 결과가 코드 수정 0이라 “아무것도 안 한 것”처럼 보일 수 있어, 결론의 근거는 리포트에 명시했다. “클라이언트에 결함이 없다는 결론이고, 근거는 우리 환경에서의 정상 동작 실측.”
무지한 도메인에서 내가 할 수 있었던 일
이 이슈를 돌아보면 내가 한 일은 세 번 멈춘 것뿐이다. 재현이 끝났을 때, 리포트를 쓸 때, 회신을 보내기 직전. 세 번 다 “여기서 더 나가면 내가 모르는 걸 아는 척하게 된다” 싶은 자리였다. Kerberos를 잘 알았다면 원인을 직접 짚었겠지만, 모르는 도메인에서 내가 통제할 수 있는 건 답이 아니라 멈추는 지점이었다. 가설을 세우는 것과 원인이라 못 박는 것을 구분하는 일, 누가 먼저 읽어야 빠른지로 분업을 다시 자르는 일은 도메인 지식이 아니라 멈출 줄 아는 데서 나왔다.
그래서 코드 수정이 0이어도 이건 성과였다. 멈춘 자리마다 “왜 여기서 멈췄는가”를 리포트에 적어뒀기 때문이다. 클라이언트에 결함이 없다는 결론, 그 근거는 우리 환경에서의 정상 동작 실측이라는 것. 근거가 적힌 “수정 없음”은 “아무것도 안 함”이 아니라, 모르는 영역에서 낼 수 있는 가장 정확한 답이었다.