💨

SSH接続を楽にするSSH ConfigとSSH Agent 使ってますか?

2025/02/23に公開

SSHするときに毎回IPアドレスや秘密鍵を確認して、それをSSHコマンドで入力していませんか?
それとても面倒ですよね...
実は事前に設定しておけば省略できるんです。

SSHとは

SSH(Secure Shell)は、ネットワーク経由で安全にリモートコンピュータに接続するためのプロトコルです。主に以下の用途で利用されます。

リモートサーバーへのログイン
ファイル転送(SCP、SFTP)
コマンド実行
ポートフォワーディング(トンネリング)

SSH Configとは

SSH Configファイルは、SSHクライアントの設定ファイルであり、接続先のホストごとに様々な設定を記述できます。これにより、SSHコマンドのオプションを省略したり、デフォルト値を変更したりできます。

SSH Configの主な設定項目

Host:         ホストの別名。この名前でssh接続できます。名前は分かりやすければなんでもよいです。
HostName:     接続先のホスト名またはIPアドレス。
Port:         接続先のポート番号(デフォルトは22)省略可
User:         接続ユーザー名
IdentityFile: 秘密鍵ファイルのパス。後述のSSH Agentを使用すればこれも省略可。
ProxyJump:    踏み台サーバー経由の場合は書いておくと便利。
ForwardAgent: SSH Agent転送を有効にするかどうか。

その他の設定は以下を参照してください。上記以外にもたくさんあります。
ssh_config(5) — Linux manual page

SSH Configのメリット

  • 接続設定の簡略化   :長いSSHコマンドを毎回入力する必要がなくなります。
  • 設定の一元管理    :複数のサーバーへの接続設定を一つのファイルで管理できます。
  • タイプミスの防止   :設定を事前に記述しておくことで、入力ミスを減らせます。
  • 複雑な接続設定の簡略化:プロキシ経由の接続やポートフォワーディングなどの設定も簡単に記述できます。

ProxyJumpについて補足

ProxyJumpとは別で似たようなProxyCommandというものもありますが、ProxyJumpを使用するのをお勧めします。
なぜかというとProxyCommandは古いうえに記述も長く分かりにくいからです。

Host bastion     # 踏み台サーバー
    HostName     bastionのIPアドレス又はホスト名
    User         bastionのユーザ名
    ProxyJump    none
    ProxyCommand none

Host web-server  # 踏み台サーバー経由で接続するサーバー
    HostName     web-serverのIPアドレス又はホスト名
    User         web-serverのユーザ名
    ProxyJump    bastion
    ProxyCommand ssh -W %h:%p bastion

上記は簡単な例ですが、これでssh web-serverとコマンドを打つと、bastionという名前で設定した踏み台サーバーを勝手に経由してweb-serverへSSHできます。
ProxyJumpProxyCommandに注目すると、実はどちらも同じことをやっているんですがProxyJumpの方が短くて分かりやいですよね。

ProxyJumpマニュアルを確認すると、

踏み台サーバーのユーザ名@踏み台サーバーのホスト名:踏み台サーバーのポート番号

を書けとあり、長いじゃんと思ったかもしれませんが、踏み台サーバーも事前にSSH Configに書いておけば、HostNameを指定するだけでよいんです。(ポートもデフォルトの22であればわざわざ書かなくてよいです)

SSH Configファイルの分割管理

今回の記事では、configファイルにまとめて書きますが、このファイルにすべての設定を記述すると管理が煩雑になります。SSH接続するサーバーの台数が多い場合は、Includeを使ってconfigファイルを分割して管理することをお勧めします。

分割管理の方法
.ssh/config に Includeを追加

Include ./conf.d/*

これで .ssh/conf.d/ ディレクトリの下のconfigファイルを読んでくれます。

.ssh の下に conf.d というディレクトリを新しく作成して、
conf.d 内に、環境や用途ごとにSSH Configファイルを分割して配置します。
例↓

.ssh/conf.d/prod : 本番環境のサーバー設定
.ssh/conf.d/dev  : 開発環境のサーバー設定
.ssh/conf.d/stg  : ステージングのサーバーの設定

このようにファイルを分割することで、設定の可読性と管理性が向上します。

SSH Agentとは

SSH Agentは、秘密鍵のパスフレーズを記憶し、SSH接続時に自動的に使用してくれるツールです。これにより、毎回秘密鍵や秘密鍵のパスフレーズの入力、SSH ConfigでもIdentityFileの設定を省略できます。

SSH Agentの仕組み
ssh-agentを起動すると、秘密鍵の保管と認証を行うデーモンが起動します。ssh-addコマンドで秘密鍵をssh-agentに登録する際に、パスフレーズを入力します。以降のSSH接続では、ssh-agentが自動的に秘密鍵を使って認証を行います。

ssh-addコマンドの主な使用方法

コマンド 意味
ssh-add <秘密鍵ファイルのパス> 指定した鍵ファイルをSSH Agentに登録する
ssh-add -l SSH Agentに登録されている鍵を一覧表示する
ssh-add -L 登録されている鍵の公開鍵一覧を表示する
ssh-add -d <秘密鍵ファイルのパス 指定した鍵ファイルをSSH Agentから削除する
ssh-add -D SSH Agentに登録されているすべての秘密鍵を削除する

SSH Agentのメリット

  • パスフレーズ入力の省略:SSH鍵にパスフレーズが設定されていても、毎回パスフレーズを入力する必要がなくなります。
  • セキュリティ向上 :ログインに必要なクリティカルなファイルであるSSH秘密鍵をローカルPCにだけ置いておけば良くなり、サーバーにコピーしておく必要がなくなるのでセキュリティが向上します。

実践

SSH Configを使用しない場合と使用した場合の違い

SSH Configを使用しない場合

ssh dareka@example.com -i ~/.ssh/id_ed25519 -J dareka@bastion.example.com:10022

上記のように、毎回長いコマンドを入力する必要がありとても面倒。
しかも業務となれば管理するサーバーは数十台になることも当然ある。そんな中でそれぞれのコマンドを覚えるのはとても生産性が悪く非効率です。というか覚えられない...
プロキシ経由の接続など、複雑な設定も毎回記述する必要があります。

SSH Configを使用した場合

~/.ssh/configに以下のように設定を記述します。パーミッションを正しく設定していないと読み込まれないのでご注意を。
※Windowsでは"C:\Users\dareka\.ssh\config"

Host bastion
    HostName     bastion.example.com
    User         dareka
    Port         10022
    ProxyJump    none
    ProxyCommand none

Host example
    HostName     example.com
    User         dareka
    IdentityFile ~/.ssh/id_ed25519
    ProxyJump    bastion
    ProxyCommand ssh -W %h:%p bastion

上記設定後、以下のように短いコマンドでexample.comというサーバーへ接続できます。

ssh example

複雑な接続設定も、configファイルに一度記述すれば、以降は意識する必要がありません。

SSH Agentを使用しない場合と使用した場合の違い

SSH Agentを使用しない場合

ssh example
Enter passphrase for key 'C:\Users\dareka/.ssh/id_ed25519':

上記のように、(秘密鍵にパスフレーズが設定してある場合)毎回パスフレーズを入力する必要があります。
複数のサーバーに接続する場合、それぞれのパスフレーズを入力する必要があります。
リモートサーバーからさらに別のサーバーへSSH接続する場合、リモートサーバーに秘密鍵を置く必要があり、セキュリティ上とてもよろしくないです...
またSSHコマンド時やSSH Configで指定する必要があり、それぞれのサーバーでどの秘密鍵を使用すればよいのかを把握している必要があります。

SSh Agentを使用した場合

Windowsでssh-agentを起動し、秘密鍵を登録します。

管理者権限でPowerShellを開いて以下を入力し起動

> Get-Service ssh-agent | Set-Service -StartupType Automatic
> Start-Service ssh-agent

> Get-Service ssh-agent

Status   Name               DisplayName
------   ----               -----------
Running  ssh-agent          OpenSSH Authentication Agent

Winキー+Qを押して、「サービス」と入力してサービスアプリを開き、サービスのリストから「OpenSSH Authentication Agent」を探してそこからでも起動できます。
スタートアップの種類が「自動」だとPCを立ち上げたときに勝手に起動してくれるので、頻繁に使用する方は「自動」にしておくとよいです。

秘密鍵をssh-agentに登録します。

> ssh-add 秘密鍵へのパス

例↓

> ssh-add .\dareka\.ssh\id_ed25519
Enter passphrase for .\dareka\.ssh\id_ed25519:
Identity added: .\dareka\.sshid_ed25519 (.\dareka\.ssh\id_ed25519)

ここまでくれば秘密鍵の指定と、パスフレーズの入力をすることなくSSH接続ができるはずです。
SSH ConfigからIdentityFileの設定も削除して問題ありません。

ssh example

SSH Agent転送により、パスフレーズの入力が不要になり、接続がとてもスムーズになりましたね。
またsshコマンド時に-Aをオプションを追加する、もしくはSSH ConfigにForwardAgent: yesの設定を追加するとSSH接続した先でもssh-agentに登録した鍵を使用することができます。

少し話がそれますが、秘密鍵が多く管理が大変という方は、KeePassXCがとてもお勧めです!ぜひ使用してみてください!

小ネタ

sshプロトコルを行うときはOpenSSHというオープンソースのソフトウェアを使用しています。
実はWindows標準のOpenSSHはバージョンが少し古いです。

PowerShell 7.5.0
PS C:\Users> ssh -V
OpenSSH_for_Windows_8.6p1, LibreSSL 3.8.2

このバージョンではSSH Agent機能がうまく動作しないことがあります。
https://github.com/PowerShell/Win32-OpenSSH/releases/tag/v8.9.0.0p1-Beta

Upstream changes from OpenSSH 8.9. Please note this release doesn't have ssh-agent restriction feature.

なので最新に更新することをお勧めします。更新手順は以下を参考にしてください。
【小ネタ】OpenSSH クライアントをバージョンアップする方法

2025/02/22の最新バージョン

PS C:\Users> winget search "OpenSSH.Beta"
名前         ID                     バージョン ソース
------------------------------------------------------
OpenSSH Beta Microsoft.OpenSSH.Beta 9.5.0.0    winget

Discussion