はい、承知いたしました。.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
に接続する場合、StrictHostKeyChecking
は yes
になりますが、それ以外のすべてのホストに接続する場合は 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
と明示的に指定するのが最も安全です。off
はno
と同じです。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で最も推奨される認証方法は、パスワード認証ではなく、公開鍵認証です。公開鍵認証では、クライアント側に秘密鍵、サーバー側に公開鍵を配置します。接続時にクライアントが秘密鍵を使って認証情報を生成し、サーバーが対応する公開鍵で検証します。
公開鍵認証の仕組み
- クライアントは、接続要求とともに使用する公開鍵の情報をサーバーに送る。
- サーバーは、受け取った公開鍵が
~/.ssh/authorized_keys
ファイルに登録されているか確認する。登録されていれば、ランダムなデータ(チャレンジ)を生成し、その公開鍵で暗号化してクライアントに送り返す。 - クライアントは、送られてきた暗号化されたチャレンジを、手元の対応する秘密鍵で復号する。
- クライアントは、復号したチャレンジにセッションIDなどを付加して署名し、その署名されたデータをサーバーに送り返す。
- サーバーは、登録されている公開鍵を使ってクライアントから送られてきた署名を検証する。検証に成功すれば、クライアントが正当な秘密鍵を持っていると判断し、認証成功となる。
この仕組みにより、秘密鍵がサーバーに送信されることはなく、安全に認証が行えます。
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/config
の IdentityFile
で明示的に指定することが重要になります。
“`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クライアントに秘密鍵を提供することで、パスフレーズの入力を一度だけにすることができます。
ssh-agent
を起動します。通常、ログイン時に自動的に起動されるか、手動で起動します。ssh-add
コマンドで、パスフレーズを入力して秘密鍵をssh-agent
に登録します。
bash
ssh-add ~/.ssh/id_rsa
パスフレーズの入力を求められるのはこの一度だけです。- 以降、SSHクライアントは認証が必要な際に
ssh-agent
と通信し、秘密鍵を使用します。パスフレーズの再入力は不要です。
ssh-agent
と .ssh/config
の連携は特に意識する必要はありません。IdentityFile
で指定された鍵が ssh-agent
に登録されていれば、自動的にエージェント経由で認証が試行されます。IdentitiesOnly yes
と ssh-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 user1Host 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 2222git clone コマンドは以下のようになる
git clone ssh://gitlab.internal/myproject/myrepo.git
``
ssh [email protected] -p 2222 myproject/myrepo.git
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 2233rsync コマンドは以下のようになる
rsync -avz /local/path backupserver:/remote/backup/path/
``
ssh -p 2233 -i ~/.ssh/keys/backup_key [email protected] ‘rsync –server …’
rsyncは内部でのようなコマンドを実行するため、
.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
をマスターしましょう!