Crea un utente non root e disabilita SSH root in Ansible


9

Sto cercando di scrivere un playbook Ansible per avviare i miei server. Per impostazione predefinita su Linode posso accedere solo come root con una password, quindi il mio playbook accede come root, crea un utente non root con una chiave SSH e disabilita SSH root e password.

Questo è un problema perché ora non riesco più a eseguire quel playbook poiché l'accesso root è disabilitato! Vorrei che il playbook fosse idempotente e non dovessi aggiungere e rimuovere host dopo averli riavviati.


1
Puoi trovare qualche ispirazione qui .
Konstantin Suvorov,

Risposte:


5

Mi piace farlo in questo modo:

- 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

Provo a connettermi all'host remoto con il mio utente Ansible. Se ciò è impossibile (al primo avvio), mi collego come root e creo l'utente responsabile insieme al suo authorized_keysfile e ai suoi sudodiritti.

Nelle successive esecuzioni, connettersi mentre l'utente risponde funziona, in modo da poter saltare il blocco di attività.

Una volta avviato l'host remoto, posso continuare con l'utente responsabile e become:

- hosts: all
  remote_user: ansible
  become: yes
  roles:
    - ...

Stai cambiando manualmente remote_usernel tuo playbook dopo quella prima esecuzione? Non è idempotente. Spero che mi manchi qualcosa.
Deefour,

1
Sì, non cambio nulla manualmente. I due esempi di codice rappresentano due diversi giochi (forse aiuta a immaginarli come chiamati bootstrap.ymle site.yml, dove site.ymlinclude bootstrap.ymlprima di ogni altra cosa). Se il primo compito bootstrap.ymlfallisce, tutti gli altri compiti di questo gioco vengono saltati e site.ymlsubentra.
Michael Trojanek,

copia-incollato il frammento di codice, ma salta ansible quel blocco di compiti: "skip_reason": "Conditional result was False". Eseguendo il gioco con -vvvviene restituito il richiamo ssh"msg": "non-zero return code", "rc": 255,
Rafa

Ho risolto cambiando la whencondizione:when: not "OK" in check_ansible_user.stdout
Rafa,

2

Vorrei fare quanto segue:

  • creare un ruolo (qualcosa come 'base') in cui tu (tra le altre cose), crei un utente adatto (e regole sudo) per poterlo usare
  • crea o adatta il tuo ruolo per SSH, da gestire sshd_config(tenderei a consigliarti di gestire l'intero file, usando a template, ma dipende da te) e disabilitare gli accessi root
  • fai dipendere il tuo ruolo SSH dal ruolo base, ad es. usando meta.

Per il primo ruolo (quello di base), tendo a usare qualcosa come:

 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

Per la configurazione SSH, vorrei usare:

- 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

Le dipendenze del ruolo di Ansible sono documentate qui .

Per fare questo, puoi anche semplicemente usare l'ordinamento nel tuo playbook.

Ho alcune cose rispondibili su Github (da cui è tratto quanto sopra), se vuoi vederlo nel contesto


2

Se si creano i server su Linode con il modulo di linode si potrebbe registrare il return valuedel linodecompito e includere i compiti di bootstrap con una condizione di verifica della outout del compito Linode. Questo dovrebbe essere idempotente. Prova qualcosa del genere:

- 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 dovrebbe contenere tutte le attività necessarie per disabilitare l'accesso root ssh e così via.


-1

Forse si potrebbe semplicemente modificare il ansible_ssh_usernel inventario dopo aver bootstrap l'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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.