Como fazer com que o Ansible use a senha se a chave foi rejeitada?

14

Minhas novas instâncias do servidor estão configuradas para efetuar login no root via ssh com senha. Quero que meu manual do Ansible reconfigure-o para usar chaves e desabilite o login root com senha na primeira execução, por isso preciso de algo como isto:

  • tente fazer login com a chave
  • se não puder fazer login com a chave:

    • Entrar com senha
    • adicione a chave a allowed_keys
    • desativar login root com senha
    • opcionalmente, reconecte usando a chave
  • fazer outras tarefas

Como posso conseguir isso?

EDIT : Para ser claro, não estou perguntando como adicionar chave ou desativar raiz, isso é apenas para o contexto. Estou perguntando como fazer backup da senha se ela não pôde se autenticar com a chave. Com --ask-passou ansible_ssh_passdefinido, o Ansible nem tentará usar a autenticação de chave pública

petr0
fonte
Boa pergunta, o que você tentou até agora?
dawud 4/11/2013
1
Levei a configuração ssh para um playbook separado e o executo com a opção -k, depois executo o playbook principal sem -k (usando a chave do agente). Eu estava esperando que ele pode ser envolto em um único playbook embora ...
petr0
@ petr0 Isso funciona para mim quando a senha de solicitação de senha é para um usuário diferente da chave (ou seja, quando você troca de usuário remoto após desativar o ssh com senha). Não estou certo se isso ajuda.
DylanYoung

Respostas:

6

Você pode tentar a PreferredAuthenticationsopção, configurando-a para publickey,password. O padrão inclui-os nesta ordem, junto com outras opções, portanto, é provável que esteja configurando isso. Adicioná-lo via -oou o cliente ssh_configpode impedir isso.

Você pode usar um script de wrapper. Por exemplo, com isso em key_or_password.she a pass.shque fornece a senha, a execução bash key_or_password.sh root@hosttentará uma chave pública seguida por um login de senha não interativo.

export DISPLAY=dummy:0
export SSH_ASKPASS=$PWD/pass.sh
exec setsid ssh -v -o 'PreferredAuthentications publickey,password' "$@"

O log indica com qual método foi bem-sucedido, por exemplo

debug1: Authentication succeeded (publickey).
eisd
fonte
7

Aqui está o que eu faço se ansible_userfor diferente para a 'primeira execução' do manual (por exemplo, se você tiver apenas um rootusuário e configurar um novo usuário com uma chave SSH):

  • Armazene a senha ansible_passcomo faria se estivesse usando logins de senha (lembre-se de usar o Vault). Essa deve ser a senha do usuário que você está usando para a 'primeira execução' do manual.
  • Defina ansible_usercomo o nome de usuário do usuário que você deseja usar após a primeira execução, quando tiver os usuários configurados corretamente no servidor.
  • Defina uma variável de ansible_user_first_runcomo o usuário que você usará para a 'primeira execução' do manual, por exemplo root.
  • Use um comando local para tentar se conectar ao servidor com a chave SSH correta, usando ignore_errorsechanged_when: False
  • Se isso falhar, atualize ansible_userpara o valor deansible_user_first_run

Aqui está o código:

---
- name: Check if connection is possible
  command: ssh -o User={{ ansible_user }} -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes {{ inventory_hostname }} echo "Worked"
  register: result
  connection: local
  ignore_errors: yes
  changed_when: False
- name: If no connection, change user_name
  connection: local
  set_fact:
    ansible_user: "{{ ansible_user_first_run }}"
  when: result|failed

Nota: Vale a pena configurar, transport = sshpois o paramiko pode falhar inesperadamente no login no servidor em algumas configurações (por exemplo, quando o servidor está configurado para não aceitar senhas, e você está tentando primeiro com uma chave e depois com uma senha ... estranho!) Além disso, o transporte ssh é mais rápido, portanto vale a pena.

Observação adicional: se você estiver usando esse método, precisará especificar gather_facts: falseno arquivo de definição do playbook para que as tarefas de configuração / coleta de fatos não sejam executadas automaticamente antes de chegar ao estágio de teste de senhas. Se você precisar de algum dos fatos ansíveis, precisará chamar explicitamente setupsua função antes de acessar qualquer dado normalmente disponível em locais como ansible_devicesetc. Uma boa maneira de fazer isso é chamar setupuma whencláusula que verifique se o fato de que você está usando está vazio ou não antes de chamá-lo em sua função.

Tom Bull
fonte
Sua solução é boa, mas você deve adicionar um gather_facts: nopara parar ansible tentando se conectar ao lançar a cartilha :)
k4cy
Você está certo. Eu tenho o gather_facts desativado para todos os meus playbooks, para que eu precise chamar 'setup' explicitamente. Esqueci de mencionar isso na resposta, vou atualizá-lo agora.
Tom Bull
5

Você pode usar --ask-passao executar o ansible-playbook.

Para outras tarefas solicitadas, é possível realizar de várias formas, por exemplo, módulo de cópia.
Desabilitar o login root também pode ser feito, por exemplo. por modelo sshd_confou inserção de linha no arquivo conf.

titus
fonte
--ask-pass (que é o mesmo que -k) é o que estou fazendo e escrevi sobre isso no comentário acima
petr0