🐕

SSH接続でのタイムアウト対策

2023/07/02に公開

はじめに

開発作業中に時々遭遇する問題があります。それは、一部のリモートタスク(例えば、大規模なソフトウェアのビルドやアップデートなど)が長時間かかる場合、SSH接続がタイムアウトになってしまうことです。

私自身も、RailsアプリをAWS上でデプロイする作業段階で、SSH接続がRubyのインストール中にタイムアウトになり、困りました😅

SSHを利用してリモートサーバーに接続するとき、長時間アイドル状態になると接続が切断されることがあります。これは一部のネットワーク機器やサーバーがアイドル状態の接続を閉じるためです。
この記事では、そのような接続切断を防ぐためのいくつかの対策を紹介します。

また、ITでのアイドル状態(アイドルタイム)とは以下のような意味になります。

コンピュータの処理で、次の作業指示やデータを待つための時間のことである

アイドルタイムアウトの解決方法

今回は3つのパターンでアイドルタイムアウトを解決していきます。

  1. クライアント側での設定
  2. サーバー側での設定
  3. ターミナルでの設定

※Ubuntuを使用してAWSのEC2インスタンスに接続している場合での説明になるため、参考にされる場合はコマンドが一部異なる場合があります。

1. クライアント側での設定

最初にSSHクライアントの設定を変更して、定期的に「keep-alive」メッセージを送信することで接続がアイドル状態にならないようにします。
そのためには、SSHサーバーの設定ファイル~/.ssh/configにあるServerAliveIntervalServerAliveCountMaxを編集する必要があります。

これらのオプションを使ってSSH接続がアイドル状態になってもタイムアウトせずに接続を保つことが可能です。

ServerAliveIntervalServerAliveCountMaxについて

  • ServerAliveInterval
    SSHクライアントがサーバーへの接続が生きているかどうか確認するために送信するnullパケットの間隔を秒単位で指定します。
    nullパケットは実際にはデータを伝送しないパケットで、接続が有効であることを示します。
    この値が設定されていると、設定された間隔が経過する度にクライアントはnullパケットを送信します。
  • ServerAliveCountMax
    このオプションはクライアントがnullパケットに対する応答を待つ回数を指定します。
    ServerAliveIntervalが10秒でServerAliveCountMaxが3だとすると、クライアントは30秒間サーバーからの応答を待ちます。
    その間に応答が得られなければ、SSHクライアントはサーバーへの接続が切れたと判断し、接続を終了します。

設定方法

  1. まず、SSH設定ファイル~/.ssh/configを開きます。もしファイルが存在しない場合は作成します。

    nano ~/.ssh/config
    
  2. 設定ファイルに次のように記述します。

    Host *
      ServerAliveInterval 60
    

    これにより、SSHクライアントは毎分サーバーに信号を送り、接続がタイムアウトするのを防ぎます。

  3. Ctrl + O を押して変更を保存し、Ctrl + X を押してエディターを閉じます。

  4. 次にSSH接続を行う際には、この設定が適用されます。

この設定はSSH接続のタイムアウトを防ぐだけでなく、ネットワークが不安定な環境での接続の安定性も向上させます。
ただし、この設定はクライアント側の設定なので、サーバー側の設定やネットワーク機器が接続を切断する場合には効果がありません。

2. サーバー側での設定

次にSSHサーバー側でアイドル接続を維持する設定を行います。そのためには、SSHサーバーの設定ファイル/etc/ssh/sshd_configにあるClientAliveIntervalおよびClientAliveCountMaxを編集する必要があります。

ClientAliveInterval および ClientAliveCountMax について

「ClientAliveInterval」および「ClientAliveCountMax」は、SSHサーバー側で設定することで接続のアイドルタイムアウトを制御するためのパラメータです。

  • ClientAliveInterval
    この値は、SSHサーバーがSSHクライアントに対して定期的にデータを送信する間隔を秒単位で設定します。クライアントからの応答がこの間隔内に返されない場合、サーバーは接続が切断されたと判断します。
  • ClientAliveCountMax
    この値は、SSHサーバーが接続を切断する前にクライアントからの応答を待つ最大回数を設定します。

設定方法

SSHのサーバー側の設定を変更するには、以下の手順で行います。

  1. ターミナルを開きます。

  2. SSHの設定ファイルを開きます。以下のコマンドを入力します:

    sudo vi /etc/ssh/sshd_config
    
  3. 設定ファイルが開いたら、以下の設定を追加します:

    ClientAliveInterval 60
    ClientAliveCountMax 3
    

    この設定は、SSHサーバーが60秒ごとにクライアントに対して生存確認の信号を送り、クライアントからの応答が3回連続で無い場合には接続を切る、というものです。

  4. 追加したら、Escを押し、:wqを入力してEnterを押すことで変更を保存し、エディターを閉じます。

  5. 設定を反映させるためにSSHのサービスを再起動します。以下のコマンドを入力します:

    sudo service ssh restart
    

    または

    sudo systemctl restart sshd
    

なお、設定項目が既に存在する場合は、その値を変更するだけでOKです。そして、各設定値は環境によって適切な値が異なるため、適宜調整してください。

この設定はSSHサーバーにアクセスして変更できる管理者権限が必要であることに注意してください。
また、これはサーバー側の設定なので、クライアント側のネットワークの不安定さによる切断を防ぐことはできません。

3. ターミナルでの設定

ターミナルでの設定では、ターミナルマルチプレクサーを利用します。
ターミナルマルチプレクサーは、複数のターミナルセッションを1つの物理ターミナル内で管理するツールです。これにより、接続が切断されてもセッションが継続され、再接続時に同じセッションに戻ることが可能になります。
今回はターミナルマルチプレクサーtmuxを用いて解決していきます。

  1. まず、tmuxをインストールします:

    sudo apt-get install tmux
    
  2. 新規tmuxセッションを作成します:

    tmux
    
  3. 新規セッション内で作業を開始します。ここでRubyのインストールなどを行います。

  4. 作業中に一時的にセッションから抜け出すには、Ctrl-bを押した後にdを押します。

  5. 再接続後、以下のコマンドでtmuxセッションに再接続します:

    tmux attach
    

この方法を用いると、SSH接続が切断されたとしてもサーバー上での作業は継続されます。再接続後にtmux attachコマンドでセッションに接続すれば、作業を中断したところから再開できます。

まとめ

これらの対策を組み合わせることで、SSH接続のアイドルタイムアウトによる切断を大幅に減らすことができます。これにより、Rubyのような大規模なソフトウェアのインストールやアップデートを安心して行うことができるようになります。

Discussion