diff --git a/.ci/docker-compose-file/Makefile.local b/.ci/docker-compose-file/Makefile.local index a8c309382..8b8c6af68 100644 --- a/.ci/docker-compose-file/Makefile.local +++ b/.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 \ diff --git a/.ci/docker-compose-file/docker-compose-mongo-single-tls.yaml b/.ci/docker-compose-file/docker-compose-mongo-single-tls.yaml index c4f162783..505d5f39b 100644 --- a/.ci/docker-compose-file/docker-compose-mongo-single-tls.yaml +++ b/.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' diff --git a/.ci/docker-compose-file/mongo/certs/ca.crt b/.ci/docker-compose-file/mongo/certs/ca.crt new file mode 100644 index 000000000..d4cd04759 --- /dev/null +++ b/.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----- diff --git a/.ci/docker-compose-file/mongo/certs/ca.key b/.ci/docker-compose-file/mongo/certs/ca.key new file mode 100644 index 000000000..5b9601853 --- /dev/null +++ b/.ci/docker-compose-file/mongo/certs/ca.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/.ci/docker-compose-file/mongo/certs/client.crt b/.ci/docker-compose-file/mongo/certs/client.crt new file mode 100644 index 000000000..78a6adbf4 --- /dev/null +++ b/.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----- diff --git a/.ci/docker-compose-file/mongo/certs/client.key b/.ci/docker-compose-file/mongo/certs/client.key new file mode 100644 index 000000000..4cf93eb49 --- /dev/null +++ b/.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----- diff --git a/.ci/docker-compose-file/mongo/certs/server.crt b/.ci/docker-compose-file/mongo/certs/server.crt new file mode 100644 index 000000000..874d84215 --- /dev/null +++ b/.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----- diff --git a/.ci/docker-compose-file/mongo/certs/server.key b/.ci/docker-compose-file/mongo/certs/server.key new file mode 100644 index 000000000..1dc07f326 --- /dev/null +++ b/.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----- diff --git a/.github/workflows/run_test_cases.yaml b/.github/workflows/run_test_cases.yaml index 2ff482a67..a88d6888b 100644 --- a/.github/workflows/run_test_cases.yaml +++ b/.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 \ diff --git a/apps/emqx_authn/test/data/certs/mongo-tls-ca.crt b/apps/emqx_authn/test/data/certs/mongo-tls-ca.crt new file mode 100644 index 000000000..d4cd04759 --- /dev/null +++ b/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----- diff --git a/apps/emqx_authn/test/data/certs/mongo-tls-client.crt b/apps/emqx_authn/test/data/certs/mongo-tls-client.crt new file mode 100644 index 000000000..78a6adbf4 --- /dev/null +++ b/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----- diff --git a/apps/emqx_authn/test/data/certs/mongo-tls-client.key b/apps/emqx_authn/test/data/certs/mongo-tls-client.key new file mode 100644 index 000000000..4cf93eb49 --- /dev/null +++ b/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----- diff --git a/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl new file mode 100644 index 000000000..7cff3eff3 --- /dev/null +++ b/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"])}. diff --git a/apps/emqx_connector/src/emqx_connector_mongo.erl b/apps/emqx_connector/src/emqx_connector_mongo.erl index 6a1b15e57..5f8cc38c6 100644 --- a/apps/emqx_connector/src/emqx_connector_mongo.erl +++ b/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, []),