MongoDB 通信の暗号化

スポンサーリンク

MongoDBの通信はBSONと呼ばれるデータ構造が平文でやりとりされます。PCI DSSのような強いセキュリティ要件を求められる場合、デフォルトの通信設定では要件を満たさないでしょう。このページでは、MongoDBの通信を暗号化する方法についてまとめます。

前提

公式ドキュメント

参考になる公式ドキュメントを以下に示します。

動作確認済環境

  • Rocky Linux 8.6
  • MongoDB Server 6.0.2

構成図

まずはMongoDBのクライアントとサーバの間の暗号化をテストするため、以下3台構成で動作確認します。

MongoDB 暗号化通信の構成図 01

次にMongoDBサーバ同士の通信が暗号化されている事をテストするため、以下9台構成で動作確認をします。

MongoDB 暗号化通信の構成図 02

事前設定

暗号化通信をするのにあたり、各サーバは自身のFQDNが正当である事を証明するサーバ証明書を使用します。MongoDBの通信をする時に、接続先のFQDNの正当性をチェックしますので、各サーバは名前解決できる事が必要になります。

このような背景を踏まえ、名前解決できるように以下のようなhostsファイルを全サーバに設定します。

cat << EOF > /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.1.10 mongod010.gokatei.go
172.16.1.11 mongod011.gokatei.go
172.16.1.12 mongod012.gokatei.go
172.16.1.20 mongoc020.gokatei.go
172.16.1.21 mongoc021.gokatei.go
172.16.1.22 mongoc022.gokatei.go
172.16.1.30 mongos030.gokatei.go
172.16.1.80 app080.gokatei.go
172.16.1.90 cert090.gokatei.go
EOF

サーバとクライアントとの間の暗号化

暗号化前の状況確認

暗号化設定前にデフォルトの状態では平文の通信が流れる事を確認します。mongod010で以下のコマンドを実行します。すると、パケットキャプチャの結果が標準出力されます。

tcpdump -nnn -i ens192 tcp port 27017 -X

別の端末を起動し、app080へログインします。その後、簡易的な通信を生成するために、以下のコマンドを実行します。

mongosh --quiet 172.16.1.10 << EOF
db.inventory.insertMany( [
   { item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
   { item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
] );
EOF

InsertMany実行後、tcpdumpコマンドが出力する標準出力を観察します。journal, inventoryなどの文字列が見える事から、平文で通信している事が読み取れます。

[root@linux010 ~]# tcpdump -nnn -i ens192 tcp port 27017 -X
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes
21:43:34.961462 IP 172.16.1.90.40666 > 172.16.1.10.27017: Flags [S], seq 1078325093, win 29200, options [mss 1460,sackOK,TS val 1329032348 ecr 0,nop,wscale 7], length 0
  0x0000:  4500 003c 1726 4000 4006 c911 ac10 015a  E..<.&@.@......Z
  0x0010:  ac10 010a 9eda 6989 4045 ef65 0000 0000  ......i.@E.e....
  0x0020:  a002 7210 8788 0000 0204 05b4 0402 080a  ..r.............
  0x0030:  4f37 6c9c 0000 0000 0103 0307            O7l.........

  <omitted>

21:43:40.850792 IP 172.16.1.10.27017 > 172.16.1.90.40668: Flags [P.], seq 2463:3098, ack 817, win 243, options [nop,nop,TS val 2786352502 ecr 1329038235], length 635
  0x0000:  4500 02af 7188 4000 4006 6c3c ac10 010a  E...q.@.@.l<....
  0x0010:  ac10 015a 6989 9edc 5e08 3269 7ab4 b1f8  ...Zi...^.2iz...
  0x0020:  8018 00f3 5d26 0000 0101 080a a614 5d76  ....]&........]v
  0x0030:  4f37 839b 7b02 0000 0f00 0000 0e00 0000  O7..{...........
  0x0040:  dd07 0000 0000 0000 0066 0200 0003 6375  .........f....cu
  0x0050:  7273 6f72 004d 0200 0004 6669 7273 7442  rsor.M....firstB
  0x0060:  6174 6368 0019 0200 0003 3000 6700 0000  atch......0.g...
  0x0070:  075f 6964 0063 5d1f 67de 3f1c aa84 f324  ._id.c].g.?....$
  0x0080:  6302 6974 656d 0007 0000 0063 616e 7661  c.item.....canva
  0x0090:  7300 1071 7479 0064 0000 0003 7369 7a65  s..qty.d....size
  0x00a0:  0023 0000 0010 6800 1c00 0000 0177 0000  .#....h......w..
  0x00b0:  0000 0000 c041 4002 756f 6d00 0300 0000  .....A@.uom.....
  0x00c0:  636d 0000 0273 7461 7475 7300 0200 0000  cm...status.....
  0x00d0:  4100 0003 3100 6400 0000 075f 6964 0063  A...1.d...._id.c
  0x00e0:  5d1f 67de 3f1c aa84 f324 6402 6974 656d  ].g.?....$d.item
  0x00f0:  0008 0000 006a 6f75 726e 616c 0010 7174  .....journal..qt
  0x0100:  7900 1900 0000 0373 697a 6500 1f00 0000  y......size.....
  0x0110:  1068 000e 0000 0010 7700 1500 0000 0275  .h......w......u
  0x0120:  6f6d 0003 0000 0063 6d00 0002 7374 6174  om.....cm...stat
  0x0130:  7573 0002 0000 0041 0000 0332 0068 0000  us.....A...2.h..
  0x0140:  0007 5f69 6400 635d 1f67 de3f 1caa 84f3  .._id.c].g.?....
  0x0150:  2465 0269 7465 6d00 0400 0000 6d61 7400  $e.item.....mat.
  0x0160:  1071 7479 0055 0000 0003 7369 7a65 0027  .qty.U....size.'
  0x0170:  0000 0001 6800 6666 6666 66e6 3b40 0177  ....h.fffff.;@.w
  0x0180:  0000 0000 0000 c041 4002 756f 6d00 0300  .......A@.uom...
  0x0190:  0000 636d 0000 0273 7461 7475 7300 0200  ..cm...status...
  0x01a0:  0000 4100 0003 3300 6900 0000 075f 6964  ..A...3.i...._id
  0x01b0:  0063 5d1f 67de 3f1c aa84 f324 6602 6974  .c].g.?....$f.it
  0x01c0:  656d 0009 0000 006d 6f75 7365 7061 6400  em.....mousepad.
  0x01d0:  1071 7479 0019 0000 0003 7369 7a65 0023  .qty......size.#
  0x01e0:  0000 0010 6800 1300 0000 0177 009a 9999  ....h......w....
  0x01f0:  9999 d936 4002 756f 6d00 0300 0000 636d  ...6@.uom.....cm
  0x0200:  0000 0273 7461 7475 7300 0200 0000 5000  ...status.....P.
  0x0210:  0003 3400 6900 0000 075f 6964 0063 5d1f  ..4.i...._id.c].
  0x0220:  67de 3f1c aa84 f324 6702 6974 656d 0009  g.?....$g.item..
  0x0230:  0000 006e 6f74 6562 6f6f 6b00 1071 7479  ...notebook..qty
  0x0240:  0032 0000 0003 7369 7a65 0023 0000 0001  .2....size.#....
  0x0250:  6800 0000 0000 0000 2140 1077 000b 0000  h.......!@.w....
  0x0260:  0002 756f 6d00 0300 0000 696e 0000 0273  ..uom.....in...s
  0x0270:  7461 7475 7300 0200 0000 5000 0000 1269  tatus.....P....i
  0x0280:  6400 0000 0000 0000 0000 026e 7300 0f00  d..........ns...
  0x0290:  0000 7465 7374 2e69 6e76 656e 746f 7279  ..test.inventory
  0x02a0:  0000 016f 6b00 0000 0000 0000 f03f 00    ...ok........?.

俺々認証局

サーバ証明書を発行するには認証局が必要です。MongoDBの暗号化通信をするには、公的な認証局を使っても、俺々認証局を使っても、どちらでも差し支えございません。ここでは公的な認証局を使った操作を説明します。

このシナリオではcert090という認証局専用の仮想マシンを構築していますが、専用の仮想マシンは必須ではありません。操作をイメージしやすくするために、敢えて専用の仮想マシンを設けています。

作業用のディレクトリを作成します。

mkdir -p /etc/mongod/ssl
cd /etc/mongod/ssl

俺々認証局の秘密鍵を作成します。

openssl genrsa -out ROOTCA.key 2048

秘密鍵を元に、俺々認証局のサーバ証明書を作成します。

openssl \
  req -x509 \
  -new -nodes \
  -key ROOTCA.key \
  -sha256 \
  -days 3560 \
  -subj "/CN=cert090.gokatei.go" \
  -out ROOTCA.crt

以上の操作完了時点で、俺々認証局の秘密鍵とサーバ証明書が作成されます。以下のようなファイルが作成されていれば想定通りです。

[root@cert090 ssl]# pwd
/etc/mongod/ssl
[root@cert090 ssl]# ls -l
合計 8
-rw-r--r-- 1 root root 1139 10月 29 22:39 ROOTCA.crt
-rw------- 1 root root 1675 10月 29 22:39 ROOTCA.key
[root@cert090 ssl]# 

クライアント(app080)の証明書作成

作業用のディレクトリを作成します。

mkdir -p /etc/mongod/ssl
cd /etc/mongod/ssl

クライアント(app080.gokatei.go)の秘密鍵を作成します。

openssl genrsa -out app080.key 2048

クライアント(app080.gokatei.go)の証明書署名要求を作成します。

openssl req -new \
  -key app080.key \
  -subj "/CN=app080.gokatei.go" \
  -out app080.csr

証明書署名要求を俺々認証局(cert090.gokatei.go)へ転送します。

scp app080.csr cert090.gokatei.go:/etc/mongod/ssl/

俺々認証局は自身の秘密鍵と証明書を元に、証明書署名要求に対して署名をします。すなわち、app080.gokatei.goである事を証明する証明書を発行します。

openssl x509 \
  -req \
  -in app080.csr \
  -CA ROOTCA.crt \
  -CAkey ROOTCA.key \
  -CAcreateserial \
  -out app080.crt \
  -days 365 \
  -sha256

俺々認証局に「app080.crt」というファイルがapp080.gokatei.goである事を証明する証明書です。

[root@cert090 ssl]# ls -l
合計 20
-rw-r--r-- 1 root root 1139 10月 29 22:39 ROOTCA.crt
-rw------- 1 root root 1675 10月 29 22:39 ROOTCA.key
-rw-r--r-- 1 root root   41 10月 29 22:56 ROOTCA.srl
-rw-r--r-- 1 root root 1013 10月 29 22:56 app080.crt
-rw-r--r-- 1 root root  903 10月 29 22:53 app080.csr
[root@cert090 ssl]# 

俺々認証局は、証明書(app080.crt)とCA証明書(ROOTCA.crt)をapp080.gokatie.goへ返送します。

scp ROOTCA.crt app080.gokatei.go:/etc/mongod/ssl/
scp app080.crt app080.gokatei.go:/etc/mongod/ssl/

MongoDBへ接続する時に使用するKeyFileは、証明書と秘密鍵をセットにしたファイルである事を前提にしています。クライアント(app080.gokatei.go)にて、証明書と秘密鍵をセットにする操作をします。

cat app080.key app080.crt > app080.pem

最終的に、クライアント(app080.gokatei.go)にて、以下5ファイルが作成されていれば想定通りです。

[root@app080 ssl]# ls -l
合計 20
-rw-r--r-- 1 root root 1139 10月 29 23:00 ROOTCA.crt
-rw-r--r-- 1 root root 1013 10月 29 23:00 app080.crt
-rw-r--r-- 1 root root  903 10月 29 22:46 app080.csr
-rw------- 1 root root 1675 10月 29 22:45 app080.key
-rw-r--r-- 1 root root 2688 10月 29 23:02 app080.pem
[root@app080 ssl]# 

サーバ(mongod010)の証明書作成

作業用のディレクトリを作成します。

mkdir -p /etc/mongod/ssl
cd /etc/mongod/ssl

サーバ(mongod010.gokatei.go)の秘密鍵を作成します。

openssl genrsa -out mongod010.key 2048

サーバ(mongod010.gokatei.go)の証明書署名要求を作成します。

openssl req -new \
  -key mongod010.key \
  -subj "/CN=mongod010.gokatei.go" \
  -out mongod010.csr

証明書署名要求を俺々認証局(cert090.gokatei.go)へ転送します。

scp mongod010.csr cert090.gokatei.go:/etc/mongod/ssl/

俺々認証局は自身の秘密鍵と証明書を元に、証明書署名要求に対して署名をします。すなわち、mongod010.gokatei.goである事を証明する証明書を発行します。

openssl x509 \
  -req \
  -in mongod010.csr \
  -CA ROOTCA.crt \
  -CAkey ROOTCA.key \
  -CAcreateserial \
  -out mongod010.crt \
  -days 365 \
  -sha256

俺々認証局に「mongod010.crt」というファイルがmongod010.gokatei.goである事を証明する証明書です。

[root@cert090 ssl]# ls -l
合計 28
-rw-r--r-- 1 root root 1139 10月 29 22:39 ROOTCA.crt
-rw------- 1 root root 1675 10月 29 22:39 ROOTCA.key
-rw-r--r-- 1 root root   41 10月 29 23:06 ROOTCA.srl
-rw-r--r-- 1 root root 1013 10月 29 22:56 app080.crt
-rw-r--r-- 1 root root  903 10月 29 22:53 app080.csr
-rw-r--r-- 1 root root 1017 10月 29 23:06 mongod010.crt
-rw-r--r-- 1 root root  907 10月 29 23:05 mongod010.csr
[root@cert090 ssl]# 

俺々認証局は、証明書(mongod010.crt)とCA証明書(ROOTCA.crt)をmongod010.gokatie.goへ返送します。

scp ROOTCA.crt mongod010.gokatei.go:/etc/mongod/ssl/
scp mongod010.crt mongod010.gokatei.go:/etc/mongod/ssl/

MongoDBへ接続する時に使用するKeyFileは、証明書と秘密鍵をセットにしたファイルである事を前提にしています。サーバ(mongod010.gokatei.go)にて、証明書と秘密鍵をセットにする操作をします。

cat mongod010.key mongod010.crt > mongod010.pem

最終的に、クライアント(app080.gokatei.go)にて、以下5ファイルが作成されていれば想定通りです。

[root@mongod010 ssl]# ls -l
合計 20
-rw-r--r-- 1 root root 1139 10月 29 23:06 ROOTCA.crt
-rw-r--r-- 1 root root 1017 10月 29 23:06 mongod010.crt
-rw-r--r-- 1 root root  907 10月 29 23:05 mongod010.csr
-rw------- 1 root root 1675 10月 29 23:05 mongod010.key
-rw-r--r-- 1 root root 2692 10月 29 23:07 mongod010.pem
[root@mongod010 ssl]# 

サーバ(mongod010)の暗号化強制設定

サーバ(mongod010)にて、/etc/mongod.confを以下のように設定します。net.tls.modeをrequireTLSにする事で暗号化を強制する事ができます。また、net.tls.certificateKeyFileには自身の証明書と秘密鍵を結合したpemファイルを指定し、net.tls.CAFileにはCA認証局の証明書を指定します。

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
  tls:
    mode: requireTLS
    allowConnectionsWithoutCertificates: false
    certificateKeyFile: /etc/mongod/ssl/mongod010.pem
    CAFile: /etc/mongod/ssl/ROOTCA.crt

設定を反映させるために再起動をします。

systemctl restart mongod.service 

疎通確認

まずはクライアント(app080.gokatie.go)から暗号化をせずに接続を試みます。

[root@app080 ~]# mongosh mongod010.gokatei.go
Current Mongosh Log ID: 635d349ee6fa120ceb342819
Connecting to:    mongodb://mongod010.gokatei.go:27017/?directConnection=true&appName=mongosh+1.6.0
MongoServerSelectionError: connection <monitor> to 172.16.1.10:27017 closed
[root@app080 ~]# 


それでは暗号化をしつつの接続を試みます。以下のようにtls, tlsCAFile, tlsCertificateKeyFileのオプションを与えてmongoshを実行します。


cd /etc/mongod/ssl/
mongosh \
  --quiet \
  --tls \
  --tlsCAFile ROOTCA.crt \
  --tlsCertificateKeyFile app080.pem \
  mongodb://mongod010.gokatei.go:27017

操作ログは以下の通りです。接続操作やfindコマンドの実行が可能である事を確認できます。

[root@app080 ~]# cd /etc/mongod/ssl/
[root@app080 ssl]# mongosh \
>   --quiet \
>   --tls \
>   --tlsCAFile ROOTCA.crt \
>   --tlsCertificateKeyFile app080.pem \
>   mongodb://mongod010.gokatei.go:27017
test> db.inventory.find()
[
  {
    _id: ObjectId("635d2a701949833719915913"),
    item: 'canvas',
    qty: 100,
    size: { h: 28, w: 35.5, uom: 'cm' },
    status: 'A'
  },
  {
    _id: ObjectId("635d2a701949833719915914"),
    item: 'journal',
    qty: 25,
    size: { h: 14, w: 21, uom: 'cm' },
    status: 'A'
  },
  {
    _id: ObjectId("635d2a701949833719915915"),
    item: 'mat',
    qty: 85,
    size: { h: 27.9, w: 35.5, uom: 'cm' },
    status: 'A'
  },
  {
    _id: ObjectId("635d2a701949833719915916"),
    item: 'mousepad',
    qty: 25,
    size: { h: 19, w: 22.85, uom: 'cm' },
    status: 'P'
  },
  {
    _id: ObjectId("635d2a701949833719915917"),
    item: 'notebook',
    qty: 50,
    size: { h: 8.5, w: 11, uom: 'in' },
    status: 'P'
  }
]
test> 

上記findコマンド実行時のパケットキャプチャを観察します。inventory, sizeなどの平文の文字が見当たらない事から暗号化されているのが読み取れます。

[root@mongod010 ~]# tcpdump -nnn -i ens192 tcp port 27017 -X
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes

  <omitted>

23:18:18.833897 IP 172.16.1.10.27017 > 172.16.1.80.60320: Flags [P.], seq 4519:4854, ack 2844, win 294, options [nop,nop,TS val 4075150155 ecr 980796541], length 335
  0x0000:  4500 0183 0e9d 4000 4006 d05d ac10 010a  E.....@.@..]....
  0x0010:  ac10 0150 6989 eba0 f5ee 0b5d 3f27 7d3c  ...Pi......]?'}<
  0x0020:  8018 0126 5bf0 0000 0101 080a f2e5 db4b  ...&[..........K
  0x0030:  3a75 c47d 1703 0301 4ade edc4 8e40 45ab  :u.}....J....@E.
  0x0040:  7020 3c8f 8d57 2969 c28d 2324 3d35 ac99  p.<..W)i..#$=5..
  0x0050:  5890 2fcc ad5e 5430 2346 67f5 8a1b 1fbe  X./..^T0#Fg.....
  0x0060:  9ec5 99cd fffc e424 2aa7 7bc1 11ef a0b8  .......$*.{.....
  0x0070:  711d b239 c000 2059 b2c9 b29b f57b 2f43  q..9...Y.....{/C
  0x0080:  a896 8931 ea4b 5569 4799 8e72 cb55 ac84  ...1.KUiG..r.U..
  0x0090:  1fc6 0e3e b110 0da4 403d 71a6 e8b0 2906  ...>....@=q...).
  0x00a0:  6993 2178 847d 36cc a253 b4ff 7108 031d  i.!x.}6..S..q...
  0x00b0:  ffb4 f097 4c92 6e0b 9157 d835 f733 7d26  ....L.n..W.5.3}&
  0x00c0:  6f08 d983 68df fdc8 ac4a 07df 14fa 2327  o...h....J....#'
  0x00d0:  ef78 b5b7 de73 59e6 a5eb 05a8 6ad3 192d  .x...sY.....j..-
  0x00e0:  c893 66e2 bc9c 05bf 6c5e 49bc 65bd cfb4  ..f.....l^I.e...
  0x00f0:  e3d6 6ec1 53ee 3406 7467 32e4 7b8d 42bd  ..n.S.4.tg2.{.B.
  0x0100:  67a0 1ede f543 df04 8ab2 a77f 11d3 7a98  g....C........z.
  0x0110:  1809 854c faa0 6421 5b26 b814 ce1f 359f  ...L..d![&....5.
  0x0120:  ba3b ef9a 4d5c 6f5c 087a 6750 a98b d141  .;..M\o\.zgP...A
  0x0130:  d1b1 bc7a e981 2980 d049 cd1f ec07 a59b  ...z..)..I......
  0x0140:  b141 35a8 86e2 7dad 1a06 e0bf 2617 64ba  .A5...}.....&.d.
  0x0150:  0af7 f531 59ed 3a4a fc15 4aa6 e2b4 85fd  ...1Y.:J..J.....
  0x0160:  c838 4411 8896 cc76 aec0 fc02 a9ce 0861  .8D....v.......a
  0x0170:  3dd2 d3a2 cdfb 6447 e1e2 7d17 c209 0014  =.....dG..}.....
  0x0180:  e8d4 b3

サーバ間の暗号化

証明書作成

mongod011, mongod012, mongoc020, mongoc021, mongoc022, mongos030の6台のサーバについて、同様の操作でサーバ証明書を作成します。

作業用ディレクトリを作成し、秘密鍵と証明書署名要求を作成します。その後、俺々認証局に証明書署名要求を転送します。

「hostname -s」は短縮ホスト名を返すコマンドです。以下をコピー&ペーストすれば、4台とも同じコマンドで証明書署名要求を作成する事ができます。

# create working directory
mkdir -p /etc/mongod/ssl
cd /etc/mongod/ssl

# create private key
openssl genrsa -out $(hostname -s).key 2048

# create CSR(certificate signing request)
openssl req -new \
  -key $(hostname -s).key \
  -subj "/CN=$(hostname -s).gokatei.go" \
  -out $(hostname -s).csr

# transfer CSR(certificate signing request)
scp $(hostname -s).csr cert090.gokatei.go:/etc/mongod/ssl/

俺々認証局は自身の秘密鍵と証明書を元に、証明書署名要求に対して署名をします。その後、証明書とCA証明書を返送します。

cd /etc/mongod/ssl

for host in mongod011 mongod012 mongoc020 mongoc021 mongoc022 mongos030
do
  openssl x509 \
    -req \
    -in ${host}.csr \
    -CA ROOTCA.crt \
    -CAkey ROOTCA.key \
    -CAcreateserial \
    -out ${host}.crt \
    -days 365 \
    -sha256

  scp ROOTCA.crt ${host}.gokatei.go:/etc/mongod/ssl/
  scp ${host}.crt ${host}.gokatei.go:/etc/mongod/ssl/
done

証明書と秘密鍵をセットにするpemファイルを作成します。

cat $(hostname -s).key $(hostname -s).crt > $(hostname -s).pem

Shard Replica Setsの構築

Shard Replica Sets用途として構築するmongod010, mongod011, mongod012について、/etc/mongod.confを以下のように編集します。

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
  tls:
    mode: requireTLS
    allowConnectionsWithoutCertificates: false
    certificateKeyFile: /etc/mongod/ssl/mongod010.pem
    CAFile: /etc/mongod/ssl/ROOTCA.crt

#replication:
replication:
  replSetName: rs1

#sharding:
sharding:
  clusterRole: shardsvr
# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
  tls:
    mode: requireTLS
    allowConnectionsWithoutCertificates: false
    certificateKeyFile: /etc/mongod/ssl/mongod011.pem
    CAFile: /etc/mongod/ssl/ROOTCA.crt

#replication:
replication:
  replSetName: rs1

#sharding:
sharding:
  clusterRole: shardsvr
# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
  tls:
    mode: requireTLS
    allowConnectionsWithoutCertificates: false
    certificateKeyFile: /etc/mongod/ssl/mongod012.pem
    CAFile: /etc/mongod/ssl/ROOTCA.crt

#replication:
replication:
  replSetName: rs1

#sharding:
sharding:
  clusterRole: shardsvr

設定を反映させるために再起動をします。

systemctl restart mongod.service

レプリケーションを開始するために、mongoshコマンドで接続しrs.initiateコマンドの実行を試みます。ですが、少し工夫が必要です。すでにMongoDBサーバは平文による接続を許容しませんので、単純なmongoshコマンドでは接続できなくなってしまいました。

[root@mongod010 ~]# mongosh
Current Mongosh Log ID: 635d465bdb9043a81ba09a45
Connecting to:    mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.6.0
MongoServerSelectionError: connection <monitor> to 127.0.0.1:27017 closed
[root@mongod010 ~]# 

ですので、以下のようにサーバ証明書とCA証明書を指定してMongoDBへの接続を試みます。

mongosh \
  --quiet \
  --tls \
  --tlsCAFile /etc/mongod/ssl/ROOTCA.crt \
  --tlsCertificateKeyFile /etc/mongod/ssl/mongod010.pem \
  mongodb://mongod010.gokatei.go:27017

レプリケーションを開始します。

  rs.initiate(
    {
      _id : "rs1",
      members: [
        { _id : 0, host : "mongod010.gokatei.go:27017" , priority : 4 },
        { _id : 1, host : "mongod011.gokatei.go:27017" , priority : 2 },
        { _id : 2, host : "mongod012.gokatei.go:27017" , priority : 1 }
      ]
    }
  )

レプリケーションに関する操作ログは以下の通りです。

[root@mongod010 ~]# mongosh \
>   --quiet \
>   --tls \
>   --tlsCAFile /etc/mongod/ssl/ROOTCA.crt \
>   --tlsCertificateKeyFile /etc/mongod/ssl/mongod010.pem \
>   mongodb://mongod010.gokatei.go:27017
test>   rs.initiate(
...     {
...       _id : "rs1",
...       members: [
...         { _id : 0, host : "mongod010.gokatei.go:27017" , priority : 4 },
...         { _id : 1, host : "mongod011.gokatei.go:27017" , priority : 2 },
...         { _id : 2, host : "mongod012.gokatei.go:27017" , priority : 1 }
...       ]
...     }
...   )
{ ok: 1 }
rs1 [direct: secondary] test> 

rs1 [direct: primary] test> 

configサーバの構築

configサーバ用途として構築するmongoc020, mongoc021, mongoc022について、/etc/mongod.confを以下のように編集します。

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
  tls:
    mode: requireTLS
    allowConnectionsWithoutCertificates: false
    certificateKeyFile: /etc/mongod/ssl/mongoc020.pem
    CAFile: /etc/mongod/ssl/ROOTCA.crt

#replication:
replication:
  replSetName: rs2

#sharding:
sharding:
  clusterRole: configsvr
# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
  tls:
    mode: requireTLS
    allowConnectionsWithoutCertificates: false
    certificateKeyFile: /etc/mongod/ssl/mongoc021.pem
    CAFile: /etc/mongod/ssl/ROOTCA.crt

#replication:
replication:
  replSetName: rs2

#sharding:
sharding:
  clusterRole: configsvr
# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
  tls:
    mode: requireTLS
    allowConnectionsWithoutCertificates: false
    certificateKeyFile: /etc/mongod/ssl/mongoc022.pem
    CAFile: /etc/mongod/ssl/ROOTCA.crt

#replication:
replication:
  replSetName: rs2

#sharding:
sharding:
  clusterRole: configsvr

設定を反映させるために再起動をします。

systemctl restart mongod.service

以下のようにサーバ証明書とCA証明書を指定してMongoDBへの接続を試みます。

mongosh \
  --quiet \
  --tls \
  --tlsCAFile /etc/mongod/ssl/ROOTCA.crt \
  --tlsCertificateKeyFile /etc/mongod/ssl/mongoc020.pem \
  mongodb://mongoc020.gokatei.go:27017

レプリケーションを開始します。

rs.initiate(
  {
    _id: "rs2",
    configsvr: true,
    members: [
      { _id : 0, host : "mongoc020.gokatei.go:27017", priority : 4 },
      { _id : 1, host : "mongoc021.gokatei.go:27017", priority : 2 },
      { _id : 2, host : "mongoc022.gokatei.go:27017", priority : 1 }
    ]
  }
)

レプリケーションに関する操作ログは以下の通りです。

[root@mongoc020 ~]# mongosh \
>   --quiet \
>   --tls \
>   --tlsCAFile /etc/mongod/ssl/ROOTCA.crt \
>   --tlsCertificateKeyFile /etc/mongod/ssl/mongoc020.pem \
>   mongodb://mongoc020.gokatei.go:27017
test> rs.initiate(
...   {
...     _id: "rs2",
...     configsvr: true,
...     members: [
...       { _id : 0, host : "mongoc020.gokatei.go:27017", priority : 4 },
...       { _id : 1, host : "mongoc021.gokatei.go:27017", priority : 2 },
...       { _id : 2, host : "mongoc022.gokatei.go:27017", priority : 1 }
...     ]
...   }
... )
{ ok: 1, lastCommittedOpTime: Timestamp({ t: 1667058115, i: 1 }) }
rs2 [direct: other] test> 

rs2 [direct: primary] test> 

mongosサーバの構築

mongod同様にmongosも暗号化通信を強制する事ができます。mongos.confの設定例を以下に記します。

cat << 'EOF' > /etc/mongos.conf 
net:
  port: 27017
  bindIp: 0.0.0.0
  tls:
    mode: requireTLS
    allowConnectionsWithoutCertificates: false
    certificateKeyFile: /etc/mongod/ssl/mongos030.pem
    CAFile: /etc/mongod/ssl/ROOTCA.crt

sharding:
  configDB: rs2/mongoc020.gokatei.go:27017,mongoc021.gokatei.go:27017,mongoc022.gokatei.go:27017
EOF

mongosを起動します。

mongos --config /etc/mongos.conf 

クライアント(app080.gokatei.go)からmongosへ接続します。

mongosh \
  --quiet \
  --tls \
  --tlsCAFile /etc/mongod/ssl/ROOTCA.crt \
  --tlsCertificateKeyFile /etc/mongod/ssl/app080.pem \
  mongodb://mongos030.gokatei.go:27017

接続後、レプリカセットをシャードに加えます。

sh.addShard("rs1/mongod010.gokatei.go:27017,mongod011.gokatei.go:27017,mongod012.gokatei.go:27017")

以上の操作により、MongoDBのサーバ間も暗号化を実現する事ができます。

タイトルとURLをコピーしました