5
1

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 と Tera Term で X Forwarding

Last updated at Posted at 2020-07-26

概要

Windows Subsystem for Linux 2 (WSL2) に Tera Term で SSH で接続し X Forwarding で X クライアント アプリケーションを動作させる手順をまとめます。また、接続を自動化する Tera Term マクロを作成しました。

利点

  • VcXsrv に対する Windows Defender ファイアウォールでパブリックはもちろんプライベートも閉じてしまってよい。
  • VcXsrv のデフォルト インストールではディスプレイ番号 0 の場合 Disable access control (-ac) オプションが不要。
  • X Forwarding が WSL2 の $DISPLAY を自動的に設定。
  • ターミナル側からディスプレイ番号を指定可能1
  • /etc/ssh/sshd_config も (Ubuntu-18.04 の場合) デフォルトのまま。

ちなみに、 SSH の X Forwarding を使わない場合は Can't use X-Server in WSL 2 #4106 の代表的な投稿 によれば

  1. Windows Security -> Firewall & network protection -> Allow an app through firewall -> make sure VcXsrv has both public and private checked
  2. Launch VcXsrv with "Disable access control" ticked
  3. DISPLAY variable:
export DISPLAY=`grep -oP "(?<=nameserver ).+" /etc/resolv.conf`:0.0

欠点

  • $DISPLAY を手動で .bash_profile に書くのに比べ随分と手間暇がかかる。
  • ($DISPLAY の自動設定と Windows ファイアウォールのデフォルトにこだわると) 他のターミナル アプリから X を使えない2

資材調達

動作確認バージョン

ソフトウェア バージョン
Windows 10 Home 2004 (ビルド 19041.388)
Linux ディストリビューション Ubuntu 18.04
VcXsrv 1.20.8.1
Tera Term 4.105

手順

1. 公開鍵と秘密鍵の作成

ssh-keygen.exe を使ったほうが手ばやい気もしますが、 Tera Term を使いこなすために:

  1. Tera Term を起動。
  2. Tera Term: 新しい接続キャンセル
  3. 設定(S) > SSH鍵生成(N)… > TTSSH: 鍵生成 ですべてデフォルト3のまま 生成(G)
  4. 数秒で鍵が生成されグレイアウト部分が解除される。 鍵のパスフレーズ: も今回は空欄のまま 公開鍵の保存(I)秘密鍵の保存(P) 。保存先は任意だが、次の公開鍵の登録と WSL2 への接続のときに参照する。ここでは
    1. フォルダーは C:\Users\<UserName>\Documents\TTSSH (右クリックのコンテキスト メニューで作成)
    2. 公開鍵のファイル名はデフォルトの id_rsa.pub
    3. 秘密鍵のファイル名はデフォルトの id_rsa

2. 公開鍵を WSL2 に登録

(初稿では authorized_keys に対する認識と調査が不足していて、また、 authorized_keys が存在していない状態を想定していて、単純にリネーム コピーしましたが、 authorized_keys には複数の公開鍵を追加していけるものと知りましたので、それにふさわしい方法に修正します。)

WSL2 のコンソールを開き公開鍵を ~/.ssh ディレクトリー配下の authorized_keys に追記 (存在しなければ作成):

$ test -e ~/.ssh || mkdir ~/.ssh
$ cat /mnt/c/Users/<UserName>/Documents/TTSSH/id_rsa.pub >>~/.ssh/authorized_keys

WSL2 からは上記手順での公開鍵の保存先例が /mnt/c/Users/<UserName>/Documents/TTSSH/id_rsa.pub という形で参照されます。

>> がファイルの末尾に追記 (存在しなければファイルを作成) を指示していますが、これをうっかり単一の > にしてしまうと、もし authorized_keys が存在していたとすると、上書きになってもともと登録されていた鍵が消失してしまいます。

3. WSL2 (Ubuntu 18.04) で sshd の起動

初期状態で コマンド プロンプト から sshd の状態を確認4:

C>wsl.exe --exec /usr/sbin/service ssh status
 * sshd is not running

C>echo %errorlevel%
3

sshd を起動:

C>wsl.exe --user root --exec /usr/sbin/service ssh start
 * Starting OpenBSD Secure Shell server sshd                                                                     [ OK ]

C>echo %errorlevel%
0

なお、 Windows を再起動すると sshd は停止し自動では開始しません。後に記載する Tera Term マクロはこのことに配慮しています。

4. VcXsrv の起動

次項の Tera Term で接続の前ならいつでも可。

XLaunch ウィザード経由で起動する方法

  1. XLaunch を起動。
  2. Display settings: Display number0 を入れる5次へ(N) >
  3. Client setup: 次へ(N) >
  4. Extra settings: デフォルトのインストール状態では手順 2. Display number0 の場合は Disable access control にチェックは不要。 次へ(N) >
  5. Finish configuration: 完了6
  6. システム トレイX のアイコンをポイントし ツールチップComputerName**:0.0 - 0 clients** と表示されることを確認。

コマンドラインから起動する方法

C>"%ProgramFiles%\VcXsrv\vcxsrv.exe" :0 -multiwindow

PowerShell の場合は

& "$env:ProgramFiles\VcXsrv\vcxsrv.exe" :0 -multiwindow

5. Tera Term で X Forwarding を指定して接続

  1. 設定(S) > SSH転送(O)… > SSHポート転送 > リモートのXアプリケーションをローカルのXサーバに表示する にチェック7
  2. ファイル(F) > 新しい接続(N)…
  3. Tera Term: 新しい接続: ホスト(T): localhost 。その他はデフォルトで OK
  4. SSH認証: ユーザ名: WSL2 のユーザー名。 パスフレーズ(P): は今回は空欄のまま。 RSA/DSA/ECDSA/ED25519鍵を使う を選択、 秘密鍵(K): C:\Users\<UserName>\Documents\TTSSH\id_rsa
  5. $DISPLAY が次のように設定されていれば成功8
$ echo $DISPLAY
localhost:10.0

WSL2 への localhost 接続について

当方ではあるとき突然 localhost で WSL2 への接続が拒否されるようになりました。

ここ の情報にしたがって、 コントロール パネル\ハードウェアとサウンド\電源オプション\システム設定高速スタートアップを有効にする (推奨) のチェックを外したら、 (再起動しなくても) 接続が復帰しました。

6. X クライアント アプリケーションのインストールと起動テスト

まずはパッケージをアップデート:

$ sudo apt update && sudo apt upgrade

起動テスト用として定番アイテムの x11-apps パッケージをインストール:

$ sudo apt install x11-apps

たとえば

$ xlogo -fg red -bg green &

VcXsrv のディスプレイ番号と複数起動について

TTSSH コマンドラインの /ssh-X オプションのヘルプ より引用しますと

/ssh-X[[<hostname>]:<displaynumber>[.<screennumber>]]
X11転送を有効にする
転送先ディスプレイを指定した場合は、その転送先へX11接続を転送する。
転送先ディスプレイを指定しなかった場合は、以下の優先順位で転送先が決定される。

  1. 設定ファイルの [TTSSH] セクションの X11Display 設定
  2. 環境変数 DISPLAY の値
  3. localhost:0.0

上記手順の状態では 3. localhost:0.0 で転送先が決定されます。上記手順で VcXsrv のディスプレイ番号に 0 を念のため明示的に指定したのはこのためです。

上記手順の状態で VcXsrv にディスプレイ番号 1 を指定してもう一つ起動してみます。また、状態を分かりやすくするためにマルチ ウィンドウを外します。

ここがややこしいのですが、デフォルトのインストール状態で %ProgramFiles%\VcXsrv\X0.hosts というテキスト ファイルがあり、これがディスプレイ番号 0 のアクセス許可を指定しています。

C>type "%ProgramFiles%\VcXsrv\X0.hosts"
localhost
inet6:localhost

SSH を使わないで WSL2 で /etc/resolv.conf などから VcXsrv が稼働している IP アドレスを拾って $DISPLAY に設定するやり方だと、本来ならば X0.hosts にその IP アドレスを追記してやらなければなりません。しかし、この IP アドレスは変動します。

ディスプレイ番号 1 については X1.hosts が対応しますが、デフォルトでは存在しません。

ここでは手抜きで -ac (Disable access control) オプションを使ってしまいます。

C>"%ProgramFiles%\VcXsrv\vcxsrv.exe" :1 -ac

背景が真っ黒なウインドウが一つ現れます。

そして、環境変数 %DISPLAY% をセットしてから Tera Term ももう一つ起動します。

C>set DISPLAY=localhost:1.0

C>"%ProgramFiles(x86)%\teraterm\ttermpro.exe" localhost:22 /ssh /2 /user=<WslUserName> /auth=publickey /keyfile=%USERPROFILE%\Documents\TTSSH\id_rsa /ssh-X

いま起動したほうの Tera Term のコンソールでたとえば xeyes を起動してみます。

$  xeyes &
[1] 1048

すると、先ほどの背景が真っ黒な VcXsrv のウインドウの中に xeyes が現れます。この中ではまだウインドウ マネージャーが動いていないので、この xeyes を閉じるには Tera Term のコンソールで kill %1 などとします9

なお、この Tera Term でディスプレイ番号を指定する項目は GUI には見あたりません。

Tera Term マクロ

以上を踏まえた Tera Term マクロを作成しました。

  • execwsl.exe を呼び出し sshd の状態をチェックし必要に応じて起動しています。 Windows と時刻がずれる問題 の暫定的対処もここに盛り込んでしまいました10
  • exec で外部コマンドの終了コードしかうけとれないのがつらいところです11。接続までしかしていないので、 Tera Term マクロ (TTL) に拘泥することもなかったのかもしれませんが、今回は TTL をすこし研究したかったのです。
  • VcXsrv を起動していないと警告ダイアログが二回出ますが、事後に VcXsrv を起動しても X クライアントは動作することもあって、対策はしていません。
  • 一応 /ssh-X オプションの引数を受け取れるようにしてあります。

使用例:

C>"%ProgramFiles(x86)%\teraterm\ttpmacro.exe" /V %USERPROFILE%\Documents\Scripts\connect_wsl2.ttl localhost:1.0
connect_wsl2.ttl
; https://devblogs.microsoft.com/commandline/whats-new-for-wsl-in-insiders-preview-build-18945/
host = 'localhost' 

username = '<WslUserName>'

getspecialfolder dir 'MyDocuments'
makepath keyfile dir 'TTSSH\id_rsa'

expandenv wsl '%windir%\Sysnative\wsl.exe '

; https://github.com/microsoft/WSL/issues/4245
getdate date '%Y-%m-%d %H:%M:%S'
sprintf2 wsldate '%s%s%' wsl ' --user root --exec /bin/date -s ' date
exec wsldate 'hide' 1

sprintf2 wslsshstatus '%s%s' wsl '--exec /usr/sbin/service ssh status'
exec wslsshstatus 'hide' 1
if result = 3 then
  sprintf2 wslsshstart '%s%s' wsl '--user root --exec /usr/sbin/service ssh start'
  exec wslsshstart 'hide' 1
endif
if result = 0 then
  ttsshopts = host
  strconcat ttsshopts ':22 /ssh /2 /auth=publickey /user='
  strconcat ttsshopts username
  strconcat ttsshopts ' /keyfile='
  strconcat ttsshopts keyfile
  strconcat ttsshopts ' /ssh-X'
  strconcat ttsshopts param2
  connect ttsshopts
endif

付録 Tera Term の Tips

  • 設定(S) > 設定の保存(S)… でデフォルトのまま ドキュメントTERATERM.INI として保存すると、次回からの起動時に読み込んでくれる。
  • Ubuntu のプロンプトをカラーにするには TERATERM.INITermType=xtermTermType=xterm-256color に変更する。
  • Alt キーがターミナルに伝わるようにするには 設定(S) > キーボード(K)… > Tera Term: キーボードの設定Meta キー: を好みに応じて off 以外にする。
  1. 試していませんが Putty でも可能か。 ssh.exe -Xset DISPLAY=:0.0 としてから実行するとエラーになります。

  2. 正確には X クライアントに都度都度 -display <WindowsIPAddress>:0.0 オプションをつければ使えます。

  3. オプションの意味がよく分かっていませんが、公衆網に接続するわけでもないので。

  4. PowerShell なら $LASTEXITCODE

  5. デフォルトの -1 でも最初の起動では 0 になるはずですが念のため。

  6. Save configuration はオプションですが、次回はここで保存された *.xlaunch ファイルをダブル クリックすると保存された設定ですぐに VcXsrv が起動します。

  7. この状態を保存し次回に自動で読み込むには 設定(S) > 設定の保存(S)… から ドキュメント フォルダーに TERATERM.INI という名前で保存します。

  8. Tera Term をもう一つ起動し同様に接続すると localhost:11.0 とディスプレイ番号がインクリメントされます。

  9. この 1xeyes & コマンドの下に表示された [...] の中の数字と同じものを指定。

  10. hwclock -s だと 1 秒以上ずれが残ることに気づいたので、 date -s にしてみましたが 0.5 秒程度ずれます。 (echo %TIME% && wsl -e date +%H:%M:%S.%N で確認。)

  11. 一時ファイルやクリップボード経由というのは気乗りしません。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?