はい、承知いたしました。SSH configファイルの書き方について、基本から応用、トラブルシューティングまで、設定例を豊富に含めた詳細な解説記事を作成します。約5000語(日本語の文字数で換算すると、それ以上のボリュームになる見込みです)の記述を目指します。
以下に記事内容を直接表示します。
SSH config の書き方入門【設定例で徹底解説】
日々の開発や運用作業で、リモートサーバーへの接続は欠かせません。そんなときに活躍するのがSSHです。しかし、毎回 ssh user@hostname -p port -i /path/to/key のように長いコマンドを入力するのは面倒ですし、タイプミスも起こりがちです。
ここで登場するのが、SSH config ファイルです。このファイルに接続情報を一度記述しておけば、次回からは短いエイリアス(別名)を使って簡単に接続できるようになります。さらに、単に接続情報を省略できるだけでなく、接続の高速化、セキュリティ強化、ポートフォワーディングなど、SSHの持つ様々な機能を最大限に引き出すための強力なツールでもあります。
この記事では、SSH config の基本的な書き方から、主要なキーワードを使った実践的な設定例、そして応用的な使い方やトラブルシューティングまで、SSH config を徹底的に解説します。この記事を読めば、あなたのSSHライフが劇的に快適かつ安全になるはずです。
1. はじめに:なぜSSH Configが必要なのか?
SSH (Secure Shell) は、ネットワーク経由でリモートのコンピューターと安全に通信するためのプロトコルです。主にコマンドラインでのリモート操作や、ファイルの安全な送受信(SCPやSFTP)に利用されます。
SSH接続を行う際には、通常、以下のような情報が必要になります。
- 接続先のホスト名またはIPアドレス
- 接続に使用するユーザー名
- SSHサーバーが待機しているポート番号(デフォルトは22)
- 認証に使用する秘密鍵ファイル(公開鍵認証の場合)
- その他、接続に関するオプション(例: 圧縮、エージェント転送など)
これらの情報を毎回コマンドラインで指定するのは手間がかかります。例えば、user01 というユーザーで server.example.com のポート 2222 へ、/path/to/private_key という秘密鍵を使って接続する場合、コマンドは以下のようになります。
bash
ssh -p 2222 -i /path/to/private_key [email protected]
サーバーが増えたり、異なる設定のサーバーに接続したりする場合、このコマンドはさらに複雑になることもあります。
SSH config ファイル (~/.ssh/config) は、これらの接続に関する情報をまとめて記述しておくための設定ファイルです。このファイルに接続先のエイリアス(別名)と、それに対応する接続情報を定義しておけば、エイリアスを指定するだけでSSH接続が可能になります。
例えば、上記の接続設定をconfigファイルに記述しておけば、以下のような簡単なコマンドで接続できるようになります。
bash
ssh myserver
このように、SSH config は単なるコマンド入力の省略にとどまらず、以下のようなメリットをもたらします。
- コマンド入力の省略と簡略化: 長いオプションを毎回入力する必要がなくなります。
- タイプミスの削減: 設定ファイルに記述しておけば、入力間違いによる接続失敗を防げます。
- 設定の一元管理: 複数のサーバーへの接続設定を1つのファイルで管理できます。
- SSH機能の活用: ポートフォワーディングや多重接続など、SSHの高度な機能を設定ファイルで簡単に管理・利用できます。
- セキュリティ向上: 秘密鍵のパスやポート番号をコマンド履歴に残さずに済みます。
SSH config ファイルは、ユーザーのホームディレクトリ直下の .ssh ディレクトリ内に config という名前で作成します。
bash
~/.ssh/config
もし .ssh ディレクトリや config ファイルが存在しない場合は、手動で作成する必要があります。
bash
mkdir -p ~/.ssh
touch ~/.ssh/config
また、セキュリティのため、~/.ssh/config ファイルのパーミッションは自分自身のみが読み書きできるように設定することが推奨されます。
bash
chmod 600 ~/.ssh/config
これで、SSH config を記述する準備が整いました。次に、configファイルの基本的な書き方を見ていきましょう。
2. SSH Config の基本
SSH config ファイルは、プレーンテキスト形式で記述します。基本的な構造は非常にシンプルで、接続先の「ホスト」ごとに設定を記述していきます。
ファイルの基本構造
SSH config ファイルは、一つ以上の「セクション」から構成されます。各セクションは Host キーワードで始まり、その後に接続先のエイリアスを指定します。
“`
これはコメントです
Host <エイリアス名>
<キーワード> <値>
<キーワード> <値>
…
Host <別のエイリアス名>
<キーワード> <値>
…
Host *
<キーワード> <値>
…
“`
#: 行頭に#を置くと、その行はコメントとして扱われます。設定の内容や目的をメモしておくのに便利です。Host <エイリアス名>: これは必須のキーワードで、新しいセクションの開始を示します。ここで指定する<エイリアス名>が、SSHコマンドで接続する際に指定する名前になります(例:ssh <エイリアス名>)。エイリアス名には、任意の文字列を使用できます。ワイルドカード (*,?) を使うことも可能です。<キーワード> <値>:Host行に続いて、そのエイリアスに対する各種設定を記述します。各設定は「キーワード」とそれに続く「値」から構成され、通常はインデント(空白やタブ)を入れて記述します。インデントは必須ではありませんが、視認性を高めるために強く推奨されます。キーワードと値の間には、1つ以上の空白またはタブを置きます。
最も基本的な設定例
最も頻繁に使用される基本的なキーワードは以下の4つです。
Host: 接続エイリアス (必須)Hostname: 実際の接続先ホスト名またはIPアドレスUser: 接続に使用するユーザー名Port: 接続に使用するポート番号
これらを使った基本的な設定例を見てみましょう。
“`config
開発サーバーへの接続設定
Host devserver
Hostname 192.168.1.100
User developer
Port 22
本番サーバーへの接続設定
Host prodserver
Hostname server.example.com
User prodadmin
Port 2222
別の開発サーバー (IP指定、ユーザー名とポートはデフォルト)
Host devserver2
Hostname 192.168.1.101
エイリアスを使わず、Hostnameをそのまま使う場合 (HostとHostnameが同じ)
Host example.com
Hostname example.com
User myuser
Port 22
“`
この設定ファイルを作成・保存した後、それぞれのサーバーには以下のコマンドで接続できます。
bash
ssh devserver # -> ssh [email protected] -p 22 と同じ
ssh prodserver # -> ssh [email protected] -p 2222 と同じ
ssh devserver2 # -> ssh <現在のローカルユーザー名>@192.168.1.101 -p 22 と同じ
Hostname, User, Port を省略した場合、SSHクライアントは以下のデフォルト値を使用します。
Hostname:Hostで指定したエイリアス名と同じとみなされます。User: 現在のローカルユーザー名と同じとみなされます。Port: 標準のSSHポートである22とみなされます。
例えば、devserver2 の設定では User と Port を省略しているため、ローカルでの実行ユーザーが user01 であれば ssh [email protected] -p 22 と同等になります。
ワイルドカード (*, ?) の使い方
Host ディレクティブでは、ワイルドカードを使って複数のホストに一致する設定を記述できます。
*: 0個以上の任意の文字に一致します。?: 1個の任意の文字に一致します。
ワイルドカードを使った設定は、ファイル内でより具体的に一致する設定よりも先に評価されることに注意が必要です。ただし、同じレベルのHostディレクティブの中では、より具体的な指定(ワイルドカードを含まない指定)が優先され、ワイルドカード指定は最後に評価されます。慣習として、ワイルドカードを使った包括的な設定はファイルの末尾に記述することが多いです。
例:
“`config
すべてのホストに対する共通設定
Host *
ServerAliveInterval 60 # 60秒ごとにキープアライブパケットを送信
ServerAliveCountMax 3 # 3回応答がなければ切断とみなす
TCPKeepAlive yes # OSレベルのTCPキープアライブを有効化
Compression yes # データ圧縮を有効化
特定のドメインに対する設定
Host *.example.com
User exampleuser
IdentityFile ~/.ssh/keys/example.com/id_rsa
特定の命名規則に従うホストに対する設定
Host app-server-?
User appuser
Port 2222
より具体的な設定(ワイルドカードよりも優先される)
Host app-server-1
User adminuser # この設定が app-server-? よりも優先される
Port 22 # この設定が app-server-? よりも優先される
“`
この設定では、ssh app-server-1 と実行した場合、Host app-server-1 セクションの設定が適用され、User は adminuser、Port は 22 になります。一方、ssh app-server-2 と実行した場合、Host app-server-? セクションの設定が適用され、User は appuser、Port は 2222 になります。
そして、どちらの接続の場合でも、最も包括的な Host * の設定(ServerAliveInterval, ServerAliveCountMax, TCPKeepAlive, Compression)が適用されます。
ワイルドカードと具体的な設定を組み合わせることで、共通の設定を持ちつつ、特定のホストに対して例外的な設定を適用するといった柔軟な構成が可能になります。
3. 主要なキーワードと設定例
SSH config には非常に多くのキーワードがありますが、ここでは特によく使われる重要なキーワードとその設定例を詳しく解説します。
3.1. 接続関連の設定
IdentityFile:秘密鍵ファイルの指定
公開鍵認証で接続する場合、使用する秘密鍵ファイルを指定します。デフォルトでは ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 などが自動的に試されますが、それ以外の鍵を使用する場合や、複数の鍵を使い分ける場合に明示的に指定します。
config
Host server_with_custom_key
Hostname 192.168.1.200
User customuser
IdentityFile ~/.ssh/keys/my_custom_key
複数の秘密鍵ファイルを指定することも可能です。SSHクライアントは指定された順に鍵を試していきます。
config
Host server_with_multiple_keys
Hostname 192.168.1.201
User someuser
IdentityFile ~/.ssh/keys/key_for_server201
IdentityFile ~/.ssh/keys/another_key
IdentityFile ~/.ssh/id_rsa # デフォルト鍵も試す
補足: IdentityFile で指定するパスは、ホームディレクトリからの相対パス (~/.ssh/keys/...) または絶対パス (/home/user/.ssh/keys/...) で記述します。
IdentitiesOnly:指定した鍵のみを使用する
yes を指定すると、IdentityFile で明示的に指定された秘密鍵ファイルのみを使用し、デフォルトの鍵(~/.ssh/id_rsa など)や、SSHエージェントに登録されている鍵は試行されなくなります。複数の鍵を持っている場合に、意図しない鍵での認証試行を防ぎたい場合に便利です。
config
Host server_strict_key
Hostname 192.168.1.202
User strictuser
IdentityFile ~/.ssh/keys/strict_server_key
IdentitiesOnly yes # この鍵だけを使う
デフォルトは no です。
PreferredAuthentications:認証方法の優先順位
サーバーが複数の認証方法(公開鍵認証、パスワード認証、GSSAPI認証など)を許可している場合、クライアントが試行する認証方法とその優先順位を指定できます。カンマ区切りで優先度の高い順に記述します。
config
Host server_prefer_pubkey
Hostname 192.168.1.203
User pubkeyuser
PreferredAuthentications publickey,password
この設定では、まず公開鍵認証を試行し、それが失敗した場合にパスワード認証を試行します。セキュリティの観点から、公開鍵認証を最優先にすることが一般的です。
PasswordAuthentication:パスワード認証の許可/不許可
yes または no を指定します。サーバー側でパスワード認証が許可されている場合でも、クライアント側でこれを no に設定することで、誤ってパスワード認証を試行してしまうことを防げます。公開鍵認証のみで接続したい場合に設定すると良いでしょう。
config
Host server_no_password
Hostname 192.168.1.204
User secureuser
IdentityFile ~/.ssh/keys/secure_key
PasswordAuthentication no # パスワード認証は絶対にしない
デフォルトは yes です。
PubkeyAuthentication:公開鍵認証の許可/不許可
yes または no を指定します。公開鍵認証を使わない(使えない)サーバーに接続する場合や、意図的に無効化したい場合に設定します。ほとんどの場合、デフォルトの yes のままで問題ありません。
config
Host server_no_pubkey
Hostname 192.168.1.205
User legacyuser
PasswordAuthentication yes
PubkeyAuthentication no # 公開鍵認証はしない
デフォルトは yes です。
3.2. 接続の維持/最適化
ConnectTimeout:接続タイムアウト
SSHサーバーへのTCP接続確立に待機する最大時間を秒単位で指定します。指定した時間内に接続できない場合、接続試行を中止します。ネットワークが不安定な場合や、存在しないホストへの接続試行時に無駄な待機時間を減らすのに役立ちます。
config
Host *
ConnectTimeout 10 # 接続試行は10秒でタイムアウト
デフォルトはシステムのTCPタイムアウトに依存しますが、通常は数十秒から数分です。短く設定することで、応答のないサーバーへの接続試行を素早く諦めることができます。
ServerAliveInterval と ServerAliveCountMax:キープアライブ設定
これらの設定は、SSHセッションがアイドル状態になったときに、接続が維持されているかを確認するために使用されます。特に、NATやファイアウォールによってアイドル状態のTCP接続が切断されてしまうような環境で有効です。
ServerAliveInterval <秒>: クライアントがサーバーに対して無応答を確認するためのメッセージを送信する間隔を秒単位で指定します。ServerAliveCountMax <回数>:ServerAliveIntervalで指定したメッセージに対して、サーバーから応答がない場合に、接続を切断するまでに再試行する最大回数を指定します。
config
Host *
ServerAliveInterval 60 # 60秒ごとにキープアライブを送信
ServerAliveCountMax 3 # 最大3回無応答なら切断
この設定では、アイドル状態が180秒(60秒 * 3回)続くと、クライアントは接続が切断されたと判断します。これらの設定は、セッションが予期せず切断されるのを防ぐのに役立ちますが、ネットワークトラフィックはわずかに増加します。
補足: これらはSSHプロトコルレベルのキープアライブであり、TCPレベルのキープアライブとは異なります。
TCPKeepAlive:OSレベルのTCPキープアライブ
yes または no を指定します。これを yes に設定すると、SSHクライアントはOSのTCPスタックに対して、接続が維持されているかを確認するためのTCPキープアライブパケットを定期的に送信するように指示します。
config
Host *
TCPKeepAlive yes
デフォルトは yes です。通常はこのままで問題ありません。これは ServerAliveInterval/ServerAliveCountMax とは独立した機能です。どちらを使うかは状況によりますが、多くの場合は両方有効にしておいても問題ありません。
Compression:データ圧縮
yes または no を指定します。これを yes に設定すると、SSHセッションで送受信されるデータが圧縮されます。帯域幅が狭いネットワーク環境では効果がありますが、CPUリソースを消費するため、高速なネットワークでは逆にパフォーマンスが低下する場合もあります。
config
Host slowlink_server
Hostname 10.0.0.1
User user
Compression yes # 低速回線なので圧縮有効
デフォルトは no です。
ControlMaster, ControlPath, ControlPersist:多重接続による高速化
これはSSH接続を劇的に高速化できる非常に便利な設定です。ControlMaster を有効にすると、最初に確立したSSH接続を「マスター」として、以降同じホストへの新しいSSH接続(例: 別のセッションを開く、SCPでファイルを転送するなど)はそのマスター接続を再利用します。これにより、認証プロセスをスキップできるため、2回目以降の接続が非常に高速になります。
ControlMaster yes: このホストへの接続をマスター接続として使用することを許可します。ControlPath <パス>: マスター接続用の通信ソケットファイルを作成するパスを指定します。通常は~/.ssh/controlmasters/%r@%h:%pのような形式で、%r(ユーザー名)、%h(ホスト名)、%p(ポート番号) といった置換文字列を使用します。一意で識別しやすいパスを指定することが重要です。ControlPersist <秒数またはyes>: マスター接続を、最後のクライアントセッションが終了した後も指定した時間だけ維持します。これにより、次に同じホストに接続する際に、マスター接続がまだ生きている場合はすぐに再利用できます。yesまたは0を指定すると、明示的にssh -O exit <エイリアス名>で終了させるまでマスター接続を維持します。時間 (秒) を指定することも可能です(例:300で5分間)。
“`config
多重接続設定の例
Host *
ControlMaster auto # yes/no/auto: 自動でマスター接続を開始
ControlPath ~/.ssh/controlmasters/%r@%h:%p # ソケットファイルのパス
ControlPersist 600 # 最後のセッション終了後も600秒(10分)維持
Host myserver
Hostname server.example.com
User myuser
Port 2222
# 個別設定があればここに記述
“`
この設定例では、初めて ssh myserver と接続したときにマスター接続が確立され、~/.ssh/controlmasters/[email protected]:2222 というソケットファイルが作成されます。同じターミナルや別のターミナルから再度 ssh myserver や scp file myserver:/tmp と実行すると、このソケットファイル経由で既存のマスター接続が再利用されるため、パスワードや秘密鍵の認証なしに瞬時に接続が確立されます。最後のセッションが終了した後も、マスター接続は10分間維持されます。
注意点:
ControlPathで指定するディレクトリは存在している必要があります (mkdir -p ~/.ssh/controlmasters)。- ソケットファイルのパーミッションに注意してください。通常は
ControlPathのディレクトリに適切なパーミッション (700) を設定します。 ControlMasterをyesに設定すると、最初のSSHコマンドはバックグラウンドでマスター接続を維持し続けます。フォアグラウンドでセッションを開きつつマスター接続も確立したい場合は、ControlMaster autoが便利です (sshコマンド自体がマスター接続となり、そのセッションが終了してもControlPersistで指定した時間だけバックグラウンドでマスター接続が維持されます)。ControlMaster autoはOpenSSH 5.6以降で利用可能です。- マスター接続を明示的に終了させるには
ssh -O exit <エイリアス名>を実行します。
3.3. セキュリティ関連の設定
StrictHostKeyChecking:ホスト鍵の検証
SSH接続時に、接続先サーバーのホスト鍵を検証するかどうかを設定します。ホスト鍵は、初めて接続するサーバーの識別に使われ、~/.ssh/known_hosts ファイルに記録されます。次回以降の接続時には、known_hosts に記録されたホスト鍵と、サーバーが提示するホスト鍵が一致するかを確認することで、中間者攻撃(Man-in-the-Middle attack)を防ぎます。
このキーワードの値にはいくつか種類があります。
yes(デフォルト): ホスト鍵がknown_hostsに存在しない場合、接続を拒否します。ホスト鍵が変更されている場合も接続を拒否します。最も安全な設定です。no: ホスト鍵が存在しない場合でも警告なしに接続し、新しいホスト鍵をknown_hostsに追加します。ホスト鍵が変更されていても警告なしに接続します。セキュリティリスクが非常に高いため、絶対に使用しないでください。ask: ホスト鍵がknown_hostsに存在しない場合や変更されている場合に、ユーザーに確認を求めます。確認後に接続を許可するか、新しいホスト鍵を追加するかを決定できます。対話的な使用に適しています。accept-new: ホスト鍵がknown_hostsに存在しない場合は警告なしに接続し、新しいホスト鍵を自動的に追加します。ただし、既存のホスト鍵が変更されている場合は接続を拒否します。一時的な環境や頻繁にサーバーが入れ替わる環境で利便性とセキュリティのバランスを取る場合に検討できますが、リスクはあります。
“`config
Host *
StrictHostKeyChecking yes # デフォルトだが明示的に記述
Host temp_env_*
StrictHostKeyChecking accept-new # 一時環境では新しい鍵を自動で追加
“`
セキュリティの観点からは、yes を使用するのが最も安全です。新しいサーバーに初めて接続する際は、サーバー管理者に正しいホスト鍵のフィンガープリントを確認するなどの対策と併せて使用してください。
UserKnownHostsFile:known_hostsファイルの指定
ホスト鍵を記録する known_hosts ファイルのパスを指定します。デフォルトは ~/.ssh/known_hosts および /etc/ssh/ssh_known_hosts です。用途に応じて複数の known_hosts ファイルを使い分けたい場合に指定します。カンマ区切りで複数のファイルを指定できます。
config
Host specific_group_server
Hostname 192.168.1.210
User groupuser
UserKnownHostsFile ~/.ssh/group_known_hosts
ForwardAgent:SSHエージェント転送
yes または no を指定します。これを yes に設定すると、ローカル環境で起動しているSSHエージェント(認証情報を記憶しておくプログラム)を、接続先のリモートサーバーに転送できます。これにより、リモートサーバーからさらに別のサーバーにSSH接続する際に、ローカルの秘密鍵をリモートサーバーに置くことなく認証できるようになります。
例えば、ローカルPC -> 踏み台サーバー -> 最終接続先サーバー という多段接続の場合、ローカルPCでエージェント起動&鍵登録し、踏み台サーバーへの接続時に ForwardAgent yes と設定しておけば、踏み台サーバーから最終接続先サーバーへの接続時にローカルPCのエージェント経由で認証が完了します。
“`config
Host bastion_server
Hostname 10.0.0.1
User bastionuser
ForwardAgent yes # 踏み台サーバーへエージェント転送
Host final_server
Hostname 192.168.1.220
User finaluser
ProxyJump bastion_server # 踏み台サーバーを経由して接続
# IdentityFile や User はローカルPCから bastion_server へのもの、
# そして bastion_server から final_server へのものがそれぞれ適用される
“`
セキュリティリスク: ForwardAgent yes は便利ですが、セキュリティ上のリスクも伴います。転送されたSSHエージェントは、リモートサーバー上で /tmp 以下に作成されるソケットファイル経由でアクセス可能になります。もしそのリモートサーバーが侵害された場合、攻撃者はそのソケットファイルを利用して、エージェントに登録されている鍵でアクセス可能なすべてのサーバーに、あなたの権限でSSH接続できてしまいます。
このリスクを考慮すると、ForwardAgent yes は必要最低限の場合にのみ使用し、信頼できるサーバー以外には設定しないことが強く推奨されます。また、短時間のみ必要な場合は、セッション終了時に自動的にソケットが削除されるように設定を検討してください(多くの場合、デフォルトでそうなっています)。
PermitLocalCommand:ローカルコマンド実行の許可
yes または no を指定します。LocalCommand キーワードと組み合わせて使用し、SSH接続を確立する直前にローカル環境で任意のコマンドを実行することを許可します。デフォルトは no であり、セキュリティの観点から no のままにしておくことが推奨されます。安易に yes にすると、悪意のある ssh_config ファイルによって意図しないコマンドが実行されるリスクがあります。
“`config
以下の設定はセキュリティリスクがあるため、理解した上で慎重に使用すること
Host risky_server
Hostname risky.example.com
PermitLocalCommand yes
LocalCommand echo “Connecting to %h…” # 接続前にローカルで実行されるコマンド
“`
この設定は、例えば接続先の情報を事前にローカルファイルに記録する、VPN接続を確認する、などの用途で限定的に使用されることがあります。
3.4. ポートフォワードとプロキシ
SSHの強力な機能の一つにポートフォワーディングがあります。これは、SSH接続を経由してローカルポートとリモートポート、またはリモートポートとローカルポートの間で通信を転送する機能です。SSH config を使うことで、これらの設定をエイリアスに関連付けて簡単に利用できます。
LocalForward:ローカルポートフォワード (L 転送)
ローカルマシン上の特定のポートに来た通信を、SSHサーバーを経由して、SSHサーバーから見た指定のホスト・ポートに転送します。
構文: LocalForward <ローカルの待受ポート> <転送先ホスト>:<転送先ポート>
“`config
ローカルの8080ポートへのアクセスを、remote.example.com上のWebサーバー(ポート80)に転送
Host webserver_access
Hostname remote.example.com
User webuser
LocalForward 8080 localhost:80
“`
この設定で ssh webserver_access と接続を確立すると、ローカルマシンで http://localhost:8080 にアクセスした際の通信が、remote.example.com サーバーを経由して、そのサーバーから見た localhost:80(つまり remote.example.com 自身のポート80)に転送されます。
これにより、ファイアウォールの内側にあるサーバーのポートや、外部に公開されていないポートにローカル環境からアクセスできるようになります。
複数のポートフォワードを設定することも可能です。
config
Host multi_forward
Hostname 192.168.1.230
User someuser
LocalForward 8080 localhost:80 # Webサーバー
LocalForward 33060 localhost:3306 # MySQLサーバー
RemoteForward:リモートポートフォワード (R 転送)
SSHサーバー上の特定のポートに来た通信を、SSHクライアントを経由して、SSHクライアントから見た指定のホスト・ポートに転送します。
構文: RemoteForward <リモートの待受ポート> <転送先ホスト>:<転送先ポート>
“`config
remote.example.com上の8000ポートへのアクセスを、ローカルマシンの3000ポートに転送
Host webhook_receiver
Hostname remote.example.com
User deployuser
RemoteForward 8000 localhost:3000 # リモートの8000 -> ローカルの3000
“`
この設定で ssh webhook_receiver と接続を確立すると、remote.example.com サーバー上で localhost:8000 (または remote.example.com が許可する他のインターフェース)にアクセスした際の通信が、ローカルマシンを経由して、ローカルマシンの localhost:3000 に転送されます。
これは、ローカル開発環境で動作しているWebhook受信エンドポイントなどを、インターネット上のサーバー経由で外部に一時的に公開したい場合などに便利です。
RemoteForward で指定するリモートの待受ポートは、デフォルトではSSHサーバー自身が待機しているインターフェース(通常は localhost または 127.0.0.1)にバインドされます。他のホストからアクセスできるようにするには、SSHサーバー側の設定(sshd_config の GatewayPorts yes)が必要な場合があります。
DynamicForward:動的ポートフォワード (D 転送, SOCKSプロキシ)
ローカルマシン上の特定のポートを SOCKS プロキシサーバーとして機能させます。このSOCKSプロキシ経由で接続した通信は、すべてSSHサーバーを経由して転送されます。SSHサーバーが踏み台となり、そのサーバーからアクセス可能な任意のホスト・ポートに接続できるようになります。
構文: DynamicForward <ローカルの待受ポート>
“`config
ローカルの1080ポートをSOCKSプロキシとして設定
Host socks_proxy_server
Hostname internal_server.example.com # 社内サーバーなど
User proxyuser
DynamicForward 1080 # ローカルの1080ポートでSOCKSプロキシを待機
“`
この設定で ssh socks_proxy_server と接続を確立すると、ローカルマシンのポート 1080 でSOCKSプロキシが起動します。ウェブブラウザやアプリケーションのプロキシ設定で SOCKS5ホスト: localhost, ポート: 1080 を指定すると、それ以降の通信はすべて internal_server.example.com を経由して行われます。これにより、社内ネットワークのサーバーや、SSHサーバーからしかアクセスできないリソースにローカル環境から安全にアクセスできるようになります。
3.5. 中継ホスト経由の接続 (Jump Host)
複数のサーバーを経由して目的のサーバーに接続したい場合があります(例: 社内ネットワークのサーバーにアクセスするために、まず踏み台サーバーにSSH接続し、そこから目的のサーバーに接続する)。これを「Jump Host」または「踏み台サーバー」経由の接続と呼びます。SSH config では、ProxyJump または ProxyCommand を使って設定できます。
ProxyJump:SSHクライアント自身が多段接続を処理 (OpenSSH 7.3以降)
OpenSSH 7.3で導入された比較的新しい機能です。SSHクライアントが自動的に中継ホストへのSSH接続を確立し、その接続を経由して目的のホストへのSSH接続を行います。
構文: ProxyJump <中継ホストのエイリアスまたは[user@]host[:port]>
“`config
踏み台サーバーの設定
Host bastion
Hostname bastion.example.com
User myuser
Port 22
最終接続先サーバーの設定(踏み台サーバーを経由)
Host final_server
Hostname final.internal
User internaluser
ProxyJump bastion # bastionエイリアスで定義されたサーバーを経由
“`
この設定で ssh final_server と実行すると、SSHクライアントはまず bastion.example.com に myuser でSSH接続します。その接続が確立された後、その接続内を通して final.internal に internaluser でSSH接続を試みます。ローカルマシンから直接 final.internal にはアクセスできないが、bastion サーバーからはアクセスできる場合に有効です。
ProxyJump は、複数のホストをカンマ区切りで指定することも可能です。
“`config
Host relay1
Hostname relay1.example.com
User user1
Host relay2
Hostname relay2.example.com
User user2
Host final_server_multi_jump
Hostname final.internal
User finaluser
ProxyJump relay1,relay2 # relay1 -> relay2 -> final_server_multi_jump の順に経由
“`
ProxyCommand:任意のコマンドを使った接続 (古い方式だが柔軟)
ProxyJump が導入される以前から使われている方法で、SSH接続を確立する際に任意の外部コマンドを実行し、その標準入出力をSSHサーバーとの通信路として利用します。これにより、SSHプロトコルではない様々な方法で接続を確立することが可能になります。Jump Hostの場合、よく nc (netcat) や ncat コマンドと組み合わせて使用されます。
構文: ProxyCommand <実行するコマンド>
“`config
踏み台サーバーを経由して接続する例 (nc コマンドを使用)
Host final_server_proxy_command
Hostname final.internal
User internaluser
ProxyCommand ssh bastion.example.com -W %h:%p # bastionを経由してfinal.internal:%pに接続
“`
この設定で ssh final_server_proxy_command と実行すると、SSHクライアントは ssh bastion.example.com -W final.internal:22 (デフォルトポートが22の場合) というコマンドをローカルで実行します。ssh -W オプションは、標準入出力を要求されたホスト・ポートへの標準的なTCPフォワードチャネルに接続します。つまり、ローカルのSSHクライアントと bastion.example.com の sshd プロセス間でSSHセッションが確立され、そのセッション内で final.internal:22 へのTCP接続が確立され、そのTCP接続がローカルのSSHクライアントの標準入出力に「転送」されるイメージです。最終的なSSHプロトコル通信はこの転送されたTCP接続上で行われます。
ProxyCommand は ProxyJump よりも柔軟性が高く、SSH以外のプロトコルやカスタムスクリプトを使って接続を確立したい場合に有効ですが、コマンドの記述が少し複雑になります。一般的なJump Hostであれば ProxyJump を使うのが推奨されます。
3.6. その他の便利機能
LogLevel:ログレベル
SSHクライアントの出力するログの詳細度を設定します。接続や認証のデバッグに非常に役立ちます。
QUIET: 最も少ない出力。FATAL: 致命的なエラーのみ。ERROR: エラーのみ。INFO(デフォルト): 一般的な情報メッセージ。VERBOSE: 冗長な出力。デバッグによく使われます。DEBUG,DEBUG1,DEBUG2,DEBUG3: さらに詳細なデバッグ情報。
config
Host debug_server
Hostname debug.example.com
User debuguser
LogLevel VERBOSE # このサーバーへの接続時は詳細なログを出力
コマンドラインオプションの -v, -vv, -vvv はそれぞれ VERBOSE, DEBUG, DEBUG (または DEBUG1, DEBUG2 に相当) のログレベルを指定します。configファイルの設定はコマンドラインオプションよりも優先順位が低いため、コマンドラインで -v などを指定するとconfigファイルの設定は上書きされます。
BatchMode:対話的プロンプトの無効化
yes または no を指定します。yes に設定すると、パスワードやパスフレーズなどの対話的な入力を要求するプロンプトを無効化します。これにより、認証に成功しない場合はエラーとなって終了するため、スクリプトなどでの自動化処理に適しています。
config
Host automated_task
Hostname 192.168.1.240
User taskuser
IdentityFile ~/.ssh/keys/task_key
BatchMode yes # スクリプトから実行するので対話しない
パスワード認証を使うサーバーに対して BatchMode yes を設定すると、パスワード入力が求められずに認証失敗となります。
AddKeysToAgent:鍵をSSHエージェントに追加
認証成功時に使用した秘密鍵を、自動的にSSHエージェントに追加するかどうかを設定します。
yes: 使用した秘密鍵をエージェントに追加します。no: 秘密鍵をエージェントに追加しません。ask: 秘密鍵を使用する前に、エージェントに追加するかユーザーに確認します。confirm: 秘密鍵を使用する前に、エージェントから公開鍵フィンガープリントの確認を要求します。<時間>(秒): 使用した秘密鍵を指定時間だけエージェントに追加します。
config
Host frequent_server
Hostname 192.168.1.250
User frequentuser
IdentityFile ~/.ssh/keys/frequent_key
AddKeysToAgent yes # この鍵は頻繁に使うのでエージェントに追加
AddKeysToAgent yes を設定すると、SSH接続時に秘密鍵のパスフレーズが求められますが、一度入力すれば、SSHエージェントが起動している間は再度パスフレーズを入力する必要がなくなります(ssh-agent に鍵が追加されるため)。これは複数のサーバーへの接続や、SSHエージェント転送を使う場合に非常に便利です。
4. 実践的な設定例と応用
これまでに解説したキーワードを組み合わせて、より実践的なSSH config の設定例を見ていきましょう。
例1:複数の環境(開発、ステージング、本番)への接続設定
異なるユーザー名、秘密鍵、ポート番号を使用する複数の環境への接続を効率化します。
“`config
共通設定 (すべてのホストに適用)
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%r@%h:%p
ControlPersist 600
Compression yes
開発環境
Host dev
Hostname dev.example.com
User developer
Port 22
IdentityFile ~/.ssh/keys/dev_key
AddKeysToAgent yes
ステージング環境
Host staging
Hostname staging.example.com
User stguser
Port 2222
IdentityFile ~/.ssh/keys/stg_key
StrictHostKeyChecking ask # ステージングは頻繁に変わる可能性があるため確認
本番環境
Host prod
Hostname prod.example.com
User adminuser
Port 22
IdentityFile ~/.ssh/keys/prod_key
IdentitiesOnly yes # 本番用鍵のみを使用
ForwardAgent no # セキュリティのためエージェント転送は無効化
BatchMode yes # スクリプトからの実行も考慮
“`
これで、ssh dev, ssh staging, ssh prod と打つだけで、それぞれの環境に適切な設定で接続できます。
例2:特定のネットワークからの接続設定(ワイルドカードと共通設定)
特定のネットワーク内のサーバーに共通の設定を適用しつつ、特定のサーバーには個別の設定を適用します。
“`config
共通設定
Host *
ConnectTimeout 5
ServerAliveInterval 30
LogLevel INFO
社内ネットワーク (192.168.1.x) のサーバー
Host 192.168.1.*
User internal_user
IdentityFile ~/.ssh/keys/internal_key
# ControlMaster/Path/Persist は * で有効
特定のサーバー (上記より優先される)
Host 192.168.1.10
User admin # このホストだけ管理者ユーザーで接続
LogLevel VERBOSE # このホストだけログを詳細に
“`
ssh 192.168.1.5 と接続すると、User は internal_user になり、IdentityFile は ~/.ssh/keys/internal_key が使われます。ssh 192.168.1.10 と接続すると、User は admin になり、LogLevel は VERBOSE になります。
例3:踏み台サーバー(Jump Host)を使った多段接続
社内ネットワークなどに存在するサーバーへ、踏み台サーバーを経由して接続する設定です。
“`config
踏み台サーバー ( Bastion Host )
Host bastion
Hostname bastion.example.com
User jumpuser
Port 22
IdentityFile ~/.ssh/keys/bastion_key
ForwardAgent yes # 踏み台から先のサーバーに接続するためエージェント転送を許可 (注意: リスク理解必須)
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%r@%h:%p.bastion
ControlPersist 600
最終接続先サーバー (Internal Server)
Host internal_server
Hostname 192.168.10.100 # このホスト名はローカルPCからは直接解決できない/アクセスできない
User internaluser
Port 22
ProxyJump bastion # bastionエイリアスを経由して接続
# IdentityFile は bastion から internal_server への認証用鍵 (エージェント転送を使う場合はローカルPCにある鍵)
IdentityFile ~/.ssh/keys/internal_server_key # bastionから見たパスではなくローカルPCからのパス
IdentitiesOnly yes # Jump先に使う鍵はこれだけ、他の鍵は試さない
Jump先ホストへの多重接続も有効化
Host internal_server
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%r@%h:%p.internal
ControlPersist 600
注意: ProxyJump と ControlMaster を組み合わせる場合、ControlPath は各ホストで一意になるように設定する必要があります。
上記例では ‘.bastion’ と ‘.internal’ を追加してパスを分けています。
“`
この設定で ssh internal_server と実行すると、まず bastion に接続し、次にその接続を介して internal_server に接続します。ControlMaster も有効になっているため、2回目以降の ssh internal_server は非常に高速になります。また、scp /local/file internal_server:/remote/path のようなコマンドもそのまま利用可能です。
例4:ローカル開発環境からリモートWebサーバーへのポートフォワード
リモートサーバーで動作しているWebサーバーに、ローカルマシンのブラウザからアクセスしたい場合。
“`config
Host remote_web
Hostname webserver.example.com
User webuser
Port 22
LocalForward 8080 localhost:80 # ローカルの8080をリモートの80へ転送
接続後、ローカルブラウザで http://localhost:8080 にアクセスすると、
remote_webサーバー上の http://localhost:80 にアクセスできる
“`
SSH接続を確立したターミナルは開きっぱなしにしておく必要があります。バックグラウンドで実行したい場合は、ssh -N -f remote_web のようにオプションを追加して実行します (-N はリモートコマンドを実行しない、-f はバックグラウンドで実行)。
例5:リモートからローカル開発環境へのポートフォワード(Webhookなど)
リモートサーバーからの通信(例: Webhook送信、APIコールバック)をローカル開発環境で受信したい場合。
“`config
Host webhook_relay
Hostname remote_relay.example.com
User relayuser
Port 22
RemoteForward 8000 localhost:3000 # リモートの8000をローカルの3000へ転送
接続後、remote_relayサーバー上の localhost:8000 へのアクセスは、
このSSH接続を経由してローカルマシンの localhost:3000 へ届く。
必要に応じて、remote_relayのsshd_configで GatewayPorts yes を設定し、
外部からのアクセスを許可する必要があるかもしれない。
“`
これも接続を維持しておく必要があります。バックグラウンド実行は例4と同様に -Nf オプションを使用します。
例6:SOCKSプロキシとして利用
社内ネットワークなど、特定のネットワーク内のサーバーへのアクセスを、SSH接続経由でトンネル化したい場合。
“`config
Host socks_gateway
Hostname internal_access.example.com # 社内ネットワークへの入り口となるサーバー
User gatewayuser
Port 22
DynamicForward 1080 # ローカルの1080ポートをSOCKSプロキシとして利用
接続後、ブラウザやアプリケーションのプロキシ設定を
SOCKSホスト: localhost, ポート: 1080 に設定する。
その後、ローカルPCからアクセスされた通信は socks_gateway サーバーを経由して行われる。
“`
これも接続中はSSHセッションを維持する必要があります。バックグラウンド実行は -Nf オプションを使用します。
5. トラブルシューティング
SSH config ファイルを作成・編集した際に、期待通りに動作しない場合があります。ここでは、よくある問題とその対処法について解説します。
設定が反映されない
- ファイルパスの確認:
~/.ssh/configという正しいパスにファイルを作成していますか?ファイル名やディレクトリ名に間違いはありませんか? - パーミッションの確認:
~/.ssh/configファイルのパーミッションは600(オーナーのみ読み書き可) に設定されていますか?他のユーザーが読み書きできる権限になっていると、セキュリティ上の理由からSSHクライアントがファイルを無視する場合があります。chmod 600 ~/.ssh/configコマンドで設定できます。 - 構文エラー: configファイル内に構文エラーはありませんか?例えば、キーワードのスペルミス、キーワードと値の間の空白不足、コメントでない行頭にスペースやタブ以外の文字がある、などです。SSHクライアントは構文エラーのある行以降の設定を無視することがあります。エラーメッセージは表示されないことが多いため、注意が必要です。シンプルな設定で試して、どこに問題があるか切り分けるのが有効です。
- SSHクライアントの再起動: configファイルを編集・保存した後、新しくターミナルを開くか、SSHクライアントを完全に終了してから再度試してください。古い設定がキャッシュされている場合があります。
詳細なログを出力してデバッグする
SSHクライアントには、接続プロセスを詳細に表示する -v, -vv, -vvvv オプションがあります。これらのオプションを使うことで、SSHがどの設定ファイルを読み込み、どの設定を適用し、どのような認証を試行しているかなどの詳細を確認できます。
-v:LogLevel VERBOSEに相当-vv:LogLevel DEBUGに相当-vvv:LogLevel DEBUG3に相当 (最も詳細)
bash
ssh -v myhost # myhostへの接続を詳細表示
ssh -vvvv myhost # さらに詳細に表示
これらのログを見ることで、configファイルの設定が正しく読み込まれているか、意図した秘密鍵が使われているか、認証に失敗している理由などが特定しやすくなります。特に認証関連のトラブルシューティングには非常に有効です。
設定がどのように解釈されているか確認する
ssh -G <hostname> コマンドを使うと、指定したホスト名に対してSSHクライアントがconfigファイルの設定やデフォルト設定をどのように解釈するかを表示できます。これは、実際に接続せずに設定内容を確認できるため、ワイルドカードや複数の設定がどのように組み合わされるかをデバッグするのに役立ちます。
bash
ssh -G devserver
このコマンドを実行すると、devserver に対して適用されるすべての設定がキーワード=値の形式で出力されます。
devserver
user developer
hostname 192.168.1.100
port 22
identityfile ~/.ssh/keys/dev_key
addkeystoagent yes
... (他の設定も表示される)
「Host key verification failed」エラー
このエラーは、接続しようとしているサーバーのホスト鍵が、ローカルの ~/.ssh/known_hosts ファイルに記録されているホスト鍵と一致しない場合に発生します。原因としては以下の可能性があります。
- 初めて接続するサーバーである:
known_hostsにホスト鍵が記録されていないためです。この場合は、サーバー管理者に正しいホスト鍵のフィンガープリントを確認し、問題なければ表示される指示に従って新しいホスト鍵を受け入れます(通常はプロンプトでyesと入力)。 - サーバーのホスト鍵が変更された: サーバーのOSが再インストールされた、SSHサーバーの再設定が行われた、あるいは悪意のあるサーバーに接続しようとしている、などの理由でホスト鍵が以前と変わっています。正当な変更の場合は、
known_hostsファイルから該当するエントリを削除し、改めて接続して新しいホスト鍵を受け入れる必要があります。表示されるエラーメッセージに削除すべき行番号が示されていることが多いです(例:Offending key in /Users/youruser/.ssh/known_hosts:35)。ssh-keygen -R <hostname or ip>コマンドで削除することもできます。 - 中間者攻撃の可能性: 悪意のある第三者が正規のサーバーになりすましている可能性があります。
known_hostsのホスト鍵が一致しないのは、偽のサーバーに接続しようとしているためです。この場合は、絶対に接続を続行せず、サーバー管理者に連絡して状況を確認してください。
StrictHostKeyChecking yes (デフォルト) の設定は、このエラーを適切に処理し、セキュリティリスクを警告して接続を停止するために重要です。
パーミッションエラー(秘密鍵やconfigファイル)
SSH関連のファイルは、セキュリティのため厳格なパーミッションが要求されます。
~/.sshディレクトリ:700(オーナーのみ読み書き実行可) が推奨されます。~/.ssh/configファイル:600(オーナーのみ読み書き可) が推奨されます。- 秘密鍵ファイル (
~/.ssh/id_rsaなど):600(オーナーのみ読み書き可) が必須です。グループや他のユーザーに読み取り権限があると、SSHクライアントは秘密鍵ファイルを無視するか、エラーで終了します。
これらのパーミッションは chmod コマンドで設定できます。
bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/your_private_key
特に秘密鍵ファイルのパーミッションは重要で、Bad permissions や Unprotected Private Key file といったエラーが出た場合は、まず秘密鍵ファイルのパーミッションを確認してください。
6. まとめ
SSH config ファイル (~/.ssh/config) は、SSH接続を効率的かつ安全に行うための非常に強力なツールです。単に接続コマンドを短くするだけでなく、秘密鍵の使い分け、ポートフォワーディング、多段接続、接続の最適化、セキュリティ設定など、SSHの持つ多くの機能を柔軟に設定・管理できます。
この記事では、SSH config の基本的なファイル構造から始め、Host, Hostname, User, Port, IdentityFile といった必須・頻出のキーワードを解説しました。さらに、ControlMaster による接続高速化、LocalForward/RemoteForward/DynamicForward によるポートフォワード、ProxyJump/ProxyCommand による中継ホスト経由の接続といった応用的な設定方法も、具体的な例と共に詳しく見てきました。最後に、設定がうまくいかない場合のトラブルシューティング方法についても触れました。
SSH config を使いこなすことで、日々のサーバー接続の手間が大幅に削減され、より複雑なネットワーク環境へのアクセスも容易になります。また、適切なセキュリティ設定(例: StrictHostKeyChecking yes, PasswordAuthentication no, ForwardAgent no の適切な使用)を行うことで、より安全にリモート操作を行うことができます。
ぜひ、この記事で学んだ内容を参考に、ご自身の環境に合わせた ~/.ssh/config ファイルを作成・整備してみてください。最初は基本的な設定から始め、必要に応じて徐々に高度な機能を加えていくと良いでしょう。快適で安全なSSHライフを送りましょう!