6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Windows SOCKS Proxy SSH環境で Git Bash と VSCode Remote Development の ~/.ssh/config を共通にする

Last updated at Posted at 2021-09-19

Motivation

使用頻度の高いGit BashからのsshとVSCode Remote Developmentでssh_configの設定を共通化したい。

最初にまとめ

  • Git BashとWindows標準のsshで ~/.ssh/config でのパスの書き方が違う。
  • VSCodeのRemote Developmentでは標準でWindowsのsshが使われる。
  • ~/.ssh/config を以下のように書くと、Git BashとWindows標準どちらのsshからもtargetに接続できる。
~/.ssh/config
Host target
  Hostname target.example.com
  User ******
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand C:/PROGRA~1/Git/mingw64/bin/connect.exe -S socks.example.com:1080 %h %p

connect.exe のパスにスペースが入らないように、 Program Files の短いファイル名 PROGRA~1 を使うこと、ディレクトリ区切りに\ではなく/を使うことがポイント

構成:

windows_socks_proxy_gitbash_vscode_ssh_config3.png

環境

  • Windows 10 64bit (1909)
  • Git for Windows 64bit (2.22.0)
  • Visual Studio Code 1.60.1

経緯と詳細

  • Windows で SOKCKサーバー経由のSSH接続を行うにはGit for Windows付属の connect.exe を使う。
    • Git for Windows ならみんなもうインストール済み
    • ssh.exe のパスは C:\Program Files\Git\usr\bin\ssh.exe
    • connect.exe のパスは C:\Program Files\Git\mingw64\bin\connect.exe ここはPATHの通っていないディレクトリなので、connect.exeを使うにはフルパスで指定が必要
  • 最近のWindowsにはssh.exeが付属してきており、そのパスは C:\Windows\System32\OpenSSH\ssh.exe
    • VSCode の Remote Development においては標準でこちらのssh.exeが使われる

Git BashからProxy経由でsshのssh_config

~/.ssh/config
Host target
  Hostname target.example.com
  User ******
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand "C:\Program Files\Git\mingw64\bin\connect.exe" -S socks.example.com:1080 %h %p

C:\Program Files\Git\mingw64\bin\connect.exe を一つの実行ファイルと認識させるためにこのパスをダブルクォーテーションで囲んでいる。

PowerShellからProxy経由でsshのssh_config

~/.ssh/config
Host target
  Hostname target.example.com
  User ******
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand C:\Program Files\Git\mingw64\bin\connect.exe -S socks.example.com:1080 %h %p

PowerShellのCLI、cmd.exe (コマンドプロンプト)、 Visual Studio Code などWindowsネイティブでのパスの指定方法はこちら。

C:\Program Files\ のように途中にスペースがあってもなぜか C:\Program Files\Git\mingw64\bin\connect.exe までが最初の実行ファイルの指定だとわかり、connect.exe を起動して残りをconnect.exeへのパラメータとして扱ってくれる。

Git BashとPowerShellからの~/.ssh/config設定を共通にしたい

違いは ProxyCommand の connect.exe のパスの書き方だけなのでなんとか共通化したい。

ProxyCommand C:\Program Files\Git\mingw64\bin\connect.exe でGit Bashからsshすると、エラー

$ ssh target
/usr/bin/bash: line 0: exec: C:Program: not found
kex_exchange_identification: Connection closed by remote host

\ がエスケープ文字と見なされて消えているのと、 Program Files のスペースで区切られてしまい、 Program という実行ファイルを探してしまっている。
エスケープ
ProxyCommand C:\\Program\ Files\\Git\\mingw64\\bin\\connect.exe でGit Bashからsshすると、つながる。

$ ssh target
Last login: Sun Sep 19 09:37:09 2021 from xxx.xxx.xxx.xxx

この状態でPowerShellからsshするとエラー。

PS C:\Users\umorigu> ssh target
CreateProcessW failed error:2
posix_spawn: No such file or directory

逆にGit Bashで繋がっていた ProxyCommand "C:\Program Files\Git\mingw64\bin\connect.exe" でPowerShellからsshすると、これもエラー。

PS C:\Users\umorigu> ssh target
CreateProcessW failed error:87
posix_spawn: Unknown error

シングルクォートで囲んでみても ProxyCommand 'C:\Program Files\Git\mingw64\bin\connect.exe' メッセージが変わるが引き続きエラーになる。

PS C:\Users\umorigu> ssh target
CreateProcessW failed error:2
posix_spawn: No such file or directory
ssh_exchange_identification: Connection closed by remote host

Windows native のsshは、パス前後に引用符 ", ' が付いたり、パスの途中に \ が入ったりするともうつながらなくなってしまう。
ただし複数の \ は一つの \ と同一視される。(Windows一般ルール)

引用符を使わずにパス途中のスペースに対応する方法は? と考えて、短いファイル名を思い出した。

> dir /x C:\
...
2021/09/07  14:45    <DIR>          PROGRA~1     Program Files
2021/06/29  10:49    <DIR>          PROGRA~2     Program Files (x86)
...

ProxyCommand C:\PROGRA~1\Git\mingw64\bin\connect.exe を試すと
PowerShellではつながる、Git Bashでエラー

$ ssh target
/usr/bin/bash: line 0: exec: C:PROGRA~1Gitmingw64binconnect.exe: not found
kex_exchange_identification: Connection closed by remote host

\ がエスケープ文字と解釈されて消えてしまっている。

\をエスケープするために\\に変えた ProxyCommand C:\\PROGRA~1\\Git\\mingw64\\bin\\connect.exe を試すと
PowerShellではつながる。Git Bashでもつながる!

次にバックスラッシュ2つを/に変えた ProxyCommand C:/PROGRA~1/Git/mingw64/bin/connect.exe を試すと、これも
PoewrShellではつながる。Git Bashでもつながる!

以上により、 ProxyCommand の記述として正しいのは次の2パターン。

ProxyCommand C:\\PROGRA~1\\Git\\mingw64\\bin\\connect.exe -S socks.example.com:1080 %h %p
ProxyCommand C:/PROGRA~1/Git/mingw64/bin/connect.exe -S socks.example.com:1080 %h %p

どちらでも動作するがLinuxでのssh_configや IdentityFile ~/.ssh/id_rsa のような典型的な記述を意識して今回は / を採用する。

確定したパスを使ってconnect.exeのバージョンを確認する

C:/PROGRA~1/Git/mingw64/bin/connect.exe -V

を実行すると connect.exe のバージョンを確認できる。 (Git Bash, PowerShell, コマンドプロンプトすべて同じでOK)

$ C:/PROGRA~1/Git/mingw64/bin/connect.exe -V
connect --- simple relaying command via proxy.
Version 1.105
PS C:\Users\umorigu> C:/PROGRA~1/Git/mingw64/bin/connect.exe -V
connect --- simple relaying command via proxy.
Version 1.105

得られた知見

  • Git BashとWindows標準のsshで実行バイナリが異なり、 ~/.ssh/config でのパスの書き方が違う。
  • VSCodeのRemote Developmentでは標準でWindowsのsshが使われる。
  • Windows標準sshは、パスを"'で囲むと動かなくなる
  • Git Bash付属sshはShell的な解釈を行い、"'で囲まれていないパスの途中にスペースがあると動かない。
  • 短いファイル名 ( C:\Program Files に対して C:\PROGRA~1 ) を使うことでスペースも引用符もなしにGit BashとWindows標準のsshに共通のパス設定(実行ファイル指定)を行うことができる。
  • パス区切り文字列は \\ とするか / とするか、どちらでも有効。

別解

  • Git for Windows を Program Files でなくスペースの入らないディレクトリにインストールする。
    • これでもOK。ただ、そんなことをする人はほとんどいない。
  • VSCode の Remote.SSH:Path に C:\Program Files\Git\usr\bin\ssh.exe を設定する。
    • これでもOK。ただ、できるだけVSCode側のデフォルト設定は変えずにおきたい。

応用

踏み台サーバー経由で別のサーバーにログインする

踏み台サーバー(bastion)を経由してtarget-internalにログインしたい場合の設定は以下のようになる。

構成:

windows_socks_proxy_gitbash_vscode_ssh_bastion_config3.png

~/.ssh/config
Host bastion
  Hostname bastion.example.com
  User ******
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand C:/PROGRA~1/Git/mingw64/bin/connect.exe -S socks.example.com:1080 %h %p

Host target-internal
  Hostname target-internal.example.com
  User ******
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand ssh.exe -CW %h:%p bastion

こうしておくと

$ ssh target-internal

でSSHログインできる。

HTTP Proxy経由でSSH接続

HTTP Proxyの場合は、 connect.exe に指定するオプションを -S(SOCKS) から -H に変える。

~/.ssh/config
Host target
  Hostname target.example.com
  User ******
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand C:/PROGRA~1/Git/mingw64/bin/connect.exe -H proxy.example.com:10080 %h %p

感想

2021年になってショートファイル名 PROGRA~1 を使うことになるとは思わなかった。

6
4
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
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?