ssh config最強設定

# 更新履歴
- 2017/01/22 Includeについて追記
- 2017/10/28 KexAlgorithm から ecdh を削除, Macs の順序を再考
- 2017/12/07 MacsからRIPEMD系を削除
- 2019/06/13 VSCode Remoteが使えないのでLogLevelを削除
- 2020/05/27 使えるCipherなどをリストアップするコマンドの説明を追加, 各種項目の見直し
- 2020/05/29 rsa-sha2-512,rsa-sha2-256 をHostKeyAlgorithmsに追加、ついでに接続互換性のために強度のひくいhmac-sha1をMacsに追加
- 2020/09/28 ControlMasterのパスを%Cに変更
- 2020/12/09 過剰な頻度であったRekeyLimitを長く(60s->600s)した
- 2021/10/07 暗号化スイートの設定をコメントアウトし、新しいOpenSSHではデフォルト値を使うようにしたほか、設定の説明を追記
- 2022/04/29 ForwardAgent を追加
- 2022/08/17 YAMAHAルータの場合ControlMasterが使えないことを追記

----

# 前書き
- ssh/config のテンプレートとして使ってください。

- ホストキーの順序を変えると `@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @` が出る場合があります
- **SSH鍵は ed25519 (エドワーズ曲線)を推奨します**
    - [GitHubでEd25519鍵をつかう](http://jnst.hateblo.jp/entry/2014/12/15/200542)
    - [sshでed25519鍵を使うようにした](http://blog.n-z.jp/blog/2016-12-04-ssh-ed25519.html)
    - [SSH鍵の暗号化方式を強化してみた。](https://blog.ayurina.net/2016/07/15/ssh%E9%8D%B5%E3%81%AE%E6%9A%97%E5%8F%B7%E5%8C%96%E6%96%B9%E5%BC%8F%E3%82%92%E5%BC%B7%E5%8C%96%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F%E3%80%82/)
    - `ssh-keygen -t dsa` は古い。危険なので行わない　**これからは `ssh-keygen -t ed25519` の時代です。**
- **ssh configは重複があると最初の項目が優先されます**。このテンプレートは `Include` 文と併用してください。
    - Host *.example.com みたいなのは最初にかくこと
- **Includeは OpenSSH 7.3 から使える**っぽいです。以前のOpenSSHの場合、手動でファイルの内容を展開して単一のファイルで運用してください。

- ちょっとだけ古いディストリビューションを利用すると、デフォルトでは古い暗号化スイートを使わされる。
それを防ぐために暗号アルゴリズムの優先順位を明示的に記入。OpenSSHのデフォルト設定を参考に、その上で弱い暗号を削除している。
    - SHA1を使わない
        - RIPEMD160はオープンなので一応入れてある
    - RSAよりEC(楕円曲線)を優先
    - 暗号はパフォーマンスより強度を優先
        - ctrよりgcmを優先した
        - どうせAESならハードウェア支援が効く
    - 鍵付きハッシュでは安全と言われるetm (Encrypt-then-MAC; 暗号化の後にMAC)を優先する
- [AEAD](https://ja.wikipedia.org/wiki/%E8%AA%8D%E8%A8%BC%E4%BB%98%E3%81%8D%E6%9A%97%E5%8F%B7) の時代です。 GCM系の暗号を推奨します。

# ~/.ssh/ssh_config (いろいろHostを書くファイル)
普通の通りに書く。ただファイル名はssh_configとしておく。あとでIncludeされる。

```
Host ssh.example.com
    User ...
    HostName ssh.example.com
    ...
```

# ~/.ssh/config (デフォルト値用のファイル)

**先頭にHostを書いたConfigのインクルードを書く**。
これによって config → ssh_config の順に適用されるが、重複項目は最初だけ適用されるのでデフォルト値はこのファイルから取られる。

AESを優先したい場合は `Ciphers` の順序を変更すること。多くのCPUでは、AES-NIによるハードウェアアクセラレーションが利用でき、高速化できる場合がある。

```bash
Include ~/.ssh/ssh_config

# お好みで
# LogLevel DEBUG
# LogLevel VERBOSE

##### 接続系 #####
# 圧縮。gitなどのファイル転送にも適用される、テキストやプログラムファイル多ければON
# 圧縮しづらい画像・動画などのファイル転送は圧縮率が低いのでOFF(no)でも可
Compression yes

# ネットワークコネクティビティを15秒ごとにチェック
# 3回失敗で切断
ServerAliveInterval 15
ServerAliveCountMax 3

# フォワーディング失敗時にExitするかどうか
# VPN代わりのトンネルを張り続けたいときに便利
# ExitOnForwardFailure yes

# 接続試行回数
ConnectionAttempts 3

##### コントロールマスター接続で永続化するかどうか #####
# 何度も接続したり、複数コネクションを張る場合、既存接続が再利用され、
# SSHの開始が高速になります
# スリープの多用や、ノートPCなどネットワークの場所移動が多い場合は ControlPersist を10秒(10)〜数分(1m)単位の短めにしてください
# ControlMaster auto
# ControlPersist 10 # モバイル用
# ControlPersist 1h # スリープしない有線接続の据え置き機であれば、1h〜2hなど大きな値でも可能
# ControlPath ~/.ssh/%C

##### セキュリティ系！重要！！ #####
# 昔のOpenSSH(6以前)を利用している場合、コメントアウトをして、古い暗号化スイートを使わず最新の暗号を優先するように設定してください
# あなたのCPU、接続先のサーバーがAES-NIに対応していなければ、 chacha20-poly1305@openssh.com を優先してみてください
# Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

# 鍵交換アルゴリズム、楕円曲線がナウくておしゃれ。あとは強度の順
# KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256

# 鍵付きハッシュのアルゴリズム
# Macs umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-64-etm@openssh.com,umac-64@openssh.com,hmac-sha1

# ホスト鍵をモダンな順で検証
# HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,ssh-rsa-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa

# 鍵生成の頻度！あまり小さくするとパフォーマンスに影響。
# 第一引数は何バイトごとか、第二引数は鍵交換までの秒数
RekeyLimit default 600

# SSH agent をフォワードすると、手元のPCで ssh-add した鍵がリモート上で使えるようになる
# 例: 開発用サーバーに git 用の鍵を置かずとも、 git に push できるようになる
# ForwardAgent yes

# おまけ、ホストフィンガープリントを視覚的に表示
# VisualHostKey yes
```

- 6.6より前のOpenSSHを使っている場合 (`ssh -V`) CiphersとKexくらいは上記に変えたほうがいい。

- コントロールマスターの設定をすると、HTTP KeepAliveのように接続が永続化されるほか、複数のSSHを起動して接続してもコネクションは1本だけにできる（マルチプレクシング; 多重化）

- さくらのレンタルサーバーに繋がらないときは、Macsあたりを変更すること。(2020/05/29にMacsに hmac-sha1 を追加したので、繋がるはず)
- ヤマハルーターにつながらない時は `KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1` を `ssh-config` の個別のホスト設定に書く

## つながらない場合の`ssh-config`例

```
Host yamaha-router
  HostName 192.168.0.251
  User username
#  Ciphers aes128-ctr
  KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
  Macs hmac-sha1
Host sakura-rental-server
  HostName x.sakura.ne.jp
  User username
  Macs hmac-sha1
```

- YAMAHAルータはMultiplexした接続 (`ControlMaster auto`) を受け入れないため、全体で有効にしていた場合は個別に無効にすること

# 参考

- http://euske.github.io/openssh-jman/ssh_config.html
    - man ssh_config の日本語訳おすすめ。必読。
- http://labunix.hateblo.jp/entry/20160228/1456586770
- http://togakushi.bitbucket.org/build/html/openssh-6.8.html
    - OpenSSH 6.8～のデフォルト設定が分かる。
    - バージョンが上がると、デフォルトの設定では古いアルゴリズムを利用しないようにしていることに注目
- https://wiki.mozilla.org/Security/Guidelines/OpenSSH
    - mozillaの推奨設定
    - **おすすめ**
- 読んでないが↓よさそう
    - https://github.com/stribika/stribika.github.io/wiki/Secure-Secure-Shell
    - https://stribika.github.io/2015/01/04/secure-secure-shell.html
- https://qiita.com/aqmr-kino/items/8c3306ea8022b0d5cbe4
- https://qiita.com/kawaz/items/a0151d3aa2b6f9c4b3b8#controlpath-%E3%81%AF-c-%E3%81%A7%E3%82%AD%E3%83%9E%E3%83%AA

## OpenSSH で使える Ciphers/MACs/KexAlgorithms/PubkeyAcceptedKeyTypes の一覧
以下のように、コマンドを打つとあなたのPCで使える暗号化/MACの方式などをリストアップできます

Ciphers: `ssh -Q cipher`
MACs: `ssh -Q mac`
KexAlgorithms: `ssh -Q kex`
PubkeyAcceptedKeyTypes: `ssh -Q key`

```
$ ssh -Q cipher
3des-cbc
aes128-cbc
aes192-cbc
aes256-cbc
rijndael-cbc@lysator.liu.se
aes128-ctr
aes192-ctr
aes256-ctr
aes128-gcm@openssh.com
aes256-gcm@openssh.com
chacha20-poly1305@openssh.com

$ ssh -Q mac
hmac-sha1
hmac-sha1-96
hmac-sha2-256
hmac-sha2-512
hmac-md5
hmac-md5-96
umac-64@openssh.com
umac-128@openssh.com
hmac-sha1-etm@openssh.com
hmac-sha1-96-etm@openssh.com
hmac-sha2-256-etm@openssh.com
hmac-sha2-512-etm@openssh.com
hmac-md5-etm@openssh.com
hmac-md5-96-etm@openssh.com
umac-64-etm@openssh.com
umac-128-etm@openssh.com

$ ssh -Q kex
diffie-hellman-group1-sha1
diffie-hellman-group14-sha1
diffie-hellman-group14-sha256
diffie-hellman-group16-sha512
diffie-hellman-group18-sha512
diffie-hellman-group-exchange-sha1
diffie-hellman-group-exchange-sha256
ecdh-sha2-nistp256
ecdh-sha2-nistp384
ecdh-sha2-nistp521
curve25519-sha256
curve25519-sha256@libssh.org

$ ssh -Q key
ssh-ed25519
ssh-ed25519-cert-v01@openssh.com
ssh-rsa
ssh-dss
ecdsa-sha2-nistp256
ecdsa-sha2-nistp384
ecdsa-sha2-nistp521
ssh-rsa-cert-v01@openssh.com
ssh-dss-cert-v01@openssh.com
ecdsa-sha2-nistp256-cert-v01@openssh.com
ecdsa-sha2-nistp384-cert-v01@openssh.com
ecdsa-sha2-nistp521-cert-v01@openssh.com
```