【Cloudflare Zero Trust】ブラウザでUbuntuを安全にVNC操作できるようにする

やまねこです。

Linuxを触っているエンジニアなら一度は触ったことがあるであろうVNCですが，ローカルからVNCクライアントソフトで操作するのが一般的です。
しかし，外出先からVNCしたい，欲を言えばVPNを張らずにブラウザから...みたいなこと微かに思ったことはないでしょうか。

**それ， Cloudflare Zero Trustで実現できます。**
**しかも，ネットワーク機器の操作(ポート開放等)はいりません!!**
セキュリティ的にも安全ですね!

# 必要なもの
- Cloudflareアカウント
- ネームサーバーがCloudflare提供のネームサーバーに設定されているドメイン
- Ubuntu (今回は22.04LTS)

# 設定方法
基本的にはCloudflare公式ドキュメントに従って設定していきます。
https://developers.cloudflare.com/cloudflare-one/tutorials/vnc-client-in-browser/

## VNCの構築
1. いつもの。
    ```
    sudo apt-get update
    ```
2. GUI周りの諸々をインストールします。Ubuntuデスクトップの場合すでにインストール済みだと思いますが，Ubuntu Serverの場合は追加が必要です。
    ```
    sudo apt-get install gnome-core gnome-panel ubuntu-gnome-desktop tightvncserver lxde
    ```
3. VNCインスタンスを起動します。
    ```
    sudo tightvncserver
    ```
    6文字以上8文字以下でVNC用パスワードを設定します。
    ```
    You will require a password to access your desktops.

    Password:
    Verify:
    Would you like to enter a view-only password (y/n)? n
    xauth:  file /root/.Xauthority does not exist

    New 'X' desktop is hogehoge:1

    Creating default startup script /root/.vnc/xstartup
    Starting applications specified in /root/.vnc/xstartup
    Log file is /root/.vnc/hogehoge:1.log
    ```
4. VNCの設定ディレクトリを開きます。
    ```
    cd .vnc
    ```
5. xsertupファイルを開きます。
    ```
    vim xstartup
    ```
6. 以下のように編集します。
    ```
    #!/bin/sh
    xrdb $HOME/.Xresources
    xsetroot -solid grey
    x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
    #x-window-manager &
    
    # Fix to make GNOME work
    export XKL_XMODMAP_DISABLE=1
    unset SESSION_MANAGER
    unset DBUS_SESSION_BUS_ADDRESS
    /etc/X11/Xsession
    /usr/bin/startlxde
    
    #gnome-session &
    gnome-panel &
    nautilus &
    gnome-settings-daemon &
    metacity &
    gnome-terminal &
    startxfce4 &
    ```
    xstartupの権限も変更します。
    ```
    chmod +x ~/.vnc/xstartup
    ```
7. VNC Serverを立てます
    ```
    vncserver
    ```
## Cloudflareトンネルの構築
1. cloudflaredをインストールします。
    ```
    wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
    sudo apt install -y ./cloudflared-linux-amd64.deb
    ```
2. Cloudflare tunnelにログインします。
    ```
    cloudflared tunnel login
    ```
    表示されたURLからCloudflareにログインします。
    ブラウザに表示された自分のドメインを選択し，「承認」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/966594b6-7c43-5b03-6a20-d705551632ae.png)

3. トンネルを構築します。ここでは「tunnel-ubuntu」というトンネル名にします。
    ```
    cloudflared tunnel create　tunnel-ubuntu
    ```
    トンネルが作成されると，トンネルのIDが表示されます。IDは後で使用するのでどこかにメモしてください。(Cloudflare Zero Trust管理ページからも確認できます)
    ```
    Created tunnel tunnel-ubuntu with id　abcd1234-5678-abcd-123456789012
    ```
4. 設定ファイルを作成します。
    ```
    vim config.yml
    ```
    以下のように編集します。
    - hostname: ブラウザでVNCを開くときに使用したいFQDNを設定します。
    - path: ホームディレクトリの絶対パス
    ```
    tunnel: <メモしたID>
    credentials-file: path/.cloudflared/<メモしたID>.json
    ingress:
    - hostname: vnc.hogehoge.com
      service: tcp://localhost:5901
    - service: http_status:404
    ```
5. CloudflareのDNS管理ページからレコードを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/735688ff-3592-baa1-e6b5-61b3e5106342.png)
    - タイプ:CNAME
    - 名前: 4.のhostnameで設定したFQDN
    - ターゲット: 3.で表示されたID + .cfargotunnel.com

6. からトンネルを実行します。
    ```
    cloudflared tunnel --config path/config.yml run tunnel-ubuntu
    ```
    - path: 4.で作成した設定ファイルの絶対パス
    トンネルが確立すると`INF Connection ~`のようなログが表示されます。
    
    ついでに自動起動の設定もしましょう。
    ```
    sudo cloudflared --config path/config.yml service install
    sudo systemctl enable cloudflared
    ```

    `sudo systemctl enable cloudflared`でactiveになっていればOKです。

## アプリケーションの設定
1. Cloudflare Zero Trustの管理ページ > Access > Applicationから「Add an application」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/81b30897-9899-6dec-2c0f-547e8cfdd251.png)
2. Self-hostedの方を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/26ccaa5e-9aa1-bf4b-476f-da5559913991.png)
3. 必要事項を入力します。
    - Application name: Cloudflare Zero Trustで表示するアプリケーション名
    - Subdomain: 4. で設定したFQDN
    - Domain: Cloudflareに設定されているドメイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/0518229d-7dc3-66cb-0712-bd43c47b4bd5.png)
その他項目はデフォルトとします。

4. ポリシー名を付けます
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/261e2320-85de-9293-fe92-6e1f614332c3.png)
5. Zero TrustでVNCサーバーにアクセスするための認証方法を設定します。今回は，「admin@hogehoge.com」のみアクセス可能にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/ad7ae6e7-3704-9416-f317-b501c3305252.png)
    その他項目はデフォルトとします。
6. 「Additional settings」で「VNC」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/e33bf6f3-8cda-211f-137a-2b905e2f0dc7.png)

## ブラウザからVNCアクセス
1. ブラウザから4.で設定したFQDNにアクセスします。
    アクセスすると認証画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/ee68bdc7-9608-0da4-32d0-eef21812463a.png)
ワンタイムパスワードとVNCのパスワードを入力するとブラウザにVNCが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3182201/9d25f4e7-7aeb-bc6c-c9c2-5f36c335a534.png)


後は，vncserverが自動起動する設定をすれば完了です。