Windows10 HomeなゲーミングPCに乗り込んでリモート開発すべく、WindowsにOpenSSHサーバーを導入してVisual Studio Codeのリモート開発拡張機能を使ってきました。開発を進めていく上で遭遇した
- SSH経由のgit pullがハングする
- DevContainersが使えない
といった不具合を乗り越えるため、WSL2 Bashをデフォルトシェルに指定することで解決するという内容を前回記事で書きました。
まだ残っていた問題
デフォルトシェルをWSL2にすることで、当初の「SSH経由でのgit pull」や「DevContainersの利用」はできるようになったものの、新たな問題が発覚しました。
それは
- ssh-agentのForwardingが効かない
ということです。「WSL Bash SSH Agent Forward」みたいなググり方をすると、使用するSSHクライアントによって癖があるようで、「Windowsのssh-agent.exeに登録した鍵をWSL2 SSHで使用する」みたいな内容がよく出てきました。が、今回はそれとは違うような気がしています。
(そもそも、SSHのAgentForwardingってどうやって実現されているのかよくわかってないです。SSHサーバーが環境変数に参照すべきAgentの宛先を設定して、それをSSHクライアントが使用している…?詳しい人いたら教えてください…)
で、さんざん調査してわかったのはどうやらWindows向けのOpenSSHサーバーはAgentForwardingには未対応ということです。おお、マジか・・・
というわけで、AgentForwardningが効かないのはちょっと(だいぶ)つらいので、頑張って解決してみようという内容になります。
解決方法
いままで開発してきて、Windows向けのOpenSSHクライアントからLinuxのOpenSSHサーバーに向けてつないだ時はAgentForwardingが機能することは確認できていたので、WSL2のLinuxに直接SSH接続すればいい ということになります。
が、ここで立ちはだかるのは2つの壁です。
一番目のsshdの動かし方は wsl sudo service sshd start
とかやっちゃえばまぁ解決です。問題は二番目の「WSL2のsshdへの繋ぎ方」です。
これについては何が問題かというと、WSL2で使用されるIPアドレスは起動のたびに変わってしまうということが言われていて、現在固定する方法がない(Hyper-V使える人は固定できるみたい?まぁWindows Proエディションの話なので今回は対象外)ということです。
世の中の先人たちは、これに対して WSL2のIPアドレスを取得してnetshでポートフォワーディングの設定を書く という対処方法をよくとっているみたいです(著者調べ)。以下、参考にしたサイトです。
リモートマシンのWSLにOpenSSHサーバとDockerを入れてVSCodeからリモートアクセスできるようにする - てのひら
ただ、これ開発時以外もずっとポートフォワーディングしてるのが非常に気持ち悪いですし、そもそもタスクスケジューラとか普段使わないので設定したことを忘れて放置してたりしそうで怖いです。何よりファイアウォール開けるのが嫌ですね・・・
というわけで、別の方法をとりたいと思います。
Windowsホストを踏み台にしてWSL2にログインする
Windowsに開発時以外もポートフォワーディングさせるのちょっと怖いですし、昔ながらの「SSHのProxyCommandを使って接続する」という方法をとってみたいと思います。「踏み台」ってやつですね。
【ポートフォワーディングさせる場合】 クライアントマシン ==SSH==> WSL2(開発機) 【踏み台にする場合】 クライアントマシン ==SSH==> Windows(開発機) ==SSH==> WSL2(開発機)
そうだnetcatしよう
さて、踏み台にするにあたって「WSL2のIPアドレスはどう扱う?」という問題は依然としてあります。
が、ここで天啓。これ、フツーに「WSL2にnetcatさせればいいのでは????」となりました。
つまり、ProxyCommand
で踏み台に wsl nc localhost 22
させればよいのです。
やりかた
というわけで早速 .ssh\config
を書きました。WinHomeは開発機のホストで、DevWSLは開発機内のWSL2のホストです。
Host WinHome HostName 1.2.3.4 # 以下略 Host DevWSL HostName localhost Port 22 ProxyCommand ssh WinHome wsl nc %h %p # 以下略
接続時は ssh DevWSL
とするだけでOK!。VSCode からもDevWSLを開くようにポチポチしているだけでWSL2に入って開発することができます。
結局、AgentForwardingならず
はい、ここまで引っ張っておいてアレなんですが、結局AgentForwardingできていません。なんかどうもWSL2に導入するOpenSSHのバージョンによってはForwardingできない問題が発生するそうです。なんじゃそりゃー!
WSL2のOpenSSH Agent Relayが動かなくなったので調査した
結局DevContainersでいく
結果としては失敗に終わりましたが、実はAgentForwardingできる方法がありました。
VSCodeのDevContainersのAgentForwarding機能を使用する という方法です。
これ、どうやらSSHとは異なった経路(?)でAgentForwardingしているようで(確かにDockerに入るのSSHじゃないもんな)、たぶんバケツリレー的に経由するホストの各地点でAgentForwardingできていなくてもSSHクライアントと連携できるんだと思います。(適当言ってます。間違ってたら指摘してください…)
devuser@0cf0909ae8ca:/workspaces/hogehoge $ ssh -T git@github.com Hi ohayoyogi! You've successfully authenticated, but GitHub does not provide shell access.
え?じゃあこれWSL2 Bash経由で繋いでてもDevContainersだったらPortForwardingできたってこと~~~????っていう疑問もわくんですが、怖いので調べていません・・・(情報求む)
終わりに
というわけで、WSL2に対してnetshによるポートフォワーディングを使用せずにSSHで繋ぐ方法を考えてみました。
WSL2にAgentForwardingできたら最高だったんですが、それは時間が解決してくれるということで、今は頑張って何とかWSL2内でpullしてから鍵を使った作業はDevContainers内でどうにかするという方法をとりたいと思います。
それでは、みなさまもよきリモート開発ライフを。