TLS mutuo con tu propia CA

TeselaDB

TeselaDB

Equipo de TeselaDB

40 minAvanzado

Usa los certificados de tu CA en el puerto de clientes y autentica una aplicación con su certificado, sin contraseña.

TeselaDB crea su propia CA en el primer arranque y la usa entre nodos. En el puerto de clientes puedes presentar los certificados de tu CA y pedir a cada aplicación su certificado de cliente, que además sirve para autenticarla con MONGODB-X509.

Lo que vas a construir

Una CA de prueba, un certificado de servidor para node-01 y otro de cliente para la aplicación tienda-api. El nodo presenta el suyo a los clientes y la aplicación entra con su certificado, sin contraseña.

Requisitos

  • OpenSSL 3 en la máquina donde generas los certificados.
  • Un nodo de TeselaDB y acceso a sus opciones de arranque.
  • Un usuario con permiso para crear usuarios, como root.

Si tu empresa ya tiene una CA, usa sus certificados y sáltate los pasos 1 a 3.

1. Crea la CA

La clave de la CA firma todos los certificados. Guárdala fuera de los nodos:

Shell
openssl req -x509 -newkey rsa:3072 -nodes -keyout ca.key -out ca.pem -days 3650 -subj "/CN=Ejemplo CA"

2. Crea el certificado del servidor

El nombre del nodo va en subjectAltName, que es lo que comprueban los clientes, y la última orden junta el certificado y su clave en server.pem, porque el nodo lee los dos de un solo fichero PEM:

Shell
printf "subjectAltName=DNS:node-01\n" > server.ext
openssl req -newkey rsa:3072 -nodes -keyout server.key -out server.csr -subj "/CN=node-01"
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.crt -days 825 -extfile server.ext
cat server.crt server.key > server.pem

3. Crea el certificado de la aplicación

El sujeto del certificado es el nombre del usuario que crearás en $external en el paso 5. Las órdenes de abajo firman el certificado con tu CA y lo juntan con su clave en tienda-api.pem:

Shell
printf "extendedKeyUsage=clientAuth\n" > client.ext
openssl req -newkey rsa:3072 -nodes -keyout tienda-api.key -out tienda-api.csr -subj "/O=Ejemplo/OU=apps/CN=tienda-api"
openssl x509 -req -in tienda-api.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out tienda-api.crt -days 825 -extfile client.ext
cat tienda-api.crt tienda-api.key > tienda-api.pem
openssl x509 -in tienda-api.crt -noout -subject -nameopt RFC2253

La última orden escribe el sujeto en el orden que espera el nodo, CN=tienda-api,OU=apps,O=Ejemplo.

4. Arranca el nodo con tus certificados

Copia server.pem y ca.pem a /etc/teseladb en el nodo y arráncalo con las opciones de TLS de MongoDB. En el puerto de clientes, tus certificados ocupan entonces el sitio de los de la CA que TeselaDB creó en el primer arranque:

Shell
teseladb start --dbpath /var/lib/teseladb --tlsCertificateKeyFile /etc/teseladb/server.pem \
  --tlsCAFile /etc/teseladb/ca.pem --tlsAllowConnectionsWithoutCertificates

Con --tlsCAFile el nodo pide certificado a los clientes, y --tlsAllowConnectionsWithoutCertificates deja entrar también a los que no lo tienen, como root con su contraseña. Quítalo cuando todas tus aplicaciones usen certificado.

5. Crea el usuario del certificado

Conectado como root, crea el usuario en $external con el sujeto exacto del certificado:

JavaScript
db.getSiblingDB("$external").runCommand({
  createUser: "CN=tienda-api,OU=apps,O=Ejemplo",
  roles: [{ role: "readWrite", db: "tienda" }],
});

Probarlo

Conéctate con el certificado de la aplicación y pregunta con qué usuario entraste. La cadena de conexión no lleva usuario ni contraseña, porque con authMechanism=MONGODB-X509 el nodo toma el usuario del sujeto del certificado que presentas:

Shell
mongosh "mongodb://node-01:27017/?tls=true&tlsCAFile=./ca.pem&tlsCertificateKeyFile=./tienda-api.pem&authMechanism=MONGODB-X509" \
  --eval "db.runCommand({ connectionStatus: 1 }).authInfo.authenticatedUsers"

La respuesta muestra CN=tienda-api,OU=apps,O=Ejemplo en la base $external, y esa conexión puede leer y escribir en tienda.

Limpiar

Si era una prueba, borra el usuario con db.getSiblingDB("$external").dropUser("CN=tienda-api,OU=apps,O=Ejemplo") y vuelve a arrancar el nodo sin las opciones de TLS propias. Guarda ca.key fuera de las máquinas de los nodos o bórrala.

Siguientes pasos