第22章 暗号化によるデータ保護(SSH/GPG)

LPIC-1 110.3 相当

SSHの鍵認証とGPGは、どちらも公開鍵暗号という同じ数学的な仕組みを土台にしながら、「サーバーへのログイン」と「ファイルやメッセージの保護」という異なる目的のために使われます。この章では、前章で扱ったアカウント・サービスのセキュリティに続けて、通信とデータそのものを暗号化する方法を扱います。

SSHによる暗号化通信と鍵認証

パスワードでのログインに比べて、公開鍵暗号を使った鍵認証はより安全とされています。パスワード認証は総当たり攻撃(ブルートフォース)で突破される可能性がある一方、鍵認証は秘密鍵という長大なデータそのものを持っていないと成立しないため、現実的な時間で破ることは極めて困難です。

$ ssh-keygen -t ed25519          # 鍵ペア(秘密鍵・公開鍵)を生成
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:k3f9J2m8xQpR7vL1nS4wY6bC0dE5gH9iJ2kL4mN6oPq user@laptop
$ ssh-copy-id user@server        # 公開鍵をサーバーに登録
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'user@server'"
and check to make sure that only the key(s) you wanted were added.
$ ssh user@server                # 鍵認証でログイン
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-49-generic x86_64)
Last login: Fri Aug 21 08:15:44 2026 from 203.0.113.10
user@server:~$
$ ssh -p 2222 user@server        # SSHポートを22以外に変更している場合は-pで指定
user@server:~$
$ scp file.txt user@server:/tmp/ # SSHの仕組みを使ってファイルを安全にコピー
file.txt                                     100%   842    12.3KB/s   00:00

この行のこの値に注目: ssh-keygen実行後に表示されるkey fingerprintは鍵の指紋(ハッシュ値)で、初回接続時にサーバー側の指紋と照合する材料になります。ssh-copy-idのNumber of key(s) added: 1は公開鍵が正しくauthorized_keysに追加されたことを示し、この後のssh user@serverでパスワード入力なしにログインできれば鍵認証が機能している証拠です。

補足: 近年のOpenSSHでは、レガシーなSCPプロトコルに起因する制約から、scpコマンドの利用は縮小方向にあり、代わりにsftpコマンドやrsync -e sshの利用が推奨されています。scp自体は今も広く使われていますが、新しく手順を組むときはこれらの代替手段も選択肢に入れておくとよいでしょう。

秘密鍵は自分だけが持ち、絶対に他人に渡してはいけません。サーバー側には公開鍵だけを登録します(~/.ssh/authorized_keysというファイルに追記される形で登録されます)。生成した鍵ペアのうち、拡張子や名前に何も付いていないほう(例: id_ed25519)が秘密鍵、.pubが付いているほう(例: id_ed25519.pub)が公開鍵です。

注意: サーバー側のSSH設定(/etc/ssh/sshd_config)でPermitRootLogin noやPasswordAuthentication noを設定し、rootでの直接ログインやパスワード認証そのものを無効化しておくのも代表的なセキュリティ強化策です。これにより、たとえパスワードが漏洩しても、鍵を持たない攻撃者はログインできなくなります。

ssh-agentとssh-add — パスフレーズ入力を省力化する

秘密鍵にパスフレーズを設定するのは安全ですが、鍵を使うたびに毎回入力するのは面倒です。ssh-agentは、一度だけパスフレーズを入力して秘密鍵をメモリ上に保持しておき、以降のSSH接続ではそのつど入力せずに済むようにする仕組みです。

$ eval "$(ssh-agent)"           # ssh-agentを起動し、環境変数をシェルに反映する
Agent pid 4821
$ ssh-add ~/.ssh/id_ed25519      # 秘密鍵をエージェントに登録(初回のみパスフレーズを聞かれる)
Enter passphrase for /home/user/.ssh/id_ed25519:
Identity added: /home/user/.ssh/id_ed25519 (user@laptop)
$ ssh-add -l                    # 現在エージェントに登録されている鍵の一覧
256 SHA256:k3f9J2m8xQpR7vL1nS4wY6bC0dE5gH9iJ2kL4mN6oPq user@laptop (ED25519)
$ ssh user@server                # 以降はパスフレーズを聞かれずにログインできる

この行のこの値に注目: eval "$(ssh-agent)"はssh-agentが出力するSSH_AUTH_SOCK・SSH_AGENT_PIDという環境変数をそのシェルに設定するための定型的な書き方です。この環境変数が設定されていないと、ssh-addや以降のsshコマンドはエージェントを見つけられません。ssh-add -lの一覧に鍵が表示されていれば、エージェントへの登録が成功しています。

SSHポートフォワードとX11転送の基礎

SSHは、暗号化された接続の中に別の通信を通す「トンネル」としても使えます。ここでは基礎だけを扱い、実務での詳しい活用方法は上級編で改めて取り上げます。

$ ssh -L 8080:localhost:80 user@server   # ローカルフォワード:手元の8080番へのアクセスをserver上の80番へ転送
$ ssh -X user@server                     # X11転送を有効にしてログイン
user@server:~$ xclock                          # server上で実行したGUIアプリの画面が手元に表示される

-L(ローカルフォワード)は、手元のマシンの特定ポートへの通信を、SSH接続の先にあるサーバー経由で別のホスト・ポートへ転送します。上の例では、手元でhttp://localhost:8080にアクセスすると、実際にはserver上の80番ポート(例えば社内ネットワークからしか到達できないWebサーバー)にSSH経由でアクセスできます。-X(X11転送)は、リモート側で実行したGUIアプリケーションのウィンドウを、SSH接続を通じて手元の画面に表示する機能です。グラフィカル環境の章で扱ったDISPLAY変数やXサーバーの仕組みを、SSHの暗号化トンネル越しに安全に利用する応用例といえます。

関連する章: X11転送の背景となるX Window Systemの仕組み(クライアント・サーバーモデルやDISPLAY変数)については、「グラフィカル環境の設定」の章で詳しく扱っています。SSHのポートフォワードをさらに踏み込んで活用する方法は、上級編で改めて扱います。

GPGによるファイルの暗号化

GPG(GNU Privacy Guard)は、ファイルの暗号化や、送信者を証明する電子署名に使われます。SSHの鍵が「サーバーへのログイン」に特化しているのに対し、GPGは「ファイルやメールの内容そのもの」を暗号化・署名する、より汎用的な公開鍵暗号の実装です。

$ gpg --gen-key                       # 鍵ペアを生成(対話形式で名前・メールアドレス・パスフレーズを入力)
gpg: key A1B2C3D4E5F60718 marked as ultimately trusted
public and secret key created and signed.
$ gpg -e -r alice@example.com file.txt # aliceの公開鍵で暗号化(正常時は無出力。file.txt.gpgが生成される)
$ gpg -d file.txt.gpg                  # 復号(自分の秘密鍵が必要)
gpg: encrypted with 256-bit ECDH key, ID 9F1E2D3C4B5A6978, created 2026-08-15
      "Alice "
(復号された file.txt の内容がそのまま標準出力に表示される)
$ gpg --import alice_pubkey.asc        # 相手の公開鍵を自分の鍵束に取り込む
gpg: key A1B2C3D4E5F60718: public key "Alice " imported
gpg: Total number processed: 1
gpg:               imported: 1
$ gpg --list-keys                      # 取り込んだ公開鍵の一覧を表示
pub   ed25519 2026-08-15 [SC]
      A1B2C3D4E5F607189A0B1C2D3E4F50617289A0B1
uid           [ unknown] Alice <alice@example.com>
sub   cv25519 2026-08-15 [E]

この行のこの値に注目: gpg --import後のimported: 1で鍵の取り込みに成功したことが分かります。--list-keysのpub行の末尾にある長い16進数の文字列が鍵の指紋(フィンガープリント)で、他の人から受け取った公開鍵が本人のものであるかを別の経路(電話や対面)で照合する際にはこの指紋を使います。

「aliceの公開鍵で暗号化する」ということは、暗号化されたファイルを復号できるのはaliceの秘密鍵を持つ本人だけ、ということを意味します。逆に「自分の秘密鍵で署名する」ことで、受け取った相手は「自分の公開鍵」を使ってその署名を検証し、確かに本人が作成したファイルであること(改ざんされていないこと)を確認できます。暗号化と署名は目的も鍵の使い方も逆であることを整理しておくと理解しやすくなります。

$ gpg --sign -o file.txt.sig file.txt     # 自分の秘密鍵でfile.txtに署名し、file.txt.sigを作成
$ gpg --verify file.txt.sig file.txt      # 署名を検証(相手の公開鍵が鍵束に必要)
gpg: Signature made Fri 21 Aug 2026 09:12:03 AM UTC
gpg:                using EDDSA key A1B2C3D4E5F60718...
gpg: Good signature from "Alice <alice@example.com>" [ultimate]
$ gpg --export -a alice@example.com > alice_pubkey.asc  # 自分の公開鍵をテキスト形式で書き出す(他人に配布する用)
$ gpg --gen-revoke alice@example.com > revoke.asc      # 失効証明書を事前に作成しておく

この行のこの値に注目: gpg --verifyの結果がGood signature from ...であれば、そのファイルは確かに指定した相手の秘密鍵で署名されており、署名後に改ざんされていないことが確認できます。[ultimate]は自分自身の鍵に対する信頼度、他人の鍵であれば後述の信頼度(unknown/marginal/fullなど)が表示されます。

公開鍵暗号は「その公開鍵が本当に本人のものか」をどう確認するかが課題になります。GPGでは、信頼できる人が別の人の公開鍵に署名することで身元を保証し合う信頼のWeb(Web of Trust)という分散的な仕組みを採用しています。中央の認証局に頼るのではなく、知人同士が互いの鍵に署名を重ねることで、間接的に「信頼の連鎖」を築いていく考え方です。

秘密鍵を紛失したり漏洩させてしまった場合に備え、失効証明書(revocation certificate)をあらかじめ作成しておくことが推奨されます。失効証明書を公開鍵サーバーなどに公開すると、その鍵が「もう使うべきではない」ことを周囲に知らせられます。秘密鍵そのものが手元になくても失効させられるよう、鍵を生成した直後に作成し、安全な場所に保管しておくのが一般的です。

補足: GPGの鍵や設定は~/.gnupg/ディレクトリ以下に保存されます(pubring.kbxに公開鍵、private-keys-v1.d/に秘密鍵が格納されるなど、バージョンによって内部構成は異なります)。rpmやaptなどのパッケージ管理システムが、ダウンロードしたパッケージの改ざんの有無やリポジトリの真正性を検証する際にも、内部的には同じGPGの署名検証の仕組みが使われています。

確認クイズ

Q1. SSHの鍵認証において、サーバー側に登録するべき鍵はどちらですか?

解説: サーバー側には公開鍵だけを登録します。秘密鍵は自分の手元だけに保管し、絶対に他人やサーバーに渡してはいけません。

Q2. ssh-agentとssh-addを使う主な目的はどれですか?

解説: ssh-agentはパスフレーズを入力して復号した秘密鍵をメモリ上に保持し、ssh-addで登録した鍵は以降のSSH接続でパスフレーズの再入力なしに使えるようになります。

Q3. ssh -L 8080:localhost:80 user@server というコマンドの役割として正しいものはどれですか?

解説: -L(ローカルフォワード)は、手元のマシンの指定ポートへの通信を、SSH接続の先にあるサーバー経由で別のホスト・ポートへ転送します。

Q4. GPGで失効証明書(revocation certificate)をあらかじめ作成しておく目的はどれですか?

解説: 失効証明書は、秘密鍵の紛失や漏洩が起きた場合に鍵を失効させ、公開鍵サーバーなどを通じてその鍵がもう有効でないことを周囲に知らせるために、鍵の生成直後に作成しておくのが一般的です。