봇은 집 노트북에서 돕니다. 폰에서 대시보드를 확인하고 싶고, 공개 노출은 0이길 바랍니다. Tailscale이 이 둘을 공존시키는 방법입니다.
셋업
각 봇은 자기 포트에 작은 로컬 대시보드를 서빙합니다. 그 포트를 인터넷에 여는 대신 tailscale serve로 테일넷에 올립니다. 이제 대시보드는 제 소유 기기 어디서나 암호화된 메시로 닿고, 그 외 누구에게도 안 닿습니다. 리버스 프록시도, 라우터 포트포워딩도, 스캔당할 공개 URL도 없습니다.
폰에서 봇 확인은 그냥 테일넷 주소를 여는 것. 1인 셋업의 원격 운영은 이게 전부입니다.
함정: 봇을 폐기해도 경로는 폐기 안 된다
혼란을 안긴 하나입니다. 봇을 은퇴시킬 때 당연한 정리를 합니다: LaunchAgent launchctl bootout, plist 삭제, 프로젝트 디렉토리 삭제. 끝? 아닙니다.
그 포트의 tailscale serve 포워딩이 남습니다. 별개 설정이라 launchd·파일시스템 정리가 건드리지 않습니다. 이제 없는 백엔드로 포트가 계속 포워딩됩니다.
증상이 고약한 건 건강해 보이기 때문입니다: 포트가 여전히 LISTEN으로 떠서 대충 보면 "가동 중"인데, 포워딩 뒤에 아무것도 없어 모든 연결이 즉시 reset됩니다.
# 아직 무엇이 포워딩되는지 확인
tailscale serve status --json # TCPForward 아래 포트 확인
# 그 하나만 제거 (`clear`는 전부 날리니 쓰지 말 것)
tailscale serve --tcp=<PORT> off
플레이스홀더 — 실제 캡처 예정, 호스트명 마스킹.
하나 더: 로그인 화면에선 에이전트가 기동 안 함
같은 스택의 관련 실패: 맥이 재부팅되고 macOS 로그인 화면에 멈추면 gui/501 도메인이 없어 LaunchAgent가 하나도 로드되지 않습니다 — 모든 봇·대시보드가 다운. 그런데 Tailscale 포워딩이 살아있으면 포트는 응답하고 곧 reset되는데, 이게 위 고아 포트 증상과 똑같이 읽힙니다. 원인은 둘, 겉모습은 하나.
솔직한 부분
Tailscale은 원격 운영을 사소하게 만들었지만, 제 평소 폐기 절차 바깥에 사는 상태 조각을 추가했습니다. 교훈은 일반화됩니다: 별도 레이어로 무언가를 노출할 때마다 — 메시 경로, CDN 규칙, 방화벽 항목 — 그 레이어는 폐기 체크리스트에 자기 줄이 필요합니다. "앱을 지웠다"는 "앱에 닿는 모든 길을 없앴다"와 다릅니다. 이제 모든 봇 은퇴를 tailscale serve status 실행과 유령 포워딩 제거로 끝냅니다.