自宅LAN内のサーバにSSHするとき、LAN内からならローカルIPアドレス、 外からならグローバルIPアドレス(あるいはホスト名)でアクセスする必要があったりします。 .ssh/configに別々の設定を書いても良いですが、同じ名前でSSHしたいときの設定方法です。

Matchによる条件分岐

OpenSSH 6.5以降ではconfigのMatchキーワードで設定を分岐させることができます。 分岐条件には外部コマンドを使うこともでき、Match exec "cmd"のように書きます。 詳しくはman ssh_configを見てください。

自宅LANかどうかの判定

iwconfig コマンドでSSIDを取り出せるので、 grep などでマッチさせれば簡単に判定できます。

iwconfig 2>/dev/null | grep -q ’ESSID:"my-ssid"’
echo $?

ダブルクオート(")をどうにかする

上の判定コマンドをそのまま Match exec に書けば良さそうなのですが、 コマンド全体を"で囲まねばならず、その中に"を含めることができません。 そこで、シェルのエスケープシーケンスを使って"をgrepの引数に与えるようにします。

Match host myserver exec "iwconfig 2>/dev/null | grep -q ESSID:$'\x22'my-ssid$'\x22'"
  HostName ローカルIPアドレス

また、Matchは複数の条件を1行に書くことができ、左から順に検査されるので、 Match hostで先に接続先名をマッチさせています。 こうすることで、ssh myserverとしたときのみコマンドが実行されるようにできます。

自宅LAN以外でのアクセスの設定

ssh_configはファイルの先頭から順に設定を読んでいき、あとから同じ設定が出てきても上書きされません。 これを利用して、次のように自宅LAN以外での設定を書き加えます。

Match host myserver exec "iwconfig 2>/dev/null | grep -q ESSID:$'\x22'my-ssid$'\x22'"
  HostName ローカルIPアドレス
  Port 22
Host myserver
  HostName グローバルIPアドレス
  Port 2222
  User myname
  ForwardX11 yes

このように共通の設定をHostの方に、自宅LANでのみ有効な設定をMatchに書くことができ、管理もしやすくなります。

これで ssh myserver という共通のコマンドで、適切なIPアドレス(ついでにポート)で接続できるようになりました。 同じような方法で踏み台サーバの設定も動的に切り替えることもでき、便利に利用しています。

うまく動かない時は……

ssh -v myserver

のように -v オプションをつけて実行すると、configのどのキーワードがマッチしているのか確認することができます。