🐧 Linux 総合学習プラットフォーム
セキュリティ/権限強化 ・ 中級

SSH鍵認証と堅牢化

SSH はリモートのサーバへ安全に接続する仕組みです。パスワード認証は総当たり攻撃に弱いため、公開鍵認証への切り替えが推奨されます。手元で ssh-keygen により秘密鍵と公開鍵のペアを作り、公開鍵だけを ssh-copy-id でサーバに登録します。秘密鍵は絶対に渡さず手元で厳重に保管します。さらに /etc/ssh/sshd_config で root ログインの禁止やパスワード認証の無効化を行うと、入口が一段と堅牢になります。

離れた場所にあるサーバへログインしてコマンドを打つ。ふだん何気なくやっているこの操作が、なぜ安全だと言えるのか。

それを支えているのが SSH(Secure Shell)だ。通信全体が暗号化されるため、途中の経路で盗み見られても中身が読まれない。

💡
ポイントSSH は通信全体を暗号化する。既定はポート22番で、接続先の sshd というサービスが応答する。

基本の使い方は `ssh user01@192.0.2.10` のように「ユーザ名@接続先」を指定する形だ。接続先で待ち受けている sshd というサービスが応答する。SSH は既定でポート(port)22番を使う。

だが、ここに残る弱点がある。認証方法だ。

つまずき公開サーバには、ありがちなユーザ名とパスワードを片端から試す総当たり(ブルートフォース)攻撃が絶え間なく届く。

初期状態ではパスワード認証が有効なことが多い。すると、インターネットに公開されたサーバには、ありがちなユーザ名とパスワードを片端から試す総当たり(ブルートフォース)攻撃が絶え間なく届く。

パスワードがどれだけ強くても「当てられる可能性がゼロではない」入口を開け続けることになる。

そこで推奨されるのが、公開鍵認証(public key authentication)への切り替えだ。

では、鍵で認証するとは具体的にどういうことなのか。

🔑 公開鍵認証のしくみ

公開鍵認証では、対になる2つの鍵を使う。

秘密鍵(private key)は手元のPCに厳重に保管し、決して外へ出さない。公開鍵(public key)は接続先のサーバに登録する。

手元のPC秘密鍵 private key外へ出さないid_ed25519接続先サーバ公開鍵 public key登録しておくauthorized_keys① 公開鍵だけ渡す② 秘密鍵を持つか暗号的に確認秘密鍵はネットワークを流れないので経路で盗まれない

認証のとき、サーバは「この公開鍵に対応する秘密鍵を本当に持っているか」を暗号的に確認する。持っていれば本人と認めてログインを許す。

💡
ポイント秘密鍵そのものはネットワークを流れない。だから経路上で盗まれる心配がなく、パスワード認証より格段に堅牢になる。

ここが効くポイントだ。秘密鍵そのものはネットワークを流れないため、経路上で盗まれる心配がない。

鍵は十分に長く、パスワードのように人が推測したり総当たりしたりすることが現実的に不可能だ。だからパスワード認証より格段に堅牢になる。

公開鍵は他人に知られても、それ単体ではログインできないので問題ない。守るべきはあくまで手元の秘密鍵だけ。この点が理解の要になる。

では、その鍵のペアはどうやって用意し、サーバに登録するのか。

🛠 鍵を作る ssh-keygen と登録する ssh-copy-id

鍵のペアは手元のPCで `ssh-keygen` を実行して作る。

ssh-keygen -t ed25519 ……今どきの推奨。互換性を優先するなら ssh-keygen -t rsa -b 4096 でもよい。

アルゴリズムを指定して `ssh-keygen -t ed25519` とするのが今どきの推奨だ。互換性を優先するなら `ssh-keygen -t rsa -b 4096` でも構わない。

実行すると保存場所と、パスフレーズを尋ねられる。保存場所の既定は ~/.ssh/ 以下で、秘密鍵 id_ed25519 と公開鍵 id_ed25519.pub の2つができる。

コツパスフレーズは秘密鍵自体にかける合言葉。万一鍵ファイルが盗まれても即座には悪用されない。設定するのが望ましい。

パスフレーズは秘密鍵自体にかける追加の合言葉だ。万一秘密鍵ファイルが盗まれても、これがあれば即座には悪用されない。空のまま進めることもできるが、安全のため設定するのが望ましい。

ssh-copy-id user01@192.0.2.10 ……公開鍵をサーバの ~/.ssh/authorized_keys に正しい権限で追記する。

作った公開鍵をサーバへ登録するには `ssh-copy-id user01@192.0.2.10` を使うのが簡単だ。

これは公開鍵を接続先の ~/.ssh/authorized_keys に正しい権限で追記してくれるコマンドだ。登録後は `ssh user01@192.0.2.10` でパスワードなしに(パスフレーズを設定していればその入力だけで)ログインできるようになる。

ところが、ここまで正しくやっても「鍵を登録したのにパスワードを聞かれる」という壁にぶつかることがある。原因は何か。

⚠ パーミッションのつまずきに注意

公開鍵認証でよくつまずくのが、~/.ssh ディレクトリや関連ファイルのパーミッションだ。

SSH は安全のため、これらの権限がゆるいと(他人に読み書きできる状態だと)鍵を無視してログインを拒否する。

chmod 700 ~/.ssh / chmod 600 ~/.ssh/authorized_keys ……~/.ssh は 700、authorized_keys と秘密鍵は 600 に。

手で設定する場合は、~/.ssh は 700、authorized_keys は 600、秘密鍵も 600 にする(`chmod 700 ~/.ssh`、`chmod 600 ~/.ssh/authorized_keys`)。

つまずき「鍵を登録したのにパスワードを聞かれる」ときは、まず権限とサーバ側のログ /var/log/secure を確認するのが定石だ。

「鍵を登録したのにパスワードを聞かれる」ときは、まずこの権限と、サーバ側のログ /var/log/secure を確認するのが定石だ。

秘密鍵は絶対に他人へ渡したりメールに添付したりしない。もし漏れた疑いがあれば、その公開鍵をサーバの authorized_keys から削除して鍵を作り直す。

鍵認証が無事に通るようになったら、次は入口そのものをさらに固めにいく。

🧱 sshd_config による堅牢化

鍵認証に移行したら、サーバ側の設定ファイル /etc/ssh/sshd_config でさらに入口を固める。

PermitRootLogin no / PasswordAuthentication no ……root 直接ログインの禁止と、パスワード認証そのものの無効化。

代表的なのは2つだ。root での直接ログインを禁止する `PermitRootLogin no` と、パスワード認証そのものを無効化する `PasswordAuthentication no`。

後者を有効にすると総当たり攻撃は鍵を持たない限り成立しなくなり、効果が非常に大きい。

つまずき設定変更の前に、必ず別の端末で鍵ログインが成功することを確かめる。鍵が使えない状態でパスワード認証を切ると自分も締め出される。

ただし設定変更の前に、必ず別の端末で鍵ログインが成功することを確かめてから行ってほしい。鍵が使えない状態でパスワード認証を切ると、自分も締め出されるからだ。

設定を書き換えたら `sshd -t` で文法を検査し、問題なければ `systemctl restart sshd` で反映する。

必要なら待ち受けポートを22番から変更する(`Port 10022` など)ことで自動攻撃のノイズを減らせる。

コツポートを変えたら、ファイアウォールで新ポートを開け、SELinux にも教える(semanage port -a -t ssh_port_t -p tcp 10022)。

その際は後述のファイアウォールで新しいポートを開け、SELinux にもポート変更を教える(`semanage port -a -t ssh_port_t -p tcp 10022`)必要がある点に注意する。

ここまでの堅牢化は、単独で効くというより、他の対策と束ねたときに本領を発揮する。

🛠 実務の使いどころ

実務では、SSH の堅牢化は他のセキュリティ対策と組み合わせて多層で効かせる。

公開鍵認証でパスワードという弱点をなくし、root ログイン禁止で最も狙われる入口を塞ぎ、ファイアウォールで接続元を絞り、fail2ban で執拗な攻撃元を自動遮断する。これらは互いを補い合う。

コツ~/.ssh/config にホストごとの接続情報を書けば、ssh web1 のような短い別名で接続でき設定ミスも減る。

複数のサーバを行き来するなら、手元の ~/.ssh/config にホストごとの接続情報(ホスト名・ユーザ名・鍵ファイル・ポート)を書いておくとよい。`ssh web1` のような短い別名で接続でき、設定ミスも減る。

鍵は用途やマシンごとに分ける。退職や端末入れ替えのときは古い公開鍵をサーバから外す。こうした鍵の棚卸しまで含めて、SSH の安全運用だ。

この項目に出てくる用語

公開鍵認証こうかいかぎにんしょう
秘密鍵と公開鍵のペアで本人確認を行う、パスワードより安全なSSH認証方式。
ポートポート
通信の宛先サービスを区別する番号。例: SSHは22、HTTPは80。

関連コマンド

ssh-keygenssh-copy-id

▶ 学習アプリでこの続きを学ぶ・演習する