66745


WSLでUbuntu18.04 を使っています。WSLからWSL2に上げてみたところ、VcXsrvに接続できなくなりました。

magic cookieを用いた昔ながらのリモート接続を実現しようとしていますが、うまくできません。  
Xサーバの側でセキュリティチェックを全部外せば動くので、実用上はそれでもよいのですが、動かない理由が分からないのが気持ち悪いので、できたら解明したいと思っています。

いままでは WSL の中から DISPLAY=localhost:0.0
につなぎにいくと、Windows側のVcXsrvにつなぎに行っていました。これは、WSLではIPのスタックがWindowsのものだったため、成り立っていました。VcXsrvではローカルマシンからの接続はうけつけています。それはxhostで確認できます。

[code]

    C:\Program Files\VcXsrv>set DISPLAY=localhost:0.0
    
    C:\Program Files\VcXsrv>xhost
    access control enabled, only authorized clients can connect
    INET:myhost.mshome.net
    LOCAL:
    INET:myhost
    INET6:myhost
    
[/code]

追記：いただいたコメントを参考に、xhostベースで、WSL2からのアクセスのみ許可するやり方がわかりましたので、末尾に書きます。

WSL2になり、IPのスタックがWindowsと独立になり、WindowsとWSL2とではIPとしては別ホストになりました。IPアドレスをそれぞれで確認すると、Windowsでは次のようになります。

[code]

    C:\Program Files\VcXsrv>ipconfig /all
    
    Windows IP 構成
    
       ホスト名. . . . . . . . . . . . . . .: myhost
    ...
    イーサネット アダプター イーサネット:
    ...
       IPv4 アドレス . . . . . . . . . . . .: 192.168.100.13(優先)
    
[/code]

WSL2側では次のようになります。

[code]

    $ ip a
    ...
    4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    ...
        inet 172.18.66.30/20 brd 172.18.79.255 scope global eth0
           valid_lft forever preferred_lft forever
    
[/code]

そのため、DISPLAY=localhost:0.0 では、少なくとも動きません。

[code]

    $ export DISPLAY=localhost:0.0
    $ xclock
    Error: Can't open display: localhost:0.0
    
[/code]

DISPLAYにWindowsのIPアドレスを指定すると（予想通り）認証を通過できずに拒絶されます：

[code]

    $ export DISPLAY=192.168.100.13:0.0
    $ xclock
    Authorization required, but no authorization protocol specified
    Error: Can't open display: 192.168.100.13:0.0
    
[/code]

この場合、Xサーバ側でcookieを生成し、それをクライアント側の .Xauthority に登録しておけばつながるはずと考えました。

Xのセッションで magic cookie
がどのタイミングで作られるのか、知らないのですが、ふつうはgdmなどのディスプレイマネージャが作成するという記述を見かけました。  
vcxsrvに付属のランチャーコマンドXLaunchを単に実行しただけでは .Xauthority ファイルは特に作られませんでした。

そこで、Windows側でxauth generate を使ってcookieを生成してみました。

[code]

    C:\Program Files\VcXsrv>xauth generate localhost:0.0
    xauth:  file \users\hideo\.Xauthority does not exist
    
    C:\Program Files\VcXsrv>xauth list
    myhost/unix:0  MIT-MAGIC-COOKIE-1  c97dd91b6d02fdf4e4717b2b450b354f
    
    C:\Program Files\VcXsrv>
    
[/code]

これをWSL2側で $HOME/.Xauthority に追加してみます。（ローカルなDNSを立てており、適当なドメイン名でIPは引くことができます）

[code]

    $ hostname
    myhost
    $ xauth add 192.168.100.13:0.0 . c97dd91b6d02fdf4e4717b2b450b354f
    xauth:  file /home/hideo/.Xauthority does not exist
    $ xauth list
    myhost.hidehome.net:0  MIT-MAGIC-COOKIE-1  c97dd91b6d02fdf4e4717b2b450b354f
    $ export DISPLAY=192.168.100.13:0.0
    $ xclock
    Invalid MIT-MAGIC-COOKIE-1 keyError: Can't open display: 192.168.100.13:0.0
    $ export DISPLAY=myhost.hidehome.net:0.0
    $ xclock
    Invalid MIT-MAGIC-COOKIE-1 keyError: Can't open display: skylake-win.hidehome.net:0.0
    
[/code]

xauthの使い方を正しく理解できていない気がしているのが、動かせている方がいたら教えてください。

この質問を書いている途中で、xhostを使ってWSL2からやってくるリクエストを全部受け付けるようにできるのではないかと思いましたので、試みましたが、xhostが要求を受け付けてくれませんでした。

[code]

    C:\Program Files\VcXsrv>set DISPLAY=localhost:0.0
    
    C:\Program Files\VcXsrv>xhost +inet:172.18.66.30
    172.18.66.30 being added to access control list
    xhost:  must be on local machine to add or remove hosts.
    
    C:\Program Files\VcXsrv>set DISPLAY=
    
    C:\Program Files\VcXsrv>xhost +inet:172.18.66.30
    xhost:  unable to open display ""
    
    C:\Program Files\VcXsrv>
    
[/code]


CC BY-SA 4.0
2020-05-18T00:51:02.473
66736
2020-05-30T01:57:59.903
2020-05-18T08:49:33.890
40200
40200
question
ubuntu wsl x11
WSL2の中のX clientから VcXsrv に xauth で接続したい


自己回答です。

探していたものずばりそのものの回答ではありませんが、コメントで教えていただいたページの情報から、xhostによるリクエスト元ホスト単位のアクセス制御で
wsl2 からの要求を許可する方法が分かりました。

Xサーバに接続できているマシンから、

[code]

    xhost + クライアントのIPアドレス
    
[/code]

とすると、IPアドレス単位での制御ができます。WSL2の側のIPアドレスは、WSL2 で例えば

[code]

    $ ip a show dev eth0
    
[/code]

で調べることができます。このアドレスを指定してwindows側でxhostに渡します。

xhostも$DISPLAY経由でサーバと通信をするプログラムですが、ローカルホストからのアクセスでないと、許可ホストの増減操作ができません。その際、DISPLAYにlocalhostと書いたのではだめで、127.0.0.1と書くとうまく行きました。

[code]

    C:\Program Files\VcXsrv>set DISPLAY=localhost:0.0
    
    C:\Program Files\VcXsrv>xhost +172.18.70.209
    172.18.70.209 being added to access control list
    xhost:  must be on local machine to add or remove hosts.
    
    C:\Program Files\VcXsrv>set DISPLAY=127.0.0.1:0.0
    
    C:\Program Files\VcXsrv>xhost +172.18.70.209
    172.18.70.209 being added to access control list
    
    C:\Program Files\VcXsrv>xhost
    access control enabled, only authorized clients can connect
    INET:172.18.70.209
    INET:skylake-win.mshome.net
    LOCAL:
    INET:skylake-win
    INET6:skylake-win
    
    C:\Program Files\VcXsrv>
    
[/code]

このあと、WSL2側で
DISPLAYさえ設定すればOKですが、windowsマシンの一般的なIPアドレスではなく、wsl2の中で、DNSのアドレスとして自動的に登録されているアドレスを指定します。

[code]

    $ grep nameserver /etc/resolv.conf
    nameserver 172.18.64.1
    $ export DISPLAY=172.18.64.1:0.0
    
[/code]

これでwsl2の中からXのクライアントが使えるようになりました。

[code]

    $ ssh -Y server.at.university.ac.jp
    university$ xclock
    
[/code]

自分でやりたいことはひとまずできました。


CC BY-SA 4.0
2020-05-18T08:51:54.893
66743
2020-05-18T08:51:54.893
40200
66736
answer


cookie を生成する時に、`xauth generate localhost:0.0 . timeout 0` のように、`timeout
0`を指定してみて下さい。利用するアプリケーションによっては、`xauth generate localhost:0.0 . trusted timeout
0` のように`trusted`も指定する必要があるかもしれません。

timeoutのデフォルト値は60(秒)であり、cookieを生成してから利用するまでに60秒以上かかっている事からエラーになっていると思われます。  
ドキュメントには 0 で無期限になるという記述が見当たりませんが、手元で試した感じでは大丈夫そうです。  
もし駄目ならば、86400 等の十分に大きい値を指定してみて下さい。


CC BY-SA 4.0
2020-05-18T09:48:50.883
66745
2020-05-18T09:48:50.883
12203
66736
answer


自己解答 ver.2 です。

教えていただいた xauth のtimeout指定を活用して、Windows側でのcookie
の発行と、WSL側での取り込みをWSL側で実行するスクリプトとして、まとめてみました。

追加で見つけたノウハウ：

  * WSL2の側からWindowsのホストにアクセスするためのホスト名は、resolv.confに記載のnameserverのアドレスを引っ張ってくるほかに、ホスト名.mshome.net というホスト名を使う方法がある。
  * WSL2の側からWindowsのxauth.exeを実行できるが(※xhostからxauthに訂正)、そのためにはフルパスでxauth.exeを指定するほかに、カレントディレクトリをWSL内のディレクトリではなく、Windowsのホームディレクトリのあるドライブの上のディレクトリにしておく必要があるっぽい。

上記のノウハウを投入したスクリプトが以下のものになります。:

[code]

    WXAUTH="/mnt/c/Program Files/VcXsrv/xauth.exe"
    HN=$(hostname).mshome.net
    export DISPLAY=$HN:0.0
    
    ( cd /mnt/c ; "$WXAUTH" generate $HN:0.0 . trusted timeout 0 )
    
    ( cd /mnt/c ; "$WXAUTH" extract - $HN:0.0 ) | xauth merge -
    
[/code]

使い方：

  * windows側でvcxsrvを従来通り起動します。
  * このスクリプトをsourceします。するとDISPLAYの設定もします。
  * そのシェルからXのクライアントを起動します。追加でWSLのターミナルを立ち上げた場合は DISPLAYの設定を自分でしてください。


CC BY-SA 4.0
2020-05-23T04:35:50.080
66905
2020-05-30T01:57:59.903
2020-05-30T01:57:59.903
40200
40200
66736
answer