Windowsクライアントを使って、クラウド上のLinuxサーバでGUIアプリを実行したい（2）

# 1. 今回は設定編

[前回](https://qiita.com/yamada-hakase/items/952406904beffb9f5e85)は代表的な実現方法と、それぞれの特徴について説明した。今回はXサーバ「VcXsrv」での設定方法や使い方を説明する。

* [Windowsクライアントを使って、クラウド上のLinuxサーバでGUIアプリを実行したい（1）](https://qiita.com/yamada-hakase/items/952406904beffb9f5e85)

### 1-2. 作業の流れ

設定手順は以下の通り。1から2がLinuxサーバでの手順で、3から6がWindowsクライアントの手順である。今回はPuTTYを使用するが、Tera Termでも同じことができる。

**Linuxサーバで実施：**
　1. X11フォワーディングに必要なライブラリをLinuxにインストールする
　2. X11フォワーディングするようにsshdを設定する
**Windowsクライアントで実施：**
　3. VcXsrvをWindowsクライアントにインストールする
　4. VcXsrvを起動する
　5. sshクライアント（PuTTY）をX11フォワーディング用に設定する
　6. sshクライアント（PuTTY）でLinuxサーバに接続する

### 1-3. 使用環境

今回は以下の環境を使用している。またOracle Cloud Infrastructureを使用しているが、他のクラウドでもほとんど同じはずだ。

* RHEL9および互換ディストリビューション
* RHEL8および互換ディストリビューション
* RHEL7および互換ディストリビューション
* RHEL6および互換ディストリビューション
* PuTTY 0.71（他のバージョンやごった煮版などでも同じ）

### 1-4. 前提条件

* WindowsクライアントにPuTTYがインストール済みで、Linuxサーバに接続可能な状態になっていること。Tera Termについては説明しないので、他の記事を参考にしてほしい。

# 2. Linuxサーバにライブラリをインストールする

X11フォワーディング（画面転送）を使用するときは、Linuxサーバに完全なデスクトップ環境は不要である。しかし必要最小限のライブラリ群は必要になる。

### 2-1. Linuxサーバに必要なライブラリ

X11フォワーディングに必要なライブラリは以下の通り。一般には`xorg-x11-xauth`だけで十分だ。しかし以前使ったGUIツール（WebLogicのインストーラ）ではライブラリが不足していて起動できないことがあった。

* `xorg-x11-xauth`（`xauth`）
* `libXtst`
* `libXrender`

たいした大きさでもないし、不足していたときのトラブルシュートが意外と大変なので、念のため`libXtst`と`libXrender`を追加している。

### 2-2. ライブラリをインストールする

以下のコマンドでインストールする。

注目して欲しいのが、末尾の`Installed size`である。GNOMEデスクトップのインストールには数百MBytesのパッケージが必要になるが、今回のライブラリは5MBytesにも満たない。

```shell-session
#  yum install xauth libXtst libXrender -y
---以下コマンドの実行結果---
★中略★
================================================================================
 Package              Arch         Version               Repository        Size
================================================================================
Installing:
 libXrender           x86_64       0.9.10-1.el7          ol7_latest        25 k
 libXtst              x86_64       1.2.3-1.el7           ol7_latest        20 k
 xorg-x11-xauth       x86_64       1:1.0.9-1.el7         ol7_latest        29 k
Installing for dependencies:
 libICE               x86_64       1.0.9-9.el7           ol7_latest        66 k
 libSM                x86_64       1.2.2-2.el7           ol7_latest        39 k
 libX11               x86_64       1.6.5-2.el7           ol7_latest       606 k
 libX11-common        noarch       1.6.5-2.el7           ol7_latest       163 k
 libXau               x86_64       1.0.8-2.1.el7         ol7_latest        28 k
 libXext              x86_64       1.3.3-3.el7           ol7_latest        38 k
 libXi                x86_64       1.7.9-1.el7           ol7_latest        40 k
 libXmu               x86_64       1.1.2-2.el7           ol7_latest        70 k
 libXt                x86_64       1.1.5-3.el7           ol7_latest       172 k
 libxcb               x86_64       1.13-1.el7            ol7_latest       213 k

Transaction Summary
================================================================================
Install  3 Packages (+10 Dependent packages)
Total download size: 1.5 M
Installed size: 4.6 M ★とてもサイズが小さい
★以下省略
```

### 2-3. 動作確認用のGUIアプリケーションをインストールする

動作確認用のGUIアプリケーションには`xeyes`を使用するが、Linuxディストリビューションのバージョンによって状況が異なっている。そのため利用しているバージョンによってインストール方法が異なる。

* RHEL6/RHEL7系では`xeyes`は標準リポジトリに含まれている
* RHEL8系では`xeyes`は`codeready_builder`リポジトリに含まれている
* RHEL9系では`xeyes`は廃止されているので、xtermなどを使用する

### 2-3-1. RHEL6/RHEL7系の場合

動作確認用のGUIアプリケーション`xeyes`をインストールする。`xeyes`は`xorg-x11-apps`に含まれるプログラムなので次のように実行する。

```shell-session
# yum install xorg-x11-apps -y
```

### 2-3-2. RHEL8系の場合

`xeyes`は`codeready_builder`リポジトリに含まれているので次のように実行する。ただし、リポジトリ名はディストリビューションによって異なるので、適切なリポジトリに変更すること。

```shell-session
# yum --enablerepo=codeready_builder install xorg-x11-apps -y
```

| ディストリビューション | リポジトリ名 | 
|:-|:-|
| RHEL8  | codeready_builder  |   
| Oracle Linux 8 | ol8_codeready_builder  |   
| AlmaLinux 8/ RockyLinux 8 / CentOS Stream 8  | powertools |   


### 2-3-3. RHEL9系の場合

RHEL9系では`xeyes`は廃止されているので`xterm`などを使用する。

```shell-session
# yum install xterm -y
```

# 3. Linuxサーバのsshdを設定する

X11フォワーディングできるようにsshdを設定する。設定値を確認して、設定が不足していれば変更する。

### 3-1. X11フォワーディングで設定するパラメータ

確認するパラメータは以下の通り。

* `X11Forwarding yes`であること
* `X11UseLocalhost`はコメントアウトされているか`no`であること
* `AddressFamily inet`であること（IPv6が無効化されている環境のみ）。それ以外はデフォルトの`any`でも問題ない

それぞれのパラメータの意味は`man sshd_config`で確認できる。

### 3-2. 現在のsshdパラメータを確認する

`sshd`の設定ファイル`/etc/ssh/sshd_config`に設定されている値を確認する。

```shell-session
# grep -e X11UseLocalhost -e X11Forwarding -e AddressFamily /etc/ssh/sshd_config
---以下コマンドの実行結果---
#AddressFamily any
#X11Forwarding no
X11Forwarding yes
#X11UseLocalhost yes
#       X11Forwarding no
```

### 3-3. sshdのパラメータを変更する

どの値を変更するかは各自の状況に応じて判断して欲しい。当然エディタで変更してもかまわない。今回は`AddressFamily`を`any`から`inet`に変更する。

```shell-session
# sed -i -e "s/^\#AddressFamily any/AddressFamily inet/" /etc/ssh/sshd_config
```

今回一番ハマったのが`AddressFamily`の値である。デフォルトの`any`でも問題ないはずだが、Oracle Cloud Infrastructure Computeの2019年5月OSイメージでは、これが原因で接続できなかった。

半年以上前に以下のホワイトペーパー通りに試したときには問題なかった気がするのだが…。Oracle Cloud Infrastructureを使用していなくても、IPv6が無効化されているときは変更した方がいいかもしれない。


* [Running Graphical Applications Securely on Oracle Cloud Infrastructure（PDF）](https://cloud.oracle.com/iaas/whitepapers/run_graphical_apps_securely_on_oci.pdf)

今回は↓のエントリを参考にさせていただきました。[ora_gonsuke777さん](https://qiita.com/ora_gonsuke777)、ありがとうございます。

* [OCI(Oracle Cloud Infrastructure)のComputeインスタンスで端末へのX Window ssh転送が出来るように設定する。](https://qiita.com/ora_gonsuke777/items/765189e9e301415e7ba5)

**IPv6が無効化の確認方法：**
IPv6が無効化されていることは`ip`コマンドで判別できる。以下のように`inet`で始まる行だけで、`inet6`で始まる行がないときはIPv6が無効化されている可能性がある。

```shell-session
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
    link/ether 02:00:17:00:13:0c brd ff:ff:ff:ff:ff:ff
    inet 10.5.0.2/24 brd 10.5.0.255 scope global dynamic ens3
       valid_lft 81375sec preferred_lft 81375sec
```

### 3-4. パラメータが正しく設定されていることを確認する

最後にもう一度、正しく設定されていることを確認する。

```shell-session
# grep -e X11UseLocalhost -e X11Forwarding -e AddressFamily /etc/ssh/sshd_config
---以下コマンドの実行結果---
AddressFamily inet
X11Forwarding yes
#X11UseLocalhost yes
#       X11Forwarding no
```

### 3-5. sshdのパラメータを有効化する

パラメータを有効にするために`sshd`を再起動する。

　**RHEL7/8/9系の場合**

```shell-session
# systemctl restart sshd
```

　**RHEL6系の場合**

```shell-session
# service sshd restart
```

これでLinuxサーバ側の作業はおわりだ。次にWindowsクライアント側で設定する。

### 3-6. まとめ版（7/8/9系Linux OS用）
コピペ用のまとめ版。使用環境よって/etc/ssh/sshd_configの内容は異なるので、grepの結果を確認すること。

```shell-session
# 必要ライブラリのインストール
yum install xauth libXtst libXrender -y

# GUIツールのインストール（使用ディストリビューションに応じて選択）
# ---
# RHEL6/7系
yum install xorg-x11-apps -y
# ---
# AlmaLinux8/RockyLinux8/CentOS Stream8
yum --enablerepo=powertools install xorg-x11-apps -y
# Oracle Linux 8
yum --enablerepo=ol8_codeready_builder install xorg-x11-apps -y
# RHEL8
yum --enablerepo=codeready_builder install xorg-x11-apps -y
# ---
# RHEL9系
yum install xterm

# AddressFamilyの変更（環境に応じて）
sed -i -e "s/^\#AddressFamily any/AddressFamily inet/" /etc/ssh/sshd_config

# 設定値の確認。X11UseLocalhostが
grep -e X11UseLocalhost -e X11Forwarding -e AddressFamily /etc/ssh/sshd_config

# sshd再起動
systemctl restart sshd
```

# 4. VcXsrvをインストールする

ここからはWindowsクライアントでの作業になる。

1. [VcXsrv公式サイト（SourceForge）](https://sourceforge.net/projects/vcxsrv/)からインストーラをダウンロードして実行する。これ以降は基本的にデフォルトのままでよい。
![SnapCrab_VcXsrv Setup Installation Options_2019-5-23_17-57-28_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/bcc6f91d-e3b1-f70e-8944-c216c93ae22e.png)

2. インストール先フォルダが表示されるので、このままでよいときは **[Install]** をクリックする。
![SnapCrab_VcXsrv Setup Installation Folder_2019-5-23_17-57-41_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/b24d89b9-8ac7-9e0d-c8e2-403ff5e942cd.png)

3. Completedと表示されたら、 **[Close]** をクリックしてインストーラを終了する。
![SnapCrab_VcXsrv Setup Completed_2019-5-23_17-58-4_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/0896a5c8-12c6-de5e-7c45-0131f1d16052.png)

# 5. VcXsrvを起動する

X11フォワーディングで画面を転送できるようにVcXsrvを起動する。

1. Windowsデスクトップの`XLaunch`アイコンをクリックしてVcXsrvを起動する。
![SnapCrab_NoName_2019-5-23_17-59-38_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/657423ec-9e1a-1389-9d5d-e52514d3bbc5.png)
なおVcXsrvとXmingの両方をインストールしているときは、アイコンも名前も同じで区別しづらい。名前を変えたほうがいいだろう。

2. どれを選んでもよいが、デフォルトのまま **[次へ]** をクリックする
![SnapCrab_Display settings_2019-5-23_18-1-46_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/ae1323b8-d3c1-e6d8-10ed-ac349e537051.png)

3. まだPuTTYを起動していないので、 **[start no client]** を選択してから **[次へ]** をクリックする。
![SnapCrab_Client startup_2019-5-23_18-59-33_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/5ddd0e21-d9d3-8a88-1669-937511a06330.png)

4. **[Disable access control]** をチェックしてから **[次へ]** をクリックする。今回の検証環境では必須ではないが、チェックが必要な環境もある。
![VcXsrv05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/c46cb011-1388-ef87-df55-f28311184247.png)

5. これで設定は終了である。今後も同じ設定を利用するときは **[Save configuration]** をクリックする。
![SnapCrab_Finish configuration_2019-5-23_18-3-24_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/bf920c14-dc55-dcac-7d49-67ee436ac28b.png)

6. 起動に成功するとデスクトップ右下のタスクバーにアイコンが表示される。これ以降、Windowsをシャットダウンしたり、VcXsrvを明示的に停止したりしない限り、起動したままになっている。
![xserver03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/49938b83-8372-e7cb-7f5b-582eaf74d135.png)

# 6. PuTTYを設定する

PuTTYはLinuxサーバに接続する設定があることを前提に、それをカスタマイズする。

1. PuTTYを起動して、使用する接続情報をロードする。

2. 左側のツリーから[Connection]-[SSH]-[X11]を選択し、X11フォワーディングを有効化する。
![SnapCrab_PuTTY Configuration_2019-5-23_18-8-42_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/a1974a17-61a1-c58c-5e83-0c6d03c64fc3.png)

3. 必須項目でないが圧縮を有効化する。
![SnapCrab_PuTTY Configuration_2019-5-23_18-21-24_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/d15e630d-a461-c7af-7c85-01262efa9a0c.png)

4. 最後に左側ツリーの[Session]に戻り、変更した設定を保存する。これを忘れると変更が消えるので注意すること。

5. これで設定は終了である。次から実際にLinuxサーバに接続する。


# 7. Linuxサーバに接続する(基本編)

まずは基本編として、踏み台なしでLinuxサーバに接続する。

1. 右下のタスクバーで、VcXsrvが起動していることを確認する。アイコンが無いときは起動する。
![xserver03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/49938b83-8372-e7cb-7f5b-582eaf74d135.png)

2. 前のステップで保存した設定を利用し、PuTTYでLinuxサーバに接続する。

3. `DISPLAY`環境変数が設定されていることを確認する。sshdとPuTTYを正しく設定していれば、自動的に設定されているはずである。

```shell-session
$ echo $DISPLAY
localhost:10.0
```

4.動作確認のため`xeyes`を起動する。デスクトップに以下の目玉が表示されれば成功している。

```shell-session
$ xeyes &
```

![xeyes.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/d0ee88d6-b1ad-88ae-d5c6-c20a02f4110c.png)

**<font color="red">注意：ログイン後にsuするときは追加作業が必要</font>**

SSHログイン後に`su`してからGUIアプリを起動すると、次のエラーが出て実行できない。

```
X11 connection rejected because of wrong authentication.
Error: Can't open display: localhost:10.0
```

これは~/.Xauthorityの認証クッキーが他のユーザーに無いことが原因だ。対応方法は以下のとおり。


1. SSHログインしたユーザーでクッキーを確認する（今回の場合はopc）。複数表示されたときは自ホスト名でディスプレイ番号:10が該当のクッキーである。

```shell-session
$ xauth list
<hostname2>:1  MIT-MAGIC-COOKIE-1  XXXXXXXXXXXXXXXXXX(32桁の英数字)
<hostname1>/unix:1  MIT-MAGIC-COOKIE-1  XXXXXXXXXXXXXXXXXX(32桁の英数字)
<hostname1>/unix:10  MIT-MAGIC-COOKIE-1  XXXXXXXXXXXXXXXXXX(32桁の英数字)★これ
```

2.目的のユーザーにsuする。`-i`は、suしたユーザーの.bashrcや.bash_profileを読み込むオプション。

```shell-session
$ sudo -i su - oracle
```

3.`xauth add`コマンドでクッキーを追加する。このとき先頭部分からすべて指定する。

```shell-session
$ xauth add <hostname1>/unix:10  MIT-MAGIC-COOKIE-1  XXXXXXXXXXXXXXXXXX(32桁の英数字)
```

4.ディスプレイ番号を設定したら準備完了。

```shell-session
$ export DISPLAY=localhost:10.0
```

5.目的のGUIアプリケーションを実行する。

```shell-session
$ xeyes &
```

こちらのブログに教えてもらいました。

* [Oracle Database 19cを Oracle CloudのIaaS(computeインスタンス)へインストールする(Oracle Universal Installerを起動する)](https://qiita.com/ts_carp/items/f79d85971c977c760245)

# 8. 次回は？

事前にsshで接続できていれば、驚くほど簡単な作業だったかもしれない。[次回](Windowsクライアントを使って、クラウド上のLinuxサーバでGUIアプリを実行したい（2）)は踏み台経由の接続方法を説明する。

* [Windowsクライアントを使って、クラウド上のLinuxサーバでGUIアプリを実行したい（3）](https://qiita.com/yamada-hakase/items/e1946b8a598f4cc0bcfa)