0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ssh config でマシンが所属するネットワークを判断して使用する設定を切り替える (Windows版)

Posted at

本記事は下記記事のWindows対応版です。

あるホストにSSHで接続する際に、LAN内からかインターネットからかで使用するIPやポート番号などが異なるのはよくあることかと思う。Linuxでのやり方は過去に上げたが、Windowsにはないコマンドを利用していたため、Windowsで使えなかった。判定時に外部アクセスしない点を引き継ぎ、PowerShellの Get-NetRoute コマンドレットを活用する方式を使っている。

なお、ホスト名は example アドレスは 192.168.0.5/24 であり、それが外部からだと 203.0.113.10 で接続できるものとする。

Match host example exec "powershell -NoProfile -Command if((Get-NetRoute -DestinationPrefix 192.168.0.0/24 -NextHop 0.0.0.0 -ErrorAction SilentlyContinue) -eq $null) {exit 1}"
  Hostname 192.168.0.5
Host example
  Hostname 203.0.113.10

Linux版と比べるとかなりトリッキーになっている。まず、核となるネットワーク判定は Get-NetRoute -DestinationPrefix 192.168.0.0/24 -NextHop 0.0.0.0 により、ローカルサブネットで検索している。ここを工夫すれば様々な複雑な条件に変更可能だ。問題は ssh.exe にその結果をどう伝えるかだ。 ssh.exe がこの設定ファイルの exec で呼び出すのは、 cmd.exe であるため、PowerShellコマンドを実行するには powershell.exe を実行する必要がある。また、 exec は実行したコマンドの終了コードで分岐するので、PowerShellがいい感じの終了コードで終わってくれる必要がある。

こちらのドキュメントを見ると、最後に実行したコマンドの終了コードが返されるとあるのだが、ここでややこしいのが、PowerShellにおけるエラーの扱いだ。PowerShellには例外を発し、スクリプトを停止させるエラーや、エラー出力を表示はするが続行するエラー等、少々変わったエラーがあり、コマンドレットのそれらの挙動を変える ErrorAction というオプションがある。

色々作戦は考えられるが、今回は他のコマンドレットを組合せた拡張などを見据え、 SilentlyContinue として、該当ネットワークがないときに単純に $null を返してそれを判定するというアプローチをとった。

このSSHの設定ファイルの exec に関しては、エスケープの構文が無かったりと、そもそもの仕様面でかなり頭が痛いため、外部プログラムを用意したくもなるが、そうなると今度はパスをどうするか問題が勃発し(execのカレントディレクトリはsshを実行した場所)、設定ファイルの可搬性問題に波及する。 localnetwork オプションのサポートがもうちょいまともなら…

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?