
MongoDBのTLS/SSL設定と構築
-
2021年4月7日
初めまして、インフラチームで DB を担当している M です。
今回は MongoDB のセキュリティー強化のための TLS/SSL 構成についてご紹介します。
TLS/SSLとX.509とは
まず MongoDB の TLS/SSL 設定のため知るべきの重要な 2 つのポイント、TLS/SSL と X.509 について紹介します。
● TLS/SSLとは?
セキュリティを要求される通信を行うためのプロトコルです。
バージョンは SSL1.0 から現在 TLS1.3 まで出ています。
● X.509とは?
X.509 は、ITU-T の公開鍵基盤 (PKI)の規格です。
その規格で MonogDB 用の証明書を発行します。
簡単にまとめると、TLS/SSL はプロトコル、X.509 は暗号化規格です。
テスト構築環境の構成
それではテスト環境を考えてみましょう。
今回のテスト環境について、OS は CentOS 7.8 , MongoDB server versionは 4.4.4 を利用して構築します。
MongoDB の構成は router 1 台、configサーバー 1 台、mongod サーバー 2 台の replica 構成で、mongod のうち 1 台は master、1 台は slave になります。
<テスト環境構成>
SERVER
|
HOSTNAME
|
port
|
---|---|---|
mongoc | mongotest-mongoc.example.com | 27018 |
mongod | mongotest-mongod-1.example.com | 27019 |
mongod | mongotest-mongod-2.example.com | 27019 |
mongos | mongotest-mongos.example.com | 27017 |
<構成図>
秘密鍵/証明書の作成
では、まず秘密鍵/証明書を作成してみましょう。
すでに信頼されている認証局から発行された証明書がある場合はパスします。
認証局から発行された証明書がない場合にはどこかのサーバーから秘密鍵/証明書を作成します。
ここでは mongos がインストールされているサーバーから作成します。
$ openssl req -nodes -x509 -newkey rsa:2048 -days 365 -keyout ca.key -out ca.crt
コマンドを実行すると DN 情報が必要です。以下の表を参考にして入力します。
<DN項目の入力例>
項目
|
説明
|
DN項目
|
sample
|
etc
|
---|---|---|---|---|
countryName | 国コード | C | JP | |
State | 都道府県名 | ST | Tokyo | |
Locality | 市区町村名 | L | setagaya | |
Organizational Name | 組織名 | O | cocone | |
Organizational Unit | 部門名 | OU | infra | |
Common Name | コモンネーム | CN | *.example.com | 同じドメイン内部ではワイルドカードを使うと良い |
emailAddress | メールアドレス | emailAddress | zrfni@example.com |
openssl コマンドを実行して DN 情報を入力すると以下のようなファイルが生成されます。
ca.crt ca.key
次は mongos 用の秘密鍵・証明書・CSR ファイルを作成します。
CSR とは、サーバIDを申請・取得するために認証局へ提出する署名リクエスト(Certificate Signing Request)です。
また、秘密鍵・証明書を挟んでつなげた pem ファイルを作成します。
さらに ca のシリアル番号も発行します。
● mongosの crt, key, pemとca.srlの作成
$ openssl req -nodes -newkey rsa:2048 -days 365 -keyout mongos.key -out mongos.csr $ openssl x509 -req -days 365 -in mongos.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out mongos.crt $ cat mongos.key mongos.crt > mongos.pem
生成されるファイルは下記です。
ca.srl mongos.crt mongos.csr mongos.key mongos.pem
同じやり方でmongoc, mongodの crt, key, pemを作成します。
● mongocの crt, key, pemの作成
-CAcreateserial オプションでシリアル番号を発行することができます。
$ openssl req -nodes -newkey rsa:2048 -days 365 -keyout mongoc.key -out mongoc.csr $ openssl x509 -req -days 365 -in mongoc.csr -CA ca.crt -CAkey ca.key -CAserial ca.srl -out mongoc.crt $ cat mongoc.key mongoc.crt > mongoc.pem
生成されるファイルは下記です。
mongoc.crt mongoc.csr mongoc.key mongoc.pem
● mongod1の crt, key, pemの作成
$ openssl req -nodes -newkey rsa:2048 -days 365 -keyout mongod1.key -out mongod1.csr $ openssl x509 -req -days 365 -in mongod1.csr -CA ca.crt -CAkey ca.key -CAserial ca.srl -out mongod1.crt $ cat mongod1.key mongod1.crt > mongod1.pem
生成されるファイルは下記です。
mongod1.crt mongod1.csr mongod1.key mongod1.pem
● mongod2の crt, key, pemの作成
openssl req -nodes -newkey rsa:2048 -days 365 -keyout mongod2.key -out mongod2.csr openssl x509 -req -days 365 -in mongod2.csr -CA ca.crt -CAkey ca.key -CAserial ca.srl -out mongod2.crt cat mongod2.key mongod2.crt > mongod2.pem
生成されるファイルは下記です。
mongod2.crt mongod2.csr mongod2.key mongod2.pem
● clientの crt, key, pemの作成
$ openssl req -nodes -newkey rsa:2048 -days 365 -keyout client.key -out client.csr $ openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -CAserial ca.srl -out client.crt $ cat client.key client.crt > client.pem
作成されたファイルをそれぞれのサーバーに配置します。
<crt, pemファイルの配置>
SERVER | HOSTNAME | port | ディレクトリー | crt, pemファイル |
---|---|---|---|---|
mongos | mongotest-mongos.example.com | 27017 | /etc/mongodb/conf/key | ca.crt, mongos.pem |
mongoc | mongotest-mongos.example.com | 27018 | ca.crt, mongoc.pem | |
mongod | mongotest-mongod-1.example.com | 27019 | ca.crt, mongod1.pem | |
mongod | mongotest-mongod-2.example.com | 27019 | ca.crt, mongod2.pem |
crt, pemファイルの配置が終わったら、各 mongodb の conf ファイルの net の項目に TLS 設定を適用します。
● mongodb の conf ファイルの mode, allowConnectionsWithoutCertificates, certificateKeyFile, CAFileを設定
net: bindIpAll: true port: 27017 tls: mode: requireTLS allowConnectionsWithoutCertificates: false certificateKeyFile: /etc/mongodb/conf/key/client.pem CAFile: /etc/mongodb/mongodb/conf/key/ca.crt
設定が終わったら mongodb を再起動します。
これで MongoDB のセキュリティー通信ができるようになりました。
<SSL / TLSの連携図>
SSL/TLSで接続してみよう
SSL/TLSを設定したことで、接続する際には ca.crt と client の pem ファイルを指定する必要があります。
$ mongo --host mongotest-mongos.example.com:27017 --tls --tlsCAFile ca.crt --tlsCertificateKeyFile client.pem --authenticationDatabase=database
Studio 3Tからも接続してみましょう。
・Use SSL Protocol to connect にチェック
・Use own Root CA file を選択し、ca.crt ファイルパスを入力
・Use Client Certificate にチェック
・Client Certificate に pem ファイルのパスを入力
<Studio 3Tでの設定>
<Test Connection 結果>
その他Tips
● 秘密鍵や証明書の有効期限について
キーを作成する際に -days 365 のように有効期限を設定しますが、指定しないと基本 30 日になりますので注意してください。
● 認証有効期限確認の方法は?
以下のコマンドで確認できます。
$ openssl x509 -enddate -noout -in ca.crt >> notAfter=Mar 17 10:06:21 2022 GMT
● 証明書の情報確認方法は?
このコマンドでDNの情報や暗号化のアルゴリズムなどの確認ができます。
$ openssl x509 -text -noout -in client.crt
最後に
MongoDB で何かをする時に一番困ることは、他の RDB に比べて参考できる資料が少ないことです。
大体は MongoDB のマニュアルを参考していますが、そこには出てない様々なパターン、特に MongoDB Cloud Manager 関連の問題などはいろんなやり方を試しながらやるしかないと思います。
今回の TLS/SSL 設定も試行錯誤をしながら分かったことも多いです。
例えば、証明書を発行する際に期限を設定しないとデフォルト 30 日になるのを知らなかったため、重要なプレゼンテーションの直前に有効期間が切れてしまった場合もありました。
しかし、そのように一つ一つの知識を広げていくこともエンジニアの喜びはないでしょうか?
参考)
https://ja.wikipedia.org/wiki/Transport_Layer_Security
https://ja.wikipedia.org/wiki/X.509
現在、ココネではサービスインフラエンジニアの仲間を募集しています。
この記事を見て気になった方は、是非お気軽にエントリーください!お待ちしております。