
MongoDB admite varios mecanismos de autenticación, incluidos SCRAM, LDAP, Kerberos y autenticación de certificados x.509 predeterminados.
En el sistema X.509, que será el punto principal de esta publicación de blog, una organización puede identificar sus entidades con un par de certificados y claves privadas firmadas y confiables por una determinada Autoridad de Certificación (CA).
Este modelo es bien conocido en la industria y es lo suficientemente popular como para delegar la autenticación a servicios de terceros. La otra forma similar de delegar la autenticación es LDAP, que también forma parte del mismo grupo X.500 estándar denominado servicios de directorio.
Si bien la autenticación funciona bien para MongoDB, y en general para todos los sistemas de bases de datos, el problema con la autorización persiste. Un clúster de MongoDB siempre necesita obtener información sobre los recursos a los que tiene acceso un usuario. Los roles ayudan mucho aquí, pero en un modelo de confianza cero, la práctica requiere información duplicada: los datos de autenticación se almacenan en LDAP, X.509 o cualquier otro sistema, y los modelos de autorización residen en MongoDB.
Y aquí, entra en juego una característica genial de X.509 y… una característica no documentada de MongoDB.
Un certificado X.509 es de facto un objeto serializado. Utiliza la Notación de sintaxis abstracta uno (ASN.1), que es un lenguaje de descripción de interfaz estándar para definir estructuras de datos que se pueden serializar y deserializar de manera multiplataforma. Es ampliamente utilizado en criptografía.
Un certificado de muestra deserializado se ve así:
# openssl asn1parse -in client.crt 0: d = 0 hl = 4 l = 957 contras: SECUENCIA 4: d = 1 hl = 4 l = 677 contras: SECUENCIA 8: d = 2 hl = 2 l = 3 contras: cont [ 0 ]
10: d = 3 hl = 2 l = 1 prim: ENTERO: 02 13: d = 2 hl = 2 l = 20 prim: ENTERO: 22BC2E27B24B5A47123C6CB2FA0904B4F3663322 35: d = 2 hl = 2 l = 2 l = 1337: SECUENCIA 3: SECUENCIA 3 = 2 l = 9 prim: OBJETO: sha256WithRSAEncryption 48: d = 3 hl = 2 l = 0 prim: NULL 50: d = 2 hl = 2 l = 82 contras: SECUENCIA 52: d = 3 hl = 2 l = 11 contras : SET 54: d = 4 hl = 2 l = 9 contras: SECUENCIA 56: d = 5 hl = 2 l = 3 prim: OBJECT: countryName 61: d = 5 hl = 2 l = 2 prim: PRINTABLESTRING: AU…
# openssl asn1parse -in cliente.crt 0:D=0 hola=4 yo= 957 contras: SECUENCIA 4:D=1 hola=4 yo= 677 contras: SECUENCIA 8:D=2 hola=2 yo= 3 contras: continuación [ 0 ] 10:D=3 hola=2 yo= 1 remilgado: ENTERO :02 13:D=2 hola=2 yo= 20 remilgado: ENTERO :22BC2E27B24B5A47123C6CB2FA0904B4F3663322 35:D=2 hola=2 yo= 13 contras: SECUENCIA 37:D=3 hola=2 yo= 9 remilgado: OBJETO :sha256 con cifrado RSAE 48:D=3 hola=2 yo= 0 remilgado: NULO 50:D=2 hola=2 yo= 82 contras: SECUENCIA 52:D=3 hola=2 yo= 11 contras: COLOCAR 54:D=4 hola=2 yo= 9 contras: SECUENCIA 56:D=5 hola=2 yo= 3 remilgado: OBJETO :nombre del país 61:D=5 hola=2 yo= 2 remilgado: CUERDAS IMPRIMIBLES :AL ⁇ |
La principal ventaja de lo anterior es que casi cualquier información se puede almacenar en un certificado. Dado que la Autoridad de Certificación debe firmar, un usuario que presente el certificado no podrá modificarlo. Lo que lo hace seguro. También le permite almacenar información de autorización en él.
¿Cómo utilizar?
1) Comenzamos con la preparación de la Autoridad de Certificación
# openssl req -x509 -new -newkey rsa: 2048 -nodes -keyout myCA.key -sha256 -days 1825 -out myCA.pem …
# openssl req -x509 -new -newkey rsa: 2048 -nodes -keyout myCA.key -sha256 -days 1825 -out myCA.pem ⁇ |
2) Crear un certificado de servidor
Configuración OpenSSL:
default_bits = 2048 default_keyfile = server.key encrypt_key = no default_md = sha256 prompt = no utf8 = sí nombre_distinguido = server_req_distinguished_name req_extensions = server_extensions
[ server_req_distinguished_name ]
C = AU ST = Algún estado O = Percona OU = NA CN = servidor
[ server_extensions ]
basicConstraints = CA: FALSE subjectKeyIdentifier = hash keyUsage = keyEncipherment, digitalSignature extendedKeyUsage = serverAuth, clientAuth # openssl req -config server.cnf -new -newkey rsa: 2048 -out server.csr # openssl x509 -cre. myCA.pem -CAkey myCA.key -CAcreateserial -out server.crt -days 825 -sha256 -extensions server_extensions -extfile server.cnf # cat server.crt server.key> server.pem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 27 |
[ req ] bits_predeterminados = 2048 archivo_clave_predeterminado = servidor.llave cifrar_clave = No default_md = sha256 inmediato = No utf8 = sí nombre distinguido = servidor_req_nombre_distinguido req_extensiones = extensiones_servidor [ server_req_distinguished_name ] C = AL S T = Ciertamente–Expresar O = percona UNED = N / A CN = servidor [ server_extensions ] limitaciones básicas=California:FALSO identificador de clave de sujeto = picadillo uso de clave = Cifrado clave, firma digital uso extendido de clave = autenticación del servidor, clienteAuth # openssl req -config server.cnf -new -newkey rsa: 2048 -out server.csr # openssl x509 -req -in server.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out server.crt -days 825 -sha256 -extensions server_extensions -extfile server.cnf # cat servidor.crt servidor.clave> servidor.pem |
3) Creamos un Certificado de Cliente
default_bits = 2048 default_keyfile = client.key encrypt_key = no default_md = sha256 prompt = no utf8 = sí nombre_distinguido = client_req_distinguished_name req_extensions = client_extensions x509_extensions = client_extensions
[ client_req_distinguished_name ]
C = AU ST = Algún estado L = XO = Percona OU = Clientes CN = cliente
[ client_extensions ]
basicConstraints = CA: FALSE subjectKeyIdentifier = hash keyUsage = digitalSignature extendedKeyUsage = clientAuth 1.3.6.1.4.1.34601.2.1.1 = ASN1: SET: subvenciones
[ grants ]
concesión.1 = SECUENCIA: MongoDBRole concesión.2 = SECUENCIA: MongoDBRole2
[ MongoDBRole ]
rol = UTF8: base de datos de respaldo = UTF8: administrador
[ MongoDBRole2 ]
rol = UTF8: readAnyDatabase base de datos = UTF8: administrador
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
[ req ] bits_predeterminados = 2048 archivo_clave_predeterminado = cliente.llave cifrar_clave = No default_md = sha256 inmediato = No utf8 = sí nombre distinguido = client_req_distinguished_name req_extensiones = extensiones_cliente x509_extensiones = extensiones_cliente [ client_req_distinguished_name ] C = AL S T = Ciertamente–Expresar L = X O = percona UNED = Clientes CN = cliente [ client_extensions ] limitaciones básicas=California:FALSO identificador de clave de sujeto = picadillo uso de clave = firma digital uso extendido de clave = clienteAuth 1.3.6.1.4.1.34601.2.1.1= ASN1:COLOCAR:concesiones [ grants ] conceder.1 = SECUENCIA:MongoDBRol conceder.2 = SECUENCIA:MongoDBRole2 [ MongoDBRole ] papel = UTF8:respaldo base de datos = UTF8:administrador [ MongoDBRole2 ] papel = UTF8:leer cualquier base de datos base de datos = UTF8:administrador |
La configuración anterior utilizará MongoDBAuthorizationGrant OID 1.3.6.1.4.1.34601.2.1.1 y otorgará al titular del certificado dos funciones: copia de seguridad para el administrador de la base de datos y readAnyDatabase para el administrador de la base de datos.
Es importante recordar que el asunto del Certificado de Cliente x.509, que contiene el Nombre Distinguido (DN), debe ser diferente al de un Certificado de Miembro x.509. Además, al menos uno de los atributos Organización (O), Unidad organizativa (OU) o Componente de dominio (DC) del certificado de cliente debe diferir de los del certificado de cliente. net.tls.clusterFile
y net.tls.certificateKeyFile
certificados de servidor.
Además, un certificado de cliente debe contener los siguientes campos:
keyUsage = digitalSignature
extendedKeyUsage = clientAuth
Si no se cumplen los requisitos anteriores, MongoDB denegará cualquier autenticación del cliente x509 con un error:
AuthenticationFailed: el certificado proporcionado solo se puede usar para la autenticación del clúster, no para la autenticación del cliente. La configuración actual no permite la autenticación de clúster x.509, verifique el indicador –clusterAuthMode
Error de autenticación: tu amueblado certificado Puerto solo ser – estar usado en orden grupo autenticación, No cliente autenticación. tu Actual configuración tú haces No permite X.509 grupo autenticación, verificado Lu –clusterAuthMode bandera |
Continuaremos generando la aplicación y firmando el certificado:
# openssl req -config client.cnf -new -newkey rsa: 2048 -out client.csr # openssl x509 -req -in client.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out client.crt -days 825 -sha256 -extensiones client_extensions -extfile client.cnf # cat client.crt client.key> client.pem
# openssl req -config client.cnf -new -newkey rsa: 2048 -out client.csr # openssl x509 -req -in client.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out client.crt -days 825 -sha256 -extensions client_extensions -extfile client.cnf # cat cliente.crt cliente.clave> cliente.pem |
4) Probemos
En esta etapa MongoDB debe permitir la autenticación y autorización con certificados generados previamente:
$ mongo –tls –tlsCertificateKeyFile client.pem –tlsCAFile ./myCA.pem –authenticationDatabase ‘$ external’ –authenticationMechanism Server MONGODB-X509 /> db.runCommand ({connectionStatus: 1, showPrivileges}); {«authInfo»: {«Usuarios autenticados»: [
{
«user» : «CN=client,OU=Clients,O=Percona,L=X,ST=Some-State,C=AU»,
«db» : «$external»
}
], «Roles de usuario autenticados»: [
{
«role» : «backup»,
«db» : «admin»
},
{
«role» : «readAnyDatabase»,
«db» : «admin»
}
]
}, «bien»: 1}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 |
PS mungu –tls –tlsCertificateKeyFile cliente.pem –archivo tlsCA ./mi ca.pem –autenticaciónBase de datos ‘$ externo’ –mecanismo de autenticación MONGODB–X509 servidor/ > base de datos.ejecutar comando({ Estado de conexión: 1, mostrar privilegios: falso }); { «información de autenticación» : { «usuarios autenticados» : [ { «user» : «CN=client,OU=Clients,O=Percona,L=X,ST=Some-State,C=AU», «db» : «$external» } ], «Roles de usuario autenticados» : [ { «role» : «backup», «db» : «admin» }, { «role» : «readAnyDatabase», «db» : «admin» } ] }, «OK» : 1 } |
¡Funciona sin agregar un solo usuario!
Conclusiones
- MongoDB permite la incorporación de concesiones en un archivo de certificado x.509.
- Es especialmente útil en entornos de nube porque saca la capa de autorización de MongoDB.
- Los certificados se pueden reutilizar para diferentes clústeres.
- Forzar el uso de PKI, que es mucho más seguro que una simple contraseña.
Percona Distribution for MongoDB es una alternativa de base de datos MongoDB disponible gratuitamente, que le brinda una solución única que combina los mejores y más importantes componentes comerciales de la comunidad de código abierto, diseñada y probada para trabajar en conjunto.
¡Descarga Percona Distribution para MongoDB hoy!