Créer un utilisateur non root et désactiver SSH root dans Ansible


9

J'essaie d'écrire un playbook Ansible pour démarrer mes serveurs. Par défaut sur Linode, je ne peux me connecter qu'en tant que root avec un mot de passe, donc mon playbook se connecte en tant que root, crée un utilisateur non root avec une clé SSH et désactive le root et le mot de passe SSH.

C'est un problème car je ne peux plus exécuter ce playbook car la connexion root est désactivée! Je voudrais que le playbook soit idempotent et ne doive pas ajouter et supprimer des hôtes après les avoir initialisés.


1
Vous pouvez trouver de l'inspiration ici .
Konstantin Suvorov

Réponses:


5

J'aime le faire de cette façon:

- 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

J'essaie de me connecter à l'hôte distant avec mon utilisateur ansible. Si cela est impossible (lors de la première exécution), je me connecte en tant que root et crée l'utilisateur ansible avec son authorized_keysfichier et ses sudodroits.

Lors des exécutions suivantes, la connexion en tant qu'utilisateur ansible fonctionne, de sorte que le bloc de tâches peut être ignoré.

Une fois l'hôte distant démarré, je peux continuer avec l'utilisateur ansible et become:

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

Modifiez-vous manuellement le remote_userdans votre playbook après cette première exécution? Ce n'est pas idempotent. J'espère que je manque quelque chose.
Deefour

1
Vous le faites, je ne change rien manuellement. Les deux exemples de codes représentent deux jeux différents (peut-être que cela aide à les imaginer comme étant appelés bootstrap.ymlet site.yml, où site.ymlinclut bootstrap.ymlavant toute autre chose). Si la première tâche bootstrap.ymléchoue, toutes les autres tâches de ce jeu sont ignorées et site.ymlprennent le relais.
Michael Trojanek

copier-coller l'extrait de code, mais skips Ansible ce bloc de tâches: "skip_reason": "Conditional result was False". Exécution de la pièce avec des -vvvspectacles que l'appel ssh revient"msg": "non-zero return code", "rc": 255,
Rafa

J'ai corrigé le changement de whencondition:when: not "OK" in check_ansible_user.stdout
Rafa

2

Je ferais ce qui suit:

  • créer un rôle (quelque chose comme «base») où vous (entre autres choses), créez un utilisateur approprié (et des règles sudo) à utiliser par ansible
  • créez ou adaptez votre rôle pour SSH, à gérer sshd_config(j'aurais tendance à vous recommander de gérer l'intégralité du fichier, en utilisant un template, mais cela dépend de vous), et désactivez les connexions root
  • faites dépendre votre rôle SSH du rôle de base, par exemple en utilisant la méta.

Pour le premier rôle (celui de base), j'ai tendance à utiliser quelque chose comme:

 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

Pour la configuration SSH, j'utiliserais:

- 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

Les dépendances de rôle d'Ansible sont documentées ici .

Pour cela, vous pouvez également utiliser la commande dans votre livre de lecture.

J'ai quelques trucs ansibles sur github (dont ce qui précède est pris), si vous voulez le voir dans le contexte


2

Si vous créez vos serveurs sur Linode avec le module linode vous pouvez enregistrer la return valuede la linodetâche et inclure les tâches d'amorçage avec une condition de vérification du outout de la tâche linode. Cela devrait être idempotent. Essayez quelque chose comme ceci:

- 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 contiendrait alors toutes les tâches nécessaires pour désactiver la connexion root ssh, etc.


-1

Peut-être vous pouvez simplement modifier le ansible_ssh_userdans l' inventaire une fois que vous avez bootstrapped l'hôte?

[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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.