SSH とは — 仕組み・公開鍵認証・主要コマンド のサムネイル

SSH とは — 仕組み・公開鍵認証・主要コマンド

⏱ 約 6 分 view 69 like 0 LOG_DATE:2026-05-09
目次 / TOC

SSH とは #

SSH (Secure Shell) は、ネットワーク越しに別のコンピュータへ安全にアクセスし、リモート操作・ファイル転送を行うためのプロトコルである。通信を暗号化することで、Telnet や rlogin などの平文プロトコルが抱えていた 盗聴・改ざん・なりすまし を一掃した。デフォルトで TCP の 22 番ポート を使い、RFC 4253 で標準化されている。

サーバ運用・GitHub への push・CI/CD のデプロイなど、現代の開発に欠かせないインフラの 1 つ。OpenSSH (OpenBSD 由来の OSS 実装) がほぼあらゆる Linux / macOS / Windows 10 以降に同梱され、事実上の標準となっている。

SSH の全体像 — クライアント・サーバ間を暗号化チャネルで結ぶ

接続の 3 ステップ #

SSH 接続は次の順に進む。これだけ掴めば仕組みは理解しやすい。

  1. ホスト認証 — クライアントが「相手は本物のサーバか?」を検証
  2. ユーザ認証 — サーバが「相手は本物のユーザか?」を検証
  3. 暗号化通信 — 双方で生成した共通鍵で全データを暗号化

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-Poly1305AES-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 も自動でセットされる)。

認証フロー (チャレンジ・レスポンス) #

  1. クライアントが「この公開鍵で入りたい」と申告
  2. サーバが乱数 (チャレンジ) を送る
  3. クライアントが 秘密鍵で署名 して返す
  4. サーバが 公開鍵で署名を検証 ─ 一致すれば認証成功

秘密鍵そのものはネットワークを流れない。リプレイ攻撃にも耐性がある、というのがこのフローの核心。

基本コマンド #

# 接続
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

参考 #