Cloud9にリモートデスクトップする方法

# はじめに
AWSのCloud9は、AWSマネジメントコンソールからIDEとターミナルで開発や検証を進めますが、時々、ローカルのデスクトップ環境が欲しくなることがあります。

例えば、Webサイトやアプリケーションを開発すれば、ローカルのApache等に配置し、ブラウザから動作確認したいところです。
Pythonでrunserverを実行して、簡易的にWebサーバを起動して同様に動作確認したい場面もあるかと思います。
また、Cloud9にはdockerがプリインストールされているため、コンテナをbuildしたりupしたりすれば、ローカルで接続テストをしたい場面があるでしょう。
このような場面で、解説書やブログを参考にしていると、ブラウザで http://127.0.0.1:8000 や http://localhost 等に接続してGUIを確認する手順 (以下画像のようなこと) を指示される場合がありますが、Cloud9で開発していると手順通りに行かないため、先に進まなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/4fa63279-453f-3737-c2a3-36314d9b2b24.png)

もしCloud9にローカルのデスクトップ環境があれば、Cloud9でローカル上にテスト環境を作った後、ブラウザを開いて、さくっと接続確認できるので、生産性が上がります。

そこで、Cloud9にデスクトップ環境をインストールし、リモートデスクトップする手順を調査し、整理してみました。

# 前提環境
* Cloud9: EC2環境 (OS: Ubuntu Server 18.04 LTS)
* インスタンスタイプ: t3.micro以上を推奨
* インストールするデスクトップ環境: MATE

※ 最後の接続確認はMacから実施しています。

## 構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/3a22f791-9eb4-51df-b8a2-30b6874f1bda.png)

# Cloud9 (AWS) で実施する手順
## 1. Cloud9を構築する
環境の名前や説明はお好みで付ければOKです。
以下の画像の通り、Environment typeをEC2、PlatformをUbuntu Server 18.04 LTSとして構築します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/606b7bb4-e9c3-0a86-fdd4-931487718cfc.png)

### Point: 何故Amazon Linuxにしないのか
ここでAmazon Linuxを選んでも良いのですが、2020年1月の時点では、以下の理由で推奨しません。

* ここでAmazon Linuxを選択しても、Amazon Linux 2にはなりませんので、[公式チュートリアル](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-2-install-gui/)の手順でデスクトップ環境を作ることができません。
    * Amazon Linux 2でCloud9を構築するにはSSH環境にする必要がありますが、SSH環境では一定時間操作がない時の自動停止機能が使えないので、私のようなズボラな方にはお勧めできません。
* Amazon Linuxは、2020年6月にサポートが終了します。
    * [Q: Amazon Linux AMI はどれくらいの期間、サポートされますか?](https://aws.amazon.com/jp/amazon-linux-ami/faqs/#how_long)

>Q: Amazon Linux AMI はどれくらいの期間、サポートされますか?
AWS では 2020 年 6 月 30 日まで、Amazon Linux AMI 2018.03 の最新バージョンに対するセキュリティ更新の提供を継続し、Amazon Linux 2 への移行を促進します。Amazon Linux 2 では、2023 年 6 月 30 日まで長期サポートを受けることができます。

## 2. デフォルトで作成されたEBSを拡張する
早速Cloud9に接続してデスクトップ環境をインストールしたいところですが、何もしないままにこの後紹介する手順でインストールを進めると、**デフォルトで作成されるEBSボリュームの容量 (10GB) では不足してしまい、インストールが失敗します。**

そこで、EBSボリュームを 10GB → 15GB に拡張します。
まずはAWSのマネジメントコンソールで、ボリュームの変更を行い、容量を拡張します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/622e3b1b-713f-b7c1-a481-36b797ef6bce.png)

次に、拡張したEBSの容量を、OS上でも認識させます。
Cloud9のマネジメントコンソールを開き、ターミナルのウインドウで操作します。

まず`lsblk`でパーティションを確認すると、拡張すべきパーティションが/dev/nvme0n1の1番目(MOUNTPOINTが/)だと分かりますので、`sudo growpart /dev/nvme0n1 1`を実行して拡張します。
上記の実行後、パーティションを拡張した結果を`lsblk`で確認すると、15GBになっていることが分かります。
次に`df -h`でファイルシステムを確認し、拡張すべきファイルシステムが/dev/nvme0n1p1だと分かりますので、`sudo resize2fs /dev/nvme0n1p1` を実行して拡張します。
上記の実行後、ファイルシステムを拡張した結果を`df -h`で確認すると、15GBになっていることが分かります。

コマンドは以下の通りとなります。

```bash:bash
ubuntu:~/environment $ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0         7:0    0 12.7M  1 loop /snap/amazon-ssm-agent/495
loop1         7:1    0 87.9M  1 loop /snap/core/5328
loop2         7:2    0 89.1M  1 loop /snap/core/8268
nvme0n1     259:0    0   15G  0 disk 
└─nvme0n1p1 259:1    0   10G  0 part /

ubuntu:~/environment $ sudo growpart /dev/nvme0n1 1
CHANGED: partition=1 start=2048 old: size=20969439 end=20971487 new: size=31455199,end=31457247

ubuntu:~/environment $ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0         7:0    0 12.7M  1 loop /snap/amazon-ssm-agent/495
loop1         7:1    0 87.9M  1 loop /snap/core/5328
loop2         7:2    0 89.1M  1 loop /snap/core/8268
loop3         7:3    0   18M  1 loop /snap/amazon-ssm-agent/1480
nvme0n1     259:0    0   15G  0 disk 
└─nvme0n1p1 259:1    0   15G  0 part /

ubuntu:~/environment $ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            468M     0  468M   0% /dev
tmpfs            96M  764K   96M   1% /run
/dev/nvme0n1p1  9.7G  7.6G  2.1G  79% /
tmpfs           479M     0  479M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           479M     0  479M   0% /sys/fs/cgroup
/dev/loop0       13M   13M     0 100% /snap/amazon-ssm-agent/495
/dev/loop1       88M   88M     0 100% /snap/core/5328
tmpfs            96M     0   96M   0% /run/user/1000
/dev/loop2       90M   90M     0 100% /snap/core/8268
/dev/loop3       18M   18M     0 100% /snap/amazon-ssm-agent/1480
ubuntu:~/environment $ sudo resize2fs /dev/nvme0n1p1 
resize2fs 1.44.1 (24-Mar-2018)
Filesystem at /dev/nvme0n1p1 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 2
The filesystem on /dev/nvme0n1p1 is now 3931899 (4k) blocks long.

ubuntu:~/environment $ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            468M     0  468M   0% /dev
tmpfs            96M  764K   96M   1% /run
/dev/nvme0n1p1   15G  7.6G  7.0G  53% /
tmpfs           479M     0  479M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           479M     0  479M   0% /sys/fs/cgroup
/dev/loop0       13M   13M     0 100% /snap/amazon-ssm-agent/495
/dev/loop1       88M   88M     0 100% /snap/core/5328
tmpfs            96M     0   96M   0% /run/user/1000
/dev/loop2       90M   90M     0 100% /snap/core/8268
/dev/loop3       18M   18M     0 100% /snap/amazon-ssm-agent/1480
```

ここまでの手順で、EBSの容量を 10GB → 15GB に拡張できました。

## 3. デスクトップ環境 (MATE) をインストールする
以下のコマンドを実行するだけです。

```bash:bash
ubuntu:~/environment $ sudo apt install ubuntu-mate-desktop
```

## 4. vnc4serverをインストールして設定する

Cloud9にリモートデスクトップするために、以下のコマンドで、vnc4serverをインストールします。

```bash:bash
ubuntu:~/environment $ sudo apt install vnc4server
```

インストールが完了したら、以下のコマンド`vncserver :1`を実行し、一度VNCサーバを起動します。
コマンドを実行すると、デスクトップ環境にログインするためのパスワードの設定を求められますので、入力して設定します。
このパスワードは6文字以上8文字以下となり、**8文字以上入力した時は、8文字目までがパスワードとして設定されます。**

```bash:bash
ubuntu:~/environment $ vncserver :1

You will require a password to access your desktops.

Password:
Verify:
Password too long - only the first 8 characters will be used
xauth:  file /home/ubuntu/.Xauthority does not exist

New 'ip-172-31-43-50:1 (ubuntu)' desktop is ip-172-31-43-50:1

Creating default startup script /home/ubuntu/.vnc/xstartup
Starting applications specified in /home/ubuntu/.vnc/xstartup
Log file is /home/ubuntu/.vnc/ip-172-31-43-50:1.log
```

起動が完了したら、すぐVNCサーバを停止します。

```bash:bash
ubuntu:~/environment $ vncserver -kill :1
Killing Xvnc4 process ID 1058
```

次に、一度起動したことによって、VNCサーバの設定ファイル`/home/ubuntu/.vnc/xstartup` が生成されていますので、この設定ファイルをMATE用に編集します。

```bash:bash
$ vi /home/ubuntu/.vnc/xstartup
```

設定ファイルの中身を、以下の内容に編集して保存します。

```bash:/home/ubuntu/.vnc/xstartup
#!/bin/sh

# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc

unset DBUS_SESSION_BUS_ADDRESS
export XMODIFIERS="@im=fcitx"
fcitx

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
# vncconfig -iconic &
# x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
# x-window-manager &
mate-session &
```

## 5. vnc4serverの自動起動を設定
Cloud9を起動した時に、vnc4serverも自動起動するようにします。
`~/.bashrc`を開き、最下行に起動コマンドを追記します。

```bash:bash
ubuntu:~/environment $ vi ~/.bashrc
```

以下のように、最下行に起動コマンドを追記して保存します。
オプションの`-geometry`は解像度、`-depth`はビットカラー (8: 256色、16: 最大65536色、24: 最大16777216色)を示しますので、リモートデスクトップするクライアントの環境に合わせて変えてください。

```~/.bashrc
# .bashrc

export PATH=$PATH:$HOME/.local/bin:$HOME/bin

(中略)

# Add RVM to PATH for scripting. Make sure this is the last PATH variable change.
export PATH="$PATH:$HOME/.rvm/bin"

# ここから追記
vncserver :1 -geometry 1280x800 -depth 24
```

保存後、OSを再起動します。

```bash:bash
ubuntu:~/environment $ sudo shutdown -r now
```

Cloud9のマネジメントコンソール上に 「Connecting...」と表示されますので、自然に消えるのを待った後、次の手順に進みます。

## 6. SSHポートフォワードするため、パスワード認証を有効にする

デスクトップ環境にはインターネット経由で接続することになりますので、SSHポートフォワードを利用して、暗号化されたセキュアな接続にします。
Cloud9をubuntuユーザで利用する場合が殆どだと思いますので、デスクトップ環境もubuntuユーザで接続できるようにします。

まず、ubuntuユーザのパスワードを設定します。

```bash:bash
$ sudo passwd ubuntu
Enter new UNIX password: 

Retype new UNIX password: 

passwd: password updated successfully
```

次に、`/etc/ssh/sshd_config`ファイルを編集し、PasswordAuthenticationのパラメータをyesに更新して保存します。

```bash:bash
ubuntu:~/environment $ sudo vi /etc/ssh/sshd_config
```

```text:/etc/ssh/sshd_config
(中略)

# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes
#PermitEmptyPasswords no

(中略)
```

保存後、SSHのサービスを再起動します。

```bash:bash
ubuntu:~/environment $ sudo service ssh restart
```

## 7. Security Groupで22番ポートを開放
クライアントPCからSSHポートフォワードを利用してリモートデスクトップするために、Cloud9のEC2インスタンスにアタッチされているSecurity Groupで22番ポートを開放します。
**必ずクライアント側のグローバルIPを指定して/32で開放します。**
**開放すべきIPアドレスが分からない場合は、プルダウンで「マイIP」を選ぶと自動的に入力されます。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/ba451e07-84db-007c-38fd-a4cae94617fd.png)

ここまでがCloud9側 (AWS側) の設定です。

# クライアントPC側の設定
## 1. ターミナルからSSHポートフォワードする
AWSマネジメントコンソールでCloud9のEC2インスタンスにアタッチされたパブリックIPアドレスを確認し、クライアントPC側のターミナルで以下のコマンドを実行します。
以下のコマンドを実行した後、localhostの8888番ポートに接続すると、SSH経由でxxx.xxx.xxx.xxx(Cloud9)の5901番ポートに接続されます。

```bash:bash
$ ssh -L 8888:localhost:5901 ubuntu@xxx.xxx.xxx.xxx
```

## 2. リモートデスクトップする
Macでは、Finderで「サーバへ接続」を開き、以下の通り入力して接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/4d9a2088-f117-5682-2a6d-d5ab37311427.png)
接続すると、以下のようにデスクトップが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/d9b2d844-90ca-20da-62ba-4b3f55c96da0.png)

ここまでの手順で、Cloud9にデスクトップ環境をインストールして、クライアントからリモートデスクトップ接続ができました。

# Cloud9でWebサーバを起動し、リモートデスクトップで動作確認する
Cloud9のMATEデスクトップ環境上のブラウザ (Firefox) を利用して、localhostに接続して動作確認できるかどうか試してみます。
まず、Cloud9でhttpd (Apache) を起動して、/var/www/htmlにテストファイルを置きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/058be957-c628-4058-e4b8-285a89adcb82.png)

その後、リモートデスクトップでCloud9に接続して、ブラウザを開いて接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/27e476ed-a18c-507a-33d1-06ad25362f14.png)

このように、ブラウザを必要とする動作確認も、Cloud9のEC2インスタンス内だけで完結しますので、Cloud9で開発や検証を進める際の不便が一つ解消します。