概要
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 の代表的な投稿 によれば
- Windows Security -> Firewall & network protection -> Allow an app through firewall -> make sure VcXsrv has both public and private checked
- Launch VcXsrv with "Disable access control" ticked
- 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 を使いこなすために:
- Tera Term を起動。
- Tera Term: 新しい接続 は キャンセル 。
- 設定(S) > SSH鍵生成(N)… > TTSSH: 鍵生成 ですべてデフォルト3のまま 生成(G) 。
- 数秒で鍵が生成されグレイアウト部分が解除される。 鍵のパスフレーズ: も今回は空欄のまま 公開鍵の保存(I) と 秘密鍵の保存(P) 。保存先は任意だが、次の公開鍵の登録と WSL2 への接続のときに参照する。ここでは
- フォルダーは
C:\Users\<UserName>\Documents\TTSSH
(右クリックのコンテキスト メニューで作成) - 公開鍵のファイル名はデフォルトの
id_rsa.pub
- 秘密鍵のファイル名はデフォルトの
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 ウィザード経由で起動する方法
- XLaunch を起動。
- Display settings: Display number に 0 を入れる5。 次へ(N) > 。
- Client setup: 次へ(N) > 。
- Extra settings: デフォルトのインストール状態では手順 2. Display number が 0 の場合は Disable access control にチェックは不要。 次へ(N) > 。
- Finish configuration: 完了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 を指定して接続
- 設定(S) > SSH転送(O)… > SSHポート転送 > リモートのXアプリケーションをローカルのXサーバに表示する にチェック7。
- ファイル(F) > 新しい接続(N)…
-
Tera Term: 新しい接続: ホスト(T):
localhost
。その他はデフォルトで OK 。 -
SSH認証: ユーザ名: WSL2 のユーザー名。 パスフレーズ(P): は今回は空欄のまま。 RSA/DSA/ECDSA/ED25519鍵を使う を選択、 秘密鍵(K):
C:\Users\<UserName>\Documents\TTSSH\id_rsa
。 -
$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接続を転送する。
転送先ディスプレイを指定しなかった場合は、以下の優先順位で転送先が決定される。
- 設定ファイルの [TTSSH] セクションの X11Display 設定
- 環境変数 DISPLAY の値
- 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 マクロを作成しました。
-
exec
でwsl.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
; 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.INI
のTermType=xterm
をTermType=xterm-256color
に変更する。 - Alt キーがターミナルに伝わるようにするには 設定(S) > キーボード(K)… > Tera Term: キーボードの設定 で Meta キー: を好みに応じて off 以外にする。
-
試していませんが Putty でも可能か。
ssh.exe -X
はset DISPLAY=:0.0
としてから実行するとエラーになります。 ↩ -
正確には X クライアントに都度都度
-display <WindowsIPAddress>:0.0
オプションをつければ使えます。 ↩ -
オプションの意味がよく分かっていませんが、公衆網に接続するわけでもないので。 ↩
-
PowerShell なら
$LASTEXITCODE
。 ↩ -
デフォルトの -1 でも最初の起動では 0 になるはずですが念のため。 ↩
-
Save configuration はオプションですが、次回はここで保存された
*.xlaunch
ファイルをダブル クリックすると保存された設定ですぐに VcXsrv が起動します。 ↩ -
この状態を保存し次回に自動で読み込むには 設定(S) > 設定の保存(S)… から ドキュメント フォルダーに
TERATERM.INI
という名前で保存します。 ↩ -
Tera Term をもう一つ起動し同様に接続すると
localhost:11.0
とディスプレイ番号がインクリメントされます。 ↩ -
この
1
はxeyes &
コマンドの下に表示された[...]
の中の数字と同じものを指定。 ↩ -
hwclock -s
だと 1 秒以上ずれが残ることに気づいたので、date -s
にしてみましたが 0.5 秒程度ずれます。 (echo %TIME% && wsl -e date +%H:%M:%S.%N
で確認。) ↩ -
一時ファイルやクリップボード経由というのは気乗りしません。 ↩