今さら書く SSH 設定ベストプラクティス

SSH 設定のベストプラクティスを今更書く

はじめに


SSH の設定について言及する記事はそこら中にあるが、説明が不足していたり設定がまとまっていなかったり、そもそも何故設定する必要があるかの言及が無いなど…微妙なところがあるので本記事では設定理由を含めた SSH の設定ベストプラクティスをまとめる。

なお、セキュリティに完璧は存在しないので本記事は参考程度に読むこと。

サーバによっては管理方法や接続の認証方式が異なる場合があるため、本記事で紹介するコマンドは一例として出します、特に認証方式は色々ありますが余程の理由が無い限りは「公開鍵認証方式」を使用することを推奨します。

なのでコマンドの完コピなどはせず、必ず自分の環境ポリシーに沿ったコマンドを検証・実行すること。ディストリビューションによっては対策方法の手順が少し違うなど、一手間加える必要があるものもあります。

SSH とは


ネットワークを介して Linux 等のリモートのコンピュータを操作するための通信プロトコル。サーバを遠隔操作するためのやり取りだと思えば良い。

なお、似たようなプロトコルに Telnet などがあるがこちらは SSH とは違いデータを平文でやり取りするためよっぽどの理由が無い限りこちらは使用しないほうが良い。

設定をミスると最悪サーバに接続できなくなってしまう恐れがあるため、コンソール接続ができる環境で作業したりサーバのスナップショットなどを事前に取っておいて元に戻せるようにしておくと良い。

Linux では /etc/ssh/sshd_config 、もしくは /etc/ssh/sshd_config.d ディレクトリ配下に設定ファイルが格納されている。 (sshd_config.d 配下に設定ファイルがあるかどうかはディストリビューションによるらしい)

基本操作コマンド


vim や nano コマンドで設定ファイルを編集した後、次のコマンドを実行すると良い。「-t」オプションは設定ファイルにミスが無いかをチェックする。

# sshd -t

何も出力されていなければ正常、何か出力される場合はエラーの可能性が高いので該当項目を修正して再度「sshd -t」を実行し出力が無いことを再確認する。

問題が無ければ設定ファイルを反映させるため、次のコマンドを実行する。

# systemctl reload sshd
もしくは
# systemctl restart sshd

実行すると即座に設定ファイルの内容が反映される。既存のセッションはタイムアウトされない限りは残るので別のターミナル画面を開いて問題ないかチェックを行い、問題があれば既存セッションからファイル内容を元に戻すと良い。

必要最低限の設定項目


結論を先に出しておくと下記の内容を設定しておくと良い、理由は後述する。

項目

推奨値

1.設定ファイルに不要な権限が付与されていないこと

権限が600より厳格であること
所有者・グループが root ユーザであること

2.秘密鍵に不要な権限が付与されていないこと

権限が600より厳格であること
グループが root もしくは ssh_keys であること

3.公開鍵に不要な権限が付与されていないこと

権限が644より厳格であること
所有者・グループが root ユーザであること

4.アクセスできるユーザやグループが制限されていること

次の設定項目いずれかが存在すること
・AllowUsers
・AllowGroups
・DenyUsers
・DenyGroups

5.暗号方式に強固なものが使用されていること

CBCなどの古い暗号方式を避けていること

6.鍵交換方式に強固なものが使用されていること

推奨は以下のような設定が含まれていること
・ecdh-sha2-nistp256
・ecdh-sha2-nistp384
・ecdh-sha2-nistp521
・diffie-hellman-group-exchange-sha256
・diffie-hellman-group16-sha512
・diffie-hellman-group18-sha512
・diffie-hellman-group14-sha256

7.MACアルゴリズムに強固なものが使用されていること

推奨は以下のような設定が含まれていること
・hmac-sha2-256-etm@openssh.com
・hmac-sha2-512-etm@openssh.com
・hmac-sha2-256
・hmac-sha2-512

8.タイムアウト設定がされていること

以下のディレクティブが明示的に指定されていること
・ClientAliveInterval
・ClientAliveCountMax

9.SSH 経由のポートフォワーディングが無効にされていること

以下のディレクティブが yes に指定されていること
・DisableForwarding

10.GSSAPI 認証が無効化されていること

以下のディレクティブが no に指定されていること
・GSSAPIAuthentication

11.ホストベース認証が無効化されていること

以下のディレクティブが no に指定されていること
・HostbasedAuthentication

12.キーボードインタラクティブ認証が無効化されていること

以下のディレクティブが no に設定されていること
・KbdInteractiveAuthentication

13. .rhosts および .shosts ファイルが使用されていないこと

以下のディレクティブが yes に設定されていること
・IgnoreRhosts

14.ログイン承認までに時間を設けていること

以下のディレクティブが短く設定されていること
・LoginGraceTime

15.ログ出力のレベルが指定されていること

以下のディレクティブが INFO もしくは VERBOSEであること
・LogLevel

16.接続トライの回数が少なく設定されていること

以下のディレクティブが少なく設定されていること
・MaxAuthTries

17.認証前の接続数に制限を設けていること

以下のディレクティブが少なく設定されていること
・MaxStartups

18.最大オープンセッション数に制限を設けていること

以下のディレクティブが少なく設定されていること
・MaxSessions

19.空パスワードが禁止されていること

以下のディレクティブが no に設定されていること
・PermitEmptyPasswords

20.root による SSH 接続が禁止されていること

以下のディレクティブが no に設定されていること
・PermitRootLogin

21.環境変数の設定を無効化していること

以下のディレクティブが no に設定されていること
・PermitUserEnvironment

22.PAM が有効であること

以下のディレクティブが yes に設定されていること
・UsePAM

23.公開鍵認証方式が有効になっていること

以下のディレクティブが yes に設定されていること
・PubkeyAuthentication

24.パスワード認証が無効になっていること

以下のディレクティブが no に設定されていること
・PasswordAuthentication

1.設定ファイルに不要な付与されていないか


SSH の設定ファイルが次のような出力になっていること。(/etc/ssh/sshd_config.d配下を含む)

$ ls -la /etc/ssh/sshd_config
-rw------- 1 root root 4307 Mar 18  2026 /etc/ssh/sshd_config

理由:

不要な権限が付与されている場合、設定を他ユーザに上書きされる恐れがあるため。

対策:

次のように、権限モードを600(-rw-------)にし、root ユーザがファイルの編集権限を持つように設定すること。

# chmod u-x,og-rwx /etc/ssh/sshd_config
# chown root:root /etc/ssh/sshd_config

2.秘密鍵に不要な権限が付与されていないこと


次のように秘密鍵のファイルが以下のようになっていること。

# ls -la /etc/ssh/ssh_host_*_key

-rw------- 1 root root 2590 Sep 10 10:18 /etc/ssh/ssh_host_rsa_key
-rw------- 1 root root 505 Sep 10 10:18 /etc/ssh/ssh_host_ecdsa_key
-rw------- 1 root root 399 Sep 10 10:18 /etc/ssh/ssh_host_ed25519_key

理由:

SSH の秘密鍵ファイルを不正入手された場合、そのホストに成りすます可能性があるため。

対策:

次のように、権限を600より厳格にし root ユーザ(もしくは ssh_keys)のみがファイルの編集権限を持つこと。

# chown root:root /etc/ssh/ssh_host_*_key
# chmod 600 /etc/ssh/ssh_host_*_key

3.公開鍵に不要な権限が付与されていないこと


次のように公開鍵のファイルが以下のようになっていること。

# ls -la /etc/ssh/*.pub
-rw-r--r-- 1 root root 171 Sep 10 10:18 /etc/ssh/ssh_host_ecdsa_key.pub
-rw-r--r-- 1 root root  91 Sep 10 10:18 /etc/ssh/ssh_host_ed25519_key.pub
-rw-r--r-- 1 root root 563 Sep 10 10:18 /etc/ssh/ssh_host_rsa_key.pub

理由:

不正なユーザによる改ざんを防止するため

対策:

次のように権限を644より厳格にし root ユーザのみがファイルの編集権限を持つこと。

# chown root:root /etc/ssh/*.pub
# chmod 644 /etc/ssh/*.pub

4.アクセスできるユーザやグループが制限されていること


次の grep 結果が返ってくること、返って来ない場合設定がされていません。

# grep -Ei '^(AllowUsers|AllowGroups|DenyUsers|DenyGroups)' /etc/ssh/sshd_config

理由:

意図していないユーザがログイン・侵害する恐れがあります。

対策:

設定ファイルに AllowUsers・AllowGroups・DenyUsers・DenyGroups いずれかを記載してください。例えば以下の設定の場合ログインできるユーザが「test」であることかつ IP アドレスが「10.0.2.2」のみの通信を許可します。

なお、AllowUsers のみ記載した場合、指定されたユーザ以外は自動的に DenyUsers となるため注意。

# cat /etc/ssh/sshd_config | grep AllowUsers
AllowUsers test@10.0.2.2

詳細な設定手順についてはマニュアルや他の記事を参考にし、検証してください。

5.暗号方式に強固なものが使用されていること


以下のコマンドを実行し、使用が許可されている暗号方式を確認すること。「CBC」といった古い暗号方式の表示が無く、AES といった表記があることを確認してください。

# sshd -T | grep '^ciphers'

理由:

ダウングレード攻撃のリスクを減らすため。

対策:

Ciphers ディレクティブを編集し、不要な暗号方式は除外してください。

Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com

6.鍵交換方式に強固なものが使用されていること


以下のコマンドを実行し、使用されている鍵交換方式を確認すること。「diffie-hellman-group1-sha1」や「diffie-hellman-group14-sha1」などの古い方式が無いことを確認してください。

sshd -T | grep '^kexalgorithms'

理由:

ダウングレード攻撃のリスクを減らすため。

対策:

KexAlgorithms ディレクティブを編集し、不要な鍵交換方式は除外してください。

KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org

7.MACアルゴリズムに強固なものが使用されていること


以下のコマンドを実行し、使用されている MAC アルゴリズムを確認すること。「MD5」や「SHA1」、「96ビット」といった古い・短い方式が無いことを確認してください。

sshd -T | grep '^macs'

理由:

ダウングレード攻撃のリスクを減らすため。

対策:

MACs ディレクティブを編集し、不要なアルゴリズムは除外してください。

macs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256

8.タイムアウト設定がされていること


以下のコマンドを実行し、明示的に設定されていることを確認してください。clientaliveinterval が「0」は非推奨です。

# sshd -T | grep -E '^(clientaliveinterval|clientalivecountmax)'
clientaliveinterval 20
clientalivecountmax 3

理由:

接続を無期限で開けたままにした場合、DDoS 攻撃などによるリソース枯渇を引き起こす恐れがあります。

対策:

clientaliveinterval 及び clientalivecountmax ディレクティブに明示的に数値を指定してください。例えば以下の設定の場合は20秒間隔でセッションが生きているかを確認し、3回チェックに失敗すると強制的にセッションを切断します。

clientaliveinterval 20
clientalivecountmax 3

設定する値は自身の運用ポリシーで決めること。短すぎる場合、ネットワークの遅延などによりセッションが強制的に切断される恐れがあるため調整する必要があります。

9.SSH 経由のポートフォワーディングが無効にされていること


以下のコマンドを実行し、設定値が yes であることを確認してください。

# sshd -T | grep -i disableforwarding

理由:

バックドアとして使用されるリスクを塞ぐため。

対策:
X11 Forwarding や TCP ポートフォワーディングを使用していない場合は disableforwarding ディレクティブで明示的に無効化する「yes」を指定してください。使用している環境で有効にすると接続ができなくなるので注意してください。

disableforwarding yes

10.GSSAPI 認証が無効化されていること


以下のコマンドを実行し、設定値が no であることを確認してください。

# sshd -T | grep gssapiauthentication

理由:

システムの攻撃リスクがある部分を減らすため。

対策:

GSSAPIAuthentication ディテクティブに明示的に「no」を指定してください。逆に Kerberos/Active Directory 認証を使っている環境で「no」にすると接続ができません。

GSSAPIAuthentication no

11.ホストベース認証が無効化されていること


以下のコマンドを実行し、設定値が no であることを確認してください。

# sshd -T | grep hostbasedauthentication

理由:

システムの攻撃リスクがある部分を減らすため。

対策:
HostbasedAuthentication ディテクティブに明示的に「no」を指定してください。逆にホストベース認証を使っている環境で「no」にすると接続ができません。

HostbasedAuthentication no

12.キーボードインタラクティブ認証が無効化されていること


以下のコマンドを実行し、設定値が no であることを確認してください。

# sshd -T | grep '^kbdinteractiveauthentication'

理由:

システムの攻撃リスクがある部分を減らすため。

対策:

KbdInteractiveAuthentication ディレクティブに明示的に「no」を設定してください。逆にキーボードインタラクティブ認証を使っている環境で「no」にすると接続ができません。

KbdInteractiveAuthentication no

13. .rhosts および .shosts ファイルが使用されていないこと


以下のコマンドを実行し、設定値が yes であることを確認してください。

# sshd -T | grep '^ignorerhosts'

理由:

システムの攻撃リスクがある部分を減らすため。

対策:

IgnoreRhosts ディレクティブを明示的に「yes」を指定してください。

IgnoreRhosts yes

14.ログイン承認までに時間を設けていること


以下のコマンドを実行し、値が短いことを確認してください。0は非推奨です。

# sshd -T | grep logingracetime

理由:

設定時間が長すぎる場合、DDoS による攻撃リスクが上がります。

対策:

LoginGraceTime ディレクティブの値を自身のポリシーに従い時間設定をしてください、以下の例では30秒以内に認証を通さないと接続情報が正しくてもセッションを確立しません。

LoginGraceTime 30

15.ログ出力のレベルが指定されていること


以下のコマンドを実行し、値が INFO もしくは VERBOSE であることを確認してください。

# sshd -T | grep loglevel

理由:

フォレンジック調査に必須な情報のため。

DEBUG はセキュリティ調査で情報が埋もれたりプライバシー侵害の影響も高いため非推奨です。

対策:

LogLevel ディレクティブに明示的に INFO もしくは VERBOSE どちらかを指定してください。

LogLevel VERBOSE 
もしくは
LogLevel INFO

16 .接続トライの回数が少なく設定されていること


以下のコマンドを実行し、値が少ない回数で設定されていることを確認してください。

# sshd -T | grep maxauthtries

理由:

ブルートフォース攻撃によるリスクを軽減するため。

対策:

MaxAuthTries ディレクティブにポリシーに従って値を決めてください。例えば以下の場合、3回 SSH 接続の情報にミスがあると強制的にセッションを切断しログに記録します。

MaxAuthTries 3

17.認証前の接続数に制限を設けていること


以下のコマンドを実行し、値が少ない値で設定されていることを確認してください。

# sshd -T | grep '^maxstartups'

理由:

DDoS 攻撃によるリソースの保護

対策:

MaxStartups ディレクティブに小さい値を設定してください。例えば以下のように設定した場合は認証前接続を2本までは許可し、それを超えたら30%の確率で拒否し始め、50本に達したら完全に拒否します。

MaxStartups 3:30:50

18.最大オープンセッション数に制限を設けていること


以下のコマンドを実行し、値が少ない値で設定されていることを確認してください。

# sshd -T | grep -i maxsessions

理由:

DDoS 攻撃によるリソース保護のため。

対策:

MaxSessions ディレクティブに小さい値を設定してください。例えば以下のように設定した場合オープンセッション数が10個(シェル・サブシステムなどを含む)に制限されます。

MaxSessions 10

19.空パスワードが禁止されていること


以下のコマンドを実行し、値が no に設定されていることを確認してください。

sshd -T | grep permitemptypasswords

理由:

不正アクセスのリスクを軽減するため。

対策:

PermitEmptyPasswords ディレクティブに明示的に「no」を設定してください。

PermitEmptyPasswords no

20.root による SSH 接続が禁止されていること


以下のコマンドを実行し、値が no に設定されていることを確認してください。

# sshd -T | grep permitrootlogin

理由:

root 権限は強力であり、不正アクセスされた場合システム全体の乗っ取りに繋がる恐れがあるため。

対策:

PermitRootLogin ディレクティブに明示的に「no」を設定してください。

PermitRootLogin no

21.環境変数の設定を無効化していること


以下のコマンドを実行し、設定値が no であることを確認してください。

# sshd -T | grep permituserenvironment

理由:

環境変数が有効になっている場合、セキュリティ制御を迂回される危険性があります。

対策:

PermitUserEnvironment ディレクティブに明示的に「no」を設定してください。

PermitUserEnvironment no

22.PAM が有効であること


以下のコマンドを実行し、設定値が yes であることを確認してください。

# sshd -T | grep -i usepam

理由:

PAM が提供するセキュリティ機能を受けるため。

対策:

UsePAM ディレクティブに明示的に「yes」を設定してください。

UsePAM yes

23.公開鍵認証方式が有効になっていること


以下のコマンドを実行し、設定値が yes であることを確認してください。

# sshd -T | grep '^pubkeyauthentication'

理由:

署名を利用し認証を許可します。パスワード使い回しによる漏洩リスクやユーザ管理の観点から推奨される認証方式です。

対策:

PubkeyAuthentication ディレクティブに明示的に「yes」を設定してください。

PubkeyAuthentication yes

24.パスワード認証が無効になっていること


以下のコマンドを実行し、設定値が no であることを確認してください。

# sshd -T | grep '^passwordauthentication'

理由:

システムの攻撃リスクがある部分を減らすため。

対策:

PasswordAuthentication ディレクティブを明示的に「no」を指定してください。事前に秘密鍵でログインができることを確認したうえで設定を行ってください。

PasswordAuthentication no

オマケ


他のセキュリティ項目として

  • ポートが22番以外であること
  • バナー広告が設定されており、権限が600より厳格であること
  • fail2ban が導入されていること

などもある。が、下記理由により取り扱わない、個別で調べて貰えると良いかと。

  • ポートが22番以外であること

→22番ポートばかり狙ってる bot には有用だがポートをフルスキャンするような bot にはあまり意味を成さないのでベストとは言いにくいと判断。

  • バナー広告が設定されており、権限が600より厳格であること

→ポリシー次第、あっても無くてもセキュリティ的には関係があまり無い。

  • fail2ban が導入されていること

→SSH と関係ないツールになるので割愛。

以上。