SSHが超短時間で切断される

やたらめったらSSHが切断される。なんやねん。
測ったら10秒で切れやがる。

## 環境

```
$ sudo cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)

$ sudo sshd --version
unknown option -- -
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]
            [-E log_file] [-f config_file] [-g login_grace_time]
            [-h host_key_file] [-o option] [-p port] [-u len]
```

sshdに ``--version`` なんてオプションねーから！て怒られた。恥ずい。

## まっさきに疑う ``ClientAliveInterval``

参考：[SSHのタイムアウト防止策](https://qiita.com/u_nako/items/c545e7fc0dd5b8ec85fb)

基本の「き」ですね。
なお今回は間にルータ/NATを介さないのでルータ側ではないと思われる。

## サーバ側の設定確認

```
$ sudo grep ClientAlive /etc/ssh/sshd_config

#ClientAliveInterval 0
#ClientAliveCountMax 3
```

「0」って言ったら「無限」ってイメージあるんけど違うんかな。

```bash
$ man sshd_config

:(省略)

ClientAliveCountMax
        Sets the number of client alive messages which may be sent without sshd(8) receiving any messages
        back from the client.  If this threshold is reached while client alive messages are being sent,
        sshd will disconnect the client, terminating the session.  It is important to note that the use
        of client alive messages is very different from TCPKeepAlive.  The client alive messages are sent
        through the encrypted channel and therefore will not be spoofable.  The TCP keepalive option
        enabled by TCPKeepAlive is spoofable.  The client alive mechanism is valuable when the client or
        server depend on knowing when a connection has become inactive.

        The default value is 3.  If ClientAliveInterval is set to 15, and ClientAliveCountMax is left at
        the default, unresponsive SSH clients will be disconnected after approximately 45 seconds.

ClientAliveInterval
        Sets a timeout interval in seconds after which if no data has been received from the client,
        sshd(8) will send a message through the encrypted channel to request a response from the client.
        The default is 0, indicating that these messages will not be sent to the client.

:(省略)
```

OK, Google。翻訳して！

>ClientAliveCountMax
>>sshdがクライアントからメッセージを受信せずに送信できるクライアントアライブメッセージの数を設定します。
>クライアントアライブメッセージの送信中にこのしきい値に達すると、sshdはクライアントを切断し、セッションを終了します。
>クライアントアライブメッセージの使用は、TCPKeepAliveとは非常に異なることに注意することが重要です。
>クライアントアライブメッセージは暗号化されたチャネルを介して送信されるため、なりすましはできません。
>TCPKeepAliveによって有効にされるTCPキープアライブオプションは、なりすまし可能です。
>クライアントまたはサーバーが接続がいつ非アクティブになったかを知ることに依存している場合、クライアントアライブメカニズムは貴重です。
>デフォルト値は3です。ClientAliveIntervalが15に設定され、ClientAliveCountMaxがデフォルトのままになっている場合、応答しないSSHクライアントは約45秒後に切断されます。

>ClientAliveInterval
>>クライアントからデータを受信しなかった場合、sshdが暗号化されたチャネルを介してメッセージを送信し、クライアントからの応答を要求するまでのタイムアウト間隔を秒単位で設定します。
>デフォルトは0で、これらのメッセージがクライアントに送信されないことを示します。

送信しない、送信しないのか。

## 試してみる

現状、何秒で切断されるのか確認してみる。
WindowsPC側でWireSharkでキャプチャしてみる。

![ScreenShot_2019年12月06日 14時06分31秒.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/7ad3f261-931b-3e46-acbe-164be4eb1046.png)

```
[Time since previous frame in this TCP stream: 10.056218000 seconds]
```

10秒で切れたらしい。
じゃあ ``ClientAliveInterval`` を ``15`` にしてみよう。

```
$ sudo vim /etc/ssh/sshd_config
$ sudo grep ClientAlive /etc/ssh/sshd_config
ClientAliveInterval 15
#ClientAliveCountMax 3
$ sudo systemctl restart sshd.service
```

そのままWindowsPC側でWireSharkでキャプチャ。
あ、切れたぞ。

```
[Time since previous frame in this TCP stream: 10.045026000 seconds]
```

いやいや、<b>記録更新してますやん</b>。

あれかな。変更後に接続したSSHじゃないと意味ないのかな。
もう1度SSH接続して放置。

![ScreenShot_2019年12月06日 14時12分38秒.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/5b1a66e3-fb98-f96b-b2a2-65a419f76b46.png)

お、おお！切れないぞ！
サーバ側(``192.168.10.120``)からクライアント側(``192.168.200.98``)に
5秒毎に``[TCP Keep-Alive ACK]``が…

・・・<b>なんで5秒毎なんだ？</b>

![ScreenShot_2019年12月06日 14時15分05秒.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/ffea5bd4-3db5-533c-c63a-73846a0cda54.png)


とか言ってたらSSH切れた。

```
[Time since previous frame in this TCP stream: 10.048855000 seconds]
```

おしぃ～！<b>記録更新ならず！！</b>
なんでや。。

```
$ while :
> do
> echo "a"
> sleep 8
> done
```

試しに上記のとおり8秒ごとに「a」を標準出力してみたところセッションが切れることはなかった。

もうちょっと値を変えてみよう。

```
$ sudo vim /etc/ssh/sshd_config
$ sudo grep ClientAlive /etc/ssh/sshd_config
ClientAliveInterval 60
#ClientAliveCountMax 3
$ sudo systemctl restart sshd.service
```

今度は一度ログアウトして再ログイン。…あかんわ。切れた。

```
[Time since previous frame in this TCP stream: 10.049564000 seconds]
```

これはクライアント側が問題なのか？

![ScreenShot_2019年12月06日 14時50分37秒.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259373/71db7f2d-500b-cfc7-fe9f-d4327a03ae5d.png)

Teraterのココらへんはデフォルトのままなのだが。
試しに「ハートビート」を「8」にしてみる。

うーん、相変わらず5秒毎に ``Keep-Alive`` が飛んでくるな。
でも切断されなくなったぞ。これでいいのかな。取り敢えず様子見。

## 2019-12-09 追記

Teratermでログインしたまま3日間放置したけど接続は切れていなかった。
これで大丈夫そうだ。