SSH 타임아웃 문제 방지를 위한 모범 사례

클라이언트 keepalive, 적절한 서버 설정, tmux 또는 screen을 사용한 장기 작업으로 유휴 SSH 연결 끊김을 방지하세요.

SSH 타임아웃 문제 방지를 위한 모범 사례

SSH 타임아웃은 일반적으로 몇 분 동안 유휴 상태인 후 터미널이 멈추고, broken pipe 또는 connection reset 오류가 출력될 때 나타납니다. 원인은 종종 방화벽, NAT 게이트웨이, VPN 또는 로드 밸런서가 SSH 클라이언트가 감지하기 전에 유휴 TCP 세션을 끊기 때문입니다.

가장 유용한 해결책은 클라이언트의 SSH keepalive입니다. 서버 측 설정도 도움이 될 수 있지만, 목적이 다르며 너무 공격적으로 설정하면 죽은 클라이언트를 연결 해제할 수 있습니다.

SSH 타임아웃의 근본 원인 이해

SSH 타임아웃은 클라이언트와 서버 간의 통신 링크가 특정 시간 동안 활동이 감지되지 않아 끊어질 때 발생합니다. 이는 일반적으로 SSH 소프트웨어 자체가 아니라, 리소스를 절약하기 위해 유휴 연결을 적극적으로 정리하는 중간 네트워크 장치(방화벽, 라우터, NAT 테이블) 때문입니다.

방화벽이 특정 TCP 연결에서 몇 분 동안 트래픽을 보지 못하면 세션이 죽었다고 가정하고 연결 상태를 삭제합니다. SSH 클라이언트가 다음에 데이터를 보내려고 하면 서버가 이를 수신하지 못하여 세션이 정지되고 결국 타임아웃 오류가 발생합니다.

해결책은 SSH가 정기적으로 keep-alive 신호(작은 비데이터 패킷)를 보내 중간 장치가 연결을 활성 상태로 인식하도록 구성하는 것입니다.

1. 클라이언트 측 솔루션: ServerAliveInterval

타임아웃을 방지하는 가장 일반적이고 쉬운 솔루션은 SSH 클라이언트가 서버에 주기적으로 keep-alive 메시지를 보내도록 구성하는 것입니다. 이는 ServerAliveInterval 지시문으로 제어됩니다.

ServerAliveInterval 작동 방식

ServerAliveInterval은 서버로부터 데이터를 수신하지 않은 경우 클라이언트가 서버에 널 패킷을 보낼 시간(초)을 지정합니다. 이 값은 클라이언트 측이 연결 상태를 유지하도록 보장합니다.

~/.ssh/config를 통한 구성

이 방법은 전역 또는 호스트별로 설정을 구성할 수 있어 재부팅 및 다른 터미널 세션에서도 유지되므로 권장됩니다.

클라이언트 구성 파일(일반적으로 ~/.ssh/config에 위치)을 생성하거나 수정합니다:

nano ~/.ssh/config

설정을 전역(모든 호스트)으로 적용하려면:

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

값 설명:

  • ServerAliveInterval 60: 연결이 유휴 상태일 때 클라이언트가 60초마다 keep-alive 패킷을 보냅니다.
  • ServerAliveCountMax 3: 클라이언트가 서버로부터 응답 없이 3개의 연속 keep-alive 메시지를 보내면 연결을 종료합니다. (총 타임아웃 시간: 60초 * 3회 = 180초).

명령줄을 통한 구성

임시 해결책이 필요하거나 단일 세션에만 설정을 적용하려면 연결 시 -o 옵션을 사용합니다:

ssh -o "ServerAliveInterval 60" user@remote_host

팁: 30~60초 값이 일반적으로 이상적입니다. 대부분의 방화벽 규칙(보통 5분 정도 설정)을 우회할 만큼 자주 발생하지만 과도한 네트워크 오버헤드를 생성하지 않을 만큼 충분히 드뭅니다.

2. 서버 측 솔루션: Keep-Alive 강제

클라이언트 측 솔루션(ServerAliveInterval)이 일반적으로 충분하지만, 많은 사용자가 액세스하는 서버를 관리하는 관리자는 중앙에서 keep-alive 설정을 강제하거나 유휴 연결에 대한 하드 제한을 설정하려 할 수 있습니다. 이는 SSH 데몬 구성 파일인 /etc/ssh/sshd_config에서 수행됩니다.

ClientAliveIntervalClientAliveCountMax 사용

이 지시문은 클라이언트 설정의 서버 측 대응입니다. 서버가 클라이언트가 여전히 연결되어 있는지 확인하도록 지시합니다.

  1. SSH 데몬 구성 파일을 엽니다:

    sudo nano /etc/ssh/sshd_config
    
  2. 다음 줄을 추가하거나 수정합니다:

    # 서버가 클라이언트 트래픽 없이 300초 후에 클라이언트-알림 메시지를 보냅니다.
    ClientAliveInterval 300
    
    # 응답하지 않은 클라이언트-알림 메시지 3개 후 연결을 해제합니다.
    ClientAliveCountMax 3
    

ClientAliveCountMax 참고:

ClientAliveInterval 메시지는 SSH 수준 프로브이며, 단순한 "이 유휴 시간 후 연결 해제" 설정이 아닙니다. ClientAliveInterval 300ClientAliveCountMax 3을 사용하면 서버는 응답 없는 프로브 후 약 15분 후에만 연결을 해제합니다. OpenSSH에서 ClientAliveCountMax 0은 이러한 서버 keepalive 메시지를 비활성화하므로 타임아웃 강제 적용의 좋은 예가 아닙니다.

  1. 변경 사항을 적용하려면 SSH 서비스를 다시 시작합니다:

    sudo systemctl reload sshd
    # 또는
    sudo service ssh reload
    

3. 고급 복원력 전략

SSH keep-alive는 짧은 비활성 기간을 처리하지만, 완전한 네트워크 중단(예: Wi-Fi 네트워크 변경 또는 일시적인 신호 손실)은 여전히 TCP 연결을 끊습니다. 진정한 복원력을 위해 세션 관리 도구를 사용하세요.

터미널 멀티플렉서 사용 (tmux 또는 screen)

터미널 멀티플렉서는 연결 끊김에 대한 최고의 방어책입니다. 클라이언트 연결이 끊어져도 원격 서버에서 지속되는 세션을 실행합니다. 세션에서 분리하고 나중에(동일하거나 다른 클라이언트에서) 다시 연결하여 중단한 지점에서 정확히 재개할 수 있습니다.

기본 tmux 워크플로:

  1. 서버에 연결합니다:
    ssh user@remote_host
    
  2. 서버에서 새 tmux 세션을 시작합니다:
    tmux new -s my_session
    
  3. tmux 세션 내에서 작업합니다.
  4. 연결이 끊어지거나 떠나야 하는 경우 세션을 분리합니다(Ctrl+B, D).
  5. SSH를 통해 서버에 다시 연결합니다.
  6. 기존 세션에 다시 연결합니다:
    tmux attach -t my_session
    

SSH Keep-Alive와 TCP Keep-Alive 구분

기본 운영 체제의 TCP Keep-Alive 메커니즘을 사용할 수 있으며, 이는 종종 sshd_configTCPKeepAlive yes 지시문을 통해 구성됩니다. 그러나 SSH 수준 keep-alive(ServerAliveInterval)가 일반적으로 선호됩니다:

  1. 이식성: SSH 지시문은 기본 OS 커널 튜닝에 관계없이 일관되게 작동합니다.
  2. 애플리케이션 계층: SSH keep-alive는 애플리케이션 계층 내에서 작동하여 SSH 데몬이 응답 상태를 유지하도록 보장합니다.
  3. 방화벽 인식: TCP keep-alive는 페이로드 활동만 확인하는 방화벽이나 NAT 장치에 의해 자동으로 차단될 수 있지만, SSH keep-alive는 이러한 계층을 성공적으로 통과하도록 특별히 설계되었습니다.

TCPKeepAlive yes를 사용하기로 선택한 경우 실제 간격 타이밍은 SSH 구성이 아닌 운영 체제(예: Linux의 net.ipv4.tcp_keepalive_time)에 의해 제어됩니다.

모범 사례 요약

문제 구성 지시문 위치 권장 값 목적
클라이언트 타임아웃 ServerAliveInterval ~/.ssh/config (클라이언트) 30 - 60초 방화벽 차단을 방지하기 위해 클라이언트에서 서버로 널 패킷을 보냅니다.
클라이언트 연결 해제 임계값 ServerAliveCountMax ~/.ssh/config (클라이언트) 3 - 5 클라이언트가 연결을 해제하기 전에 놓친 응답 수입니다.
서버 유휴 강제 ClientAliveInterval /etc/ssh/sshd_config (서버) 300초 (5분) 활동을 모니터링하기 위해 서버에서 클라이언트로 검사를 보냅니다.
연결 복원력 해당 없음 서버 세션 tmux 또는 screen 네트워크 장애에도 세션 지속성을 허용합니다.

클라이언트 구성에서 ServerAliveInterval로 시작하세요. 장기 실행 마이그레이션, 패키지 업그레이드 또는 로그 조사의 경우 tmux 또는 screen 내에서 작업을 실행하여 네트워크 경로가 끊어져도 작업이 중단되지 않도록 하세요.