Crie um usuário não raiz e desative o SSH raiz no Ansible

9

Estou tentando escrever um manual do Ansible para inicializar meus servidores. Por padrão, no Linode, eu posso logar apenas como root com uma senha, para que o meu playbook efetue login como root, crie um usuário não root com uma chave SSH e desabilite o SSH de root e senha.

Este é um problema, porque agora não consigo executar esse manual novamente, pois o login root está desativado! Eu gostaria que o manual fosse idempotente e não tivesse que adicionar e remover hosts depois de inicializá-los.

JonathanR
fonte
1
Você pode encontrar alguma inspiração aqui .
Konstantin Suvorov 23/03

Respostas:

5

Eu gosto de fazer assim:

- hosts: all
  remote_user: root
  gather_facts: no
  tasks:
    - name: Check ansible user
      command: ssh -q -o BatchMode=yes -o ConnectTimeout=3 ansible@{{ inventory_hostname }} "echo OK"
      delegate_to: 127.0.0.1
      changed_when: false
      failed_when: false
      register: check_ansible_user
    - block:
      - name: Create Ansible user
        user:
          name: ansible
          comment: "Ansible user"
          password: $6$u3GdHI6FzXL01U9q$LENkJYHcA/NbnXAoJ1jzj.n3a7X6W35rj2TU1kSx4cDtgOEV9S6UboZ4BQ414UDjVvpaQhTt8sXVtkPvOuNt.0
          shell: /bin/bash
      - name: Add authorized key
        authorized_key:
          user: ansible
          key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
          exclusive: yes
      - name: Allow sudo for ansible
        copy:
          content: ansible ALL=(ALL) ALL
          dest: /etc/sudoers.d/ansible
          mode: 0600
      when: check_ansible_user | failed

Tento me conectar ao host remoto com meu usuário ansible. Se isso for impossível (na primeira execução), eu me conecto como root e crio o usuário ansible junto com seu authorized_keysarquivo e sudodireitos.

Nas execuções subseqüentes, a conexão como usuário ansible funciona, para que o bloco de tarefas possa ser ignorado.

Depois que o host remoto é inicializado, posso continuar com o usuário ansible e become:

- hosts: all
  remote_user: ansible
  become: yes
  roles:
    - ...
Michael Trojanek
fonte
Você está alterando manualmente o remote_userseu manual após a primeira execução? Isso não é idempotente. Espero estar perdendo alguma coisa.
Deefour 16/09
1
Você faz, eu não mudo nada manualmente. Os dois exemplos de código representam duas peças diferentes (talvez ajude a imaginá-las como sendo chamadas bootstrap.ymle site.yml, onde site.ymlinclui bootstrap.ymlantes de mais nada). Se a primeira tarefa de bootstrap.ymlfalhar, todas as outras tarefas desta peça serão ignoradas e site.ymlassumidas.
Michael Trojanek
copiar-colar o trecho de código, mas salta ansible esse bloco de tarefas: "skip_reason": "Conditional result was False". Executando o jogo com -vvvmostra a chamada ssh retornos"msg": "non-zero return code", "rc": 255,
Rafa
Corrigi a alteração da whencondição:when: not "OK" in check_ansible_user.stdout
Rafa
2

Eu faria o seguinte:

  • crie uma função (algo como 'base') em que você (entre outras coisas), crie um usuário adequado (e regras do sudo) para poder usar
  • crie ou adapte sua função para SSH, para gerenciar sshd_config(eu recomendaria que você gerencie o arquivo inteiro, usando a template, mas isso depende de você) e desative os logins raiz
  • faça sua função SSH depender da função base, por exemplo, usando meta.

Para o primeiro papel (o básico), costumo usar algo como:

 name: base | local ansible user | create user
  user:
    name: "{{ local_ansible_user }}"
    group: "{{ local_ansible_group }}"
    home: "/home/{{ local_ansible_user }}"
    state: present
    generate_ssh_key: "{{ local_ansible_generate_key }}"
    ssh_key_bits: 4096
    ssh_key_type: rsa
  tags:
    - ansible
    - local_user

- name: base | local ansible user | provision authorised keys
  authorized_key:
    user: "{{ local_ansible_user }}"
    state: present
    key: "{{ item }}"
  with_items: "{{ local_ansible_authorised_keys }}"
  tags:
    - ansible
    - authorised_keys

Para a configuração SSH, eu usaria:

- name: openssh | server | create configuration
  template:
    src: sshd_config.j2
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: "0640"
    validate: "/usr/sbin/sshd -tf %s"
  notify:
    - openssh | server | restart
  tags:
    - ssh
    - openssh

As dependências de função da Ansible estão documentadas aqui .

Você também pode usar pedidos no seu manual para fazer isso.

Eu tenho algumas coisas ansible no github (do qual o acima foi tirado), se você quiser vê-lo no contexto

iwaseatenbyagrue
fonte
2

Se você criar seus servidores Linode com o módulo linode você poderia registrar o return valueda linodetarefa e incluir as tarefas de bootstrap com uma condição de verificação da outout da tarefa linode. Isso deve ser idempotente. Tente algo como isto:

- linode:
    api_key: 'longStringFromLinodeApi'
    name: linode-test1
    plan: 1
    datacenter: 2
    distribution: 99
    password: 'superSecureRootPassword'
    private_ip: yes
    ssh_pub_key: 'ssh-rsa qwerty'
    swap: 768
    wait: yes
    wait_timeout: 600
    state: present
  register: linode_node

- include: bootstrap.yml
  when: linode_node.changed

bootstrap.yml conteria todas as tarefas necessárias para desativar o login root ssh e assim por diante.

Henrik Pingel
fonte
-1

Talvez você possa modificar ansible_ssh_usero inventário depois de inicializar o host?

[targets]

other1.example.com ansible_connection=ssh ansible_ssh_user=root # new host
other2.example.com ansible_connection=ssh ansible_ssh_user=user # bootstrapped host
kal3v
fonte