Kaynağa Gözat

chore(authn): test MongoDB authn via ssl connection

Ilya Averyanov 4 yıl önce
ebeveyn
işleme
a7ca6cb39f

+ 2 - 0
.ci/docker-compose-file/Makefile.local

@@ -19,6 +19,7 @@ up:
 	docker-compose \
 		-f .ci/docker-compose-file/docker-compose.yaml \
 		-f .ci/docker-compose-file/docker-compose-mongo-single-tcp.yaml \
+		-f .ci/docker-compose-file/docker-compose-mongo-single-tls.yaml \
 		-f .ci/docker-compose-file/docker-compose-mysql-tcp.yaml \
 		-f .ci/docker-compose-file/docker-compose-mysql-tls.yaml \
 		-f .ci/docker-compose-file/docker-compose-pgsql-tcp.yaml \
@@ -31,6 +32,7 @@ down:
 	docker-compose \
 		-f .ci/docker-compose-file/docker-compose.yaml \
 		-f .ci/docker-compose-file/docker-compose-mongo-single-tcp.yaml \
+		-f .ci/docker-compose-file/docker-compose-mongo-single-tls.yaml \
 		-f .ci/docker-compose-file/docker-compose-mysql-tcp.yaml \
 		-f .ci/docker-compose-file/docker-compose-mysql-tls.yaml \
 		-f .ci/docker-compose-file/docker-compose-pgsql-tcp.yaml \

+ 14 - 7
.ci/docker-compose-file/docker-compose-mongo-single-tls.yaml

@@ -1,23 +1,30 @@
 version: '3.9'
 
 services:
-  mongo_server:
-    container_name: mongo
+  mongo_server_tls:
+    container_name: mongo-tls
     image: mongo:${MONGO_TAG}
     restart: always
     environment:
       MONGO_INITDB_DATABASE: mqtt
     volumes:
-      - ../../apps/emqx/etc/certs/cert.pem:/etc/certs/cert.pem
-      - ../../apps/emqx/etc/certs/key.pem:/etc/certs/key.pem
+      - ./mongo/certs/server.crt:/etc/certs/cert.pem
+      - ./mongo/certs/server.key:/etc/certs/key.pem
+      - ./mongo/certs/ca.crt:/etc/certs/cacert.pem
     networks:
       - emqx_bridge
     ports:
-      - "27017:27017"
+      - "27018:27017"
     command:
       - /bin/bash
       - -c
       - |
-        cat /etc/certs/key.pem /etc/certs/cert.pem >  /etc/certs/mongodb.pem
-        mongod --ipv6 --bind_ip_all --sslMode requireSSL --sslPEMKeyFile /etc/certs/mongodb.pem
+        cat /etc/certs/key.pem /etc/certs/cert.pem > /etc/certs/mongodb.pem
+        mongod --ipv6 --bind_ip_all \
+          --tlsOnNormalPorts \
+          --tlsMode requireSSL \
+          --tlsCertificateKeyFile /etc/certs/mongodb.pem \
+          --tlsCAFile /etc/certs/cacert.pem \
+          --tlsDisabledProtocols TLS1_0,TLS1_1 \
+          --setParameter opensslCipherConfig='HIGH:!EXPORT:!aNULL:!DHE:!kDHE@STRENGTH'
 

+ 29 - 0
.ci/docker-compose-file/mongo/certs/ca.crt

@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE5DCCAswCCQD8UL+glAaqCDANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlF
+TVFYIFRlc3QxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMTEy
+MjcwODIzNDhaFw00OTA1MTQwODIzNDhaMDQxEjAQBgNVBAoMCUVNUVggVGVzdDEe
+MBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA5uzGSZYswJSGceegV78c29D0nGwD3xCE/DaHk5JYQ60R
+SY1V+3ICoIrN80u3hj4IbDOjHEmzeoUeeorlhnTH7T42lY+GwnFp2hRqAsMuZfZD
+dlLGjlIswf2THZ92aQwSRsHe9j2BTfGyMa9lP6D0D9Bq4Qadk0KM+irG6rETwPvA
+CUxKDhPdIyp0hAmuYsZOENFZeuyVexqiOxh8exVRQIFCKfh7DTV4ziXpoNy1xqH/
+Gjg57DsX+J1hPraOvfZga/fpGwjMqzYCHMMtnnqrrV2IWBShdYET5swm9g2FmQES
+oJ3ScFptcA27AhQSikK1kMrCvOVqWvzJDsr/x2Auv+aGxSOi+NGEf4qrGHQan99g
+C82hbeGRBffuPKFxPqPuIFzVekRhcAjoNhwzxbYZnGmV+cTSvVk8RF0pB+uj8L2Y
+OtBWuAxDl6p4/RPU8KIGO5jkka4eVsucnoqcXS2WnWbPewfAMOPDOhR8asFWCxE5
+snknoRlo8cRv9JN/8qsQLW8ibeZTTsw6fe2Kv0hyhpErQqw6QEbKn0bp+ZcGOw7O
+tkjye9l1OwL3GIwNGrF1B2mLw6TUrAxHWZQgrjfFHQk+nsZtQDUi19rPvwK1Vk+Z
+g6TSYJPbWZBcRzsZxuezn5sJ4XO56zwCXaP2gohsOVZPd6U+n5vtKhs6eLHJLU0C
+AwEAATANBgkqhkiG9w0BAQsFAAOCAgEAw2PK8Nr3lQyF9pipvahEkHSIz8TVeLue
+lT8h6Hrkn1UcDHpECja/tPKLxYEVUoyMKeKR3K6AO5RmCgDObcZRkMdMmNYocvb5
+1BvGhlv3uk5rNUz+PW8F6cwVp+3RevBD5OSEkBzq6fuSyC0g8dk17IPKnfwNJCue
+gkgsyEUgSHK8t3g/uE0Jdx//svTdnc7dmB43uU3o3tl+qhMwm7Zjr58gP1t7fMTD
+Zu8Yq8en39lMDt1lv4LZG5JyEL5GQMr9B9ft5ZJpg6LGxRUmC7J8d+5Swux6MjcZ
+pAG2/V0VJwrR+joT8BZqnj/pR2Mk+34Ul1DIF7iSS/P+Wwy4+oP3XaNmXPJPTX8Y
+acVYYO2Q9o0B6zPQk5e2ECSMqQ2NW0+RJv2YJl77WoCWScYhixqOwWNrXu8CSeQ9
+99rZrwN9lDN3I/bXLqzjUlTwL49YDSy50GkVKC14mZNSIAegJqGv3SwmITRZRaYF
+UNhdmLldCCZ686QkGGsiIWmKug0IxJxYtLQKpajHuBQKhyyRgfIq+CfdyjsxmVNE
+1h1bmi7Hy30KAx4qGHXGhKbITAUvAOHDNs5G9R8vv6J/AjOPGeuy9mayHg3CIarx
+z0p0b9dYMK9yL9dEC8KHfUSIh7ZoR6JENkdq0Uj/8AE4+NwzrNbFRMKNAGMjFi8K
+UPcPKDe8WZQ=
+-----END CERTIFICATE-----

+ 51 - 0
.ci/docker-compose-file/mongo/certs/ca.key

@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----

+ 24 - 0
.ci/docker-compose-file/mongo/certs/client.crt

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/jCCAeagAwIBAgIJAKyzto6kgv4EMA0GCSqGSIb3DQEBCwUAMDQxEjAQBgNV
+BAoMCUVNUVggVGVzdDEeMBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X
+DTIxMTIyNzA4MjM0OFoXDTQ5MDUxNDA4MjM0OFowJTESMBAGA1UECgwJRU1RWCBU
+ZXN0MQ8wDQYDVQQDDAZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQCzgIQamGaqpP+SzwmEYtNL8koAUs0XNw6ohJ4s1lopkqOY2fnbWKO6JOSv
+RPPStRiRklsPNno59cKfoN8j+Psfne6nkQbq1fbsZRzYGX3LdQVsD4QMEC4X63oJ
+neEQ7hsEFaYW0bpkppVF300E23VT7CEDkEYBWhbXCTsdbQltffSG10ZT9XVHbqTL
+cTmQzicn6TWQ8jH++VoY1q76OBd98gHcV6BocR61oXyjyArkUlGDsj3s5Xfsbfay
+fagy6Q4cEBOrqWQvSqnenAll6IhEZ2KPDiXZWDPWMyLpLNO13ECp9+m7CMAo+15y
+Zw/UUFeUyWlLtDXfV+GJzAA1Rv9vAgMBAAGjIjAgMAsGA1UdDwQEAwIFoDARBglg
+hkgBhvhCAQEEBAMCB4AwDQYJKoZIhvcNAQELBQADggIBALYlv9OxmYtj0BOdQrM5
+oIhivrA/bl8/Kzn4Bioqth8iWtpgZcZK15NKCGiDEKCkm+cKXWkC9tQcQzHpVas2
+aAKeiXIkYiSj1NiNDMrv5XLKOeFrMDVLWUAJzfSEr3Jsci+Wf8dX/VoYhgkH247w
+j8cI8x7Vhi6Iun4pbp+ltuVtfcVAfUPhdrIXiif+hCLDbxdgj6qQ4MHC/Zpx1i+7
+4NVX8BVHsigFzN09GfHs3n+Uiq2Lzd3FaHnXWx+rueycQyXI5655YUbPJdWPO8Pu
+JX+++GlpY91ni/UTMPdgmcqzMQo8kxV9+16sU4PjLcSKsgpJ0pT2ZJ+OJgtiMrEO
+IS41ht4yhpx3G3FXim5MzUTsGHV7rr8ZzZ6wN46QXjzWtsLX98nzI1Dlz2USlbbz
+N0NjgdPROUZsRDwEinnb1D96Rfn79qnfJhGmCXd5QSvM4HGW5SqqzzyvE0nLRnDg
+davqHzA0en3Rt1/INCjr/+3GM4qy5lCG1fz1iuv5lfTVahljkkxnzSXyPW2E+0nZ
+05bq/fAEbkQaOBwPWGTNCc4InzaUU0XKtx4IcnprgF6846lNRE7aFHjAWqOjOnZj
+secfrzXDRLNJ58+eZpdJvVsaRl22bRHKI0MDNk5VzDKp/rqw/8+2f+Y2LXNKOJEQ
+KLXCWq2sh5ReRiyDSaK+IP1z
+-----END CERTIFICATE-----

+ 27 - 0
.ci/docker-compose-file/mongo/certs/client.key

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAs4CEGphmqqT/ks8JhGLTS/JKAFLNFzcOqISeLNZaKZKjmNn5
+21ijuiTkr0Tz0rUYkZJbDzZ6OfXCn6DfI/j7H53up5EG6tX27GUc2Bl9y3UFbA+E
+DBAuF+t6CZ3hEO4bBBWmFtG6ZKaVRd9NBNt1U+whA5BGAVoW1wk7HW0JbX30htdG
+U/V1R26ky3E5kM4nJ+k1kPIx/vlaGNau+jgXffIB3FegaHEetaF8o8gK5FJRg7I9
+7OV37G32sn2oMukOHBATq6lkL0qp3pwJZeiIRGdijw4l2Vgz1jMi6SzTtdxAqffp
+uwjAKPtecmcP1FBXlMlpS7Q131fhicwANUb/bwIDAQABAoIBAQCL0JOVP5XgXwqu
+6FLKakuYwU1AuT4EUh85xaqK1B+AeDazbT1/y6gj6m6x0mx0eBh98ti4nb9QfAuv
+WJfWJi48b0CgBoezzRs7AHsaG6jvG+QwSlmZJ9UvTnxNF0tia4RhhxdKeOvNUC+/
+L/KG0QWva6I/a1YL4Yce0ZLZFcAdJouJpjv0Bqe0xgcK7rld2AqGY54YvUqeoSjA
+Uv2mhCy4xoRtF2XXyjJ1R/JOlsN8mHZvae4teWipSUf91zzd7thLT7s5CPcd2gj+
+2CQps0HkwbvpEB9Y3sGW5pVwacY9fOZkZPiaCqQ0cWDCj0qh9xi1m0/yL2sUrbet
+S08YBThhAoGBANxR3armXC9G2jomBSvEq3kVpjQbaZwgFTKgf9nCMVlrayD8J507
+cvuUNtgf9h7U3N4cPFZLU77wiM4b0P0Q1wxWcfkTssg/kFY9WHwXPUj+DGA4q+Oc
+7PvxNOyaX61816n6mTIH9+IloRYCYA8Qfoa8furvkMc7xPK5MYI3phaxAoGBANCS
+Z8X5VU/LXK+bgjVnJYqrG5cqKU8VpBSvwEXpv5BGmKU/39aRBsWUHgffyNMVffia
+UNIvXXIZQhhKDKMAwJFCi7ilpz2+8kErndtXXinyLkrLg4BC6vANMTkOWQJMj4T1
+6fqPKEk2iF6iXhZWje9Ako+qBPHbB9sBbznV3kAfAoGAEDQlLXCLzx5S5nvtXW61
+fc5Nzv9FISpq5LJRNN7HamAwHNjuwO2iY0ZfUj3niBT3uY4yEdawbhaauS3qjPI0
+HsAs2bjNKVUjdHRGkbnT1A57Moh4e+EKvOzci5o+9y97XREFO1zCqmtCEbBTCEia
+RaaPXxAHgd+veHqOXZliKcECgYBThl3ibVAZzWHHvWnugukI2C8LYUn7rrnvwtYn
+6UzatTrJ6oN0RM3Gb+N62cZtqcyxsvKsyWUNnUnXukfHOzTitxiHEGeiFYakTJhB
+z4IZIDAjqc52ndXB3jaZF8LTZd+Pqn9R5OSINTt1UmaFYZIjfuNyfu7OAB3sOW3W
+ZmxDlwKBgQCbhkHL+tHi3oj1AASc5CSTMsY+DqqfS7VLWBhr6d6u/QrEMqKZWy2E
+NeeKkK/ImzTU0HJOIsAg+H57fU6S9zBlhxGYHlAu09rYJNZ9Eo5VGYSatNaJVzvy
+9/khjpL0Y5rnK0mWC2sNqGzJHVgGDWERYGs2W3hOYfRalTldY6yxkA==
+-----END RSA PRIVATE KEY-----

+ 24 - 0
.ci/docker-compose-file/mongo/certs/server.crt

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEATCCAemgAwIBAgIJAKyzto6kgv4DMA0GCSqGSIb3DQEBCwUAMDQxEjAQBgNV
+BAoMCUVNUVggVGVzdDEeMBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X
+DTIxMTIyNzA4MjM0OFoXDTQ5MDUxNDA4MjM0OFowKDESMBAGA1UECgwJRU1RWCBU
+ZXN0MRIwEAYDVQQDDAltb25nby10bHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDYkaO97KPcCgpQljzKWN4SJD9fFQ0aN16HN4aBdFPqZKp3h8L8n3Rd
+oo6kLQxpcTT33FY7fTPAEZ04hQgogM6XUEAGAyl+C5ENPUO//0bDw5TA7jAu7AvJ
+3kcEkG9ipYTJde71ogeiNm5U6RR6kS3mRcRXX3EAp7Aut+hgTrwTTMVGcoz1qJQm
+B4hK84mGWHqgVHwsow+XROJkm/aYKHBEq2Xau6MpJFQ2rBZBG8vgp8qsfaK6hNcR
+kTmEn7gBC/ix5RWkPNKoE5zi1btNrAPQilo/uPdpTTQInkGKij7fYWPT90aEuQfp
+76eJGHy74B+nN3qcKPw9UfUTSeo95Na/AgMBAAGjIjAgMAsGA1UdDwQEAwIFoDAR
+BglghkgBhvhCAQEEBAMCBkAwDQYJKoZIhvcNAQELBQADggIBAIYWKJtgtfe3RDG5
+Bqny3nRWsKXIxJj5FO3n/9B85v64J4Vwr7GVRc05dQVvlVg68ElqjHhI4rqyvaPm
+ZZMwccRRuv9kk5BJTz5jbGYbRFIB5NNrrk5IjABZPZi0poEY1xYGuKakOLnTCA+C
+N92YM09uCiudfbgHiIkaMsJ8BO3fbN8AgTAfj2Xpd9ozMjSv8gLVWougfw5vgr0f
+0WzTObhCHsRwVRnWqko/TME/5weUEbQPUJI1R7D2PwDTi728mpwX1ru9nirYfGOY
+7HdyrP1R5dyD+zBiFs8A9jbIJAtoC5TjIxREOGUh9YRs605BivdrQ/cZg0qJVMCX
+1pJm5i5/ilN48PnMP3QD/K6dZj1wxP3GueRh4pDMfbmhsVicCTonu85nZJ6oAoQ5
+RT5ZzmViyuN3jFCZHX564gc676HdsKtkC8dufKtNI+tUoJTEv7AnJgCc+554CTMC
+zBwtln44TqHrCR1hGEG1iik/hEAnLW5YDnzrRASxYiY0fhWfy0rpojr+WRFrdoE2
+l9uXLcpXmPuy05Am+nNg5qxFCqBSbRCMat8Mb1sof7pkObheztOTTq01peMzEYCe
+zIgowGgW8U0nN04UTo5bYYLxtVVx51QMNw0vckqDXB06Y9s/HFjTphLnGknauJiC
+CV0XmCFIb0qM/5HGS/lBm4mEvwOc
+-----END CERTIFICATE-----

+ 27 - 0
.ci/docker-compose-file/mongo/certs/server.key

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA2JGjveyj3AoKUJY8yljeEiQ/XxUNGjdehzeGgXRT6mSqd4fC
+/J90XaKOpC0MaXE099xWO30zwBGdOIUIKIDOl1BABgMpfguRDT1Dv/9Gw8OUwO4w
+LuwLyd5HBJBvYqWEyXXu9aIHojZuVOkUepEt5kXEV19xAKewLrfoYE68E0zFRnKM
+9aiUJgeISvOJhlh6oFR8LKMPl0TiZJv2mChwRKtl2rujKSRUNqwWQRvL4KfKrH2i
+uoTXEZE5hJ+4AQv4seUVpDzSqBOc4tW7TawD0IpaP7j3aU00CJ5Bioo+32Fj0/dG
+hLkH6e+niRh8u+Afpzd6nCj8PVH1E0nqPeTWvwIDAQABAoIBAFJQAIk2QQ1n74Wz
+pIVQA4+noUJ1UNaPBumjzAa1/RMQkc3+lrjHrkXMfCSgTqBg+73dTBUuQBYXW8dY
+oMIsOtk+Eid22jVjFg2PJIn775yGYKp3nW6oHs7qIdn1P7ChsneT0HAh1n7r60Fw
+mW0Acw6bo8WFrACQu6D2G2dHZap7hy0mVD9U53BjaopomKlqyyzVgVuZOCqg4lnR
+V+pjfalNQc1ZdyuaTRpV/ru244f1u/pZSC5ehzdg10bePH3dVLjX2FCwY84lNfly
+Jnli3LoR32eLrAnyA3Vnbwy8+P5JO4H8DaLXOz1BLyK7TG9ee6IkldwLykCzADG3
+IJ/ny+kCgYEA9qXa7XTGOq0gF3npHwPHsRR5NrKG+B/GsrrYkvvenfucvSDza9H8
+Mj74NCidLvsoJJHyBRr8LiLH2i59AhP1AL4o32KRuE+SiHldDsVHOKCsnbptLh/m
+JXI90X7QYCQ+hSg68LV0Z49y/8rmM/tiZ974nI/DwsKQp2cayM+/L6UCgYEA4MfQ
+4nwdKMEdWK/fw5rQyfYTq/467SK8DnB4RjWnatMn2RMe8R/epvilrdkrR/csTLhf
+dWFjqly+eLwk1ZmeUOa6e9Q/cSSqMCoewfnqHxJnqiaRgJFVaBGK08vsdU179N4p
+QlMjjYfQ9PKd9Xo8TVprPsXdejjf0XEy4Nthn5MCgYBhZEA8Pz3+8VmYq4THwGBb
+pe/vDzOISlPVQz49W8MdsrrDW32C95mT5ZVwUxEt+fJx7kcYiP1G4mjz2CN4bJTz
+xCKzgmJz2sfLp9B9Ap0K2TcP2Qs/iU0BQEj0rhRtwiIFxkrvvVbHhbctFdssb3j9
+9udIOuRbxSQFVgsXfCDMGQKBgQCh5emCp0hNSUJ81TgC5+gH/vBOSe9hS0pN0B4g
+25Y479tck1QO8hhpBOA4JhnxXIsQux8uKTYix2f9B+4z1tBbjsO0WrxTHshhpoS+
+y+Uf+h6mQ986zfLI4RGv2Mn39xYX2Ue4WK9byf3r3y98Vk1GnaBu9w69cGdsr+6o
+W/qldwKBgQCgLHHMr5ZQonemuNz2LO/pYTljlObhopTf7rZ4ygrWsKgA0Mdep93r
+VKeczhxTZi78CjtDWIR7HdKpoZJUgCIwa9o+RCAAETHtfMQPT2J8H/s+os8rAmUe
+W/YvpcgCYs1g3GK4Ih4YLJrWA0MmdkXYgE2FSAxo8VriiA4fLYs+qw==
+-----END RSA PRIVATE KEY-----

+ 1 - 0
.github/workflows/run_test_cases.yaml

@@ -63,6 +63,7 @@ jobs:
           run: |
             docker-compose \
                 -f .ci/docker-compose-file/docker-compose-mongo-single-tcp.yaml \
+                -f .ci/docker-compose-file/docker-compose-mongo-single-tls.yaml \
                 -f .ci/docker-compose-file/docker-compose-mysql-tcp.yaml \
                 -f .ci/docker-compose-file/docker-compose-mysql-tls.yaml \
                 -f .ci/docker-compose-file/docker-compose-pgsql-tcp.yaml \

+ 29 - 0
apps/emqx_authn/test/data/certs/mongo-tls-ca.crt

@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE5DCCAswCCQD8UL+glAaqCDANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlF
+TVFYIFRlc3QxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMTEy
+MjcwODIzNDhaFw00OTA1MTQwODIzNDhaMDQxEjAQBgNVBAoMCUVNUVggVGVzdDEe
+MBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA5uzGSZYswJSGceegV78c29D0nGwD3xCE/DaHk5JYQ60R
+SY1V+3ICoIrN80u3hj4IbDOjHEmzeoUeeorlhnTH7T42lY+GwnFp2hRqAsMuZfZD
+dlLGjlIswf2THZ92aQwSRsHe9j2BTfGyMa9lP6D0D9Bq4Qadk0KM+irG6rETwPvA
+CUxKDhPdIyp0hAmuYsZOENFZeuyVexqiOxh8exVRQIFCKfh7DTV4ziXpoNy1xqH/
+Gjg57DsX+J1hPraOvfZga/fpGwjMqzYCHMMtnnqrrV2IWBShdYET5swm9g2FmQES
+oJ3ScFptcA27AhQSikK1kMrCvOVqWvzJDsr/x2Auv+aGxSOi+NGEf4qrGHQan99g
+C82hbeGRBffuPKFxPqPuIFzVekRhcAjoNhwzxbYZnGmV+cTSvVk8RF0pB+uj8L2Y
+OtBWuAxDl6p4/RPU8KIGO5jkka4eVsucnoqcXS2WnWbPewfAMOPDOhR8asFWCxE5
+snknoRlo8cRv9JN/8qsQLW8ibeZTTsw6fe2Kv0hyhpErQqw6QEbKn0bp+ZcGOw7O
+tkjye9l1OwL3GIwNGrF1B2mLw6TUrAxHWZQgrjfFHQk+nsZtQDUi19rPvwK1Vk+Z
+g6TSYJPbWZBcRzsZxuezn5sJ4XO56zwCXaP2gohsOVZPd6U+n5vtKhs6eLHJLU0C
+AwEAATANBgkqhkiG9w0BAQsFAAOCAgEAw2PK8Nr3lQyF9pipvahEkHSIz8TVeLue
+lT8h6Hrkn1UcDHpECja/tPKLxYEVUoyMKeKR3K6AO5RmCgDObcZRkMdMmNYocvb5
+1BvGhlv3uk5rNUz+PW8F6cwVp+3RevBD5OSEkBzq6fuSyC0g8dk17IPKnfwNJCue
+gkgsyEUgSHK8t3g/uE0Jdx//svTdnc7dmB43uU3o3tl+qhMwm7Zjr58gP1t7fMTD
+Zu8Yq8en39lMDt1lv4LZG5JyEL5GQMr9B9ft5ZJpg6LGxRUmC7J8d+5Swux6MjcZ
+pAG2/V0VJwrR+joT8BZqnj/pR2Mk+34Ul1DIF7iSS/P+Wwy4+oP3XaNmXPJPTX8Y
+acVYYO2Q9o0B6zPQk5e2ECSMqQ2NW0+RJv2YJl77WoCWScYhixqOwWNrXu8CSeQ9
+99rZrwN9lDN3I/bXLqzjUlTwL49YDSy50GkVKC14mZNSIAegJqGv3SwmITRZRaYF
+UNhdmLldCCZ686QkGGsiIWmKug0IxJxYtLQKpajHuBQKhyyRgfIq+CfdyjsxmVNE
+1h1bmi7Hy30KAx4qGHXGhKbITAUvAOHDNs5G9R8vv6J/AjOPGeuy9mayHg3CIarx
+z0p0b9dYMK9yL9dEC8KHfUSIh7ZoR6JENkdq0Uj/8AE4+NwzrNbFRMKNAGMjFi8K
+UPcPKDe8WZQ=
+-----END CERTIFICATE-----

+ 24 - 0
apps/emqx_authn/test/data/certs/mongo-tls-client.crt

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/jCCAeagAwIBAgIJAKyzto6kgv4EMA0GCSqGSIb3DQEBCwUAMDQxEjAQBgNV
+BAoMCUVNUVggVGVzdDEeMBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X
+DTIxMTIyNzA4MjM0OFoXDTQ5MDUxNDA4MjM0OFowJTESMBAGA1UECgwJRU1RWCBU
+ZXN0MQ8wDQYDVQQDDAZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQCzgIQamGaqpP+SzwmEYtNL8koAUs0XNw6ohJ4s1lopkqOY2fnbWKO6JOSv
+RPPStRiRklsPNno59cKfoN8j+Psfne6nkQbq1fbsZRzYGX3LdQVsD4QMEC4X63oJ
+neEQ7hsEFaYW0bpkppVF300E23VT7CEDkEYBWhbXCTsdbQltffSG10ZT9XVHbqTL
+cTmQzicn6TWQ8jH++VoY1q76OBd98gHcV6BocR61oXyjyArkUlGDsj3s5Xfsbfay
+fagy6Q4cEBOrqWQvSqnenAll6IhEZ2KPDiXZWDPWMyLpLNO13ECp9+m7CMAo+15y
+Zw/UUFeUyWlLtDXfV+GJzAA1Rv9vAgMBAAGjIjAgMAsGA1UdDwQEAwIFoDARBglg
+hkgBhvhCAQEEBAMCB4AwDQYJKoZIhvcNAQELBQADggIBALYlv9OxmYtj0BOdQrM5
+oIhivrA/bl8/Kzn4Bioqth8iWtpgZcZK15NKCGiDEKCkm+cKXWkC9tQcQzHpVas2
+aAKeiXIkYiSj1NiNDMrv5XLKOeFrMDVLWUAJzfSEr3Jsci+Wf8dX/VoYhgkH247w
+j8cI8x7Vhi6Iun4pbp+ltuVtfcVAfUPhdrIXiif+hCLDbxdgj6qQ4MHC/Zpx1i+7
+4NVX8BVHsigFzN09GfHs3n+Uiq2Lzd3FaHnXWx+rueycQyXI5655YUbPJdWPO8Pu
+JX+++GlpY91ni/UTMPdgmcqzMQo8kxV9+16sU4PjLcSKsgpJ0pT2ZJ+OJgtiMrEO
+IS41ht4yhpx3G3FXim5MzUTsGHV7rr8ZzZ6wN46QXjzWtsLX98nzI1Dlz2USlbbz
+N0NjgdPROUZsRDwEinnb1D96Rfn79qnfJhGmCXd5QSvM4HGW5SqqzzyvE0nLRnDg
+davqHzA0en3Rt1/INCjr/+3GM4qy5lCG1fz1iuv5lfTVahljkkxnzSXyPW2E+0nZ
+05bq/fAEbkQaOBwPWGTNCc4InzaUU0XKtx4IcnprgF6846lNRE7aFHjAWqOjOnZj
+secfrzXDRLNJ58+eZpdJvVsaRl22bRHKI0MDNk5VzDKp/rqw/8+2f+Y2LXNKOJEQ
+KLXCWq2sh5ReRiyDSaK+IP1z
+-----END CERTIFICATE-----

+ 27 - 0
apps/emqx_authn/test/data/certs/mongo-tls-client.key

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAs4CEGphmqqT/ks8JhGLTS/JKAFLNFzcOqISeLNZaKZKjmNn5
+21ijuiTkr0Tz0rUYkZJbDzZ6OfXCn6DfI/j7H53up5EG6tX27GUc2Bl9y3UFbA+E
+DBAuF+t6CZ3hEO4bBBWmFtG6ZKaVRd9NBNt1U+whA5BGAVoW1wk7HW0JbX30htdG
+U/V1R26ky3E5kM4nJ+k1kPIx/vlaGNau+jgXffIB3FegaHEetaF8o8gK5FJRg7I9
+7OV37G32sn2oMukOHBATq6lkL0qp3pwJZeiIRGdijw4l2Vgz1jMi6SzTtdxAqffp
+uwjAKPtecmcP1FBXlMlpS7Q131fhicwANUb/bwIDAQABAoIBAQCL0JOVP5XgXwqu
+6FLKakuYwU1AuT4EUh85xaqK1B+AeDazbT1/y6gj6m6x0mx0eBh98ti4nb9QfAuv
+WJfWJi48b0CgBoezzRs7AHsaG6jvG+QwSlmZJ9UvTnxNF0tia4RhhxdKeOvNUC+/
+L/KG0QWva6I/a1YL4Yce0ZLZFcAdJouJpjv0Bqe0xgcK7rld2AqGY54YvUqeoSjA
+Uv2mhCy4xoRtF2XXyjJ1R/JOlsN8mHZvae4teWipSUf91zzd7thLT7s5CPcd2gj+
+2CQps0HkwbvpEB9Y3sGW5pVwacY9fOZkZPiaCqQ0cWDCj0qh9xi1m0/yL2sUrbet
+S08YBThhAoGBANxR3armXC9G2jomBSvEq3kVpjQbaZwgFTKgf9nCMVlrayD8J507
+cvuUNtgf9h7U3N4cPFZLU77wiM4b0P0Q1wxWcfkTssg/kFY9WHwXPUj+DGA4q+Oc
+7PvxNOyaX61816n6mTIH9+IloRYCYA8Qfoa8furvkMc7xPK5MYI3phaxAoGBANCS
+Z8X5VU/LXK+bgjVnJYqrG5cqKU8VpBSvwEXpv5BGmKU/39aRBsWUHgffyNMVffia
+UNIvXXIZQhhKDKMAwJFCi7ilpz2+8kErndtXXinyLkrLg4BC6vANMTkOWQJMj4T1
+6fqPKEk2iF6iXhZWje9Ako+qBPHbB9sBbznV3kAfAoGAEDQlLXCLzx5S5nvtXW61
+fc5Nzv9FISpq5LJRNN7HamAwHNjuwO2iY0ZfUj3niBT3uY4yEdawbhaauS3qjPI0
+HsAs2bjNKVUjdHRGkbnT1A57Moh4e+EKvOzci5o+9y97XREFO1zCqmtCEbBTCEia
+RaaPXxAHgd+veHqOXZliKcECgYBThl3ibVAZzWHHvWnugukI2C8LYUn7rrnvwtYn
+6UzatTrJ6oN0RM3Gb+N62cZtqcyxsvKsyWUNnUnXukfHOzTitxiHEGeiFYakTJhB
+z4IZIDAjqc52ndXB3jaZF8LTZd+Pqn9R5OSINTt1UmaFYZIjfuNyfu7OAB3sOW3W
+ZmxDlwKBgQCbhkHL+tHi3oj1AASc5CSTMsY+DqqfS7VLWBhr6d6u/QrEMqKZWy2E
+NeeKkK/ImzTU0HJOIsAg+H57fU6S9zBlhxGYHlAu09rYJNZ9Eo5VGYSatNaJVzvy
+9/khjpL0Y5rnK0mWC2sNqGzJHVgGDWERYGs2W3hOYfRalTldY6yxkA==
+-----END RSA PRIVATE KEY-----

+ 191 - 0
apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl

@@ -0,0 +1,191 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%--------------------------------------------------------------------
+
+-module(emqx_authn_mongo_tls_SUITE).
+
+-compile(nowarn_export_all).
+-compile(export_all).
+
+-include("emqx_authn.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include_lib("common_test/include/ct.hrl").
+-include_lib("snabbkaffe/include/snabbkaffe.hrl").
+
+
+-define(MONGO_HOST, "mongo-tls").
+-define(MONGO_PORT, 27017).
+
+-define(PATH, [authentication]).
+
+all() ->
+    emqx_common_test_helpers:all(?MODULE).
+
+init_per_testcase(_TestCase, Config) ->
+    {ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
+    emqx_authentication:initialize_authentication(?GLOBAL, []),
+    emqx_authn_test_lib:delete_authenticators(
+      [authentication],
+      ?GLOBAL),
+    Config.
+
+init_per_suite(Config) ->
+    _ = application:load(emqx_conf),
+    case emqx_authn_test_lib:is_tcp_server_available(?MONGO_HOST, ?MONGO_PORT) of
+        true ->
+            ok = emqx_common_test_helpers:start_apps([emqx_authn]),
+            ok = start_apps([emqx_resource, emqx_connector]),
+            Config;
+        false ->
+            {skip, no_mongo}
+    end.
+
+end_per_suite(_Config) ->
+    emqx_authn_test_lib:delete_authenticators(
+      [authentication],
+      ?GLOBAL),
+    ok = stop_apps([emqx_resource, emqx_connector]),
+    ok = emqx_common_test_helpers:stop_apps([emqx_authn]).
+
+%%------------------------------------------------------------------------------
+%% Tests
+%%------------------------------------------------------------------------------
+
+%% emqx_connector_mongo connects asyncronously,
+%% so we check failure/success indirectly (through snabbkaffe).
+
+%% openssl s_client -tls1_2 -cipher ECDHE-RSA-AES256-GCM-SHA384 \
+%%   -connect mongo-tls:27017 \
+%%   -cert mongo-tls-client.crt -key mongo-tls-client.key -CAfile mongo-tls-ca.crt
+
+t_create(_Config) ->
+    ?check_trace(
+       create_mongo_auth_with_ssl_opts(
+         #{<<"server_name_indication">> => <<"mongo-tls">>,
+           <<"verify">> => <<"verify_peer">>,
+           <<"versions">> => [<<"tlsv1.2">>],
+           <<"ciphers">> => [<<"ECDHE-RSA-AES256-GCM-SHA384">>]}),
+       fun({ok, _}, Trace) ->
+            ?assertEqual(
+               [ok],
+               ?projection(
+                  status,
+                  ?of_kind(emqx_connector_mongo_health_check, Trace)))
+       end).
+
+
+t_create_invalid_server_name(_Config) ->
+    ?check_trace(
+       create_mongo_auth_with_ssl_opts(
+         #{<<"server_name_indication">> => <<"mongo-tls-unknown-host">>,
+           <<"verify">> => <<"verify_peer">>}),
+       fun({ok, _}, Trace) ->
+               ?assertEqual(
+                  [failed],
+                  ?projection(
+                     status,
+                     ?of_kind(emqx_connector_mongo_health_check, Trace)))
+       end).
+
+
+%% docker-compose-mongo-single-tls.yaml: 
+%% --tlsDisabledProtocols TLS1_0,TLS1_1
+
+t_create_invalid_version(_Config) ->
+    ?check_trace(
+       create_mongo_auth_with_ssl_opts(
+         #{<<"server_name_indication">> => <<"mongo-tls">>,
+           <<"verify">> => <<"verify_peer">>,
+           <<"versions">> => [<<"tlsv1.1">>]}),
+       fun({ok, _}, Trace) ->
+               ?assertEqual(
+                  [failed],
+                  ?projection(
+                     status,
+                     ?of_kind(emqx_connector_mongo_health_check, Trace)))
+       end).
+
+
+%% docker-compose-mongo-single-tls.yaml: 
+%% --setParameter opensslCipherConfig='HIGH:!EXPORT:!aNULL:!DHE:!kDHE@STRENGTH'
+
+t_invalid_ciphers(_Config) ->
+    ?check_trace(
+       create_mongo_auth_with_ssl_opts(
+         #{<<"server_name_indication">> => <<"mongo-tls">>,
+           <<"verify">> => <<"verify_peer">>,
+           <<"versions">> => [<<"tlsv1.2">>],
+           <<"ciphers">> => [<<"DHE-RSA-AES256-GCM-SHA384">>]}),
+       fun({ok, _}, Trace) ->
+               ?assertEqual(
+                  [failed],
+                  ?projection(
+                     status,
+                     ?of_kind(emqx_connector_mongo_health_check, Trace)))
+       end).
+
+%%------------------------------------------------------------------------------
+%% Helpers
+%%------------------------------------------------------------------------------
+
+create_mongo_auth_with_ssl_opts(SpecificSSLOpts) ->
+    AuthConfig = raw_mongo_auth_config(SpecificSSLOpts),
+    emqx:update_config(?PATH, {create_authenticator, ?GLOBAL, AuthConfig}).
+
+raw_mongo_auth_config(SpecificSSLOpts) ->
+    SSLOpts = maps:merge(
+                client_ssl_opts(),
+                #{enable => <<"true">>}),
+    #{
+      mechanism => <<"password-based">>,
+      password_hash_algorithm => #{name => <<"plain">>,
+                                   salt_position => <<"suffix">>},
+      enable => <<"true">>,
+
+      backend => <<"mongodb">>,
+      pool_size => 2,
+      mongo_type => <<"single">>,
+      database => <<"mqtt">>,
+      collection => <<"users">>,
+      server => mongo_server(),
+
+      selector => #{<<"username">> => <<"${username}">>},
+      password_hash_field => <<"password_hash">>,
+      salt_field => <<"salt">>,
+      is_superuser_field => <<"is_superuser">>,
+      topology => #{
+                    server_selection_timeout_ms => <<"10000ms">>
+                   },
+      
+      ssl => maps:merge(SSLOpts, SpecificSSLOpts)
+     }.
+
+mongo_server() ->
+    iolist_to_binary(
+      io_lib:format(
+        "~s:~b",
+        [?MONGO_HOST, ?MONGO_PORT])).
+
+start_apps(Apps) ->
+    lists:foreach(fun application:ensure_all_started/1, Apps).
+
+stop_apps(Apps) ->
+    lists:foreach(fun application:stop/1, Apps).
+
+client_ssl_opts() ->
+    Dir = code:lib_dir(emqx_authn, test),
+    #{keyfile    => filename:join([Dir, <<"data/certs">>, "mongo-tls-client.key"]),
+      certfile   => filename:join([Dir, <<"data/certs">>, "mongo-tls-client.crt"]),
+      cacertfile => filename:join([Dir, <<"data/certs">>, "mongo-tls-ca.crt"])}.

+ 32 - 17
apps/emqx_connector/src/emqx_connector_mongo.erl

@@ -18,6 +18,7 @@
 -include("emqx_connector.hrl").
 -include_lib("typerefl/include/types.hrl").
 -include_lib("emqx/include/logger.hrl").
+-include_lib("snabbkaffe/include/snabbkaffe.hrl").
 
 -type server() :: emqx_schema:ip_port().
 -reflect_type([server/0]).
@@ -37,7 +38,7 @@
 
 -export([roots/0, fields/1]).
 
--export([mongo_query/5]).
+-export([mongo_query/5, check_worker_health/1]).
 
 %%=====================================================================
 roots() ->
@@ -158,28 +159,42 @@ on_query(InstId,
     end.
 
 -dialyzer({nowarn_function, [on_health_check/2]}).
-on_health_check(_InstId, #{poolname := PoolName} = State) ->
+on_health_check(InstId, #{poolname := PoolName} = State) ->
     case health_check(PoolName) of
-        true -> {ok, State};
-        false -> {error, health_check_failed, State}
+        true ->
+            ?tp(debug, emqx_connector_mongo_health_check, #{instance_id => InstId,
+                                                            status => ok}),
+            {ok, State};
+        false ->
+            ?tp(warning, emqx_connector_mongo_health_check, #{instance_id => InstId,
+                                                              status => failed}),
+            {error, health_check_failed, State}
     end.
 
 health_check(PoolName) ->
-    Status = [begin
-        case ecpool_worker:client(Worker) of
-            {ok, Conn} ->
-                %% we don't care if this returns something or not, we just to test the connection
-                try mongo_api:find_one(Conn, <<"foo">>, {}, #{}) of
-                    _ -> true
-                catch
-                    _Class:_Error -> false
-                end;
-            _ -> false
-        end
-    end || {_WorkerName, Worker} <- ecpool:workers(PoolName)],
-    length(Status) > 0 andalso lists:all(fun(St) -> St =:= true end, Status).
+    Workers = [Worker || {_WorkerName, Worker} <- ecpool:workers(PoolName)],
+    Status = rpc:pmap({?MODULE, check_worker_health}, [], Workers),
+    length(Status) > 0 andalso lists:all(fun(St) -> St end, Status).
 
 %% ===================================================================
+
+%% mongo_api:find_one/4 typing is invalid
+-dialyzer({nowarn_function, [check_worker_health/1]}).
+
+check_worker_health(Worker) -> 
+    case ecpool_worker:client(Worker) of
+        {ok, Conn} ->
+            %% we don't care if this returns something or not, we just to test the connection
+            try mongo_api:find_one(Conn, <<"foo">>, #{}, #{}) of
+                {error, _} -> false;
+                _ ->
+                    true
+            catch
+                _Class:_Error -> false
+            end;
+        _ -> false
+    end.
+
 connect(Opts) ->
     Type = proplists:get_value(mongo_type, Opts, single),
     Hosts = proplists:get_value(hosts, Opts, []),