導入
サーバーを1台立てて数時間放置するだけで、ログには Failed password for root from 203.0.113.9 のような行が大量に積み上がります。世界中から自動でパスワードを総当たりしてくる攻撃(ブルートフォース)が、常に飛んできているのです。パスワードだけに頼るログインは、実は最初から危険な賭けをしています。
説明
そこで現場の標準になっているのが 公開鍵認証 です。「1本の鍵」ではなく、対になった 秘密鍵 と 公開鍵 の2つを使います。
- 秘密鍵 … あなたの手元の PC だけに置く、絶対に人に見せないファイル
- 公開鍵 … サーバー側に登録しておく、見られても問題ないファイル
鍵は ssh-keygen というコマンドでペア生成し、公開鍵だけをサーバーの ~/.ssh/authorized_keys(「このユーザーとしてログインしてよい公開鍵の一覧」ファイル)に追加します。この登録作業を自動でやってくれるのが ssh-copy-id です。
ssh-keygen -t ed25519 # 手元のPCで鍵ペアを作る
ssh-copy-id user@203.0.113.10 # 公開鍵をサーバーへ登録する
ログイン時には、サーバーが「あなたの手元の秘密鍵」と「登録済みの公開鍵」が対になっているかを暗号的に確認します。秘密鍵は一度もネットワークを流れません——これがパスワードより安全な理由です。
flowchart LR
subgraph 手元["あなたの手元のPC"]
SK["秘密鍵<br/>(絶対に渡さない)"]
end
subgraph サーバー["サーバー"]
PK["公開鍵<br/>~/.ssh/authorized_keys"]
end
SK -->|"暗号的に照合<br/>(秘密鍵そのものは送らない)"| PK
PK -->|"対になっていれば<br/>ログイン許可"| 手元
例えるなら、公開鍵は「南京錠」、秘密鍵は「その鍵」です。南京錠(公開鍵)は誰に見られても複製されても問題ありませんが、鍵(秘密鍵)を持っている人だけが開けられます。サーバーには南京錠だけを配って回り、鍵は自分の手元から離さない——それが公開鍵認証の考え方です。
ログインが成功すると、サーバー側にその記録が残ります。前章の journalctl -u ssh.service で、実際にこんな行を確認できます。
journalctl -u ssh.service
Jul 25 09:12:03 becomecoder sshd[420]: Accepted publickey for user from 203.0.113.9 port 51234 ssh2
Accepted publickey for user ——「公開鍵で user のログインを受け入れた」という意味です。もしパスワード認証だったら Accepted password と記録されます。ログの中の一言から、どちらの方式でログインしたかまで読み取れるのです。
秘密鍵ファイルは、盗まれるとそのまま「あなたとしてログインできる合鍵」になります。パスフレーズを付けて暗号化しておく、他人と共有しない、不要になったサーバーの
authorized_keysからは公開鍵を削除する——鍵の管理そのものが、セキュリティの土台です。
この章のまとめ
- 公開鍵認証=秘密鍵(手元)と公開鍵(サーバー)のペアで安全にログインする仕組み
ssh-keygenで鍵ペアを作り、ssh-copy-idで公開鍵をサーバーへ登録する- 秘密鍵はネットワークを流れない。南京錠(公開鍵)と鍵(秘密鍵)の関係に近い
journalctl -u ssh.serviceのAccepted publickeyでログイン方式を確認できる