EC2にGUIアクセスを設定する

AmazonEC2にGUIでアクセスできるとリモートPCとして使えるし、各種開発もセキュアにできるのでは？と考え、いろいろ調べてみました

選択肢がいくつかあり、要件によって使い分けるのが良さそうです

# 今回の目的
* パソコンが故障したり古くなった時のリスク回避
* パソコンに依存せずに各種開発のできる環境をリモートに持っておきたい
* 商用システムへのデプロイなどセキュリティを確保するために、アクセスできる環境を絞っておきたい

# 前提知識
リモートからLinux環境にGUI環境にアクセスするにはXRDPまたはVNCを利用するのが一般的です
## VNC
サーバ側はTigerVNCをインストールし、クライエント側はVNCクライアントアプリを入れてアクセスする方法が一般的、MacではVNCクライアントアプリを入れなくてもアクセス可能

https://ebi-works.com/mac-vnc/

## XRDP
Microsoftが提供するRDP技術を利用する方法です
Windowsであれば標準インストールされている「リモートデスクトップ」を利用する形になります
Macの場合も「MicrosoftRemoteDesktop」をインストールすれば利用できます

# まずはコンテナを検討
LinuxベースでGUI対応しているコンテナを利用するとサクッと環境を作れて、AppRunnerなどでデプロイできるかなと考えました
実際、そのようなコンテナがいくつか提供されています
* [dorowu/ubuntu-desktop-lxde-vnc:latest](https://hub.docker.com/r/dorowu/ubuntu-desktop-lxde-vnc/#!)
* [consol/debian-xfce-vnc](https://hub.docker.com/r/consol/debian-xfce-vnc)

しかし、以下のような懸念点がありました

:::note warn
コンテナにすると、せっかく開発のためにnode.jやamplifyなどを入れても、コンテナを廃棄すると全てリセットされてしまう
:::
:::note warn
コンテナによってvncやxrdpがうまく動かなかったり、日本語化がされていなかったりする
:::

# EC2でGUIアクセスを可能にする
BindVolumeを使えば永続化できるのですがそこまでするくらいなら、AMIから起動するEC2でも変わらないよな、ってことでEC2インスタンスにGUIアクセスする方法にすることにしました

と言ってもこれもいくつか方法があります

## 新たにインスタンスを立ち上げる場合
新たにインスタンスを立ち上げる場合は以下の方法があります

### AmazonLinux2 MATEデスクトップAMIを利用する
AmazonLinux上で稼働するMATEデスクトップというデスクトップ環境が提供されています
これがあらかじめ入っているAMIがありますのでそれを使ってEC2インスタンスを立ち上げる方法です
詳しくはこちらの記事を確認してみてください(英語)

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/amazon-linux-ami-mate.html

### Amazon Workspacesを利用する
リモートデスクトップ環境を提供するAWSサービスです

https://aws.amazon.com/jp/workspaces/ 

## 既存のEC2インスタンスに接続環境を構築する
### 手動でMATEおよびTigerVNCをEC2にインストールする

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-2-install-gui/

### 手動でxrdpをインストールする
上記の方法を使いながらVNCではなくXRDPでアクセスできるようにする方法です

https://soypocket.com/it/amazon-linux-2-rdp/

今回は新たにインスタンスを立ち上げたので、最終的に「AmazonLinux2 MATEデスクトップAMIを利用する」の形にしました

# 具体的な手順
基本的には以下の手順に従うのですが、結構ざっくりとしか手順が書かれていませんので少し細かく記載したいと思います

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/amazon-linux-ami-mate.html

## 準備
まずは、AWS CLIをインストールしてください

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

## 最新のMATE入りAMIを検索する
Windowsの場合はPowershell、Macのシェルを立ち上げて、以下のコマンドを叩きます

```
aws ec2 describe-images --filters "Name=name,Values=amzn2*MATE*" --query "Images[*].[ImageId,Name,Description]"
```

ずらっとMATEが使えるAMIがリストアップされます
私はこの時最新だった`ami-0cc49fbe09280147c`を利用しました

## キーペアの作成
これから作成するEC2インスタンスにSSH接続するためにキーペアを作成しておく必要があります
AWSコンソールでEC2の画面を開き、メニューから「ネットワーク＆セキュリティ」>「キーペア」を選択します
新たにキーペアを作成しておきます

## EC2インスタンスの作成
AWSコンソールでEC2の画面を開き、メニューから「イメージ」>「AMI」を選択します
先ほどのAMIの名前で検索して選択します

![スクリーンショット 2023-02-10 11.40.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/a1564a07-ae3e-f8dc-c2fb-1cb43f6c7a38.png)

その後は常の通りでインスタンスタイプを選択してEC2インスタンスを作成してください
その際作成したキーペアを紐づけてください

## VPC、セキュリティグループ、ACLなどの設定
この辺はEC2を作る時に一番苦労するところですね
「VPC EC2 作成」などで検索するとたくさん出てくるので参考にしながら頑張ってください

* セキュリティグループ・ACLのインバウンドルール、アウトバンドルールの設定
* インターネットゲートウェイの設定
* ElasticIPアドレスの紐付け
* ルートテーブルの設定

などなど・・・

## SSH接続してパスワードの設定とxrdp用の証明書とキーを生成する
EC2に接続してec2-userのパスワードを設定します

```
sudo passwd ec2-user
```

その後、以下のコマンドを実行し、xrdp用の証明書とキーを生成します
365日で期限が切れるので適宜最後の`-days 365`を書き換えてください

```
sudo openssl req -x509 -sha384 -newkey rsa:3072 -nodes -keyout /etc/xrdp/key.pem -out /etc/xrdp/cert.pem -days 365
```

## リモートデスクトップアプリから接続する
Windowsでは「リモートデスクトップ」、Macでは「MicrosoftRemoteDesktop」をAppStoreからインストールして起動します
EC2に紐付けたIPアドレスを設定してアクセスしてみてください

以下のような画面が表示されれば接続成功です😊

![スクリーンショット 2023-02-10 11.53.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/9f3f374c-f8d3-b81e-d113-4f7e8e9f20f4.png)

## 日本語化
インストール完了時点ではメニューなども英語、Chromiumを開いても日本語が表示されません
日本語化は以下のサイトにある内容で行うことができます
結構サクサクと進められました

https://zapping.beccou.com/2021/06/17/aws-japaneseize-mate-on-amazon-linux-2/

追加でタイムゾーンも変更しました

```
sudo timedatectl set-timezone Asia/Tokyo
```

# まとめ
無事リモートデスクトップをゲットしました！
選択できるサービスが多いので何を選択するかは悩むところです
何を目的にするのか？やコストなども考えながら最適な方法を常に考えていくことが大事ですね