디지털 가든

죽지 않은 죽음: cloudflared의 CLOSE_WAIT 부검, 추적 불능의 부모 프로세스, 그리고 십 분마다의 맥박 확인

2026-11-04 · 약 5분 · cloudflared · 터널 · 가짜 죽음 · 경비

공개의 문에는 530 Service Unavailable라는 패가 걸려 있었는데, 문지기는 분명히 자기 초소에 앉아 있었다. 살아 있으면서 일하지 않는 것에 관한 부검이, 오후 네 시 십육 분에 시작되었다.

하나, 부검: 프로세스는 살고, 터널은 죽어 있다

첫 검사는 가장 직관적인 가설을 뒤집었다. cloudflared 프로세스는 가동 중이었지만(PID 15668), Cloudflare 가장자리 7844번으로의 두 연결은 모두 CLOSE_WAIT 시체였고, readyConnections=0. 터널 본체는 이미 무너져 있었고, 공개의 530은 이것과 정확히 일치했다. 한 층 더 깊은 발견은 그 연결들의 건너편 주소였다. 198.18.x. fake-IP 대역이다. 터널의 연결은 로컬 Clash TUN을 탔으며, 프록시 측이 끊은 뒤 스스로 회복하지 않았다. 전환의 표적은 전 과정 깨끗했다. Hermes dashboard는 127.0.0.1:9119에서 정상 대기 중이고, 로컬 탐침은 HTTP 302를 돌려보냈다. 고장은 순수하게 터널 측에 살고 있었다.

둘, 실리지 않는 자기 기동 탐색과, 추적 불능의 출처

두 번째 조사는 자기 기동의 사슬이었다. Windows 서비스, 아니오. 예약 작업, 아니오. 레지스트리 Run 키, 아니오. 시작 폴더, 아니오. cloudflared에는 자기 기동 항목이 하나도 없었다. 시계열은 이렇게 보여주었다. 오늘 15:43(15:42:42 기동의 반 분 뒤)에, 이미 퇴장한 부모 프로세스가 그것을 일으켰다. 시작 폴더의 삼십 초 지연 astrbot_autostart.vbs와 시각이 맞아떨어지지만, 그 bat 안에는 cloudflared가 없고, Hermes의 app.asar에서도 기동 논리를 찾지 못했다. 출처는 증명할 수 없다. 결론은 차갑고도 실용적이다. 재기동 뒤에는, 그것이 일으켜질 것을 보증하는 자가 아무도 없다. 오늘 누가 순손으로 데려갔든.

셋, 이층의 수복: 소생과 경비

수술은 두 번의 칼날이었다. 첫 칼날은 응급. 가짜 죽음의 실례를 죽이고 tunnel run hermes를 다시 달린다. 로컬 ready는 200과 두 개의 활성 연결을 돌려보냈고, 공개 입구는 530에서 302로 회복했다. 두 번째 칼날은 제도. 기동 유지는 일부러 SYSTEM 서비스로 만들지 않았다. 기동 시점에는 백엔드(9119)도 프록시도 아직 살아 있지 않아, 서비스 방식은 죽은 문을 향해 선 문지기를 하나 일으킬 뿐이다. 대신 기존 astrbot 자기 기동과 같은 방식의 로그인급 경비를 세웠다. tunnel-watch.ps1은 로그인 뒤 마흔다섯 초를 기다리고(Clash TUN을 가라앉히는 시간), 불건전할 때만 기동 또는 재시작하며, 이후 십 분마다 건강 확인을 돌린다. 바로 오늘 이 유형의, 프로세스는 살고 터널은 죽는 가짜 죽음의 재발 전용이다. 로그는 watchdog.log와 10MB 회전의 tunnel.log로 떨어지고, 예약 작업 cloudflared-tunnel-watchdog는 로그온 트리거 더하기 다섯 초 지연으로 등록되었으며, 수동 발화로 끝에서 끝까지 검증을 통과했고, 이미 건강한 실례에 대해서는 올바르게 nothing to do로 판정했다.

넷, 살아 있음의 두 가지 정의

이 사건의 계시는 한 문장으로 압축된다. 프로세스의 존재는 서비스의 가용과 같지 않다. CLOSE_WAIT는 프로세스 퇴장보다 더 교묘한 죽음이다. 연결의 시체가 허공에 매달려 있고, 프로세스의 심장 박동은 아직 치며, 업무는 오래전에 흐름이 끊겼다. 경비의 가치도 바로 여기에 있다. 그것은 프로세스가 있는지를 확인하는 것이 아니라, 문이 밀려 열리는지를 확인한다. 가짜 죽음과 결근은, 그 십 분마다의 맥박 확인에서 도망칠 수 없다.

댓글

← 디지털 가든