Tutorial

Cómo proteger MongoDB en Ubuntu 20.04

MongoDBUbuntuSecurityNoSQLDatabasesUbuntu 20.04

Melissa Anderson escribió una versión anterior de este tutorial.

Introducción

MongoDB, también conocido como Mongo, es una base de datos de documentos de código abierto que se utiliza en muchas aplicaciones web modernas. Se clasifica como base de datos NoSQL porque no sigue la estructura de las bases de datos relacionales tradicionales basadas en tablas. En su lugar, utiliza documentos similares a JSON con esquemas dinámicos.

En MongoDB, la autenticación no está habilitada por defecto, por lo tanto, cualquier usuario con acceso al servidor donde se haya instalado la base de datos puede agregar y eliminar datos sin restricciones. Este tutorial le servirá como guía para crear un usuario administrativo y habilitar la autenticación para brindar protección contra estas vulnerabilidades. Luego, realizará una prueba para confirmar que solo ese usuario administrativo tenga acceso a la base de datos.

Requisitos previos

Para completar este tutorial, necesitará lo siguiente:

Paso 1: Añadir un usuario administrativo

Desde el lanzamiento de la versión 3.0, el demonio de MongoDB está configurado para aceptar únicamente conexiones del socket local de Unix y no se abre automáticamente a Internet en general. Sin embargo, la autenticación se sigue manteniendo desactivada de forma predeterminada. Esto significa que cualquier usuario que tenga acceso al servidor donde se haya instalado MongoDB también tiene pleno acceso a las bases de datos.

Como primer paso para brindar protección contra esta vulnerabilidad, creará un usuario administrativo. A continuación, habilitará la autenticación y se conectará como este usuario administrativo para acceder a la base de datos.

Para agregar un usuario administrativo, primero, debe conectarse al shell de Mongo. Como la autenticación está desactivada, puede hacerlo con el comando mongo, sin ninguna otra opción:

  • mongo

Verá un resultado arriba de la línea de comandos del shell de Mongo. Como todavía no habilitó la autenticación, incluirá una advertencia de que el control de acceso no está habilitado para la base de datos y que el acceso de lectura y escritura a los datos y a la configuración de la base de datos no está restringido:

Output
MongoDB shell version v4.4.0 . . . 2020-06-09T13:26:51.391+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2020-06-09T13:26:51.391+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. . . . >

Estas advertencias desaparecerán una vez que habilite la autenticación; por ahora, indican que cualquier persona que pueda acceder a su servidor de Ubuntu también puede tomar control de su base de datos.

Para demostrar esto, ejecute el comando show dbs de Mongo:

  • show dbs

Este comando devuelve una lista de todas las bases de datos del servidor. Sin embargo, cuando la autenticación está habilitada, la lista cambia según el rol del usuario de Mongo o el nivel de acceso que tenga a ciertas bases de datos. Pero, como la autenticación está desactivada, devolverá todas las bases de datos que se encuentren en el sistema sin restricciones:

Output
admin 0.000GB config 0.000GB local 0.000GB

En este resultado de ejemplo, solo se muestran las bases de datos predeterminadas. Sin embargo, si tiene alguna base de datos que contenga datos confidenciales en su sistema, cualquier usuario podría encontrarla con este comando.

Este paso se centra en agregar un usuario administrativo como parte de la mitigación de esta vulnerabilidad. Para hacerlo, primero, debe conectarse a la base de datos admin. Allí es donde se almacena la información sobre los usuarios, como sus nombres de usuario, contraseñas y roles:

  • use admin
Output
switched to db admin

MongoDB viene instalado con varios métodos de shell basados en JavaScript que puede usar para administrar su base de datos. Uno de ellos, el método db.createUser, se utiliza para crear usuarios nuevos en la base de datos en la que se ejecuta el método.

Inicie el método db.createUser:

  • db.createUser(

Este método requiere que especifique un nombre de usuario y una contraseña para el usuario, así como los roles que desee asignarle. Recuerde que MongoDB almacena sus datos en documentos similares a JSON. Por lo tanto, al crear un usuario nuevo, lo que hace es crear un documento para almacenar los datos correspondientes del usuario en campos individuales.

Tal como sucede con los objetos en JSON, los documentos de MongoDB comienzan y terminan con llaves ({ y }). Para comenzar a agregar un usuario, ingrese una llave de apertura:

Nota: Mongo no registrará el método db.createUser como completo hasta que ingrese un paréntesis de cierre. Hasta que lo haga, el símbolo del sistema cambiará del signo de mayor que (>) al de puntos suspensivos (...).

  • {

A continuación, ingrese un campo user:, con el nombre de usuario que desee como valor entre comillas dobles seguido por un coma. En el siguiente ejemplo, se especifica el nombre de usuario AdminSammy, pero puede ingresar el que desee:

  • user: "AdminSammy",

Luego, ingrese un campo pwd con el método passwordPrompt() como valor. Cuando ejecute el método db.createUser, el método passwordPrompt() le presentará un mensaje para que ingrese su contraseña. Esta alternativa es más segura que escribir la contraseña en texto no cifrado, como hizo con el nombre de usuario.

Nota: El método passwordPrompt() solo es compatible con MongoDB 4.2 y versiones posteriores. Si está utilizando una versión anterior de Mongo, deberá escribir la contraseña en texto no cifrado, como hizo al escribir el nombre de usuario:

  • pwd: "password",

Asegúrese de también incluir una coma al final de este campo:

  • pwd: passwordPrompt(),

A continuación, ingrese los roles que desea que tenga su usuario administrativo. Como está creando un usuario administrativo, como mínimo, debería concederle el rol userAdminAnyDatabase en la base de datos admin. Esto le permitirá crear y modificar usuarios nuevos y roles. Como el usuario administrativo tiene este rol en la base de datos admin, también tendrá acceso de superusuario a todo el clúster.

Además, en el siguiente ejemplo, también se le otorga al usuario administrativo el rol readWriteAnyDatabase. Esto le brinda la posibilidad de leer y modificar datos en cualquier base de datos del clúster, a excepción de las bases de datos config y locales, que, en su mayoría, son de uso interno:

  • roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]

A continuación, ingrese una llave de cierre para indicar el final del documento:

  • }

Luego, ingrese un paréntesis de cierre para cerrar y ejecutar el método db.createUser:

  • )

En conjunto, así es como debería verse su método db.createUser:

> db.createUser(
... {
... user: "AdminSammy",
... pwd: passwordPrompt(),
... roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
... }
... )

Si la sintaxis de cada línea es correcta, el método se ejecutará de forma adecuada y se le solicitará ingresar una contraseña:

Output
Enter password:

Ingrese una contraseña segura de su elección. A continuación, recibirá una confirmación de que el usuario se añadió:

Output
Successfully added user: { "user" : "AdminSammy", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" }, "readWriteAnyDatabase" ] }

Una vez que la reciba, puede salir del cliente MongoDB:

  • exit

En este punto, su usuario podrá ingresar credenciales. Sin embargo, no se le requerirá hacerlo hasta que habilite la autenticación y reinicie el demonio de MongoDB.

Paso 2: Habilitar la autenticación

Para habilitar la autenticación, debe editar mongod.conf, el archivo de configuración de MongoDB. Una vez que la habilite y reinicie el servicio de Mongo, los usuarios podrán seguir conectándose a la base de datos sin autenticación. Sin embargo, no podrán leer ni modificar datos sin proporcionar un nombre de usuario y una contraseña correctos.

Abra el archivo de configuración en su editor de texto preferido. En este caso, utilizaremos nano:

  • sudo nano /etc/mongod.conf

Desplácese hacia abajo hasta la sección security marcada con comentarios:

/etc/mongod.conf
. . .
#security:

#operationProfiling:

. . .

Quite la marca de comentario de esta línea eliminando el signo de numeral (#):

/etc/mongod.conf
. . .
security:

#operationProfiling:

. . .

A continuación, añada el parámetro authorization y establézcalo en "enabled". Cuando haya terminado, las líneas deberían tener el siguiente aspecto:

/etc/mongod.conf
. . .
security:
  authorization: "enabled"
. . .

Tenga en cuenta que la línea security: no tiene espacios al principio, pero la línea authorization: tiene dos espacios de sangría.

Después de agregar estas líneas, guarde y cierre el archivo. Si utilizó nano para abrir el archivo, hágalo pulsando CTRL + X, Y y, luego, ENTER.

A continuación, reinicie el demonio para que estos cambios nuevos surtan efecto:

  • sudo systemctl restart mongod

Luego, compruebe el estado del servicio para asegurarse de que se haya reiniciado correctamente:

  • sudo systemctl status mongod

Si el comando restart se ejecutó correctamente, obtendrá un resultado que indica que el servicio mongod está activo y se ha iniciado recientemente:

Output
● mongod.service - MongoDB Database Server Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-06-09 22:06:20 UTC; 7s ago Docs: https://docs.mongodb.org/manual Main PID: 15370 (mongod) Memory: 170.1M CGroup: /system.slice/mongod.service └─15370 /usr/bin/mongod --config /etc/mongod.conf Jun 09 22:06:20 your_host systemd[1]: Started MongoDB Database Server.

Después de verificar que el demonio esté en funcionamiento, puede realizar una prueba para determinar si la configuración de autenticación que añadió funciona de la manera prevista.

Paso 3: Probar la configuración de autenticación

Para comenzar a probar si los requisitos de autenticación que añadió en el paso anterior funcionan correctamente, comience por conectarse sin especificar credenciales para verificar si sus acciones efectivamente están restringidas:

  • mongo

Ahora que habilitó la autenticación, no se mostrará ninguna de las advertencias que se le presentaron anteriormente:

Output
MongoDB shell version v4.4.0 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("5d50ed96-f7e1-493a-b4da-076067b2d898") } MongoDB server version: 4.4.0 >

Confirme si su acceso está restringido al volver a ejecutar el comando show dbs:

  • show dbs

Recuerde que, como vio en el Paso 1, hay algunas bases de datos predeterminadas en su servidor. Sin embargo, en este caso, el comando no generará ningún resultado porque no se identificó como usuario con privilegios.

Dado que este comando no devuelve ningún dato, se puede decir que la configuración de autenticación está funcionando de la manera prevista. Tampoco podrá crear usuarios ni realizar otras tareas que requieren privilegios sin autenticarse.

Proceda a salir del shell de MongoDB:

Nota: En lugar de ejecutar el siguiente comando exit, como hizo en el Paso 1, alternativamente, puede cerrar el shell presionando CTRL + C.

  • exit

A continuación, asegúrese de que su usuario administrativo pueda autenticarse correctamente ejecutando el siguiente comando mongo para conectarse con las credenciales de este usuario. Este comando incluye el indicador -u, que precede el nombre de usuario con el que se desea conectar. Asegúrese de sustituir AdminSammy por el nombre de usuario de su propio usuario administrativo. También incluye el indicador -p, que le solicitará la contraseña del usuario, y especifica admin como la base de datos de autenticación en la que se creó el nombre de usuario indicado:

  • mongo -u AdminSammy -p --authenticationDatabase admin

Ingrese la contraseña del usuario cuando se le solicite hacerlo; luego, se lo dirigirá al shell . Una vez allí, intente volver a emitir el comando show dbs:

  • show dbs

Esta vez, dado que se autenticó de forma adecuada, el comando devolverá correctamente una lista de todas las bases de datos que se encuentran en el servidor:

Output
admin 0.000GB config 0.000GB local 0.000GB

Esto confirma que la autenticación se habilitó de forma correcta.

Conclusión

Al completar esta guía, creó un usuario administrativo de MongoDB que puede utilizar tanto para crear y modificar nuevos usuarios y roles como para administrar su instancia de MongoDB. También configuró su instancia de MongoDB para exigir que los usuarios se autentiquen con un nombre de usuario y una contraseña válidos para poder interactuar con cualquier dato.

Para obtener más información sobre cómo administrar usuarios en MongoDB, consulte la documentación oficial sobre el tema. También puede interesarle aprender más sobre el funcionamiento de la autenticación en MongoDB.

Además, si planea interactuar de forma remota con su instancia de MongoDB, puede consultar nuestra guía Cómo configurar el acceso remoto para MongoDB en Ubuntu 20.04.

Creative Commons License