Melhores práticas de segurança possíveis

37

Vou apresentar o Ansible no meu datacenter e estou procurando algumas práticas recomendadas de segurança sobre onde localizar a máquina de controle e como gerenciar as chaves SSH.

Pergunta 1: a máquina de controle

É claro que precisamos de uma máquina de controle. A máquina de controle tem chaves SSH públicas salvas nela. Se um invasor tiver acesso à máquina de controle, potencialmente terá acesso a todo o datacenter (ou aos servidores gerenciados pela Ansible). Portanto, é melhor ter uma máquina de controle dedicada no data center ou uma máquina de controle remoto (como meu laptop conectado remotamente ao data center)?

Se a melhor prática é usar meu laptop (que pode ser roubado, é claro, mas eu poderia ter minhas chaves públicas salvas com segurança online na nuvem ou offline em um dispositivo criptografado portátil), e se eu precisar usar algumas interfaces da Web com Ansible, como Ansible Tower, Semaphore, Rundeck ou Foreman, que precisa ser instalado em uma máquina centralizada no datacenter? Como protegê-lo e evitar que ele se torne um "único ponto de ataque"?

Pergunta 2: as chaves SSH

Suponha que eu precise usar o Ansible para fazer algumas tarefas que precisam ser executadas pelo root (como instalar pacotes de software ou algo assim). Eu acho que a melhor prática não é usar o usuário root em servidores controlados, mas adicionar um usuário normal ao Ansible com permissões de sudo. Mas, se o Ansible precisa executar quase todas as tarefas, ele precisa ter acesso a todos os comandos através do sudo. Então, qual é a melhor escolha:

  • deixe o Ansible usar o usuário root (com sua chave pública salva em ~/.ssh/authorized_keys
  • crie um usuário não privilegiado dedicado ao Ansible com acesso sudo
  • permite que o usuário Ansible execute todos os comandos através do sudo especificando uma senha (que é única precisa ser conhecida por todo administrador de sistemas que usa Ansible para controlar esses servidores)
  • permite ao usuário Ansible executar todos os comandos através do sudo sem especificar nenhuma senha
  • alguma outra dica?
Esteira
fonte
você deseja uma sub-rede de gerenciamento dedicada (ou VLAN). seu computador de controle ansible está nessa sub-rede. Se você precisar se comunicar com o computador de controle, faça uma VPN nessa sub-rede. Não deixe que ser root ansible
Neil McGuigan
11
O host de controle Ansible estará na LAN interna e não poderá ser acessado de fora, mas acho que isso não é suficiente.
Mat

Respostas:

15

O host bastião (o centro de controle ansible) pertence a uma sub-rede separada. Não deve ser diretamente acessível de fora, não deve ser diretamente acessível a partir dos servidores gerenciados!

Seu laptop é o dispositivo menos seguro de todos. Um e-mail idiota, uma vulnerabilidade idiota do flash, um convidado idiota do Wifi e ele aparece.

Para servidores, não permita acesso root via ssh. Muitas auditorias zombam disso.

Por exemplo, permita que cada administrador use sua própria conta pessoal em cada servidor de destino e deixe que eles usem senhas. Dessa forma, nenhuma senha é compartilhada entre duas pessoas. Você pode verificar quem fez o quê em cada servidor. Depende de você se as contas pessoais permitirem o login com senha, apenas chave ssh ou exigir as duas.

Para esclarecer o ansible, não é necessário usar um único nome de login de destino . Cada administrador pode e deve ter um nome de login de destino pessoal.

Uma observação: tente nunca criar uma conta chamada alguma palavra (como "ansible" ou "admin" ou "cluster" ou "management" ou "operator") se ela tiver uma senha. O único bom nome para a conta que possui uma senha é o nome de um ser humano, como "jkowalski". Somente um ser humano pode ser responsável pelas ações realizadas através da conta e responsável por proteger indevidamente sua senha, "ansible" não pode.

kubanczyk
fonte
Obrigado, você me convenceu sobre o uso de um host bastião centralizado em uma sub-rede separada no data center. Também estou ciente de que é melhor usar um usuário pessoal por cada administrador de sistema, mas agora tenho outra pergunta (talvez isso seja melhor em uma pergunta separada sobre Serverfault): como centralizar usuários e chaves SSH em hosts Linux sem usar NIS, NFS ações ou algo assim? Observe que eu já tenho o Active Directory para servidores Windows.
Mat
Ok, pensando melhor na minha pergunta, tenho duas respostas possíveis: use o armazenamento de chaves LDAP ou o Userify (veja duas respostas abaixo). Mas ... eu realmente preciso disso? Não, se eu usar meu próprio usuário para implantar novos usuários e chaves através do próprio Ansible! :-)
Mat
@ Mat, concordo completamente - como eu disse abaixo, você realmente não precisa do Userify ou de qualquer ferramenta semelhante até que sua equipe fique maior. (No entanto, é muito mais agradável.) O LDAP é meio difícil de instalar (pesquise pam_ldap e nss_ldap), mas criamos ferramentas para integrar em segundos com Ansible, Chef, Puppet, etc. Além disso, é gratuito para <20 servidores.
Jamieson Becker
16

> Pergunta 1: a máquina de controle

No Userify (divulgação completa: na verdade, oferecemos software para gerenciar chaves ssh), lidamos com isso o tempo todo, pois também executamos o maior armazém de chaves SSH. Geralmente, recomendamos a instalação local, em vez de usar a nuvem, já que você aumentou o controle, reduz a área de superfície e pode realmente bloqueá-la em redes confiáveis ​​conhecidas.

O importante é lembrar que, em um sistema adequadamente construído como esse, realmente não deve haver segredos significativos que possam ser vazados para um invasor. Se alguém dirigir uma empilhadeira ao seu datacenter e sair com o servidor, ele não receberá muito, exceto algumas senhas com hash pesado, provavelmente alguns arquivos fortemente criptografados e algumas chaves públicas sem as respectivas chaves privadas correspondentes. Em outras palavras, nem tanto.

Como você aponta, os vetores de ameaças reais aqui são o que acontece se um invasor obtém o controle dessa máquina e a usa para implantar suas próprias contas de usuário e chaves (públicas). Esse é um risco para praticamente todas as plataformas em nuvem (por exemplo, Linode). Você deve estar mais concentrado em impedir o acesso ao plano de controle, o que significa minimizar a superfície de ataque (expondo apenas algumas portas e bloquear essas portas o máximo possível) e, de preferência, usar software que seja protegido contra escalonamento de privilégios e vários ataques ( Injeção SQL, XSS, CSRF etc.) Habilite o acesso 2FA / MFA ao plano de controle e concentre-se em bloquear o plano de controle o máximo possível.

Portanto, é melhor ter uma máquina de controle dedicada no data center ou uma máquina de controle remoto (como meu laptop conectado remotamente ao data center)?

É definitivamente melhor ter uma máquina de controle dedicado em um datacenter seguro, porque você pode isolá-lo e bloqueá-lo para baixo para evitar / minimizar o risco de roubo ou acesso não autorizado.

Se a melhor prática é usar meu laptop (que pode ser roubado, é claro, mas eu poderia ter minhas chaves públicas salvas com segurança online na nuvem ou offline em um dispositivo criptografado portátil), e se eu precisar usar algumas interfaces da Web com Ansible, como Ansible Tower, Semaphore, Rundeck ou Foreman, que precisa ser instalado em uma máquina centralizada no datacenter?

Você não precisa executar QUALQUER interface da web ou plano de controle secundário para gerenciar suas chaves (até mesmo o Userify) até ficar grande o suficiente para começar a entrar em problemas de gerenciamento devido a um número maior de usuários e níveis diferentes de autorização nos servidores ou precisa de mais para os usuários que talvez não tenham conhecimento ou acesso ao Ansible para atualizar as chaves. O Userify no começo não era muito mais do que um monte de scripts de shell (hoje eles seriam Ansible, provavelmente!) E não há nada de errado nisso, até você começar a precisar de um controle de gerenciamento adicional e de maneiras fáceis para as pessoas gerenciarem / rotacionarem seus scripts. próprias chaves. (Claro, por favor, dê uma olhada no Userify se você chegar a esse ponto!)

Como protegê-lo e evitar que ele se torne um "único ponto de ataque"?

Bem, é claro, verifique todos os recursos na rede para bloquear as coisas, mas o mais importante é começar com uma base segura:

1. Arquitetura sua solução com segurança em mente desde o início. Escolha a tecnologia (ou seja, banco de dados ou idiomas) que tradicionalmente teve menos problemas e, em seguida, codifique com segurança à frente. Limpe todos os dados recebidos, mesmo de usuários confiáveis. A paranóia é uma virtude.

2. Eventualmente, tudo fica quebrado. Minimize o dano quando isso ocorrer: como você já apontou, tente minimizar o manuseio de material secreto.

3. Mantenha as coisas simples. Não faça as coisas exóticas mais recentes, a menos que tenha certeza de que aumentará sua segurança de forma mensurável e comprovável. Por exemplo, selecionamos X25519 / NaCl (libsodium) sobre AES para nossa camada de criptografia (criptografamos tudo, em repouso e em movimento), porque foi originalmente projetado e escrito por alguém em quem confiamos (DJB et al) e foi revisado pelo mundo pesquisadores conhecidos como Schneier e a equipe de segurança do Google. Use coisas que tendem à simplicidade se forem mais recentes, pois a simplicidade dificulta a ocultação de bugs profundos.

4. Conheça os padrões de segurança. Mesmo que você não se enquadre em um regime de segurança como o PCI ou a regra de segurança HIPAA, leia esses padrões e descubra como cumpri-los ou pelo menos controles de compensação muito fortes. Isso ajudará a garantir que você esteja realmente atendendo às 'melhores práticas'.

5. Faça testes de penetração externos / independentes e execute recompensas de bugs para garantir que você esteja seguindo essas práticas recomendadas continuamente. Tudo fica ótimo até você ter pessoas espertas e altamente motivadas falando sobre isso ... assim que terminar, você terá muita confiança em sua solução.


Pergunta 2: as chaves SSH Qual é a melhor escolha: deixe o Ansible usar o usuário root (com sua chave pública salva em ~/.ssh/authorized_keys/ permita que o usuário Ansible execute todos os comandos através do sudo especificando uma senha (que é única e precisa ser conhecida por todos os administradores de sistema) que usa Ansible para controlar esses servidores)

Tente evitar o uso de senhas em servidores, mesmo para o sudo. Isso é lidar com segredos e, no final das contas, prejudica sua segurança (você não pode realmente variar essa senha do sudo entre máquinas com muita facilidade, é necessário armazená-la em algum lugar, a senha significa que você não pode realmente executar a automação servidor a servidor, o que é exatamente do que se trata.Além disso, se você deixar o SSH como padrão, essas senhas poderão ser forçadas com força bruta, o que torna as chaves um pouco sem sentido.Evite o uso do usuário root para qualquer finalidade e, especialmente, o login remoto.

Crie um usuário não privilegiado dedicado ao Ansible com acesso ao sudo / deixe o usuário do Ansible executar todos os comandos através do sudo sem especificar nenhuma senha

Exatamente. Um usuário sem privilégios que você pode auditar de volta para ansible, com funções sudo. Idealmente, crie um usuário padrão dedicado às comunicações servidor a servidor / ansible com acesso sudo (sem senha).

... NB, se você estivesse usando o Userify, da maneira que eu sugeriria isso seria criar um usuário do Userify para o ansible (você também pode dividir isso por projeto ou mesmo grupo de servidores se tiver várias máquinas de controle do ansible), gere uma chave SSH no servidor de controle e forneça sua chave pública em sua página de perfil do Userify. (Esta caixa de texto se torna essencialmente /home/ansible/.ssh/authorized_keys). Você deve manter a conta do sistema ansible separada de outras contas do sistema servidor a servidor, como uma conta de backup remoto, gerenciamento secreto, etc. Em seguida, convide seus humanos e eles poderão criar e gerenciar suas próprias chaves, e tudo ficará separado. Mas, assim como com o bloqueio de um servidor de controle Ansible, tente bloquear o servidor Userify (ou qualquer outra solução que você implante) da mesma maneira.

alguma outra dica?

Eu acho que você definitivamente está fazendo isso da maneira certa e fazendo as perguntas certas. Se você quiser discutir esse tipo de coisa, envie-me um e-mail (sobrenome do primeiro ponto no userify) e ficarei feliz em ter um bate-papo, independentemente da direção que você seguir. Boa sorte!

Jamieson Becker
fonte
5

Resposta 1: a máquina de controle

Um pouco de ambos, você pode usar seu laptop para conectar-se a servidores via host bastião. algo como:

Host private1
  IdentityFile ~/.ssh/rsa_private_key
  ProxyCommand ssh user@bastion -W %h:%p

Host bastion
  IdentityFile ~/.ssh/bastion_rsa_key

Mais sobre hosts bastião

Onde você tem uma chave para o servidor bastião e, em seguida, uma chave separada para o host por trás dele. (pessoalmente, eu usaria gpg-agent / ssh-agent)

Resposta 2: Autenticação

Não tenho certeza de como as práticas recomendadas específicas "ansible" diferem de outras práticas recomendadas de conexão ssh.

Uma combinação das seguintes autenticações:

Outros pensamentos:

  • Sempre armazene segredos / informações particulares no ansible-vault.
  • O Ansible não requer a execução do SUDO / Root, a menos que o que você esteja fazendo exija o sudo / root.
  • O Ansible pode elevar permissões de várias maneiras diferentes

Por fim, você não mencionou nada sobre o Windows. Então, eu posso apenas assumir que você não está usando isso. No entanto, neste caso, eu usaria a opção delegate para que seu laptop use o host bastião (delegate_to bastion.hostname.fqdn:) e o kerberos / winrm https com tíquetes kerberos.

Caso você tenha perdido, as práticas recomendadas para computação, nunca faça nada como raiz, sempre use contas nomeadas

Jacob Evans
fonte