SSH とは #
SSH (Secure Shell) は、ネットワーク越しに別のコンピュータへ安全にアクセスし、リモート操作・ファイル転送を行うためのプロトコルである。通信を暗号化することで、Telnet や rlogin などの平文プロトコルが抱えていた 盗聴・改ざん・なりすまし を一掃した。デフォルトで TCP の 22 番ポート を使い、RFC 4253 で標準化されている。
サーバ運用・GitHub への push・CI/CD のデプロイなど、現代の開発に欠かせないインフラの 1 つ。OpenSSH (OpenBSD 由来の OSS 実装) がほぼあらゆる Linux / macOS / Windows 10 以降に同梱され、事実上の標準となっている。

接続の 3 ステップ #
SSH 接続は次の順に進む。これだけ掴めば仕組みは理解しやすい。
- ホスト認証 — クライアントが「相手は本物のサーバか?」を検証
- ユーザ認証 — サーバが「相手は本物のユーザか?」を検証
- 暗号化通信 — 双方で生成した共通鍵で全データを暗号化
1. ホスト認証 #
サーバは自分の ホスト鍵 で署名を返し、クライアントはそのフィンガープリントを ~/.ssh/known_hosts に保存する。2 回目以降は保存済みの鍵と一致しなければ警告を出す ─ つまり中間者攻撃を検出できる。これを TOFU (Trust On First Use) モデルと呼ぶ。
The authenticity of host 'example.com' can't be established.
ED25519 key fingerprint is SHA256:abcd1234...
Are you sure you want to continue connecting (yes/no/[fingerprint])?
初回だけは中間者の可能性が残るので、厳密な運用ではサーバ管理者がフィンガープリントを別経路 (社内 Wiki など) で公開しておく。
2. ユーザ認証 #
主要な方式は 2 つ。
| 方式 | 仕組み | 推奨度 |
|---|---|---|
| パスワード認証 | ユーザ名 + パスワードを暗号化チャネル上で送信 | △ ブルートフォースの的 |
| 公開鍵認証 | クライアントが秘密鍵で署名、サーバが公開鍵で検証 | ◎ 本番運用の定石 |
本番では パスワード認証を無効化 し、公開鍵認証だけを許可するのが標準的な構えだ。
3. 暗号化通信 #
ユーザ認証が通った後は、Diffie-Hellman 鍵交換で双方が独立に生成した 共通鍵 を使い、ChaCha20-Poly1305 や AES-GCM といった対称暗号で全データが暗号化される。盗聴者には鍵を導出できないので、ペイロードは復号不可能 (前方秘匿性)。
公開鍵認証の仕組み #
公開鍵認証では、対 (ペア) の鍵をクライアント側で作る。
- 秘密鍵 — 自分の手元から 絶対に出さない
- 公開鍵 — サーバへ事前にコピーしておく

鍵ペアの作成 #
ssh-keygen -t ed25519 -C "your@email"
~/.ssh/id_ed25519 (秘密鍵) と ~/.ssh/id_ed25519.pub (公開鍵) が生成される。Ed25519 は鍵長が短く強度が高く、生成・検証も速い。互換性で困らない限り、今ならまずこれを選んでよい。
秘密鍵自体には パスフレーズ を付けて暗号化しておくこと。盗まれてもパスフレーズが破られない限り使えない。ssh-agent を併用すれば、ログインセッション中は再入力不要。
公開鍵をサーバに登録 #
ssh-copy-id user@example.com
サーバ側の ~/.ssh/authorized_keys に追記される (パーミッション 600 も自動でセットされる)。
認証フロー (チャレンジ・レスポンス) #
- クライアントが「この公開鍵で入りたい」と申告
- サーバが乱数 (チャレンジ) を送る
- クライアントが 秘密鍵で署名 して返す
- サーバが 公開鍵で署名を検証 ─ 一致すれば認証成功
秘密鍵そのものはネットワークを流れない。リプレイ攻撃にも耐性がある、というのがこのフローの核心。
基本コマンド #
# 接続
ssh user@example.com
ssh -p 2222 user@example.com # ポート指定
ssh -i ~/.ssh/special_key user@host # 鍵ファイル指定
ssh user@host 'uptime' # 単発コマンド実行
ssh -vvv user@host # 詳細ログ (トラブル時)
# 鍵管理
ssh-keygen -t ed25519 # 新規鍵
ssh-keygen -p -f ~/.ssh/id_ed25519 # パスフレーズ変更
ssh-keygen -l -f ~/.ssh/id_ed25519.pub # フィンガープリント表示
ssh-keygen -R example.com # known_hosts から削除 (鍵更新時)
ファイル転送 #
SSH の暗号化チャネル上で動くファイル転送が 3 つ。用途で使い分ける。
# scp — 単発コピー
scp local.txt user@host:/path/
scp -r local-dir/ user@host:/path/
# sftp — 対話的なファイル操作
sftp user@host
sftp> get remote.txt
sftp> put local.txt
# rsync over SSH — 差分転送 (大量ファイルやバックアップに最適)
rsync -avz -e ssh src/ user@host:/dst/
ポートフォワーディング (トンネリング) #
SSH 接続の暗号化チャネルに 別のアプリの通信を相乗りさせる 機能。3 パターン。
| パターン | フラグ | 用途の典型例 |
|---|---|---|
| ローカルフォワード | -L |
手元から踏み台越しのリモート DB に直接接続 |
| リモートフォワード | -R |
手元のアプリを一時的に外部サーバへ公開 (ngrok 代替) |
| ダイナミック | -D |
SOCKS プロキシ。ブラウザを SSH 経由で出口接続 |
例: 踏み台越しにリモート PostgreSQL に psql で直接つなぐ。
ssh -L 5432:localhost:5432 user@bastion.example.com
# 別ターミナルで
psql -h localhost
踏み台多段経由 (ProxyJump) #
複数の踏み台を経由する場合は -J でつなげる。古い ProxyCommand の置き換え。
ssh -J user@bastion user@internal-server
ssh -J user@b1,user@b2 user@target # 多段
最低限おさえたいサーバ設定 (sshd_config) #
/etc/ssh/sshd_config で次の 3 行は必ず設定したい。
PermitRootLogin no # root 直接ログイン禁止
PasswordAuthentication no # パスワード認証無効化 (公開鍵のみ)
PubkeyAuthentication yes # 公開鍵認証を有効化
設定後は sshd -t で構文チェック → systemctl reload sshd で反映。今のセッションは閉じずに、別ターミナルで再接続テストしてから古いセッションを切る こと (設定ミスで自分が締め出されるのを防ぐ)。
クライアント側の便利設定 (~/.ssh/config) #
接続先ごとに別名を切ると ssh internal と打つだけで済む。
Host bastion
HostName bastion.example.com
User admin
Port 2222
IdentityFile ~/.ssh/id_ed25519_admin
Host internal
HostName 10.0.0.5
User deploy
IdentityFile ~/.ssh/id_ed25519_deploy
ProxyJump bastion
参考 #
- 『図解入門 TCP/IP 第 2 版 ── 仕組み・動作が見てわかる』 6-5-2 SSH (管理アクセスプロトコル)
- OpenSSH 公式ドキュメント
- RFC 4253 — The Secure Shell (SSH) Transport Layer Protocol