手っ取り早くGUI操作のできるコンテナをつくる

Apache Guacamoleというものを使うとGUI環境の無い踏み台からも楽にGUI操作を行えるようになって便利そうだったため、これを使ってなるべくコストをかけずに簡単にGUI操作を行えるようにする方法を考えてみました。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116209/b655238a-0b8f-17d1-a819-53045d98ab1e.png width=45%> <img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116209/7991f996-2e2b-0941-2930-cf4253b3161b.png width=45%>
↑ブラウザの中でブラウザを開いている様子
（正確にはブラウザの中でXが動いてるLinuxのデスクトップを開いて、その中でブラウザを起動している）

# TL;DR

* クローズド環境で外部端末のブラウザから内部のネットワーク内のブラウザを開けるようにするよ
* DockerでGuacamoleとSeleniumのデバッグ用のコンテナたてるよ
* ブラウザからWindowsにRDPとかもできるよ

GitHub
https://github.com/sensq/bastion-guacamole

# 概要

一般的な環境だと需要はほとんど無いと思いますが、本番環境などのクローズドな環境では外部からは踏み台サーバを経由しての接続しか許されておらず、内部のWebアプリケーションやWindowsなどをGUI操作したいときにどうするかで困ったりします。
踏み台サーバにGUI環境が用意されていれば楽ですが、サーバをGUI化すると設計や構築や構成管理のコストが増えたり、いつの間にか便利ソフトで溢れて運用がブラックボックス化したりして嫌なので、ただ踏み台経由でhttpやRDPで接続したいためだけにGUI化をするのはなるべくやりたくないです。

<div align="center"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116209/12fffab2-1152-ff33-295e-4490ec06cc63.png"></div>

別にシンプルにポートフォワードで繋ぐなどでも良いのですが、今のコンテナの時代、もっと楽で便利で汎用的なやり方があるのではないかと思い、上記のような環境で手っ取り早くGUI操作を行えるようにする方法を考えます。

# Guacamoleの説明

[Guacamole](https://guacamole.apache.org/)とは、ネットワーク内のサーバへWeb上からRDP/Telnet/SSH/VNCで接続できるようにする正に踏み台のためにあるかのようなOSSのツール。「グアカモーレ」とか「ワカモレ」と読むらしい。
アーキテクチャなどの詳細はこちらのページがわかりやすい。
https://dev.classmethod.jp/cloud/aws/setup-apache-guacamole/

要するに踏み台サーバへGuacamoleを入れれば、外部のPCのブラウザから踏み台のGuacamoleにアクセスしてブラウザからWindowsに接続したり、ブラウザの中でクローズド環境内のブラウザを開いて外部からは見られないページを見たりすることができるようになる。

# 作るもの

Guacamole自体は結構古く、[公式でイメージも提供されて](https://hub.docker.com/u/guacamole)おり、ググってみるとDockerが流行りだして間もない[2016年](https://qiita.com/miyatama/items/b774965e552c0de69d6f)や[2017年](https://nyacom.net/?p=443)に既に同様のことをやっている記事が出てくる。
ただ、ブラウザで操作するUIがどんどん一般的になってきている昨今、踏み台からはVNCやRDPで接続するだけでなくブラウザを動かしてhttp(s)で接続したい需要も高まってきていると思われるため、Guacamoleと一緒にブラウザが動くだけのVNCで接続できるコンテナがあれば非常に便利そうである。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116209/0b47b82f-9f23-ed29-0614-b0244415c7bf.png)

しかし残念ながらGoogleやMozillaはそんなコンテナイメージを提供しておらず、自分でDockerfileを用意してビルドするのは嫌なため、本来の用途とは異なるがSeleniumのデバッグ用のイメージを利用することにする。

https://hub.docker.com/r/selenium/standalone-chrome-debug
https://hub.docker.com/r/selenium/standalone-firefox-debug

このイメージはとても都合がいいことにコンテナを起動すると中でVNC Serverも起動するため、Guacamoleコンテナと一緒に起動させるだけで今回の目的を果たすことができる。
よって、必要なものは既に公式イメージで提供されているものだけで十分なため、作るものは本質的には**docker-compose.yamlのみでよい。**

また、当然だが別に1つの踏み台上で一緒に動かす必要はなく、同一ネットワーク内であればstandaloneのコンテナを別のサーバで動かすことも可能である。そのため、踏み台から直接アクセスできてしまうことを嫌がる場合や、踏み台がネストされているような場合にも対応することができる。

# 作ったもの

詳細はGitHubを参照
起動手順もこちらを参照
https://github.com/sensq/bastion-guacamole

上述した通り、公式のコンテナを組み合わせて起動するだけのため自分で作る必要のあるものは本質的には**docker-compose.yamlのみ**。ただし、手間を減らすために他にもいくつかファイルを置いている。
全体的になるべく作り込まないように作成しているため、必要があれば適宜カスタマイズしてください。

* `docker-compose.yaml`
    * 最初DBはMySQLにしていたが、Postgres:alpineのイメージの方が300MBくらい軽かったのでPostgresを使うようにした
    * postgresコンテナにマウントしている`initdb.sql`は`init.sh`を実行すると生成されるファイルのため、コンテナ起動前に`init.sh`を実行しておくこと
* `insert_default_connections.sql`
    * ChromeとFirefoxコンテナへの接続設定を記載したSQLファイル
    * Postgresコンテナ起動時に自動的に実行され、デフォルト設定として登録される
* `.env`
    * `docker-compose down`でコンテナ落とすときに数分かかるため、エラーにならないようにタイムアウトの値を増やしているだけ
* `init.sh`
    * DB初期化用のSQLを生成するコマンドを実行するだけ
    * 普通にguacamoleの構築手順の中に書かれているコマンド
* `start_browser.sh`
    * 接続先のコンテナ内でブラウザを起動するコマンドを実行するだけ
    * Chromeは普通に初めて起動したときのWelcomeページがやたらCPU使う重いページだったので適当なURLを指定して起動している。クローズドな環境だと404になりそうだが特に問題ないので気にしない。

なお、初回起動のみデータベースの初期化処理が行われ、完了するまではGuacamoleのURLにアクセスしてもログイン画面が出てきません。
数分で完了するはずです。

## イメージのサイズ

参考までに2020/1/13時点での各イメージのサイズを載せておきます。合計で約2.5GBです。

```
           Repository                Tag      Size 
---------------------------------------------------
selenium/standalone-chrome-debug    latest   815 MB
selenium/standalone-firefox-debug   latest   751 MB
guacamole/guacamole                 latest   468 MB
guacamole/guacd                     latest   377 MB
postgres                            alpine   139 MB
```

MySQLはAlpine版が無く、latestは422MBでした。

## 使用感

普段遣い用として使うのはストレスたまりそうだが、踏み台の中でのみ使うものとすれば許容範囲な気はする。
まだ検証で試用してみただけなので使い続けていくと色々不満点や改善点が出てくるかもしれない。
ホストとコンテナ間で日本語のコピペが文字化けするのを直せなかった。

# 参考

Guacamoleを動かすためのdocker-compose.yamlの書き方は以下2つの記事を参考にしました。
本記事よりも詳細にGuacamoleの設定方法などが書かれています。
https://kakakakakku.hatenablog.com/entry/2019/01/09/001605
https://blog.1q77.com/2019/01/guacamole-functions/