1
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?

More than 3 years have passed since last update.

WSL2でのVcXsrvとかDjangoとかsshとか

Last updated at Posted at 2021-08-13

WSL2

個人的に最近,WSLからWSL2に移行しつつあります.

  • Gooleドライブ系ツールの疑似ドライブ(/mnt/gとかになるやつ)が普通にアクセスできるようになった
  • DockerもWSLよりWSL2の方がやりやすい

など,割といい感じかなと思っています.

X-WindowのDISPLAY環境変数

一方で,ネットワーク周りでは,WSLがWindows側と同じアドレスをデフォルト(Ubuntuとかならeth0)にしていたのに対し,WSL2では仮想NAT配下のアドレスが毎回動的にアサインされるように変更されています.
このため,X-WindowのサーバとしてVcXsrvなど,外部で起動させるサービスを使う場合には,環境変数DISPLAYを仮想NATルータに設定する必要があります.仮想NATのセグメントは毎回動的にアサインされるので,そこら辺の情報をとってくるようにしなければいけません.

この設定は,他の記事を参考にすると/etc/resolv.confのnameserver の情報を使っています.よくみかけたものはgrepとawkを組み合わせるものですが,awkだけでも以下のようにできます.

.bash.rc
# (other settings may be above)
export DISPLAY=$(awk '{ if($1=="nameserver") {printf("%s:0.0",$2); exit} }' /etc/resolv.conf)

まぁどちら(awk単体 or w/grep)で書いてもone linerなので大差ないですが.

外部接続の受付(Port Forwarding)

もう一つ,Windows側からWSL2のUbuntu環境に対しての接続についても,Windows側と連携して設定を行うと便利です.

一般論として言えば,動的に変わるWSL2側のアドレスを毎回調べることを厭わなければ,Djangoのデバッグサーバや,他にもsshなどの接続先として,WSL2側のアドレスを直接指定することで,必要とするサービスにアクセスすることはできます(もともとWSL2へのルーティングは設定されていて,WSL2側も初期では特にホストFW的な設定は入っていないため).

とはいえ,毎回WSL2に割当たったアドレスを調べて使うのも面倒なので,WSLの時と同じく,Windows側のブラウザではlocalhost:8000 へのアクセスで済むようにした方が楽かと思われます.

そこで,ここでは例として,Django等,Web開発環境をWSL2で使っていて,デバッグサーバをポート8000で立ち上げたものにWindows側のブラウザから接続したい,という状況を考えます.8000以外でも同様ですが,とりあえずここでは8000を例として話を進めます.

この場合,Windows側で,localhost:8000へのアクセスを(WSL2のアドレス):8000に転送する設定を行う必要があります.その設定には,毎回動的に変わるWSL2側のアドレスを把握しなくてはなりませんが,これをWindows側からやると面倒なので,wslコマンドを使い,Windows側から呼び出すWSL2側のシェルスクリプトでnetsh.exeを起動する,という,ちょっとねじくれた方法を使います.
なお,以下の例ではついでにssh(tcp/22)も書いています.Django,sshに限らず,外部(といっても主にWindows側でしょうが)からWSL2内に接続したい場合,以下の手順で同様にできます.

用意するファイルは,

  1. Ubuntu側で,Windows側からリモートで呼び出され,Windowsのnetsh.exe を実行するスクリプト
  2. Windows側で,1. のスクリプトをwslコマンドで呼び出すバッチファイル

という2つになります.

Ubuntu側からnetsh.exeで設定を行わせるスクリプト

まず,1.は,以下のようなBashスクリプトを作っておきます.場所は/usr/binでなくともかまいません(2.で作成するバッチファイル側で合わせればよい).また,筆者の環境でのテストでは特にroot権限(オーナーrootで+s)は必要ありませんでしたが,うまくいかないようであればrootでsetUIDしないといけないかもしれません(たぶん要らないと思いますが…).実行権限は必要なので,chmod 755 もしくは chmod a+xはしておきます.

/usr/bin/pfw.sh
# !/bin/bash
ADDR4=$(hostname -I)

for PORT in 8000 9000 22
do
  netsh.exe interface portproxy delete v4tov4 listenport=${PORT}
  netsh.exe interface portproxy add    v4tov4 listenport=${PORT} connectaddress=${ADDR4}
done

sc.exe stop  iphlpsvc
sc.exe config iphlpsvc start=auto
sc.exe start  iphlpsvc

上の例では,8000,9000,22をポートフォワードの対象として指定しています.
netsh.exeのlistenportの指定に,listenport=8000,9000とか指定できるかと思って試しましたが,コマンドはすんなり通るものの転送はされず,たぶん本気で8000,9000ポートに転送しようとしている気がしました :-p.で,とりあえず愚直にループを回しています.

Windows側から,Ubutun上の設定スクリプトを呼び出すバッチファイル

次に,Windows側から上記の設定スクリプトを呼び出すバッチファイルです.これは,管理者権限で起動したPowerShellか,cmd.exeから呼び出す必要があります(要は管理者権限が必要なのはWindows側であってUbuntu側ではない).で,管理者権限でPSを起動するとデフォルトでC:\WINDOWS\System32がcwdになるので,筆者はそこに置いています.

C:\WINDOWS\system32\pfw.bat
wsl -d Ubuntu-20.04 --exec bash /usr/bin/pfw.sh

で,これを

.\pfw.bat

で起動すると,フォワーディングが設定されます.

PS C:\WINDOWS\system32> netsh interface portproxy show all
ipv4 をリッスンする:         ipv4 に接続する:
Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               8000        172.23.99.186   8000
*               9000        172.23.99.186   9000
*               22          172.23.99.186   22
PS C:\WINDOWS\system32>

ちなみに,管理者以外でPowerShellを開いている場合は,

Start-Process -Verb runas .\pfw.bat

で起動することもできます.昇格確認ダイアログが出るのは当然として,この場合一瞬CUIウィンドウが開いて終了と同時に消えるので,結果を確認したい場合はpfw.batの最後にpauseを追加します.

Django側のrunserver

以上でポートフォワーディングはできていますが,Django側でrunserverする場合,

python3 manage.py runserver 0.0.0.0:8000

がお手軽です.
なぜなら,Windows側のブラウザでlocalhost:8000を指定しても,実際は転送されてWSL2側のプライベートアドレス(loopbackではない)に転送されているからです.もちろん,他にも方法はあり,

settingy.pyとrunserverで対応
毎回,WSL2についたアドレスを調べてsettings.pyのALLOWED_HOSTSを書き換え(sed -i でインライン編集する,等),runserverにもそのアドレスを指定する
WSL2に付与されたアドレスの特定のポートへのアクセスをlocalhostに転送
iptablesで,設定を入れるスクリプトを用意するか,WSL2ローカルのsshサーバを上げて自分自身にsshしつつポートフォワードをする  

といったあたりが思いつきますが,面倒そうですね…

まとめ

なにかと便利になったWSL2ですが,ネットワーク周りは(ある意味まっとうともいえるが)独立した仮想NWに収容されるようになったことで,若干手間は増えました.とりあえず,今のところ必要になったものについて,いくつか調べて入手した情報からまとめてみました.

1
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
1
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?