Apache Guacamoleを使ってWindowsServerにセキュアにログイン
しかしながら、昨今の急激なリモートワークへの移行に伴って、自宅からの接続も許可する必要が出てきましたが、現状オフィスへのVPN接続環境はないため、このままだと対象のWindowsマシンのセキュリティグループ設定でRDP接続の接続元をフル解放するか都度作業者のIPを許可する必要に迫られました。とはいえどちらの方法もあまり現実的ではないので、別な手段を探していたところ、GuacamoleというブラウザからRDP接続ができるツールを見つけたので、これをRDP接続するための踏み台サーバとして利用することで共通ユーザー問題を解決できると考え導入を進めています。今回はこれについて紹介したいと思います。
Apache Guacamoleとは
Guacamole(ワカモレもしくはガカモレと読むそうです)とはクライアントレスなリモートデスクトップゲートウェイです。また、接続クライアントに特別なプラグインやソフトウェアなどをインストールせずに、ブラウザからVNC、RDP、SSH接続などが可能となっています。
Guacamoleの主な機能
主に以下のような機能が提供されており、作業端末やサーバーへのアクセスにおいて、セキュリティの強化や問題が発生した際のトレースが行いやすくなっています。また、今回Guacamoleを使う大きな理由の一つとして、管理者側で接続可能な端末を登録して誰に接続させるかをコントロールできる機能があります。そのため利用者側は接続情報(ユーザー、パスワード)を意識する必要がありません。言い換えると利用者側はユーザー、パスワードを知ることができないことになります。
Gucamoleの構成
詳細は公式ドキュメントを確認してもらうとして、主に二つのコンポーネントで構成されています。
guacamole
ユーザーからのアクセスを受け付けるWebアプリケーション
guacd
RDP、VNC、SSH接続などを行うコンポーネント
guacamole.apache.org
現状の課題と解決策
本来であればWindowsをAD運用することが一番いいのですが、現状すぐにはその対応はできないというのが前提にあります。
1.ユーザー管理
現状では、ユーザー管理ができていないため、SimpleADを使ってGucamoleのユーザー管理を行います。もい担当者が異動や退職となって業務を外れた場合は、対象ユーザーを削除します。削除されたユーザーはGucamoleにログインできないため、業務用のWindowsServerへもログインでき無くなります。
2.WindowsServerへ共通ユーザーでログイン
WindowsServerへの接続情報はGucamoleだけが保持する事になるので、利用者が知ることはできません。そのため、担当者の退職などによりパスワードの再設定、再配布などの対応が不要になります。
3.いつ誰がアクセスしたか分からない
Gucamole側でいつ誰がどの端末にアクセスしたかログを保持しているため、Windows側は共通ユーザーでログインされていたとしてもGucamole側のログを確認することでトレースが可能となります。
構成
実際の構成はVPCが別れていたりするのでもう少し複雑にはなるのですが、ここではシンプルな構成とします。以下のようにGucamoleサーバーを踏み台として配置することでWindowsServerをPrivateSubnetに配置することが可能になります。
構築手順
Gucamoleのインストール方法については、サーバーにwarファイルを展開して直接インストールする方法もありますが、Dockerでインストールする方が簡単なので今回はこちらの方法で構築を行います。また、有償にはなりますがMarketPlaceでイメージ(Guacamole Bastion Host)が公開されているものもありますので興味のある方はそちらもご覧ください。
SimpleADの構築
ユーザー管理用のSimpleADを構築します。SimpleADの構築方法については以下のブログを参照してください。
以下の設定で構築してください。ドメイン名は適当な名称を設定してください。
DirectoryType | small |
---|---|
ドメイン | guacamole.local |
VPC | Gucamoleを構築するVPC |
Subnet | 上記のVPCのPrivateSubnet |
ユーザーの作成については、WorkSpacesの設定から追加が可能なのでGucamoleのログイン用ユーザーを作成しておいてください。こちらも以下のブログに追加方法がありますので参照してください。間違ってWorkspacesの立ち上げまではしないようにしてください。
Simple ADを利用したWorkSpaces構築手順 – サーバーワークスエンジニアブログ
ELBの準備
ELBはApplicationLoadBalancerを利用します。こちらも詳細は他のブログを参照してください。また、カスタムドメインを使用する場合は、必要に応じてACMなり自己証明書なりを準備しておいてください。
Amazon Linuxの準備
起動
Gucamole用のEC2を作成します。Amazon Linuxで構築します。
AMI: 最新のAmazonLinux2
インスタンスタイプ: t3.micro
VPC: Gucamoleを構築するVPCを設定
Subnet: 上記のVPCのPublicSubnet
SecurityGroup: 8080がALBから疎通可能となるよう設定
起動が完了したら作成したターゲットグループにアタッチしてください。なお、この時点ではhealthyになりません。
Dockerインストール
次にDockerをインストールします。
以下のコマンドを実行してdockerとdocker-composeをインストールします。
dockerのインストール
sudo yum install -y docker sudo service docker start sudo usermod -a -G docker ec2-user sudo systemctl enable docker
docker-composeのインストール
sudo curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
gucamoleのイメージ構築
guacamole(gucamole-client)のイメージは公式からDocker Hubでバージョン1.1.0提供されていますが、1.1.0にはMFAの設定が組み込まれていません。そのため、githubから最新のコードをチェックアウトして自分でイメージのビルドを行います。
以下のコマンドを実行してイメージを作成します。
ビルドにはかなりの時間がかかりました。
git clone https://github.com/apache/guacamole-client.git
cd guacamole-client
docker build -t guacamole_120 .
docker-composeの作成
Dockerで構築する場合、以下の3つのコンテナが必要となります。
- guacamole
- guacd
- mysql(or postresql)
以下の内容でdocker-compos.yamlを作成します。
$SIMPLE_AD_IPには作成したSimpleADのIPを設定します。
LDAP_USER_BASE_DN、LDAP_CONFIG_BASE_DNのDCにはSimpleAD作成時に設定したドメインを設定してください。
version: "3" services: guacd: image: guacamole/guacd:latest expose: - "4822" environment: - GUACD_LOG_LEVEL=debug guacamole: image: guacamole_120 links: - guacd:guacd ports: - "8080:8080" environment: - GUACD_HOSTNAME=guacd - LDAP_HOSTNAME=$SIMPLE_AD_IP - LDAP_PORT=389 - LDAP_ENCRYPTION_METHOD=none - LDAP_USER_BASE_DN=CN=Users,DC=guacamole,DC=local - LDAP_USERNAME_ATTRIBUTE=CN - LDAP_CONFIG_BASE_DN=CN=Users,DC=guacamole,DC=local - TOTP_ENABLED=true - MYSQL_HOSTNAME=mysql - MYSQL_DATABASE=guacamole - MYSQL_USER=guacamole - MYSQL_PASSWORD=guacamole mysql: image: mysql/mysql-server:5.7 volumes: - "./mysql/data:/var/lib/mysql" - "./mysql/init:/docker-entrypoint-initdb.d" environment: - MYSQL_DATABASE=guacamole - MYSQL_USER=guacamole - MYSQL_PASSWORD=guacamole
ディレクトリの作成
docker-compose.yamlファイルと同じ階層に以下のディレクトリを作成します。
mkdir -p mysql/data mkdir -p mysql/init
tree -d mysql/ mysql/ ├── data └── init
初期データ作成
以下のコマンドで初期化用のスクリプトを作成します。
docker run --rm guacamole_120 /opt/guacamole/bin/initdb.sh --mysql > mysql/init/initdb.sql
起動
docker-compose up -d
Gucamoleの使い方
接続用のWindowsServerについては事前に用意し、Gucamoleサーバーからポート3389で疎通できるようにしておいてください。
ログイン画面にアクセス
カスタムドメインを設定していなければ、以下のいずれかのURLでアクセスしてください。
https://ELB_DNS/guacamole/
http://ELB_DNS:8080/guacamole/
正常に起動されていれば以下のようなログイン画面が表示されます。もし表示されていなければ、ログを確認してみてください。
以下のユーザー、パスワードでログインできます。
ログインユーザー: guacadmin
パスワード: guacadmin
MFA設定
MFAが有効になっていますのでGoogle Authenticatorなどで設定してください。
初期画面
以下のような初期画面が表示されます。
接続設定の追加
右上のユーザー名から「設定」を選択し、「接続」タブを開いて「接続の追加」をクリックします。
以下の通り入力を行い保存します。
接続情報の選択
右上のユーザー名からホーム画面に戻ると、先ほど登録した接続設定が表示されていますので、登録した接続情報を選択します。
RDP接続
以下のようにリモートデスクトップが開きます。
RDPの切断
切断するにはMacの場合は、「Ctrl + Shift + Option」でサイドバーが表示されますので「切断」を選択してください。
他のユーザーが利用中の場合
また、別ユーザーが接続中の場合、以下のように利用中であることが分かります。ただし、日本語表記はバグのためが表示されないため、英語表記とする必要があります。日本語だと他にも微妙な動作があったりもしたので基本は英語表記の方がいいかもしれません。
なお、接続設定において最大接続数を1とすると他のユーザーが利用中の場合は接続できないような制限をかけることが可能です。
MFAの再設定
多要素認証の機能を利用するので、スマホの故障や紛失による再設定をどのように対応するのか調べてみました。現状では管理者がUIから設定する方法はなさそうです。
そのため、DBを直接いじる必要があるようです。
以下のSQLで対象のユーザーIDを特定し
select gu.user_id from guacamole_entity ge inner join guacamole_user gu on ge.entity_id = gu.entity_id where ge.name='guacadmin'
対象ユーザーの「guac-totp-key-confirmed」属性をfalseに戻すことで、MFAの再設定が可能となります。
update guacamole_user_attribute set attribute_value='false' where attribute_name='guac-totp-key-confirmed' and user_id=${USER_ID}
Workspacesについて
検証しながら気が付いたのですが、この接続の仕組みをWorkSpacesでも利用できることに思い至りました。
WorkSpacesについては、そもそも業務都合上、利用者が自宅でも接続できる必要があるため、IP制限ができず専用のクライアントツールがあればどこからでもユーザー、パスワードでログイン可能となることが悩みとしてありました。
そのため、WorkSpacesについてもGucamole経由でアクセスすることで認証をMFAを使ってセキュアにすることができかつアクセス状況もトレースが可能となります。
設定方法の詳細は割愛させていただきますが、WorkSpacesに割り当てられているENIにアタッチされたセキュリティグループにGucamoleサーバーから3389で疎通可能となるルールを設定することで、RDPで接続が可能となります。さらにIPアクセスコントールでルールなしの状態で設定すると、クライアントツールからは接続ができません。ただし、この方法は実行モードが「AutoStop」モードでは利用できないので注意してください。