はじめに
社内のVPNの仕組みも社員数が増えてくるにつれてそれなりに管理がしやすいような方がいいよね、ということで、仕組み自体を更改するにあたり、VPNサーバを簡単に構築 & 管理することのできるPritunlと、ここが一番肝心なのですが、どうせならPritunlが使用するデータソースをAWS上で構築したいよねということで、Amazon DocumentDBを使用しようという話になり、ちょっとPoCをしてみましたというのがこの記事の趣旨になります。
まぁ最終的にはPritunlのデータソースとしてAmazon DocumentDBが使えない! という結論に至ったのですが、その理由は後述します。
構成
ざっくりと構成図書くとこんな感じになります。他にも社内のルータとかが登場するのですが、それは流石に出せないので、あくまでもVPNサーバとAmazon DocumentDBの関係性だけを記述しています。
Amazon DocumentDBの前段には、Public Subnetにルータとしての機能を持つEC2インスタンスを構築します。可用性はあまり求められないのでシングルAZ(AZ-a)にしていますが、Amazon DocumentDB側でサブネットグループの構築が必須となるため、AZ-cを空っぽの状態で構成しています。
VPS上に構築するVPNサーバは、今回はUbuntu 22.04 LTSを使用しています。
EC2インスタンスからAmazon DocumentDBへの接続確認
構築したEC2インスタンスにmongoDBをインストールして、内部的にAmazon DocumentDBへ接続が可能かどうかを確認します。当然のことながら、EC2インスタンスにはAmazon DocumentDBに対する接続を許可するIAMロールの設定をして、Amazon DocumentDBに対してはインバウンドでEC2インスタンスからのtcp/27017の通信を許可するSecurity Groupのインバウンドルールを設定しています。
まずはEC2インスタンスにmongoDBをインストール。
sudo echo -e "[mongodb-org-6.0] \nname=MongoDB Repository\nbaseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/6.0/aarch64/\ngpgcheck=1 \nenabled=1 \ngpgkey=https://www.mongodb.org/static/pgp/server-6.0.asc" | sudo tee /etc/yum.repos.d/mongodb-org-6.0.repo
sudo yum install -y mongodb-org -y
これが完了したら、Amazon DocumentDBに接続するための証明書を取得してきます。
wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
そして、以下のコマンドで接続確認を実行します。
sudo mongosh --tls --host <cluster name>.cluster-<cluster identifier>.ap-northeast-1.docdb.amazonaws.com:27017 --tlsCAFile rds-combined-ca-bundle.pem --username <username> --password <password>
実行後、以下のように出力されれば接続は成功です。
Current Mongosh Log ID: <Log ID>
Connecting to: mongosh://<credentials>@<cluster name>.cluster-<cluster identifier>.ap-northeast.docdb.amazonaws.com:27017/?directConnection=true&tls=true&tlsCAFile=rds-combined-ca-bundle.pem&appName=mongosh+1.6.2
Using MongoDB: 4.0.0
Using Mongosh: 1.6.2
(snip...)
rs0 [direct : primary] test>
VPNサーバの構築
AWS側の構築と設定が完了したら、次にVPS上のVPNサーバを構築していきます。
まずはAWS CLIのインストールから。
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
次にPritunlをインストールしていきます。
# まずは既存でインストールされているパッケージを最新バージョンに更新
sudo apt update && sudo apt upgrade
# PritunlとMongoDBをインストール
sudo apt update && sudo apt install pritunl mongodb-org
# インストールしたPritunlとMongoDBを起動
sudo systemctl start pritunl mongod
sudo systemctl enable pritunl mongod
ここまで終われば、あとはPritunlとローカルのMongoDBの起動状態を確認すればOKです。
Pritunlの設定
Pritunlを初期セットアップするためには、セットアップキーの取得が必要なため、以下のコマンドを実行します。
sudo pritunl setup-key
実行すると16進数のセットアップキーが表示されるので、それを控えておきます。
次に、https://<VPNサーバのIP Address>/setup をブラウザで開き、表示されたダイアログにセットアップキーを入力します。
[Save]ボタンを入力すると、管理者のユーザ名とパスワードを作成しろというダイアログが表示されるので、コンソールに戻り、以下のコマンドを実行して管理者のユーザ名とパスワードを作成します。
sudo pritunl default-password
ここで出力されたユーザ名とパスワードを控えておきます。
もしもVPNサーバのローカルに構築されたMongoDBを使用してPritunlを使用する場合は、ここで構築は完了なのですが、ここで、一旦VPNサーバからDocumentDBに接続が可能かどうかを、EC2インスタンスから接続確認した時と同じ手順で接続を確認します。
sudo mongosh --tls --host <cluster name>.cluster-<cluster identifier>.ap-northeast-1.docdb.amazonaws.com:27017 --tlsCAFile rds-combined-ca-bundle.pem --username <username> --password <password> --tlsAllowInvalidHostnames
ここまでは普通に成功するはずです。
PritunlのデータソースとしてAmazon DocumentDBが使えないことが発覚
ここで、/etc/mongod.confのデータベース接続文字列を修正して、Amazon DocumentDBを向くように設定したのですが、ここでInternal Server Errorが発生。/var/log/pritunl.logに以下のような大量のエラーが吐かれます。
[undefined][2023-01-20 09:38:17,828][INFO] Starting setup server
[undefined][2023-01-20 09:38:18,153][INFO] Generating setup server ssl cert
[undefined][2023-01-20 09:38:22,654][ERROR] Pritunl setup failed
Traceback (most recent call last):
File "/usr/lib/pritunl/lib/python3.10/site-packages/pritunl/setup/__init__.py", line 43, in setup_all
setup_mongo()
File "/usr/lib/pritunl/lib/python3.10/site-packages/pritunl/setup/mongo.py", line 446, in setup_mongo
mongo.secondary_database.create_collection(
File "/usr/lib/pritunl/lib/python3.10/site-packages/pymongo/database.py", line 425, in create_collection
return Collection(self, name, True, codec_options,
File "/usr/lib/pritunl/lib/python3.10/site-packages/pymongo/collection.py", line 187, in __init__
self.__create(kwargs, collation, session)
File "/usr/lib/pritunl/lib/python3.10/site-packages/pymongo/collection.py", line 264, in __create
self._command(
File "/usr/lib/pritunl/lib/python3.10/site-packages/pymongo/collection.py", line 238, in _command
return sock_info.command(
File "/usr/lib/pritunl/lib/python3.10/site-packages/pymongo/pool.py", line 710, in command
return command(self, dbname, spec, secondary_ok,
File "/usr/lib/pritunl/lib/python3.10/site-packages/pymongo/network.py", line 161, in command
helpers._check_command_response(
File "/usr/lib/pritunl/lib/python3.10/site-packages/pymongo/helpers.py", line 167, in _check_command_response
raise OperationFailure(errmsg, code, response, max_wire_version)
pymongo.errors.OperationFailure: Feature not supported: capped:true, full error: {'ok': 0.0, 'code': 303, 'errmsg': 'Feature not sup
ported: capped:true', 'operationTime': Timestamp(1674175102, 1)}
[undefined][2023-01-20 09:38:22,658][INFO] Stopping server
該当するコードを調べてみたのですが、Pritunl側では、セットアップ時のmongoDBに対する設定として、上限付きコレクションが True
になっているのですが、Amazon DocumentDBの仕様ではFalse
になっており、変更不可であるため、セットアップそのものができない状態になってしまっているのでした。万事休す。
というわけで、PoCはここで泣く泣く終了になってしまいました。この辺のPoCに関してはなかなかまとまったドキュメントがないので、ここに至るまでに結構時間を溶かしてしまいました。Pritunl側のUpdateを待つか、Amazon DocumentDB側で上限付きコレクションの設定がサポートされるかどうか、今はちょっと待ちの状態ですね。
ただ、どちらかがサポートされれば、AWSのリソースで効率的にVPNサーバの管理ができるようになるかもしれません。