문제 해결

SSH "Broken pipe"와 "client_loop: send disconnect": 근본부터 고치는 해법

Broken pipe는 TCP 연결이 죽었다는 뜻입니다 ── 보통 NAT의 유휴 끊김이거나, 발밑에서 네트워크가 바뀐 것입니다. 킵얼라이브(ServerAliveInterval / ClientAliveInterval), 로밍에는 mosh나 안정적인 주소로 재연결, 그리고 tmux로 작업을 지키세요.

CC Chen Chen· 창업자·2026년 6월 24일·5분 분량

"Broken pipe" / "client_loop: send disconnect"의 의미

SSH 세션이 죽은 것은 그 아래에 있던 TCP 연결이 사라졌기 때문입니다 ── 보통 한동안 유휴 상태로 두었을 때 발생합니다. packet_write_wait: Broken pipeclient_loop: send disconnect: Broken pipe는 같은 일을 조금 다른 각도에서 본 것입니다: 클라이언트가 이제는 존재하지 않는 연결로 데이터를 보내려 한 것이죠. 이것은 인증이나 서버의 문제가 아니라 연결 지속성의 문제이며, 전형적인 원인이 세 가지 있습니다: NAT 라우터가 유휴 연결을 조용히 끊는 것, 발밑에서 네트워크가 바뀌는 것(Wi-Fi ↔ 셀룰러), 그리고 어느 한쪽 끝의 공격적인 유휴 타임아웃 설정입니다.

세 가지 원인

#원인패턴
1NAT/라우터 유휴 타임아웃조용한 상태가 N 분 지나면 죽음;입력 중에는 괜찮음
2발밑에서 네트워크가 바뀜Wi-Fi 범위를 벗어나거나 / 네트워크를 전환하면 죽음
3설정된 유휴 끊김서버의 ClientAliveInterval/CountMax가 조용한 세션을 닫음

해결책 1 ── 킵얼라이브(표준 해법)

킵얼라이브는 작은 하트비트 패킷을 보내서 NAT 테이블과 유휴 타이머가 연결을 "조용하다"고 보지 않게 합니다. 클라이언트 측(~/.ssh/config):

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
# = ping the server every 60s; give up after 3 misses

또는 서버 측(/etc/ssh/sshd_config)에서 설정하면 모바일 앱을 포함한 모든 클라이언트를 커버할 수 있습니다:

ClientAliveInterval 60
ClientAliveCountMax 3

둘 중 하나만 설정해도 보통 유휴 끊김 부류는 완전히 멈춥니다. 모바일 클라이언트는 보통 앱이 포그라운드에 있는 동안 자체 킵얼라이브를 보냅니다 ── 서버 측 설정은 어떤 클라이언트에서든 작동하는 이중 안전장치입니다.

해결책 2 ── 모바일 네트워크는 로밍한다는 것을 받아들이고 대비하라

휴대폰이 Wi-Fi에서 셀룰러로 넘어가면 TCP 연결의 주소가 바뀝니다 ── 순수 SSH는 그것을 견딜 수 없습니다. 킵얼라이브를 어떻게 설정하든 세션은 끊깁니다. 선택지는:

  • mosh ── 로밍을 견디도록 만들어졌습니다(UDP, 주소에 무관). 서버에 설치가 필요합니다;터널/SFTP는 없습니다. Mosh vs SSH 참조.
  • 안정적인 주소 위에서의 빠른 재연결 ── 모바일에서 실용적인 답: Tailscale를 쓰면 서버가 모든 네트워크에서 하나의 동일한 주소를 유지하므로, 재연결은 탭 한 번이면 되고 다시 입력할 것이 없습니다. TermAI는 Tailscale를 내장하고 있어 있던 자리에서 세션을 다시 엽니다.
  • 서버의 tmux/screen ── 연결에 무슨 일이 생기든 당신의 작업은 살아남습니다: tmux attach로 다시 붙으면 실행 중이던 프로세스가 그대로 있습니다. 위의 어느 선택지와도 완벽하게 맞물립니다.
안정적인 주소를 통해 휴대폰에서 재연결된 SSH 세션
모바일의 현실:네트워크는 바뀌고 순수 SSH는 끊긴다. 안정적인 Tailscale 주소 + 서버의 tmux는 끊김을 탭 한 번·손실 제로의 일로 만든다.

해결책 3 ── 애초에 장시간 작업은 세션에 의존해서는 안 된다

끊김으로 장시간 실행 중인 명령이 죽었다면, 오래가는 습관은 작업을 터미널에 전혀 묶지 않는 것입니다: tmux 안에서 실행하거나 nohup long_command &를 씁니다. 휴대폰에서는 이것이 두 배로 중요합니다 ── 긴 대기 동안 OS가 앱을 일시 중단할 수 있습니다. 작업을 분리하여 시작하고, 죄책감 없이 앱을 닫고, 나중에 다시 확인하세요.

FAQ

왜 제 SSH 세션은 몇 분 동안 아무것도 안 하면 죽나요?
NAT 라우터나 유휴 타이머가 조용한 연결을 끊은 것입니다. 클라이언트 측에 ServerAliveInterval 60, 또는 서버 측에 ClientAliveInterval 60를 설정하세요.

SSH가 Wi-Fi에서 셀룰러로의 전환을 견딜 수 있나요?
순수 SSH는 못 합니다 ── 주소가 바뀝니다. mosh(로밍을 견딤)를 쓰거나, 안정적인 Tailscale 주소로 탭 한 번에 즉시 재연결하고, 서버의 tmux로 작업을 지키세요.

장시간 작업이 연결과 함께 죽지 않게 하려면?
분리하여 실행하세요: tmux/screen 안에서 또는 nohup으로. 그러면 작업은 어떤 끊김보다도 오래 살아남습니다.

핵심 요약

  • 의미:TCP 연결이 죽었다(보통 유휴로 끊김), 인증/서버의 잘못이 아니다
  • 표준 해법:킵얼라이브 ── ServerAliveInterval 60(클라이언트) 또는 ClientAliveInterval 60(서버)
  • 네트워크 로밍:순수 SSH는 견디지 못함 ── mosh, 또는 안정적인 주소 + 빠른 재연결
  • 작업 보호:tmux/nohup으로 작업을 세션보다 오래 살게
Try TermAI

Free on iOS and Android. 5 AI requests/day on the free tier, plus unlimited SSH/SFTP and built-in Tailscale.

CC
Chen Chen — Founder of TermAI

Writes about mobile DevOps, terminal UX, and the surprising depth of "boring" infrastructure.

Was this useful? ← Back to blog