Como posso implementar ansible com senhas por host, de forma segura?

101

Eu gostaria de usar o ansible para gerenciar um grupo de servidores existentes. Eu criei um arquivo ansible_hosts e testei com sucesso (com a opção -K ) com comandos que visam apenas um único host

ansible -i ansible_hosts host1 --sudo -K # + commands ...

Meu problema agora é que as senhas de usuário em cada host são diferentes, mas não consigo encontrar uma maneira de lidar com isso no Ansible.

Usando -K , só sou solicitado a fornecer uma única senha sudo, o que parece ser tentado para todos os hosts subseqüentes sem solicitar:

host1 | ...
host2 | FAILED => Incorrect sudo password
host3 | FAILED => Incorrect sudo password
host4 | FAILED => Incorrect sudo password
host5 | FAILED => Incorrect sudo password

Pesquisa até agora:

  • uma pergunta do StackOverflow com uma resposta incorreta ("use -K " ) e uma resposta do autor dizendo "Descobri que precisava de sudo sem senha"

  • os documentos do Ansible , que dizem "Uso de senha" o sudo torna as coisas mais fáceis de automatizar, mas não é necessário . " (ênfase minha)

  • esta pergunta do StackExchange de segurança que considera como NOPASSWD necessário

  • artigo "Provisionamento Escalável e Compreensível ..." que diz:

    "executar o sudo pode exigir a digitação de uma senha, que é uma maneira segura de bloquear o Ansible para sempre. Uma correção simples é executar visudo no host de destino e certificar-se de que o usuário Ansible usará o login tem que digitar uma senha "

  • artigo "Playbooks Básicos Ansíveis" , que diz

    "Ansible poderia logar no servidor de destino como root e evitar a necessidade de sudo, ou deixar o usuário ansible ter sudo sem uma senha, mas o pensamento de fazer o meu baço ameaçar saltar para o meu esófago e bloquear minha traqueia, então eu não "

    Meus pensamentos exatamente, mas como estender além de um único servidor?

  • número ansiável # 1227 , "O Ansible deve pedir uma senha sudo para todos os usuários em um manual ", que foi fechado há um ano por mpdehaan com o comentário" Não tenho visto muita demanda para isso, eu acho que a maioria das pessoas está sudoing de apenas uma conta de usuário ou usando chaves na maioria das vezes. "

Então ... como as pessoas estão usando o Ansible em situações como essas? A definição de NOPASSWD em /etc/sudoers , a reutilização de senhas em hosts ou a ativação do login SSH raiz, tudo parece reduzir drasticamente a segurança.

    
por supervacuo 09.12.2013 / 12:49

6 respostas

52

Você certamente fez sua pesquisa ...

De toda a minha experiência com ansible o que você está procurando realizar, não é suportado. Como você mencionou, ansible afirma que não requer sudo sem senha, e você está correto, isso não acontece. Mas ainda tenho que ver qualquer método de usar várias senhas sudo dentro de ansible, sem, claro, executar várias configurações.

Então, não posso oferecer a solução exata que você está procurando, mas você perguntou ...

"So... how are people using Ansible in situations like these? Setting NOPASSWD in /etc/sudoers, reusing password across hosts or enabling root SSH login all seem rather drastic reductions in security."

Eu posso te dar uma visão sobre isso. Meu caso de uso é de 1k nós em vários datacenters que suportam uma empresa SaaS global na qual eu tenho que projetar / implementar alguns controles de segurança insanamente rígidos devido à natureza de nossos negócios. A segurança é sempre um ato de equilíbrio, mais usabilidade menos segurança, esse processo não é diferente se você estiver executando 10 servidores ou 1.000 ou 100.000.

Você está absolutamente correto em não usar logins de raiz via senha ou chaves ssh. Na verdade, o login raiz deve ser desativado totalmente se os servidores tiverem um cabo de rede conectado a eles.

Vamos falar sobre reutilização de senha, em uma empresa grande, é razoável pedir aos administradores de sistemas que tenham senhas diferentes em cada nó? para alguns nós, talvez, mas meus administradores / engenheiros se revoltariam se tivessem senhas diferentes em 1000 nós. Implementando isso seria quase impossível também, cada usuário teria que armazenar suas próprias senhas em algum lugar, esperançosamente um keypass, não uma planilha. E toda vez que você coloca uma senha em um local onde possa ser retirada em texto simples, você diminuiu muito sua segurança. Eu preferiria que eles soubessem, de cor, uma ou duas senhas realmente strongs do que ter que consultar um arquivo keypass toda vez que precisassem se logar ou invocar o sudo em uma máquina.

Assim, a redefinição e padronização de senha é algo completamente aceitável e padrão, mesmo em um ambiente seguro. Caso contrário, ldap, keystone e outros serviços de diretório não precisariam existir.

Quando nos movemos para usuários automatizados, as chaves ssh funcionam muito bem para você entrar, mas você ainda precisa passar pelo sudo. Suas escolhas são uma senha padronizada para o usuário automatizado (o que é aceitável em muitos casos) ou para ativar o NOPASSWD como você apontou. A maioria dos usuários automatizados só executa alguns comandos, então é bem possível e certamente desejável ativar o NOPASSWD, mas apenas para comandos pré-aprovados. Eu sugiro usar seu gerenciamento de configuração (ansible neste caso) para gerenciar seu arquivo sudoers para que você possa atualizar facilmente a lista de comandos sem senha.

Agora, há algumas etapas que você pode seguir depois de começar a escalonar para isolar ainda mais o risco. Embora tenhamos 1000 ou mais nós, nem todos eles são servidores de produção, alguns são ambientes de teste, etc. Nem todos os administradores podem acessar servidores de produção, mas podem usar a mesma chave de usuário / senha do SSO . Mas os usuários automatizados são um pouco mais seguros, por exemplo, uma ferramenta automatizada que os administradores que não são de produção podem acessar tem um usuário & credenciais que não podem ser usadas na produção. Se você deseja executar ansible em todos os nós, é necessário fazer isso em dois lotes, uma para não produção e outra para produção.

Também usamos o fantoche, já que é uma ferramenta de gerenciamento de configuração imponente, portanto, a maioria das alterações em todos os ambientes seria eliminada por meio dele.

Obviamente, se a solicitação de recurso que você mencionou for reaberta / concluída, o que você deseja fazer seria totalmente compatível. Mesmo assim, a segurança é um processo de avaliação e comprometimento de riscos. Se você tiver apenas alguns nós para os quais possa se lembrar das senhas sem recorrer a uma nota de post-it, as senhas separadas seriam um pouco mais seguras. Mas para a maioria de nós, não é uma opção viável.

    
por 30.12.2013 / 17:53
36

A partir do Ansible 1.5, é possível usar um cofre criptografado para host_vars e outras variáveis. Isso permite pelo menos que você armazene uma variável ansible_sudo_pass por host (ou por grupo) com segurança. Infelizmente, --ask-vault-pass solicitará apenas uma senha de vault única por chamada invariável, de modo que você ainda estará limitado a uma única senha do vault para todos os hosts que serão usados juntos.

No entanto, para alguns usos, isso pode ser uma melhoria em ter uma única senha sudo em vários hosts, já que um invasor sem acesso a seus hosts_vars criptografados ainda precisaria de uma senha sudo separada para cada máquina (ou grupo de máquinas) que ele ou ela ela ataca.

    
por 10.05.2014 / 22:32
22

Com o Ansible 1.5, é possível definir a variável ansible_sudo_pass usando lookup('password', …) :

ansible_sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"

Acho isso mais conveniente do que usar arquivos em host_vars/ por diversos motivos:

  • Eu realmente uso with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt" para provisionar as senhas para o usuário remoto deploy (que é necessário para o sudo ), então eles já estão presentes nos arquivos (embora fazer essas pesquisas de texto simples perde o valor de sal armazenado no arquivo quando o valor em hash é gerado).

  • Isso mantém apenas as senhas no arquivo (sem ansible_sudo_pass: de texto simples conhecido) para algum aumento de epsilon na segurança criptográfica. Mais significativamente, isso significa que você não está criptografando todas as outras variáveis específicas do host, para que possam ser lidos sem a senha do vault.

  • Colocar as senhas em um diretório separado torna mais fácil manter os arquivos fora do controle de origem ou usar uma ferramenta como git-crypt para armazená-los em formato criptografado (você pode usar isso com Ansible anterior que não tenha o recurso de segurança). Eu uso o git-crypt e como eu só verifico o repositório em forma descriptografada em sistemas de arquivos criptografados, não me preocupo com o cofre e, portanto, não preciso digitar uma senha do vault. (Usar ambos seria, naturalmente, mais seguro).

Você também pode usar a função pesquisa com ansible_ssh_pass ; isso pode até ser possível com versões anteriores do Ansible que não têm ansible_sudo_pass .

    
por 26.05.2014 / 21:33
19

Usar o pass é um método simples para fornecer senhas com sudo. pass armazena uma senha por arquivo, o que facilita o compartilhamento de senhas via git ou outros métodos. Também é seguro (usando o GnuPG) e, se você usa o gpg-agent, ele permite que você use ansible sem inserir uma senha em cada uso.

Para fornecer a senha armazenada como servers/foo do servidor foo para ansible, use-a em um arquivo de inventário como este:

[servers]
foo ansible_sudo=True \
    ansible_sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"

Dado que você desbloqueou a chave para o gpg-agent anteriormente, isso será executado sem a necessidade de digitar qualquer senha.

    
por 19.01.2016 / 20:51
3

Este é um tópico bastante antigo, no entanto:

  • Usamos dois sistemas de autenticação diferentes internamente, o gerenciamento de máquinas é feito a partir de estações de trabalho locais em minha equipe.
  • Eu escrevi um vars_plugin para o Ansible (uma implementação bastante completa pode ser encontrada no link ), que diferencia várias autenticações sistemas:
  • O nome do sistema de autenticação é específico do grupo.
  • O usuário de login / sudo usado é específico do grupo e do administrador.
  • Por isso, puxo o usuário do ambiente do administrador e a senha correspondente através da biblioteca python-keyring de uma senha segura (usamos keychain do Mac OS X, mas da documentação kwallet Gnome e _win_crypto também são suportados).
  • Defino permissões nas senhas nas chaves do Mac OS X para notificar-me sobre o fato de que a segurança do programa de linha de comando solicita acesso a uma senha para cada sistema de autenticação usado por os hosts, então eu corro "ansible -s all -m ping" e recebo dois prompts (um para cada sistema de autenticação) onde eu pressiono a barra de espaço e ansible pega as senhas.
por 03.03.2015 / 18:33
0

Uma maneira possível de fazer isso é usar variáveis ambientais.

por exemplo,

pass1=foo pass2=bar ansible-playbook -i production servers.xml

Em seguida, nas jogadas, você pode pesquisar a senha do sudo usando:

lookup('env', 'pass1') 
lookup('env', 'pass2') 
    
por 21.07.2017 / 10:57