새로 깐 것이 범인처럼 보였다
집 네트워크가 끊기기 시작했고, 며칠 전에 깐 Tailscale 을 지우려 했다. 설치 시각과 증상 시작 시각을 각각 재니 이상 지표가 설치보다 18~127일 앞서 있었다.
집 인터넷이 끊기기 시작했고, 며칠 전에 깐 프로그램을 지우려 했습니다. 시각을 각각 재 보니 증상이 설치보다 «18~127일 먼저» 있었습니다.
흔한 추리
인터넷이 이상해졌습니다. 그리고 며칠 전에 새 프로그램을 하나 깔았습니다.
「저것 때문이네.」
아주 자연스러운 추리입니다. 그리고 대개 맞습니다. 그래서 더 위험합니다.
그런데 시각을 재 봤습니다
지우기 전에 두 시각을 각각 재 봤습니다.
| 무엇 | 언제 |
|---|---|
| 그 프로그램을 깐 날 | 며칠 전 |
| 증상이 처음 나타난 날 | 18~127일 «전» |
증상이 먼저 있었습니다. 최대 넉 달 전부터요.
원인이 결과보다 나중에 올 수는 없습니다. 무죄입니다.
값을 치른 것 하나 — 「파일 날짜는 설치 날짜가 아닙니다」
재는 과정에서 배운 것입니다.
「언제 깔았지?」를 확인하려고 폴더의 파일 날짜를 봤습니다. 그럴듯합니다.
틀렸습니다.
| 파일 날짜가 바뀌는 때 |
|---|
| 설치할 때 |
| 업데이트할 때 |
| 설정을 한 번 열었을 때 |
| 백신이 검사했을 때 |
그래서 파일 날짜는 「마지막으로 뭔가 일어난 날」이지 「처음 깐 날」이 아닙니다.
제대로 된 설치 기록을 따로 찾아야 했습니다. 그리고 그 값이 파일 날짜와 달랐습니다.
그럴듯한 대리 지표가 진짜 값과 다른데, 둘 다 「날짜」라서 안 의심하게 됩니다.
못 재는 자리를 「없었다」로 쓰지 않았습니다
기록이 없는 구간이 있었습니다. 그 기간에 증상이 있었는지 알 수가 없었습니다.
여기서 유혹이 하나 있습니다 — 「기록에 없으니 없었던 것」으로 쓰면 이야기가 깔끔해집니다.
안 그랬습니다. 「이 구간은 못 쟀음」으로 적었습니다.
없는 기록은 「없었다」의 증거가 아닙니다. 그냥 모르는 것입니다. 그리고 그 둘을 섞으면 결론이 실제보다 단단해 보입니다.
결론이 한 번 뒤집힌 곳은 «측정 방법» 때문이었습니다
조사 중에 결론이 한 번 뒤집혔습니다. 그리고 그 원인이 새 증거가 아니라 재는 방법이었습니다.
처음엔 한 방법으로 쟀고, 그 방법에 편향이 있었습니다. 방법을 바꾸니 같은 데이터에서 다른 답이 나왔습니다.
결론이 뒤집혔을 때, 새 사실 때문인지 재는 법 때문인지를 갈라야 합니다. 뒤쪽이면 앞서 잰 다른 값들도 같이 의심해야 합니다.
판정 — 무죄, 그리고 «원인 미규명»
여기가 이 글에서 제일 중요한 대목입니다.
결론은 「그 프로그램은 범인이 아니다」입니다. 그런데 그게 「원인을 찾았다」는 뜻은 아닙니다.
진짜 원인은 아직 모릅니다.
그리고 그 사실을 분명히 적었습니다. 안 적으면 이렇게 됩니다.
| 나중에 | |
|---|---|
| 무죄만 적으면 | 「그럼 해결됐네」로 읽힘 → 다시 끊길 때 당황 |
| 무죄 + 원인 미규명 | 아직 안 끝났다는 걸 앎 |
「누가 아니다」와 「누구다」는 다른 답입니다. 그리고 앞엣것만 나왔는데 뒤엣것이 나온 것처럼 적으면, 조사가 거기서 멈춥니다.
못 한 것
원인을 못 찾았습니다. 그래서 이 글은 한 용의자를 무죄로 만든 기록이지 사건을 해결한 기록이 아닙니다.
그리고 그 프로그램을 지우자는 제안을 다시 하지 않기로 적어 뒀습니다 — 무죄가 확정됐으니, 같은 추리가 반년 뒤에 또 나오는 걸 막으려고요.
여기부터는 자세한 기록입니다
이 글에서 무죄가 되는 도구의 이름은 Tailscale 이다. 멀리 떨어진 내 기계들을 같은 방에 있는 것처럼 이어 주는 물건이다. 집 PC와 회사 PC에 각각 깔아 두면 공유기 설정을 열거나 포트를 뚫지 않아도 둘이 서로를 찾고, 깔린 기계끼리만 통하는 사설 주소 하나씩을 나눠 준다. 그 주소로 파일을 옮기거나 원격으로 붙는다. 나는 집과 회사에서 같은 작업을 이어 하려고 깔았다.
깔고 며칠 뒤, 집 네트워크가 하루에도 몇 번씩 끊겼다. 무선은 느려지고 유선도 같이 느려지고, 30초쯤 아무것도 안 나가다 돌아왔다. 의심은 바로 붙었다 — 며칠 전에 깐 그것. 새로 들어온 것이 하나뿐이면 그게 범인이다.
그래서 지우기 전에 한 가지만 했다. 설치 시각과 증상 시작 시각을 따로 쟀다. 둘 다 재고 나니 순서가 반대였다.
파일 날짜는 설치 날짜가 아니다
처음 잡은 설치일이 틀렸다. 프로그램 폴더의 파일 날짜를 봤는데 그건 만든 쪽이 빌드한 날이지 내가 깐 날이 아니다. 3주 차이가 났고, 그 3주 안에 증상이 들어 있었다. 여기서 한 번 속았다.
제대로 된 설치 시각은 세 군데에서 같은 값이 나와야 잡힌다 — 서비스가 등록된 이벤트, 레지스트리의 설치 시각, 네트워크 어댑터가 처음 나타난 시점. 셋이 같은 날 같은 시각을 가리키고 나서야 기준선이 생겼다.
판정의 기준선을 대상이 스스로 말하게 두면 안 된다. 파일 날짜는 대상이 들고 온 숫자다.
증상은 설치보다 18일에서 127일 먼저 있었다
기준선이 생기니 비교가 가능해졌다. 유선 쪽 오류 이벤트는 설치 18일 전에 처음 찍혔고, 그 앞 넉 달은 0건이었다. 포트가 말라붙는 다른 지표는 설치 127일 전이 처음이었다.
더 결정적인 건 발생률이었다. 설치 전 하루 3.17건, 설치 후 하루 2.15건. 32% 줄었다. 범인으로 지목된 것이 들어온 뒤에 증상이 덜 났다.
도구 자체도 놀고 있었다. 외부로 나가는 경로 설정 0건, 가로채는 이름 규칙은 자기 전용 주소에만 걸려 있었고, 134일치 연결 판정 기록 전수에서 이 어댑터가 인터넷 경로로 잡힌 적이 한 번도 없었다. 데몬의 누적 CPU 사용 시간은 0초였다.
“새로 깐 것”은 용의자 목록을 만드는 근거는 되지만 판정의 근거는 못 된다. 시간 순서를 재기 전까지는 목록에 있을 뿐이다.
못 재는 자리를 “없었다”로 쓰지 않았다
무선 증상은 이 PC에서 원리적으로 확인할 수 없었다. 무선 어댑터가 아예 없는 기계다. 관련 서비스가 멈춰 있고 로그는 0건이다. 0건은 “문제가 없었다”가 아니라 “잴 수 있는 장치가 없다”였다.
30초 단절도 같았다. 이 운영체제는 연결 상태를 15초마다 확인하고 30초가 지나야 낡은 것으로 치며 35초에 판정을 내린다. 30초짜리 단절은 판정이 나기 전에 끝난다. 저수준 패킷 로그도 꺼져 있었다. 사건이 지나간 뒤에 뒤져서는 안 나오는 게 정상이다.
계측기가 꺼져 있던 구간을 무죄의 근거로 쓰면, 그건 무죄가 아니라 무기록이다. 그래서 이 두 구간은 판정에서 빼고 “못 쟀다”로 남겼다.
결론이 한 번 뒤집힌 곳은 측정 방법 때문이었다
중간에 “이름 서버가 고장 났다”는 결론을 한 번 냈다. 평균 590ms가 나왔으니 근거는 충분해 보였다. 그런데 그 측정은 존재하지 않는 임의의 주소를 물어본 것이었다. 없는 이름을 묻는 경로는 실제 조회와 다른 길을 타고, 서버마다 수십 배씩 갈린다.
실제로 쓰는 주소로, 예열을 주고, 순서를 돌려 가며 다시 쟀다. 중앙값 5ms. 비교 대상과 같은 값이었다. 꼬리 쪽만 실재했고 그건 위생 문제지 원인이 아니었다.
측정 방법이 틀리면 숫자는 여전히 나온다. 숫자가 나왔다는 사실은 그 숫자가 맞다는 증거가 아니다.
판정 — 무죄, 그리고 원인 미규명
지목된 도구는 무죄다. 지우지 않았다. 그리고 원인은 아직 모른다. 남은 용의자는 공유기 무선부, 공유기 바깥 구간, 회선 셋인데 전부 이 PC에서는 안 보이는 자리다.
이 글의 절반은 두 번째 문장을 쓰기 위해 있다. 무죄 판정과 원인 규명은 다른 일인데, 하나를 끝내고 다른 하나를 안 끝내면 무죄 쪽이 자꾸 무효가 된다. 증상이 또 나면 새로 깐 것이 다시 제일 먼저 의심받고, 잰 것을 안 적어 두면 그 사람은 같은 측정을 처음부터 다시 한다. 그래서 무죄를 재제안 금지라고 적어 뒀다 — 근거와 함께.
못 한 것
- 원인을 못 찾았다. 이 글은 범인을 잡은 기록이 아니라 한 명을 풀어 준 기록이다.
- 남은 용의자 셋 중 하나도 안 열었다. 전부 PC 밖이라 다른 관측 지점이 필요하다.
- 회선의 계약 상한을 모른다. 측정된 처리량이 정상인지 절반인지 판정할 기준이 없다.
- 무선 구간은 끝까지 못 쟀다. 기계를 바꾸지 않는 한 이 PC에서는 앞으로도 못 잰다.