Apache GuacamoleをDockerで構築してLDAPバックエンドでリバースプロキシ(長い)
以前すでにいくつか書いていますが忘れないようにメモ。
まぁ。。なんも書かんよりはマシかな程度ですが。
■Apache Guacamole
ちょっとまえに構築して現状、自分の立てたやつではぶっちぎりで利用しているので簡単に書く。
なお、ネタとしては こちら でやられていることのほぼ丸パクリ+LDAP、あとはリバースプロキシ対応をしています。
1.仮想マシン
VirtualBoxにUbuntu 18.04をインストールしてベースにする。
SELinux、Firewallを外す
2.Docker、docker-composeのインストール
・Dockerのインストール
オフィシャルのスクリプトで行います。
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
dockerグループに操作ユーザーを加えて再ログイン
$ sudo usermod -aG docker $USER
・docker-composeをインストール
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
3.Guacamoleのインストール
・作業ユーザのディレクトリにguacamoleディレクトリを作成
$ mkdir guacamole
$ cd guacamole/
・docker-compose.yml を作成
なお、ファイル内の「guacamole_root_password」と「guacamole_user_password」は,適切なパスワードに変更する。
version: "3"
services:
guacd:
container_name: my-guacd
image: guacamole/guacd
restart: always
guacamole_db:
container_name: my-guacamole-db
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: guacamole_root_password # NEED TO CHANGE
MYSQL_DATABASE: guacamole_db
MYSQL_USER: guacamole_user
MYSQL_PASSWORD: guacamole_user_password # NEED TO CHANGE
volumes:
- ./dbdata:/var/lib/mysql
- ./dbinit:/docker-entrypoint-initdb.d
guacamole:
container_name: my-guacamole
image: jkbys/guacamole:1.1.0ja
#image: guacamole/guacamole
restart: always
environment:
GUACD_HOSTNAME: my-guacd
MYSQL_HOSTNAME: my-guacamole-db
MYSQL_DATABASE: guacamole_db
MYSQL_USER: guacamole_user
MYSQL_PASSWORD: guacamole_user_password # NEED TO CHANGE
GUACAMOLE_HOME: /guacamole-home
volumes:
- ./home:/guacamole-home
depends_on:
- guacamole_db
- guacd
ports:
- "8080:8080"
・必要なディレクトリを作成
$ mkdir -p dbdata dbinit home/extensions
・MySQLの初期化スクリプトを出力
$ docker run --rm jkbys/guacamole:1.1.0ja /opt/guacamole/bin/initdb.sh --mysql > ./dbinit/initdb.sql
・docker-composeを実行してGuacamoleを起動
$ docker-compose up -d
起動するまではちょっと時間がかかるので慌てず待つ。
この時点で、
http://【ServerIP】:8080/guacamole
にアクセスすることで、Guacamoleが使える状態になっています。guacadmin/guacadminでログイン可能(パスはすぐ変更すること)
4.LDAP利用の設定を行う
docker-compose.ymlに追記
LDAP_HOSTNAME: 192.168.1.xxx ※LDAPサーバのIPアドレス
LDAP_PORT: 389
LDAP_USER_BASE_DN: dc=xxx,dc=xxx
※ユーザー検索のベース
LDAP_SEARCH_BIND_DN: uid=admin,cn=ldapadmin,ou=Group,dc=xxx,dc=xxx
※検索する際にバインドするユーザーのDN
LDAP_SEARCH_BIND_PASSWORD: 【Pass】
※検索する際にバインドするユーザーのパスワード
SKIP_IF_UNAVAILABLE: ldap
※LDAPでのログインに失敗した際に無視する
→別にSQL Serverにアカウントが登録されてればそちらで、設定ファイルに
ユーザー登録があればそれを使うための設定
今回は公開されない範囲でやってますので平文で通信してますが、必要に応じてSSL対応とかやったほうがいいとは思います。
・LDAP認証のためのGuacamoleのエクステンションを持ってくる
$ wget http://apache.org/dyn/closer.cgi?action=download&filename=guacamole/1.1.0/binary/guacamole-auth-ldap-1.1.0.tar.gz
$ tat xzf guacamole-auth-ldap-1.1.0.tar.gz
・展開した中のldap接続エクステンションを、guacamoleが認識できるようにguacamole/home/extensions/ 配下に移動
$ cp -p guacamole-auth-ldap-1.0.0/guacamole-auth-ldap-1.1.0.jar guacamole/home/extensions/guacamole-auth-ldap-1.1.0.jar
・docker-compose.ymlを書き換えたので再起動
$ docker stop
$ docker-compose up -d
これでLDAPユーザーはログインできますが、現状何も設定していないので接続ができません。
管理者アカウントでログインし、LDAPの管理アカウント(LDAPの他のユーザーが全員見られるアカウント)に対して、Guacamoleの管理権限を与えます。
※元々あるGuacamoleアカウントは、LDAP側の権限がないので他のユーザー情報が見得ません。LDAP側で権限があるアカウントに、Guacamole側の権限を与えます。
あとはそのユーザーで接続に必要な情報を展開するなどの対応を行います。
5.リバースプロキシ対応
リバースプロキシ設定の際のTomcat側のserver.xml書き換え方法です。
Tomcat側に「この通信はリバースプロキシ経由だよ」というのを教えてあげないとCSRFと判断されてエラーになります。
通常の構築であればTomcatのインストールディレクトリを探せばいいですが、今回はDockerで導入しているので、コンテナ内のファイル強引に書き換えてます。
起動時にオプションで引数として設定ファイルを渡すなり、起動のタイミングで設定ファイルをコピーする方法もあるようですが、当方はDocker自体にそこまで詳しくないので、強引にコンテナ内のファイルを書き換えています。
・Dockerイメージ内の設定ファイルをコピー
$ sudo cp /var/lib/docker/overlay2/【docker-dir】/merged/usr/local/tomcat/conf/server.xml .
・Hostディレクティブ内に追記
$ vi server.xml
<Valve className="org.apache.catalina.valves.RemoteIpValve"
internalProxies="192.168.1.91"
remoteIpHeader="x-forwarded-for"
remoteIpProxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto" />
・Dockerイメージ内の設定ファイルを書き戻し
$ sudo cp server.xml /var/lib/docker/overlay2/【docker-dir】/merged/usr/local/tomcat/conf/
6.リバースプロキシ設定(nginx側)
別途nginxでのリバースプロキシは構築済みとします。
※時間が取れれば別途書きます。
なお、基本的にリバースプロキシをかましているのは、以前にもちょっと書いた気がしますが
・SSLを全部nginx側で終端する
・自宅サーバメインなので、ルータのポートをたくさん開放したり特殊なポートを開けたりしたくない
というような理由によります。
SSL(Let's Encrypt)設定は別途実施済みの前提で、プロキシ設定は以下のようにしています。
server{
server_name 【guacamoleの接続ホスト名】;
listen 443 ssl;
listen [::]:443 ssl;
~SSL設定省略~
location / {
proxy_pass http://192.168.1.xxx:8080/guacamole/;
proxy_buffering off;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cookie_path /guacamole/ /;
}
gzip on;
}
※nginxでの各種SSL終端+リバースプロキシ設定はもしかしたら多少ニーズがあるかもしれないのでそのうち別途まとめて書きます。