はじめに
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より厳格であること |
2.秘密鍵に不要な権限が付与されていないこと | 権限が600より厳格であること |
3.公開鍵に不要な権限が付与されていないこと | 権限が644より厳格であること |
4.アクセスできるユーザやグループが制限されていること | 次の設定項目いずれかが存在すること |
5.暗号方式に強固なものが使用されていること | CBCなどの古い暗号方式を避けていること |
6.鍵交換方式に強固なものが使用されていること | 推奨は以下のような設定が含まれていること |
7.MACアルゴリズムに強固なものが使用されていること | 推奨は以下のような設定が含まれていること |
8.タイムアウト設定がされていること | 以下のディレクティブが明示的に指定されていること |
9.SSH 経由のポートフォワーディングが無効にされていること | 以下のディレクティブが yes に指定されていること |
10.GSSAPI 認証が無効化されていること | 以下のディレクティブが no に指定されていること |
11.ホストベース認証が無効化されていること | 以下のディレクティブが no に指定されていること |
12.キーボードインタラクティブ認証が無効化されていること | 以下のディレクティブが no に設定されていること |
13. .rhosts および .shosts ファイルが使用されていないこと | 以下のディレクティブが yes に設定されていること |
14.ログイン承認までに時間を設けていること | 以下のディレクティブが短く設定されていること |
15.ログ出力のレベルが指定されていること | 以下のディレクティブが INFO もしくは VERBOSEであること |
16.接続トライの回数が少なく設定されていること | 以下のディレクティブが少なく設定されていること |
17.認証前の接続数に制限を設けていること | 以下のディレクティブが少なく設定されていること |
18.最大オープンセッション数に制限を設けていること | 以下のディレクティブが少なく設定されていること |
19.空パスワードが禁止されていること | 以下のディレクティブが no に設定されていること |
20.root による SSH 接続が禁止されていること | 以下のディレクティブが no に設定されていること |
21.環境変数の設定を無効化していること | 以下のディレクティブが no に設定されていること |
22.PAM が有効であること | 以下のディレクティブが yes に設定されていること |
23.公開鍵認証方式が有効になっていること | 以下のディレクティブが yes に設定されていること |
24.パスワード認証が無効になっていること | 以下のディレクティブが no に設定されていること |
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_config2.秘密鍵に不要な権限が付与されていないこと
次のように秘密鍵のファイルが以下のようになっていること。
# 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_*_key3.公開鍵に不要な権限が付与されていないこと
次のように公開鍵のファイルが以下のようになっていること。
# 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/*.pub4.アクセスできるユーザやグループが制限されていること
次の 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.com6.鍵交換方式に強固なものが使用されていること
以下のコマンドを実行し、使用されている鍵交換方式を確認すること。「diffie-hellman-group1-sha1」や「diffie-hellman-group14-sha1」などの古い方式が無いことを確認してください。
sshd -T | grep '^kexalgorithms'理由:
ダウングレード攻撃のリスクを減らすため。
対策:
KexAlgorithms ディレクティブを編集し、不要な鍵交換方式は除外してください。
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org7.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-2568.タイムアウト設定がされていること
以下のコマンドを実行し、明示的に設定されていることを確認してください。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 yes10.GSSAPI 認証が無効化されていること
以下のコマンドを実行し、設定値が no であることを確認してください。
# sshd -T | grep gssapiauthentication理由:
システムの攻撃リスクがある部分を減らすため。
対策:
GSSAPIAuthentication ディテクティブに明示的に「no」を指定してください。逆に Kerberos/Active Directory 認証を使っている環境で「no」にすると接続ができません。
GSSAPIAuthentication no11.ホストベース認証が無効化されていること
以下のコマンドを実行し、設定値が no であることを確認してください。
# sshd -T | grep hostbasedauthentication理由:
システムの攻撃リスクがある部分を減らすため。
対策:
HostbasedAuthentication ディテクティブに明示的に「no」を指定してください。逆にホストベース認証を使っている環境で「no」にすると接続ができません。
HostbasedAuthentication no12.キーボードインタラクティブ認証が無効化されていること
以下のコマンドを実行し、設定値が no であることを確認してください。
# sshd -T | grep '^kbdinteractiveauthentication'理由:
システムの攻撃リスクがある部分を減らすため。
対策:
KbdInteractiveAuthentication ディレクティブに明示的に「no」を設定してください。逆にキーボードインタラクティブ認証を使っている環境で「no」にすると接続ができません。
KbdInteractiveAuthentication no13. .rhosts および .shosts ファイルが使用されていないこと
以下のコマンドを実行し、設定値が yes であることを確認してください。
# sshd -T | grep '^ignorerhosts'理由:
システムの攻撃リスクがある部分を減らすため。
対策:
IgnoreRhosts ディレクティブを明示的に「yes」を指定してください。
IgnoreRhosts yes14.ログイン承認までに時間を設けていること
以下のコマンドを実行し、値が短いことを確認してください。0は非推奨です。
# sshd -T | grep logingracetime理由:
設定時間が長すぎる場合、DDoS による攻撃リスクが上がります。
対策:
LoginGraceTime ディレクティブの値を自身のポリシーに従い時間設定をしてください、以下の例では30秒以内に認証を通さないと接続情報が正しくてもセッションを確立しません。
LoginGraceTime 3015.ログ出力のレベルが指定されていること
以下のコマンドを実行し、値が INFO もしくは VERBOSE であることを確認してください。
# sshd -T | grep loglevel理由:
フォレンジック調査に必須な情報のため。
DEBUG はセキュリティ調査で情報が埋もれたりプライバシー侵害の影響も高いため非推奨です。
対策:
LogLevel ディレクティブに明示的に INFO もしくは VERBOSE どちらかを指定してください。
LogLevel VERBOSE
もしくは
LogLevel INFO16 .接続トライの回数が少なく設定されていること
以下のコマンドを実行し、値が少ない回数で設定されていることを確認してください。
# sshd -T | grep maxauthtries理由:
ブルートフォース攻撃によるリスクを軽減するため。
対策:
MaxAuthTries ディレクティブにポリシーに従って値を決めてください。例えば以下の場合、3回 SSH 接続の情報にミスがあると強制的にセッションを切断しログに記録します。
MaxAuthTries 317.認証前の接続数に制限を設けていること
以下のコマンドを実行し、値が少ない値で設定されていることを確認してください。
# sshd -T | grep '^maxstartups'理由:
DDoS 攻撃によるリソースの保護
対策:
MaxStartups ディレクティブに小さい値を設定してください。例えば以下のように設定した場合は認証前接続を2本までは許可し、それを超えたら30%の確率で拒否し始め、50本に達したら完全に拒否します。
MaxStartups 3:30:5018.最大オープンセッション数に制限を設けていること
以下のコマンドを実行し、値が少ない値で設定されていることを確認してください。
# sshd -T | grep -i maxsessions理由:
DDoS 攻撃によるリソース保護のため。
対策:
MaxSessions ディレクティブに小さい値を設定してください。例えば以下のように設定した場合オープンセッション数が10個(シェル・サブシステムなどを含む)に制限されます。
MaxSessions 1019.空パスワードが禁止されていること
以下のコマンドを実行し、値が no に設定されていることを確認してください。
sshd -T | grep permitemptypasswords理由:
不正アクセスのリスクを軽減するため。
対策:
PermitEmptyPasswords ディレクティブに明示的に「no」を設定してください。
PermitEmptyPasswords no20.root による SSH 接続が禁止されていること
以下のコマンドを実行し、値が no に設定されていることを確認してください。
# sshd -T | grep permitrootlogin理由:
root 権限は強力であり、不正アクセスされた場合システム全体の乗っ取りに繋がる恐れがあるため。
対策:
PermitRootLogin ディレクティブに明示的に「no」を設定してください。
PermitRootLogin no21.環境変数の設定を無効化していること
以下のコマンドを実行し、設定値が no であることを確認してください。
# sshd -T | grep permituserenvironment理由:
環境変数が有効になっている場合、セキュリティ制御を迂回される危険性があります。
対策:
PermitUserEnvironment ディレクティブに明示的に「no」を設定してください。
PermitUserEnvironment no22.PAM が有効であること
以下のコマンドを実行し、設定値が yes であることを確認してください。
# sshd -T | grep -i usepam理由:
PAM が提供するセキュリティ機能を受けるため。
対策:
UsePAM ディレクティブに明示的に「yes」を設定してください。
UsePAM yes23.公開鍵認証方式が有効になっていること
以下のコマンドを実行し、設定値が yes であることを確認してください。
# sshd -T | grep '^pubkeyauthentication'理由:
署名を利用し認証を許可します。パスワード使い回しによる漏洩リスクやユーザ管理の観点から推奨される認証方式です。
対策:
PubkeyAuthentication ディレクティブに明示的に「yes」を設定してください。
PubkeyAuthentication yes24.パスワード認証が無効になっていること
以下のコマンドを実行し、設定値が no であることを確認してください。
# sshd -T | grep '^passwordauthentication'理由:
システムの攻撃リスクがある部分を減らすため。
対策:
PasswordAuthentication ディレクティブを明示的に「no」を指定してください。事前に秘密鍵でログインができることを確認したうえで設定を行ってください。
PasswordAuthentication noオマケ
他のセキュリティ項目として
- ポートが22番以外であること
- バナー広告が設定されており、権限が600より厳格であること
- fail2ban が導入されていること
などもある。が、下記理由により取り扱わない、個別で調べて貰えると良いかと。
- ポートが22番以外であること
→22番ポートばかり狙ってる bot には有用だがポートをフルスキャンするような bot にはあまり意味を成さないのでベストとは言いにくいと判断。
- バナー広告が設定されており、権限が600より厳格であること
→ポリシー次第、あっても無くてもセキュリティ的には関係があまり無い。
- fail2ban が導入されていること
→SSH と関係ないツールになるので割愛。
以上。



