Como proteger o MongoDB no Ubuntu 20.04

Uma versão anterior deste tutorial foi escrita por Melissa Anderson.

Introdução

O MongoDB, também conhecido como Mongo, é um banco de dados de documentos de código aberto usado em muitas aplicações Web modernas. Ele é classificado como um banco de dados NoSQL porque ele não depende de uma estrutura de banco de dados relacional tradicional baseada em tabela. Ao invés disso, ele usa documentos semelhantes ao JSON com esquemas dinâmicos.

O MongoDB não possui a autenticação habilitada por padrão, o que significa que qualquer usuário com acesso ao servidor onde o banco de dados está instalado pode adicionar e excluir dados sem restrição. Para protegê-lo dessa vulnerabilidade, este tutorial irá guiá-lo na criação de um usuário administrativo e na ativação da autenticação. Em seguida, você fará um teste para confirmar se apenas esse usuário administrativo tem acesso ao banco de dados

Pré-requisitos

Para concluir este tutorial, você precisará do seguinte:

  • Um servidor executando o Ubuntu 20.04. Cada servidor deverá ter um non-root user administrativo e um firewall configurado com o UFW. Configure isso seguindo o nosso guia de configuração inicial de servidor para o Ubuntu 20.04.
  • O MongoDB instalado em seu servidor. Este tutorial foi validado usando a versão 4.4 do MongoDB. Apesar disso, ele também deve funcionar para versões mais antigas do MongoDB. Para instalar o Mongo em seu servidor, siga nosso tutorial sobre Como instalar o MongoDB no Ubuntu 20.04.

Passo 1 — Adicionando um usuário administrativo

Desde o lançamento da versão 3.0, o daemon do MongoDB vem configurado para aceitar apenas conexões partindo do soquete local do Unix, e ele não fica automaticamente aberto à Internet como um todo. No entanto, a autenticação ainda vem desativada por padrão. Isso significa que todos os usuários que têm acesso ao servidor onde o MongoDB está instalado também têm acesso completo aos bancos de dados.

Como um primeiro passo para proteger essa vulnerabilidade, você irá criar um usuário administrativo. Mais tarde, você irá habilitar a autenticação e se conectar com esse usuário administrativo para acessar o banco de dados

Para adicionar um usuário administrativo, é necessário conectar-se primeiro ao shell do Mongo. Como a autenticação está desativada, faça isso com o comando mongo, sem nenhuma outra opção:

  • mongo

Haverá algum resultado acima do prompt do shell do Mongo. Como a autenticação ainda não foi ativada, ele irá incluir um aviso informando que o controle de acesso não está habilitado para o banco de dados e que o acesso à leitura e escrita dos dados e a configuração do banco de dados não têm restrição:

OutputMongoDB 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.   . . .  > 

Esses avisos irão desaparecer depois que você habilitar a autenticação, mas, por enquanto, eles informam que qualquer um que consiga acessar seu servidor Ubuntu também pode assumir o controle do seu banco de dados.

Para ilustrar, execute o comando show dbs do Mongo:

  • show dbs

Esse comando retorna uma lista de todos os banco de dados presentes no servidor. No entanto, quando a autenticação está habilitada, a lista muda com base na função do usuário do Mongo, ou qual nível de acesso ele tem a determinados bancos de dados. No entanto, como a autenticação está desativada, ele irá retornar todos os banco de dados atualmente presentes no sistema sem restrições:

Outputadmin   0.000GB config  0.000GB local   0.000GB 

Neste exemplo de resultado, apenas os bancos de dados padrão aparecem. Contudo, se houver algum banco de dados que contenha dados confidenciais em seu sistema, qualquer usuário pode encontrá-lo com este comando.

Como forma de mitigar essa vulnerabilidade, esse passo tem o intuito de adicionar um usuário administrativo. Para fazer isso, é necessário primeiro conectar-se ao banco de dados admin. Lá é onde as informações sobre os usuários, como seus nomes, senhas e funções, são armazenados:

  • use admin
Outputswitched to db admin 

O MongoDB vem instalado com alguns métodos de shell baseados em JavaScript que você pode usar para gerenciar seu banco de dados. Um deles, o método db.createUser, é usado para criar novos usuários no banco de dados no qual o método é executado.

Inicie o método db.createUser :

  • db.createUser(

Esse método requer que seja especificado um nome de usuário e uma senha para o usuário, bem como todas as funções que você queira que o usuário tenha. Lembre-se que o MongoDB armazena seus dados em documentos semelhantes ao JSON. Sendo assim, ao criar um novo usuário, tudo o que você está fazendo é criar um documento para manter os dados de usuário apropriados como campos individuais.

Assim como com objetos em JSON, os documentos no MongoDB começam e terminam com chaves ({ e }). Para começar a adicionar um usuário, insira uma chave de abertura:

Nota: o Mongo não irá registrar o método db.createUser como completo até que você digite um parêntese de fechamento. Até que isso seja feito, o prompt irá mudar de um sinal maior que (>) para três pontos (...).

  • {

Em seguida, insira um campo user: com o seu nome de usuário desejado como um valor entre aspas seguido de uma vírgula. O exemplo a seguir especifica o nome de usuário como AdminSammy, mas você pode digitar qualquer nome de usuário que quiser:

  • user: "AdminSammy",

Em seguida, insira um campo pwd com o método passwordPrompt() como valor. Ao executar o método db.createUser, o método passwordPrompt() fornecerá um prompt para que você digite sua senha. Isso é mais seguro do que o método alternativo, que é digitar sua senha em texto não criptografado como você fez para seu nome de usuário.

Nota: o método passwordPrompt() é compatível apenas com as versões 4.2 ou mais recentes do MongoDB. Se estiver usando uma versão mais antiga do Mongo, então será necessário escrever sua senha em texto não criptografado, da mesma forma como você escreveu seu nome de usuário:

  • pwd: "password",

Certifique-se de também adicionar uma vírgula após este campo:

  • pwd: passwordPrompt(),

Em seguida, digite as funções que você deseja que seu usuário administrativo tenha. Como está criando um usuário administrativo, você deve no mínimo dar a ele a função userAdminAnyDatabase no banco de dados admin. Isso permitirá que o usuário administrativo crie e modifique novos usuários e funções. Como o usuário administrativo possui essa função no banco de dados admin, isso também lhe concederá acesso de superusuário a todo o cluster.

Além disso, o exemplo a seguir também concede a função readWriteAnyDatabase ao usuário administrativo. Isso faz com que o usuário administrativo seja capaz de ler e modificar dados em qualquer banco de dados presentes no cluster, exceto pelos bancos de dados config e local, que existem principalmente para uso interno:

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

Depois disso, insira uma chave de fechamento para encerrar o documento:

  • }

Em seguida, digite um parêntese de fechamento para fechar e executar o método db.createUser:

  • )

Aqui está como seu método db.createUser deve se parecer, com todos os elementos presentes:

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

Se a sintaxe de todas as linhas estiver correta, o método será executado corretamente e você será solicitado a inserir uma senha:

OutputEnter password: 

Digite uma senha forte da sua escolha. Em seguida, você receberá uma confirmação de que o usuário foi adicionado:

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

Depois disso, saia do cliente MongoDB:

  • exit

Neste ponto, seu usuário será autorizado a inserir credenciais. No entanto, elas não serão necessárias até que você habilite a autenticação e reinicie o daemon do MongoDB.

Passo 2 — Habilitando a autenticação

Para habilitar a autenticação, é necessário editar o arquivo de configuração mongod.conf do MongoDB. Depois que você habilitar e reiniciar o serviço Mongo, os usuários ainda serão capazes de se conectar ao banco de dados sem autenticação. No entanto, eles não serão capazes de ler ou modificar dados até que forneçam um nome de usuário e uma senha corretos.

Abra o arquivo de configuração com seu editor de texto preferido. Aqui, usaremos o nano:

  • sudo nano /etc/mongod.conf

Role para baixo até encontrar a seção security transformada em comentário:

/etc/mongod.conf

. . . #security:  #operationProfiling:  . . . 

Descomente esta linha removendo a cerquilha (#):

/etc/mongod.conf

. . . security:  #operationProfiling:  . . . 

Em seguida, adicione o parâmetro authorization e defina ele como "enabled" (habilitado). Quando terminar, as linhas devem ficar assim:

/etc/mongod.conf

. . . security:   authorization: "enabled" . . . 

Observe que a linha security: não possui espaços no início, enquanto que a linha authorization: é iniciada com dois espaços.

Após adicionar essas linhas, salve e feche o arquivo. Se você usou o nano para abrir o arquivo, faça isso pressionando CTRL + X, Y, depois ENTER.

Em seguida, reinicie o daemon para colocar essas novas alterações em vigor:

  • sudo systemctl restart mongod

Em seguida, verifique o status do serviço para garantir que ele foi reiniciado corretamente:

  • sudo systemctl status mongod

Se o comando restart tiver sido bem sucedido, você receberá um resultado que indica que o serviço mongod está ativo e foi iniciado recentemente:

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. 

Depois de verificar que o daemon está em operação, você pode testar se a configuração de autenticação adicionada funciona como esperado.

Passo 3 — Testando as configurações de autenticação

Para começar a testar se os requisitos de autenticação adicionados no passo anterior estão funcionando corretamente, comece fazendo a conexão sem especificar nenhuma credencial para verificar se suas ações estão realmente restritas:

  • mongo

Agora que a autenticação foi habilitada, nenhum dos avisos que você encontrou anteriormente aparecerá:

OutputMongoDB 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 se seu acesso está restrito executando o comando show dbs novamente:

  • show dbs

Lembre-se que no Passo 1 foi mostrado que existem pelo menos alguns bancos de dados padrão em seu servidor. No entanto, neste caso, o comando não mostrará nenhum resultado porque você não autenticou-se como um usuário privilegiado.

Como esse comando não retorna nenhuma informação, é seguro dizer que a configuração de autenticação está funcionando como esperado. Você também não será capaz de criar usuários ou executar outras tarefas que requerem privilégios sem primeiro autenticar-se.

Vá em frente e saia do shell do MongoDB:

Nota: em vez de executar o comando exit a seguir como foi feito anteriormente no Passo 1, uma maneira alternativa de fechar o shell é apenas pressionar CTRL + C.

  • exit

Em seguida, certifique-se de que seu usuário administrativo seja capaz de autenticar-se corretamente executando o comando mongo a seguir para se conectar com este usuário. Este comando inclui o sinalizador -u, que precede o nome do usuário com o qual você deseja se conectar. Certifique-se de substituir AdminSammy pelo nome do seu próprio usuário administrativo. O comando também inclui o sinalizador -p, que irá solicitar-lhe a senha do usuário e especifica admin como o banco de dados de autenticação onde o nome de usuário especificado foi criado:

  • mongo -u AdminSammy -p --authenticationDatabase admin

Digite a senha do usuário quando solicitado, e então você será colocado dentro do shell. Uma vez lá, tente emitir o comando show dbs novamente:

  • show dbs

Desta vez, como você autenticou-se corretamente, o comando retornará com sucesso uma lista de todos os bancos de dados atualmente presentes no servidor:

Outputadmin   0.000GB config  0.000GB local   0.000GB 

Isso confirma que a autenticação foi habilitada com sucesso.

Conclusão

Ao completar este guia, você configurou um usuário administrativo do MongoDB que você pode empregar para criar e modificar novos usuários e funções, e gerenciar sua instância do MongoDB. Você também configurou sua instância do MongoDB para exigir que os usuários autentiquem-se com um nome de usuário e uma senha válidos antes que possam interagir com os dados.

Para mais informações sobre como gerenciar usuários do MongoDB, confira a documentação oficial sobre o assunto. Você também pode estar interessado em aprender mais sobre como a autenticação funciona no MongoDB.

Além disso, se você planeja interagir com sua instância do MongoDB remotamente, siga nosso guia Como configurar o acesso remoto para o MongoDB no Ubuntu 20.04.