.ssh/config の基本から応用まで – 設定と活用例

はい、承知いたしました。.ssh/configファイルの基本から応用まで、設定と活用例を詳細に記述した記事を作成します。約5000語を目指して記述します。


.ssh/config の基本から応用まで – 設定と活用例

はじめに:なぜ .ssh/config は重要なのか?

SSH(Secure Shell)は、リモートのサーバーと安全に通信するためのプロトコルであり、システム管理者、開発者、そしてリモートワークを行う多くの人々にとって不可欠なツールです。SSHクライアント(通常はsshコマンド)を使ってサーバーに接続する際、通常は以下のようなコマンドを実行します。

bash
ssh username@hostname -p port -i /path/to/identity/file

このコマンドには、接続先のホスト名(またはIPアドレス)、ユーザー名、ポート番号、そして認証に使用する秘密鍵のパスなど、いくつかの情報が含まれています。しかし、頻繁に接続するサーバーが複数ある場合、毎回これらのオプションを指定してコマンドを入力するのは面倒で、ヒューマンエラーの原因にもなり得ます。

ここで登場するのが、.ssh/config ファイルです。このファイルは、SSHクライアントの様々な接続設定を、接続先ごとにまとめて記述しておくことができる設定ファイルです。.ssh/config を適切に設定することで、上記のような複雑なコマンドを、以下のようなシンプルな形式に置き換えることができます。

bash
ssh myserver

これにより、日々のSSH接続が劇的に効率化され、タイプミスの削減、セキュリティ設定の一元管理、そして複雑な接続シナリオ(踏み台サーバー経由、ポートフォワーディングなど)の自動化が可能になります。

本記事では、.ssh/config ファイルの基本的な使い方から始め、よく使われる設定項目、パスワードなし認証の管理、より高度な設定(多重化接続、踏み台サーバー、ポートフォワーディング)、セキュリティに関する設定、そして様々な活用例まで、詳細に解説します。約5000語にわたる解説を通じて、.ssh/config をあなたのSSHワークフローに最大限に活かすための知識を身につけていきましょう。

.ssh/config の基本の「き」

まずは、.ssh/config ファイルの基本的なことについて説明します。

ファイルパスとパーミッション

.ssh/config ファイルは、SSHクライアントを実行するユーザーのホームディレクトリ直下にある .ssh ディレクトリ内に配置します。

~/.ssh/config

.ssh ディレクトリが存在しない場合は作成してください。

bash
mkdir ~/.ssh

次に、.ssh/config ファイルを作成します。

bash
touch ~/.ssh/config

SSH関連のファイル、特に秘密鍵を含む .ssh ディレクトリ内のファイルは、適切なパーミッションが設定されている必要があります。.ssh/config ファイルについても、他のユーザーから読み書きできないようにパーミッションを設定することが強く推奨されます。一般的には、所有者のみが読み書きできる 600 を設定します。

bash
chmod 600 ~/.ssh/config

.ssh ディレクトリ自体のパーミッションは、所有者のみがアクセスできるように 700 を設定するのが一般的です。

bash
chmod 700 ~/.ssh

これらのパーミッション設定は、SSHクライアントが.sshディレクトリやconfigファイルを安全に扱うために重要です。もしパーミッションが緩すぎる場合、SSHクライアントはセキュリティリスクと判断し、設定ファイルを無視したり、警告を出したりすることがあります。

基本的な書式

.ssh/config ファイルは、一つ以上の「ホスト設定ブロック」から構成されます。各ブロックは Host キーワードで始まり、その後に続く設定項目が、その Host にマッチする接続に対して適用されます。

基本的な書式は以下のようになります。

“`config

これはコメント行です

次のブロックは ‘myserver’ という名前で参照されます

Host myserver
Hostname 192.168.1.100
User myuser
Port 2222
IdentityFile ~/.ssh/id_rsa_myserver

次のブロックは ‘another_server’ という名前で参照されます

Host another_server
Hostname server.example.com
User admin
Port 22
IdentityFile ~/.ssh/id_ed25519_another
“`

  • #: シャープ記号で始まる行はコメントとして扱われます。
  • Host <alias>: このブロックを識別するためのエイリアス(短縮名)を指定します。ssh コマンドを実行する際に、このエイリアスを使用します。エイリアスにはワイルドカード (*, ?, !) も使用できます。
  • 設定項目: Host の行の後に続くインデントされた行が、そのホストブロックに対する設定項目です。各行は キーワード 値 の形式で記述します。キーワードの大文字/小文字は区別されません(例: Hostname でも hostname でも同じ)。

最初の設定例(シンプルな接続)

ローカルネットワーク内のサーバー 192.168.1.100 に、ユーザー名 mylocaluser で接続することが多いとします。通常は ssh [email protected] と入力しますが、これを .ssh/config に設定してみましょう。

“`config

~/.ssh/config

Host local-server
Hostname 192.168.1.100
User mylocaluser
Port 22
“`

この設定を保存した後、ターミナルで以下のコマンドを実行します。

bash
ssh local-server

これで、設定したユーザー名とIPアドレスを使用してSSH接続が開始されるはずです。Port 22 はSSHのデフォルトポートなので、省略しても構いませんが、明示的に書いておくと分かりやすいでしょう。

ワイルドカード (*) の利用

Host のエイリアスにはワイルドカードを使用できます。最も一般的なのは * で、これは任意の文字列にマッチします。ワイルドカードを使った設定は、ファイル内でより具体的に記述された Host 設定よりも後に評価されます。つまり、一般的な設定をファイルの先頭近くに書き、特定のホストに対する例外的な設定を後で上書きする、という使い方ができます。

例:

“`config

~/.ssh/config

全てのホストに対する共通設定

Host *
StrictHostKeyChecking ask
UserKnownHostsFile ~/.ssh/known_hosts
ServerAliveInterval 60

特定のホストに対する設定(共通設定を上書き)

Host specific-server
Hostname 192.168.1.200
User admin
StrictHostKeyChecking yes # specific-server に対しては厳格なチェックを行う
“`

この例では、specific-server に接続する場合、StrictHostKeyCheckingyes になりますが、それ以外のすべてのホストに接続する場合は ask になります。共通設定として Host * ブロックをファイルの先頭に置くのが一般的です。

.ssh/config の主要な設定項目(基本編)

ここでは、SSH接続を効率化するために最も頻繁に使用される基本的な設定項目について詳しく説明します。

Hostname

  • 説明: 接続先の実際のホスト名またはIPアドレスを指定します。ssh コマンドで指定するエイリアス (Host で指定した名前) とは異なる名前を指定できます。
  • 値: ホスト名またはIPv4/IPv6アドレス。
  • 例:
    config
    Host webserver
    Hostname 203.0.113.50

    ssh webserver と実行すると、実際には 203.0.113.50 に接続されます。ホスト名として完全修飾ドメイン名 (FQDN) を指定することもできます。

User

  • 説明: リモートホストにログインする際のユーザー名を指定します。
  • 値: ユーザー名文字列。
  • 例:
    config
    Host dbserver
    Hostname db.example.com
    User dbadmin

    ssh dbserver と実行すると、dbadmin ユーザーとして接続を試みます。コマンドラインで ssh dbadmin@dbserver と入力した場合と同じです。

Port

  • 説明: リモートホストのSSHデーモンが待ち受けているポート番号を指定します。デフォルトは22番ポートです。セキュリティ上の理由などから、デフォルト以外のポートを使用しているサーバーも多いです。
  • 値: ポート番号 (1-65535)。
  • 例:
    config
    Host custom-port-server
    Hostname 192.168.1.150
    Port 2222

    ssh custom-port-server と実行すると、192.168.1.150 の 2222番ポートに接続を試みます。

IdentityFile

  • 説明: 認証に使用する秘密鍵ファイルを指定します。通常、パスワード認証よりも公開鍵認証が推奨されます。デフォルトでは ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519, ~/.ssh/id_xmss などが自動的に試行されますが、特定の鍵を使いたい場合にこの設定を使用します。
  • 値: 秘密鍵ファイルへのパス。絶対パスでも、ホームディレクトリからの相対パス (~/.ssh/...) でも指定できます。複数の IdentityFile を指定することも可能です。
  • 例:
    config
    Host project-server
    Hostname project.example.com
    User user_for_project
    IdentityFile ~/.ssh/keys/project_rsa

    ssh project-server と実行すると、認証に ~/.ssh/keys/project_rsa という秘密鍵を使用します。

IdentitiesOnly

  • 説明: この設定が yes になっている場合、SSHクライアントは IdentityFile ディレクティブで明示的に指定された秘密鍵のみを認証に試行します。エージェント (ssh-agent) から提供される鍵や、デフォルトの場所に存在する鍵は試行されません。
  • 値: yes または no (デフォルト)。
  • 例:
    config
    Host restricted-server
    Hostname strict.example.com
    User strict_user
    IdentityFile ~/.ssh/keys/strict_server_key
    IdentitiesOnly yes # この鍵以外は使わない

    複数の鍵を使い分けている場合や、意図しない鍵で認証を試みるのを防ぎたい場合に便利です。

StrictHostKeyChecking

  • 説明: サーバーのホストキーを検証するかどうかを制御します。SSHクライアントが初めてサーバーに接続する際、サーバーのホストキーのフィンガープリントを表示し、ユーザーに接続を続行するか尋ねます。承諾すると、そのホストキーは ~/.ssh/known_hosts ファイルに保存されます。次回以降、同じホストに接続する際に、保存されたホストキーとサーバーから提示されたホストキーが一致するか確認されます。この設定は、その検証の厳格さを定義します。
    • yes: 既知のホストキーが存在しない場合、接続を拒否します。既知のホストキーと異なる場合も接続を拒否します。最も安全な設定です。
    • no: ホストキーの検証を行いません。セキュリティリスクが高いため、推奨されません。特に初めて接続するサーバーや、IPアドレスが変わる可能性があるサーバーに対して使用すると、中間者攻撃のリスクが高まります。
    • ask (デフォルト): 既知のホストキーが存在しない場合、フィンガープリントを表示して接続を続行するか尋ねます。既知のホストキーと異なる場合は、警告を表示しますが、接続自体は行いません(通常、ユーザーに手動での known_hosts の更新を促します)。OpenSSH 7.0 以降では ask がデフォルトであり、yes に近い挙動を示します。以前は yes と同じ挙動でした。最新のOpenSSHでは StrictHostKeyChecking のデフォルトは ask に近いですが、少し複雑な挙動をするため、yes と明示的に指定するのが最も安全です。
    • offno と同じです。
    • accept-new: 既知のホストキーが存在しない場合、警告なしにホストキーを自動的に known_hosts に追加し、接続を続行します。既存のホストキーと異なる場合は接続を拒否します。初めて大量のサーバーに接続する場合などに便利ですが、リスクもあります。
  • 値: yes, no, ask, off, accept-new
  • 例:
    config
    Host *
    StrictHostKeyChecking yes # 全てのサーバーでホストキーを厳格にチェック

    本番環境のサーバーなど、セキュリティが重要な接続に対しては yes を強く推奨します。開発環境など、頻繁にサーバーが再構築されるような環境では accept-new が便利な場合もありますが、そのリスクを理解しておく必要があります。

UserKnownHostsFile

  • 説明: ホストキーを保存・読み込むためのファイルを指定します。デフォルトは ~/.ssh/known_hosts および ~/.ssh/known_hosts2 です。
  • 値: ファイルパス。複数のファイルを指定する場合は、カンマ区切りで指定します。
  • 例:
    config
    Host development-servers
    Hostname dev-*.example.com
    UserKnownHostsFile ~/.ssh/dev_known_hosts
    StrictHostKeyChecking accept-new

    特定のサーバーグループに対して、個別の known_hosts ファイルを使用することで、管理を分離できます。

LogLevel

  • 説明: SSHクライアントのログレベルを指定します。接続の問題を診断する際に役立ちます。
  • 値: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, DEBUG3。デフォルトは INFO です。
  • 例:
    config
    Host problem-server
    Hostname 192.168.1.250
    LogLevel DEBUG3 # 詳細なデバッグ情報を出力

    DEBUG3 が最も詳細なログを出力します。通常はコマンドラインオプション -v, -vv, -vvv で指定することが多いですが、特定のホストの問題調査用にconfigファイルに記述しておくこともできます。

パスワードなし認証と秘密鍵管理

SSHで最も推奨される認証方法は、パスワード認証ではなく、公開鍵認証です。公開鍵認証では、クライアント側に秘密鍵、サーバー側に公開鍵を配置します。接続時にクライアントが秘密鍵を使って認証情報を生成し、サーバーが対応する公開鍵で検証します。

公開鍵認証の仕組み

  1. クライアントは、接続要求とともに使用する公開鍵の情報をサーバーに送る。
  2. サーバーは、受け取った公開鍵が ~/.ssh/authorized_keys ファイルに登録されているか確認する。登録されていれば、ランダムなデータ(チャレンジ)を生成し、その公開鍵で暗号化してクライアントに送り返す。
  3. クライアントは、送られてきた暗号化されたチャレンジを、手元の対応する秘密鍵で復号する。
  4. クライアントは、復号したチャレンジにセッションIDなどを付加して署名し、その署名されたデータをサーバーに送り返す。
  5. サーバーは、登録されている公開鍵を使ってクライアントから送られてきた署名を検証する。検証に成功すれば、クライアントが正当な秘密鍵を持っていると判断し、認証成功となる。

この仕組みにより、秘密鍵がサーバーに送信されることはなく、安全に認証が行えます。

ssh-keygen による鍵ペア生成

公開鍵と秘密鍵のペアは、ssh-keygen コマンドで生成します。

bash
ssh-keygen -t rsa -b 4096 -C "[email protected]"

  • -t rsa: 鍵のタイプを指定します。現代では ed25519 がより推奨される場合が多いです (-t ed25519)。
  • -b 4096: 鍵のビット数を指定します (RSAの場合)。大きいほど安全ですが、処理に時間がかかります。RSAの場合、2048ビット以上が推奨されます。ed25519の場合はビット数指定は不要です。
  • -C "...": 鍵に対するコメントを指定します。通常はメールアドレスなどを入れて、鍵の識別に使用します。

コマンド実行後、鍵ファイルの保存場所とパスフレーズの入力を求められます。特別な理由がなければ、鍵ファイルの場所はデフォルト (~/.ssh/id_rsa など) を使用するのが良いでしょう。パスフレーズは、秘密鍵を暗号化するためのパスワードです。セキュリティを高めるため、パスフレーズを設定することが強く推奨されます。パスフレーズを設定した場合、秘密鍵を使用するたびにパスフレーズの入力が必要になります。

生成されるファイルは以下の2つです。

  • ~/.ssh/id_rsa (または指定したファイル名): 秘密鍵です。絶対に他人に知られてはいけません。パーミッションは 600 に設定されているはずです。
  • ~/.ssh/id_rsa.pub (または指定したファイル名に .pub が付いたもの): 公開鍵です。これは認証を受けたいサーバーに配置します。

ssh-copy-id による公開鍵配布

生成した公開鍵 (~/.ssh/id_rsa.pub など) をサーバーに設置するには、通常、サーバーの接続したいユーザーのホームディレクトリにある .ssh/authorized_keys ファイルに追記します。

この作業を簡単に行うための便利なコマンドが ssh-copy-id です。

bash
ssh-copy-id -i ~/.ssh/id_rsa.pub user@server

このコマンドは、指定したサーバーにパスワード認証などで一度接続し、~/.ssh/id_rsa.pub の内容をサーバーの ~/.ssh/authorized_keys ファイルに自動的に追記してくれます。非常に便利なので、公開鍵認証を設定する際にはぜひ利用しましょう。

IdentityFile の重要性(再掲)

複数のサーバーに対して異なる鍵ペアを使用する場合、どの鍵を使うかを .ssh/configIdentityFile で明示的に指定することが重要になります。

“`config
Host server-a
Hostname 192.168.1.10
User user_a
IdentityFile ~/.ssh/keys/key_for_a

Host server-b
Hostname 192.168.1.20
User user_b
IdentityFile ~/.ssh/keys/key_for_b

Host server-c
Hostname 192.168.1.30
User user_c
IdentityFile ~/.ssh/keys/key_for_c_rsa
IdentityFile ~/.ssh/keys/key_for_c_ed25519 # 複数の鍵を指定することも可能
“`

このように設定しておけば、ssh server-a と実行するだけで、自動的に指定された秘密鍵が認証に試行されます。

ssh-agent とパスフレーズ

パスフレーズ付きの秘密鍵を使う場合、鍵を使用するたびにパスフレーズの入力が求められます。これはセキュリティ上望ましいですが、頻繁にSSH接続を行う際には手間になります。

ここで ssh-agent が役立ちます。ssh-agent は秘密鍵をメモリ上に保持し、必要に応じてSSHクライアントに秘密鍵を提供することで、パスフレーズの入力を一度だけにすることができます。

  1. ssh-agent を起動します。通常、ログイン時に自動的に起動されるか、手動で起動します。
  2. ssh-add コマンドで、パスフレーズを入力して秘密鍵を ssh-agent に登録します。
    bash
    ssh-add ~/.ssh/id_rsa

    パスフレーズの入力を求められるのはこの一度だけです。
  3. 以降、SSHクライアントは認証が必要な際に ssh-agent と通信し、秘密鍵を使用します。パスフレーズの再入力は不要です。

ssh-agent.ssh/config の連携は特に意識する必要はありません。IdentityFile で指定された鍵が ssh-agent に登録されていれば、自動的にエージェント経由で認証が試行されます。IdentitiesOnly yesssh-agent を組み合わせて使うことで、「このホストにはエージェントにある特定の鍵だけを使う」といった制御も可能です。

~/.ssh/config には、エージェントに関する便利な設定項目もあります。

  • AddKeysToAgent: yes, no, ask, confirm。秘密鍵を使用する際に、自動的に ssh-agent に追加するかどうかを制御します。yes に設定しておくと、初めて使う鍵でも ssh-add を手動で実行する手間が省けます。
  • ForwardAgent: yes, no。接続先のリモートホストにローカルの ssh-agent の能力を転送するかどうかを制御します。これは踏み台サーバー経由でさらに奥のサーバーに接続する場合などに便利ですが、セキュリティ上の注意が必要です(後述)。

より便利なSSH接続のための設定項目(応用編1)

ここからは、さらにSSH接続を便利で効率的にするための応用的な設定項目を見ていきます。

接続維持・タイムアウト関連

  • ServerAliveInterval: リモートサーバーに対して、コネクションが切断されていないか確認するためのメッセージ(”keepalive”メッセージ)を送信する間隔を秒単位で指定します。これにより、NAT環境などで長時間アイドル状態が続いた場合に勝手に接続が切断されるのを防ぐことができます。
  • ServerAliveCountMax: ServerAliveInterval で送信したkeepaliveメッセージに対する応答が、何回連続でなかった場合に接続を切断するかを指定します。
  • 例:
    config
    Host *
    ServerAliveInterval 60 # 60秒ごとにaliveメッセージ送信
    ServerAliveCountMax 3 # 3回応答がなければ接続切断

    これにより、サーバーからの応答が3回(合計180秒間)なければ接続が切断されます。これらの設定は、クライアント側からの設定であり、サーバー側のTCP keepaliveとは異なります。多くの環境で接続の安定化に役立ちます。

  • ConnectionTimeout: サーバーへの接続(TCP接続の確立)が、指定した秒数以内に完了しなかった場合にタイムアウトとして接続を中止します。ネットワークが不安定な場合などに、無駄に接続確立を待ち続けるのを防ぎます。

  • 値: 秒単位の整数。
  • 例:
    config
    Host slow-network-server
    Hostname remote.slow.example.com
    ConnectionTimeout 10 # 接続確立に10秒以上かかったら諦める

  • TCPKeepAlive: TCPレベルのキープアライブを使用するかどうかを指定します。これはOSのTCPスタックによって制御され、SSHクライアントの設定とは少し異なります。通常はデフォルトで yes になっており、ほとんどの場合変更する必要はありません。ネットワークの特定の状況下でのみ効果を発揮します。

  • 値: yes (デフォルト) または no

多重化接続(Connection Sharing)

ControlMaster, ControlPath, ControlPersist の設定を組み合わせることで、SSH接続の「多重化」を行うことができます。これは、一度確立したSSH接続(マスター接続)を使い回し、同じサーバーへの後続のSSH接続(スレーブ接続)を高速に行うための機能です。特に、同じサーバーに対して複数のSSHセッションを開いたり、SSHトンネルを張ったり、rsyncやGit over SSHなどを使用したりする場合に、接続確立のオーバーヘッド(認証など)を大幅に削減できます。

  • ControlMaster: 多重化を有効にするかどうかを指定します。
    • yes: この接続をマスター接続として確立し、後続のスレーブ接続を受け付けます。
    • no: 多重化を使用しません (デフォルト)。
    • auto: マスター接続が存在しない場合はマスター接続を確立し、存在する場合はスレーブ接続として参加します。
  • ControlPath: マスター接続の制御ソケットファイルを作成するパスを指定します。このパスは、すべてのスレーブ接続からアクセス可能である必要があります。一時ファイルとして /tmp/ssh_mux_%h_%p_%r のような形式で指定することが多いです。%h, %p, %r はそれぞれホスト名、ポート番号、ユーザー名に展開されるエスケープシーケンスです。
  • ControlPersist: ControlMaster yes または auto と組み合わせて使用します。この設定が有効な場合、マスター接続は最初のクライアント接続が終了しても、バックグラウンドで指定された秒数だけソケットファイルを保持し続けます。これにより、後続のスレーブ接続がマスター接続を再利用できるようになります。指定された秒数が経過するか、ソケットファイルが手動で削除されるか、あるいはマスター接続がエラー終了すると、ソケットファイルはクリーンアップされます。
    • 値は秒数(例: 600 で10分)、または yes/no (yes は無期限、クライアントが全て切断してもソケットは残る) です。
  • 例:
    config
    Host *
    ControlMaster auto
    ControlPath /tmp/ssh_mux_%h_%p_%r
    ControlPersist 600 # 最後の接続が切れてから10分間マスター接続を保持

    この設定を Host * ブロックに追加しておくと、すべてのSSH接続に対して多重化が有効になります。最初の接続(例: ssh myserver)は認証を伴う通常の接続ですが、バックグラウンドでマスター接続のソケットファイルが作成されます。同じ myserver に対して別のターミナルから ssh myserver を実行すると、認証なしで瞬時に接続が確立されます。さらに、rsync -e ssh ... myserver:/path/git clone myserver:/repo.git といったコマンドも、既存のマスター接続を再利用して高速に実行されます。多重化を有効にするには、クライアントだけでなくサーバー側も多重化接続に対応している必要がありますが、OpenSSHサーバーであれば通常対応しています。

踏み台サーバー経由の接続(ProxyJump / ProxyCommand)

インターネットから直接アクセスできないプライベートネットワーク内のサーバーに接続したい場合、一度インターネットからアクセス可能な踏み台サーバー(ジャンプホスト)に接続し、そこを経由して目的のサーバーに接続するというシナリオがよくあります。

この「踏み台サーバー経由」の接続を .ssh/config で簡単に設定できるのが ProxyJump ディレクティブ(OpenSSH 7.3 以降)または ProxyCommand ディレクティブ(より古いバージョンでも利用可能)です。

ProxyJump (推奨)

ProxyJump は、踏み台サーバーを指定する最も簡単な方法です。複数の踏み台をチェーンすることも可能です。

  • 説明: 接続する前に経由する踏み台ホストを指定します。
  • 値: 踏み台ホストのエイリアス(.ssh/config で定義済みのもの)または [user@]host[:port] の形式で指定します。複数の踏み台を経由する場合は、カンマ区切りで指定します。
  • 例:
    踏み台サーバー jump-host (ユーザー jumpuser) を経由して、プライベートIPを持つサーバー internal-server (ユーザー appuser) に接続する場合。

    “`config

    ~/.ssh/config

    踏み台サーバーの設定

    Host jump-host
    Hostname your.jump.server.com
    User jumpuser
    # IdentityFile ~/.ssh/id_rsa_jump # 踏み台サーバーへの認証鍵

    内部サーバーの設定(踏み台経由)

    Host internal-server
    Hostname 192.168.10.100 # 内部IPアドレス
    User appuser
    ProxyJump jump-host # <– jump-host を経由する
    # IdentityFile ~/.ssh/id_rsa_internal # 内部サーバーへの認証鍵
    “`

    この設定で ssh internal-server と実行すると、まず ssh [email protected] に接続し、その接続を利用して ssh [email protected] に接続します。非常に直感的で分かりやすい設定です。

    複数の踏み台を経由する場合:
    “`config

    ~/.ssh/config

    Host jump1
    Hostname jump1.example.com
    User user1

    Host jump2
    Hostname jump2.example.com
    User user2
    ProxyJump jump1 # jump1 を経由して jump2 へ

    Host final-server
    Hostname 192.168.20.50
    User finaluser
    ProxyJump jump1,jump2 # jump1 -> jump2 -> final-server へ
    ``ssh final-server` で jump1 -> jump2 -> final-server と接続が確立されます。

ProxyCommand (互換性重視)

ProxyCommand は、SSH接続の前に実行するコマンドを指定します。このコマンドの標準入出力が、リモートサーバーへのSSH接続とパイプされます。踏み台サーバー経由の接続では、nc (netcat) や socat といったツールと組み合わせて、踏み台サーバー上で目的ホストへのTCP接続を確立させることが多いです。

  • 説明: リモートホストへの接続を確立するために実行するコマンドを指定します。
  • 値: 実行するコマンド文字列。エスケープシーケンス (%h, %p, %r など) が使用できます。
  • 例:
    ProxyJump の例と同じシナリオを ProxyCommand で実現する場合。

    “`config

    ~/.ssh/config

    内部サーバーの設定(踏み台経由)

    Host internal-server-via-proxycommand
    Hostname 192.168.10.100
    User appuser
    # 踏み台サーバー [email protected] 経由で
    # 目的ホスト internal-server-via-proxycommand (Hostname で指定したIP) の
    # Port 22 (%p) に接続するためのコマンド
    ProxyCommand ssh [email protected] nc %h %p
    # IdentityFile ~/.ssh/id_rsa_internal # 内部サーバーへの認証鍵
    “`

    この設定で ssh internal-server-via-proxycommand と実行すると、まず ssh [email protected] コマンドが実行され、その標準入出力を通じて、踏み台サーバー上で nc 192.168.10.100 22 が実行されます。これにより、ローカルSSHクライアントは踏み台を経由して目的のサーバーと通信できるようになります。

    ProxyJump は内部的に ProxyCommand を使用しており、通常は ProxyJump の方がシンプルで推奨されます。しかし、古いSSHクライアント/サーバーとの互換性が必要な場合や、より複雑なトンネル設定を行いたい場合は ProxyCommand を使用することになります。

SSHポートフォワーディング(トンネル)

SSHポートフォワーディングは、SSH接続を利用して、あるポートへの通信を別のポートに転送する機能です。これは、ファイアウォールによって直接アクセスできない内部のサービスにアクセスしたり、暗号化されていない通信を安全なSSH接続でカプセル化したりするのに非常に役立ちます。「SSHトンネル」とも呼ばれます。

.ssh/config には、これらのポートフォワーディング設定を永続的に定義するためのディレクティブが用意されています。

SSHポートフォワーディングには主に3つの種類があります。

1. ローカルフォワーディング (LocalForward)

ローカルマシンの指定したポートへのアクセスを、SSH接続を経由してリモートサーバーから別のホスト(通常はリモートサーバー自身またはそのサーバーからアクセス可能な内部のホスト)のポートに転送します。

  • 書式: LocalForward <ローカルポート> <転送先ホスト>:<転送先ポート>
  • 説明: ローカルマシンの <ローカルポート> に来た接続を、リモートサーバー経由で <転送先ホスト><転送先ポート> へ転送します。<転送先ホスト> がリモートサーバー自身の場合は localhost または 127.0.0.1 と指定します。
  • 活用例: プライベートネットワーク内のWebサーバー (192.168.1.100:80) に、SSH接続できる踏み台サーバー (remote-host) 経由でローカルからアクセスしたい場合。

    “`config

    ~/.ssh/config

    Host remote-host
    Hostname remote.example.com
    User myuser
    # ローカルのポート 8080 へのアクセスを、
    # remote-host 経由で 192.168.1.100 の 80番ポートに転送
    LocalForward 8080 192.168.1.100:80
    ``
    設定後、
    ssh remote-hostを実行してSSH接続を確立します。接続が成功したら、ローカルマシンのブラウザでhttp://localhost:8080にアクセスすると、SSHトンネルを通って192.168.1.100:80` のWebサーバーに接続できます。SSH接続を維持している間だけトンネルは有効です。

    ローカルポートを 0 に指定すると、空いているポートが自動的に割り当てられます。

2. リモートフォワーディング (RemoteForward)

リモートサーバーの指定したポートへのアクセスを、SSH接続を経由してローカルマシンの別のホスト(通常はローカルマシン自身またはローカルマシンからアクセス可能なホスト)のポートに転送します。

  • 書式: RemoteForward <リモートポート> <転送先ホスト>:<転送先ポート>
  • 説明: リモートサーバーの <リモートポート> に来た接続を、SSH接続を経由してローカルマシンの <転送先ホスト><転送先ポート> へ転送します。<転送先ホスト> がローカルマシン自身の場合は localhost または 127.0.0.1 と指定します。
  • 活用例: プライベートネットワーク内の開発マシン (localhost:3000) で動いているWebアプリケーションを、外部からアクセス可能なリモートサーバー (remote-host) 経由で公開したい場合。

    “`config

    ~/.ssh/config

    Host remote-host
    Hostname remote.example.com
    User myuser
    # remote-host のポート 8888 へのアクセスを、
    # ローカルマシン経由でローカルの 3000番ポートに転送
    RemoteForward 8888 localhost:3000
    ``
    設定後、
    ssh remote-hostを実行してSSH接続を確立します。接続が成功したら、インターネット上の誰かがremote.example.com:8888にアクセスすると、その通信はSSHトンネルを通ってローカルマシンのlocalhost:3000` へ転送されます。SSH接続を維持している間だけトンネルは有効です。

    リモートサーバー側でこの機能を利用するには、sshd_config で GatewayPorts yes が設定されている必要がある場合があります。これは、リモートフォワーディングされたポートをリモートサーバーの localhost 以外のインターフェースでもリッスンさせるためです。

3. ダイナミックフォワーディング (DynamicForward)

ローカルマシンの指定したポートをSOCKSプロキシとして機能させ、そのポートへの接続をSSH接続を経由してリモートサーバーから任意の宛先へ転送します。これは、特定のサーバーではなく、様々な宛先へのアクセスをSSHトンネル経由で行いたい場合に便利です。

  • 書式: DynamicForward <ローカルポート>
  • 説明: ローカルマシンの <ローカルポート> をSOCKSプロキシとして確立します。このプロキシを使用するアプリケーションは、プロキシへの接続要求をリモートサーバーに送り、リモートサーバーがその要求に基づいて実際の宛先への接続を確立します。
  • 活用例: 自宅ネットワーク内のマシン (remote-host) をSOCKSプロキシとして利用し、外出先からインターネットにアクセスする際に安全性を確保したり、自宅ネットワークからしかアクセスできないリソースにアクセスしたりしたい場合。

    “`config

    ~/.ssh/config

    Host home-proxy
    Hostname my.home.server.com
    User myuser
    # ローカルのポート 1080 を SOCKS プロキシとして設定
    DynamicForward 1080
    ``
    設定後、
    ssh home-proxyを実行してSSH接続を確立します。接続が成功したら、ローカルマシンのブラウザや他のアプリケーションのプロキシ設定で、SOCKSプロキシとしてlocalhost:1080を指定します。これにより、そのアプリケーションからの通信は全てSSHトンネルを通ってmy.home.server.com` からインターネットへ出ていくようになります。

    DynamicForward はSOCKSプロトコルを使用します。バージョン4と5の両方に対応しています。

これらのポートフォワーディング設定を .ssh/config に記述しておくと、ssh <ホスト名> コマンド一つで、接続と同時にトンネルの確立が自動的に行われるようになります。セッションを切断するとトンネルも閉じます。バックグラウンドでトンネルだけを維持したい場合は、SSHコマンドに -N オプション(リモートコマンドを実行しない)と -f オプション(バックグラウンド実行)を組み合わせて使用します。

セキュリティに関する設定項目

.ssh/config には、SSH接続のセキュリティを強化するための様々な設定項目があります。適切な設定を行うことで、より安全にSSHを利用できます。

ローカルコマンド実行許可 (PermitLocalCommand)

  • 説明: LocalCommand ディレクティブで指定されたコマンドをローカルマシン上で実行することを許可するかどうかを制御します。LocalCommand はSSH接続が確立された直前または直後に実行されるコマンドを指定するディレクティブです。デフォルトは no です。
  • 値: yes または no
  • 注意: yes に設定すると、SSH設定ファイルから任意のコマンドを実行できるようになるため、セキュリティリスクが発生する可能性があります。信頼できる設定ファイル以外では no のままにしておくべきです。
  • 例:
    config
    Host my-server-with-alert
    Hostname server.example.com
    PermitLocalCommand yes
    # 接続成功後、ローカルで通知コマンドを実行
    LocalCommand growlnotify -t "SSH" -m "Connected to %h"

エージェントフォワーディング (ForwardAgent)

  • 説明: ローカルの ssh-agent の機能を、リモートサーバーに転送するかどうかを制御します。yes に設定すると、リモートサーバー上で実行されたSSHクライアントは、ローカルの ssh-agent を使用して認証を行うことができるようになります。これは、踏み台サーバーを経由してさらに奥のサーバーに接続する際に、目的のサーバーに秘密鍵を置くことなく認証できるため非常に便利です。
  • 値: yes または no (デフォルト)。
  • 例:
    “`config
    Host jump-server
    Hostname jump.example.com
    User jumpuser
    ForwardAgent yes # jump-server に agent を転送

    Host internal-server
    Hostname 192.168.10.100
    User appuser
    ProxyJump jump-server # jump-server 経由で接続
    # IdentityFile はローカルの鍵ファイルでOK
    # internal-server へは jump-server が agent 経由で認証を行う
    ``
    * **注意:**
    ForwardAgent yesは非常に便利ですが、セキュリティリスクも伴います。もし踏み台サーバー (jump-server) が不正に操作された場合、そのサーバーのrootユーザーは転送されたあなたのssh-agentのソケットにアクセスし、あなたの代わりに、あなたがエージェントに登録しているすべての鍵を使って、あなたがアクセス権限を持つ任意のサーバーに接続できてしまう可能性があります。信頼できない、または管理体制が不確かなサーバーに対してはForwardAgent yesを使用しないようにしましょう。代わりにProxyJump` を使用し、目的のサーバーへの認証には別途鍵を用意するか、目的のサーバーに直接公開鍵を配置することを検討してください。

エージェントへの鍵自動追加 (AddKeysToAgent)

  • 説明: IdentityFile で指定された秘密鍵を、その秘密鍵を初めて使用する際に自動的に ssh-agent に追加するかどうかを制御します。
  • 値: yes (永久に追加), no (追加しない), ask (追加するか毎回尋ねる), confirm (鍵を使用するたびに確認)。数値(秒数)を指定すると、その秒数だけエージェントに鍵が保持されます。
  • 例:
    config
    Host private-repo
    Hostname git.internal.example.com
    User gituser
    IdentityFile ~/.ssh/keys/git_repo_key
    AddKeysToAgent yes # この鍵を初めて使った時にagentに追加

暗号アルゴリズムの制御

SSHは接続時に、クライアントとサーバーが互いにサポートする暗号アルゴリズムを交渉して使用します。.ssh/config では、クライアント側で使用するアルゴリズムを明示的に指定・制限することで、セキュリティや互換性を制御できます。

  • HostKeyAlgorithms: サーバーが提示するホストキーのアルゴリズムのうち、クライアントが受け入れるものを指定します。サーバー証明書の検証に使用されます。古い・強度が低いアルゴリズムを無効化したい場合に指定します。
  • KexAlgorithms: 鍵交換に使用するアルゴリズムを指定します。セッション鍵の生成に使用されます。
  • Ciphers: 通信データの暗号化に使用するアルゴリズムを指定します。AES-GCMなどが推奨されます。
  • MACs: メッセージ認証コード(MAC)アルゴリズムを指定します。通信データの改ざん検出に使用されます。
  • 値: カンマ区切りのアルゴリズムリスト。- をプレフィックスに付けると、デフォルトリストからそのアルゴリズムを除外します。+ をプレフィックスに付けると、デフォルトリストに追加します。
  • 例:
    config
    Host secure-server
    Hostname sensitive.example.com
    # 強度の高いホストキーアルゴリズムのみを許可
    HostKeyAlgorithms ssh-ed25519,ssh-rsa,rsa-sha2-512,rsa-sha2-256
    # 強度の高い鍵交換アルゴリズムのみを許可
    KexAlgorithms [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
    # 強度の高い暗号アルゴリズムのみを許可
    Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
    # 強度の高いMACアルゴリズムのみを許可
    MACs [email protected],hmac-sha2-256,hmac-sha2-512

    これらの設定は、SSHのバージョンやOSによってサポートされるアルゴリズムが異なります。man ssh_config で利用可能なアルゴリズムを確認できます。これらの設定を変更する際は、接続先サーバーがサポートしているアルゴリズムとの互換性に注意が必要です。無効なアルゴリズムを指定したり、クライアント・サーバー間で共通のアルゴリズムが見つからなかったりすると、接続できなくなります。通常はデフォルト設定で問題ありませんが、特定のセキュリティ要件がある場合や、古い/新しいサーバーとの接続で問題が発生した場合に調整します。

高度な活用例

.ssh/config を使うと、さらに様々な高度なSSHの機能を簡単に利用できます。

特定のコマンドだけを実行する (RemoteCommand)

  • 説明: SSH接続を確立した後、インタラクティブシェルを提供する代わりに、リモートサーバー上で指定したコマンドのみを実行します。
  • 値: 実行するコマンド文字列。
  • 活用例: リモートサーバーで特定の監視コマンドやログ確認コマンドだけを実行したいが、フルシェルへのアクセスは制限したい場合。

    “`config

    ~/.ssh/config

    Host monitor-log
    Hostname logs.example.com
    User logreader
    RemoteCommand tail -f /var/log/app.log
    RequestTTY yes # コマンド実行のためにTTYを要求する
    PermitLocalCommand no #念のためローカルコマンドは無効に
    ``ssh monitor-logと実行すると、認証後すぐにリモートサーバーでtail -f /var/log/app.logが実行され、ログの出力が表示されます。コマンドが終了するとSSH接続も閉じます。セキュリティのために、この接続で使用するユーザー (logreader`) には、このコマンド実行に必要な最小限の権限のみを与えるべきです。

X11フォワーディング (ForwardX11, ForwardX11Trusted)

  • 説明: リモートサーバーで実行されるGUIアプリケーションの表示を、SSH接続を経由してローカルマシンで行うための設定です。
  • ForwardX11: X11フォワーディングを有効にします。セキュリティ上の制限付きでフォワーディングが行われます。
  • ForwardX11Trusted: 制限のない、信頼されたX11フォワーディングを有効にします。セキュリティリスクが増加します(リモートアプリケーションがローカルのXサーバーを完全に制御できる)。通常は ForwardX11 yes を使用し、必要に応じて ForwardX11Trusted yes を検討します。
  • 値: yes または no
  • 活用例: リモートサーバー上で動作するGUIツール(例: データベース管理ツール、IDEなど)をローカルのデスクトップ環境で使いたい場合。

    “`config

    ~/.ssh/config

    Host gui-server
    Hostname gui.example.com
    User guiuser
    ForwardX11 yes # X11フォワーディングを有効に
    ``
    設定後、
    ssh gui-serverと実行し、リモートサーバー上でGUIアプリケーション(例:xclock`)を実行すると、そのウィンドウがローカルマシンの画面に表示されます。ローカルマシンにXサーバー(Linuxデスクトップ環境には通常含まれる、Windows/macOSでは別途インストールが必要な場合がある)が起動している必要があります。

Git や rsync との連携

Gitやrsyncといったツールは、リモートホストへのアクセスにSSHを使用できます。.ssh/config に設定しておけば、これらのツールもその設定を自動的に利用します。

  • Git: リモートリポジトリのURLを ssh://user@hostname:port/path/to/repo.git の形式で指定する場合、hostname.ssh/config で定義したエイリアスを使用できます。

    “`bash

    .ssh/config で以下の設定がある場合

    Host gitlab.internal
    Hostname 192.168.1.200
    User git
    IdentityFile ~/.ssh/keys/gitlab_key
    Port 2222

    git clone コマンドは以下のようになる

    git clone ssh://gitlab.internal/myproject/myrepo.git
    ``
    Gitは内部で
    ssh [email protected] -p 2222 myproject/myrepo.gitのようなコマンドを実行するため、.ssh/config` の設定がそのまま適用されます。

  • rsync: rsyncは -e オプションでリモートシェルを指定できますが、デフォルトではSSHを使用します。.ssh/config に設定したエイリアスをそのまま使用できます。

    “`bash

    .ssh/config で以下の設定がある場合

    Host backupserver
    Hostname backup.example.com
    User backupuser
    IdentityFile ~/.ssh/keys/backup_key
    Port 2233

    rsync コマンドは以下のようになる

    rsync -avz /local/path backupserver:/remote/backup/path/
    ``
    rsyncは内部で
    ssh -p 2233 -i ~/.ssh/keys/backup_key [email protected] ‘rsync –server …’のようなコマンドを実行するため、.ssh/config` の設定が利用されます。

このように、.ssh/config はSSHクライアントだけでなく、SSHを内部的に利用する様々なツールからも活用できます。

特定のネットワーク環境向けの設定

ネットワーク環境によっては、MTU(Maximum Transmission Unit)の問題や、非常に遅延が大きい・不安定な回線でSSH接続が不安定になることがあります。このような場合も、.ssh/config で設定を調整できます。

  • IPQoS: QoS (Quality of Service) の設定を指定します。SSHトラフィックに優先度を付けたい場合などに利用できます。throughput (スループット重視), lowdelay (遅延重視), interactive (インタラクティブシェル向け), bulk (大量データ転送向け) などのキーワード、またはDSCP値やIPTOS値で指定します。
  • TCPNoDelay: TCP_NODELAY ソケットオプションを有効にするかどうかを指定します。有効にすると、小さなパケットでもすぐに送信されるようになり、インタラクティブな操作の応答性が向上する可能性がありますが、ネットワークの負荷は増加します。通常はデフォルトの yes で問題ありません。
  • Compression: 接続時に圧縮を使用するかどうかを指定します。回線速度が遅い場合にスループットが向上する可能性がありますが、CPU負荷は増加します。バイナリデータなど、既に圧縮されているデータを転送する場合は効果がありません。
  • 例:
    config
    Host hq-server-over-vpn
    Hostname 10.0.0.10
    User myuser
    Compression yes # 遅い回線なら圧縮を試す
    IPQoS lowdelay # 遅延を減らしたい

    MTUの問題など、より低レベルなTCP/IP設定が必要な場合は、OSレベルでの設定が必要になることもあります。

.ssh/config のトラブルシューティング

.ssh/config ファイルは強力ですが、設定ミスによって接続できなくなることもあります。ここでは、一般的なトラブルシューティングの方法を紹介します。

パーミッションの問題

前述の通り、.ssh ディレクトリやその中のファイルのパーミッションは非常に重要です。SSHクライアントは、パーミッションが緩すぎる(他のユーザーが読み書きできるなど)と判断した場合、設定ファイルや秘密鍵ファイルを無視することがあります。

  • .ssh ディレクトリ: chmod 700 ~/.ssh
  • ~/.ssh/config: chmod 600 ~/.ssh/config
  • 秘密鍵ファイル (~/.ssh/id_rsa など): chmod 600 ~/.ssh/id_rsa
  • 公開鍵ファイル (~/.ssh/id_rsa.pub など): chmod 600 ~/.ssh/id_rsa.pub (または 644 でも可)
  • ~/.ssh/authorized_keys (サーバー側): chmod 600 ~/.ssh/authorized_keys
  • ホームディレクトリ (サーバー側): 他のユーザーからの書き込み権限がないこと (drwx------ または drwxr-xr-x など、グループや他人に書き込み権限 W がないこと)

パーミッションを確認し、必要であれば修正してください。SSH接続時に Bad permissions のようなエラーが出る場合は、これが原因である可能性が高いです。

設定項目のtypo

.ssh/config ファイル内の設定項目のキーワードや値にスペルミスがあると、その設定が無視されたり、エラーになったりします。

  • キーワード (Hostname, User, IdentityFile など) のスペルを確認します。
  • 値(パス、ポート番号、ユーザー名など)に間違いがないか確認します。特にパスは絶対パスまたはチルダ ~ を使った相対パスで正確に指定します。

詳細なデバッグ出力 (-v, -vv, -vvv オプション)

SSHクライアントには、接続プロセスに関する詳細な情報を出力するための -v オプションがあります。これはトラブルシューティングの最も強力なツールです。

  • ssh -v <ホスト名>: 少し詳細な情報を出力します。どの設定ファイルを読み込んでいるか、どの鍵を試行しているかなどが分かります。
  • ssh -vv <ホスト名>: より詳細な情報を出力します。認証プロセスの詳細や、通信の確立に関する情報が含まれます。
  • ssh -vvv <ホスト名>: 最大の詳細度で情報を出力します。暗号化や認証の各ステップ、パケット交換に関する情報などが含まれます。

接続できない場合に ssh -vvv <ホスト名> を実行し、出力されるログを注意深く読むことで、何が問題なのか(例: 設定ファイルが見つからない、パーミッションエラー、鍵が見つからない、サーバーが認証を拒否した、ホストキーが一致しないなど)を特定できます。

設定の競合

.ssh/config ファイル内で、同じ Host ブロックに対して同じ設定項目が複数回記述されている場合、通常は最後に記述された設定が優先されます。また、Host * のような汎用的な設定と、特定の Host 設定が競合する場合、特定の Host 設定の方が優先されます。

意図した設定が適用されていない場合は、.ssh/config ファイルを上から順に確認し、設定がどのように評価されているかを追跡してみてください。ssh -v 出力でも、どの設定が適用されているかのヒントが得られることがあります。

まとめ

.ssh/config ファイルは、SSHを日常的に利用する上で非常に強力なツールです。本記事では、その基本的な書式から始まり、接続先情報 (Hostname, User, Port)、認証方法 (IdentityFile, IdentitiesOnly)、接続の安定化 (ServerAliveInterval, ConnectionTimeout)、効率化 (ControlMaster による多重化)、複雑な接続シナリオ (ProxyJump / ProxyCommand による踏み台経由)、ポートフォワーディング (LocalForward, RemoteForward, DynamicForward)、そしてセキュリティに関する設定まで、幅広く解説しました。

これらの設定を .ssh/config に集約することで、コマンドラインでのタイプミスを減らし、複雑な設定を抽象化し、日々のSSHワークフローを大幅に効率化・自動化できます。また、公開鍵認証や適切なセキュリティ設定を定義しておくことで、より安全なリモートアクセス環境を構築できます。

ぜひ、あなたのSSH利用環境に合わせて .ssh/config ファイルをカスタマイズし、その恩恵を最大限に活用してください。最初は基本的な設定から始め、徐々に必要な応用設定を取り入れていくのが良いでしょう。man ssh_config コマンドで、さらに多くの設定項目とその詳細を確認することもできます。

快適で安全なSSHライフのために、.ssh/config をマスターしましょう!


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール