Windows側で接続したVPN先のサーバーにWSL2からも接続できるようにする

Windows側で接続したVPN先のサーバーにWSL2からはどうやっても接続できなかったので回避方法を考えた。

- 「WindowsでVPNを貼るとWSL2が **インターネットに出られない** 」という症状は[各所でむっちゃいっぱい報告されている](https://github.com/microsoft/WSL/issues/5068)が、 **今回問題なのは接続したVPNの先にあるイントラサーバーに接続できない** 、というもの。自分の場合はWSL2もインターネットには出られたので、ただのapt installなどは普通に動いた。
  - 当該serverにpingしたりするとIPアドレスは取れているので、名前解決の問題ではない。tracerouteは途中で帰ってこない。
- WSL2直下だとVPN先に接続できないが、Docker Desktop for Windowsを使っていたときは作ったコンテナの中からなら到達できた。
  Windows側から何かしらネットワークに関してケアが入っていると思われるが、詳しくは分かっていない。今回は[Docker Desktop for Windowsへの依存をやめよう](https://qiita.com/ohtsuka1317/items/617a865b8a9d4fb67989)と思ったのがきっかけ。

# うまく行った方法
windowsをプロキシとして使う。opensshサーバーを立ててProxyCommandで多段sshする。

## windows側作業
- opwnsshのserverをインストールする
  - https://docs.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse
  - よくわかってないが自動起動のPowerShellのくだりも必要
- windowsのopensshを公開鍵認証にしてパスワード不要にする
  - https://qiita.com/syoyo/items/780c3a2206c99a7568ac
  - 当該ディレクトリにExplorerからファイルを書き込めなかったので、適当なフォルダで同名のファイルを作ってから移動して設置
  - ちなみに単にssh-copy-idするだけではうまく行かなかった (多分ファイルのパーミッションのせいだが、コンソールが文字化けしてエラー内容がわからず)
- 多段sshにするconfigを書く: [ProxyCommandを使って](https://notfounds.hatenablog.com/entry/2019/08/06/SSH%E3%81%A7ProxyCommand%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E5%A4%9A%E6%AE%B5%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%99%E3%82%8B)最終的な接続先へのsshコマンドの際に中継のWindowsを自動で通すようにする
  - **方法1** windowsマシンのIPアドレスをハードコードして2つエントリーを書く。シンプルだが、WSL2から見たときにWindowsホストのipアドレスが再起動のたびに変わるので、~/.ssh/configを都度書き換えるような必要が発生する。
    
    ```
    Host windows
        HostName 172.12.34.1 # 再起動のたびに変わる
        User username_on_windows
  
    Host target-server
        HostName your.target.server.co.jp
        User username_on_target
        Port 22
        ProxyCommand ssh -W %h:%p windows
    ```

  - **方法2** WSLからWindows機のIPアドレスを調べる方法 ([その1](https://qiita.com/samunohito/items/019c1432161a950892be), [その2](https://docs.microsoft.com/ja-jp/windows/wsl/networking)) を用いて一行で書く。

    ```
    Host target-server
        HostName your.target.server.co.jp
        User username_on_target
        Port 22
        # WSL直ならこちらでもOK
        # ProxyCommand ssh -W %h:%p username_on_windows@$(ip route | grep 'default via' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
        # WSL直でも、さらにdockerコンテナの中に入っても使えた↓
        ProxyCommand ssh -W %h:%p username_on_windows@$(cat /etc/resolv.conf | grep 'nameserver' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
    ```


## http/httpsも通せるようにする
たまたま自分は不要だったので試してないが、以下のどちらかの方法で到達できると思われる。

- ssh -Lを用いた静的ポートフォワーディング。接続先が数個だけで、URLが変わっても特に困らないケースなら
- [windowsにsquidもインストールし](https://www.usagi1975.com/202006082022/)、各ツールからhttps_proxy等の環境変数を設定して使う。

# 以下、うまく行かなかった方法
## WSLが直接VPN接続する
- 使っていたVPNクライアントはpulse secureだったので、同じ方式に対応しているlinuxクライアントがあればWSL2側が自力でVPN接続できるのでは？と思ったがうまくいかなかった
  - [openconnect](https://qiita.com/diegodox/items/77f1cc5c75efd0881cf1)というものがあり、[version 8.04以上](https://www.infradead.org/openconnect/pulse.html)なら`--procotol=pulse`というオプションがある。[Ubuntu 18.04からだとPPAが必要](https://launchpad.net/~dwmw2/+archive/ubuntu/openconnect)。でも接続途中でエラーが出て断念。

## 多段sshの代わりにsocksプロキシを使う
- 多段sshやsquidの代わりに`ssh -D 1080 windows`と`tsocks`によって[socksプロキシ](https://www.kmc.gr.jp/advent-calendar/ssh/2013/12/14/tsocks.html)経由でVPN先につなげればどのプロトコルも1つの方法で接続できて便利と思ったが、うまく行かなかった。tsocks curlやtsocks wgetを試しても通常と変化がなかった。
- tsocksではなくcurlのオプションで動かすのも試すべきだったがやってない: https://gihyo.jp/admin/serial/01/ubuntu-recipe/0617?page=2