ネットワークの制限でwebアクセス(HTTP/HTTPS)しか許可されておらず、SSHアクセスが使えないような環境でリモートのLinuxサーバーのシェルへアクセスしたい場合、Apache Guacamoleを使うことでwebブラウザの画面でSSHログインを行う。(webページ内にSSHアクセスしたリモートサーバーのシェルが画面表示される)
接続イメージは以下の通り。
本エントリではとりあえずSSH接続のみ。
ただしGuacamoleはSSH以外にもVNCやRDPなどいくつかのリモート接続用のプロトコルに対応している。
Kubernetesもあるのが気になる。
Guacamoleのデプロイ
サーバーへ直接インストールする方式と、Docker Hubで公開されているDockerコンテナ版のGuacamoleを使う方法がある。 本エントリではDockerイメージを使うパターンで構築。
Guacamoleは、以下の3つのコンポーネント(説明は意訳)で動作し、それぞれコンテナを実行する。(DBだけ外部とかできるけど、とりあえず全部Dockerで)
- guacamole/guacd
- SSHなどをサポートするguacamole-server
- guacamole/guacamole
- guacdに接続するguacamole webアプリケーション(Tomcat8で動作)
- mysql or postgresql
- DB
ちなみにGuacamoleのコンテナイメージは、latestタグはデイリーで更新されているため、最新安定版のバージョンのタグを指定した方が良さそう(おそらくCIで自動ビルドされてるっぽい)。
現時点で1.4.0が最新。
docker networkの作成
公式ドキュメントだと--link
使ってコンテナ間通信する手順になってるけどさすがにもうこのオプションを使うのも微妙なので、コンテナ間通信を行うためのDocekr Networkを作成。
docker network create guacamole-network
以降のコンテナデプロイは、このDocker Networkを--network
で指定。
guacdの起動
docker run --name guacd -d --network guacamole-network guacamole/guacd:1.4.0
MySQL
MySQLとPostgreSQLが使用できるが、今回はMySQLを使用。
初期化ファイル作成
まずは事前にguacamole/guacamoleコンテナ内のスクリプトを使って、DBの初期化スクリプトを作成。
docker run --rm guacamole/guacamole:1.4.0 /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
DBの起動
MySQLコンテナは、起動時に/docker-entrypoint-initdb.d
ディレクトリ以下の*.sql
ファイルでDBを初期化するので、↑で作成した初期化スクリプトをバインドマウントして起動する。
また、DBのデータ(/var/lib/mysql
)をボリュームマウントする。
docker run --name guacamole_db \ -d \ -e MYSQL_DATABASE=guacamole_db \ -e MYSQL_USER=guacamole_user \ -e MYSQL_PASSWORD=guacamole_passwd \ -e MYSQL_RANDOM_ROOT_PASSWORD=yes \ -v $PWD:/docker-entrypoint-initdb.d \ -v guacamole_db:/var/lib/mysql \ --network guacamole-network \ mysql
guacamole
アプリケーションサーバーを起動する。
GUACD_HOSTNAME
にguacdコンテナのコンテナ名、MYSQL_HOSTNAME
にmysqlコンテナのコンテナ名を指定する。
DBの接続情報はmysql起動時に指定したものと同じものを指定する。
また、このコンテナにwebブラウザでアクセスするので、ポート番号をpublishする。
docker run --name guacamole \ -d \ -e GUACD_HOSTNAME=guacd \ -e MYSQL_HOSTNAME=guacamole_db \ -e MYSQL_DATABASE=guacamole_db \ -e MYSQL_USER=guacamole_user \ -e MYSQL_PASSWORD=guacamole_passwd \ --network guacamole-network \ -p 8080:8080 \ guacamole/guacamole:1.4.0
デプロイはこれで完了。
webアクセスと接続設定
http://<docker host>:8080/guacamole
にアクセス。(ドキュメントルートでなくパス指定があるので注意)
認証
初期値としてユーザー名・パスワードともにguacadmin
がセットされている(たぶんDBの初期化ファイル作成の時点にこれになってる)のでこれでログイン。
Verifying the Guacamole install
adminのパスワードを変更するには、ログインして右上にあるメニューから「設定」を選択。
ユーザ設定メニューにパスワード変更のフィールドがあるので現在のパスワードと新しいパスワードを入力する。
接続先設定
接続先の設定は、メニューの「接続」→「接続の追加」でサーバー設定を行う。 SSH接続のために最低限必要なのは以下の通り。
これだけ入力して「保存」、ホームに戻ると接続情報に設定が追加されるのでマウスクリックすれば、ユーザー名とパスワードを聞かれてパスワード認証でSSH接続できる。
認証パラメータの「ユーザ名」「パスワード」を事前に入力しておけば、接続時の認証も省略できる。
公開鍵認証設定
公開鍵認証の設定は、パラメータセクションに最低限以下を入力すればOK。
- 認証
- ユーザ名
- 秘密鍵
ただし、秘密鍵の登録はOpenSSH形式とドキュメントに記載があるが、実際にはPEM形式である必要がある。
The private key must be in OpenSSH format, as would be generated by the OpenSSH ssh-keygen utility.
https://guacamole.apache.org/doc/gug/configuring-guacamole.html#ssh-authentication
現バージョンのOpenSSHのssh-keygen
でキーペア作成すると、デフォルトではOpenSSH形式(ファイル先頭が「-----BEGIN OPENSSH PRIVATE KEY-----」で始まる)になっているが、この形式だと公開鍵認証が上手くいかない。
PEM形式(ファイル先頭が「-----BEGIN RSA PRIVATE KEY-----」で始まる)のキーペアを作成するには、ssh-keygen
に-m
オプションで形式を指定する。
$ ssh-keygen -m PEM ...
既存のOpenSSH形式の鍵をPEM形式に変換するには以下。この場合元のファイルが更新されるので、必要があれば事前にコピーしておく。
$ ssh-keygen -p -m PEM -f ~/.ssh/id_rsa
秘密鍵の入力フィールドに、秘密鍵ファイルの中身を全て貼り付けて保存する。
これでホームに戻り、接続先を選択すれば、公開鍵認証でSSH接続できる。
環境
- ホストOS: Fedora 35
- Docker: 20.10
- Guacamole: 1.4.0
補足
Guacamoleのイメージはamd64版しかないので、arm64ではそのままでは動かせない。
デフォルトだと日本語入出力できないので要調査。
多分コンテナ内のロケールがどうとか、、、と思う。
ロケールの追加と設定は関係なく(ja_JP.UTF-8
とか入れても変化無し)、原因は日本語フォントでした。あとで別途まとめる。
まとめました。
あと今回はSSHサーバーとGuacamoleを立てたDockerホストを別にしてるが、ここは同じホストでも疎通があるなら問題ない。はず。