Utwórz użytkownika innego niż root i wyłącz root SSH w Ansible

9

Próbuję napisać podręcznik Ansible, aby uruchomić moje serwery. Domyślnie na Linode mogę zalogować się tylko jako root za pomocą hasła, więc mój playbook loguje się jako root, tworzy użytkownika innego niż root za pomocą klucza SSH oraz wyłącza root i hasło SSH.

Jest to problem, ponieważ nie mogę teraz uruchomić ponownie tego poradnika, ponieważ logowanie do konta root jest wyłączone! Chciałbym, aby podręcznik był idempotentny i nie musiał dodawać ani usuwać hostów po ich załadowaniu.

JonathanR
źródło
1
Można znaleźć inspirację tutaj .
Konstantin Suworow

Odpowiedzi:

5

Lubię to robić w ten sposób:

- 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

Próbuję połączyć się ze zdalnym hostem z moim użytkownikiem ansible. Jeśli jest to niemożliwe (przy pierwszym uruchomieniu), łączę się jako root i tworzę ansible user wraz z jego authorized_keysplikiem i sudoprawami.

Przy kolejnych uruchomieniach łączenie się jako użytkownik ansible działa, dzięki czemu blok zadań można pominąć.

Po uruchomieniu hosta zdalnego mogę kontynuować pracę z użytkownikiem ansible i become:

- hosts: all
  remote_user: ansible
  become: yes
  roles:
    - ...
Michał Trojanek
źródło
Czy zmieniasz ręcznie remote_userw swoim poradniku po pierwszym uruchomieniu? To nie jest idempotentne. Mam nadzieję, że coś przeoczyłem.
Deefour,
1
Ty nie zmieniam niczego ręcznie. Dwie próbki kodów reprezentują dwie różne sztuki (być może pomaga to wyobrazić sobie, że są wywoływane bootstrap.ymli site.yml, jeśli site.ymlobejmuje to bootstrap.ymlcokolwiek innego). Jeśli pierwsze zadanie bootstrap.ymlnie powiedzie się, wszystkie inne zadania tej gry zostaną pominięte i zostaną przejęte site.yml.
Michael Trojanek
kopia wklejony fragment kodu, ale ansibl przeskakuje że blok zadań: "skip_reason": "Conditional result was False". Uruchomienie gry z -vvvpokazuje, że połączenie ssh powraca"msg": "non-zero return code", "rc": 255,
Rafa
Naprawiłem zmianę whenwarunku:when: not "OK" in check_ansible_user.stdout
Rafa
2

Zrobiłbym następujące:

  • utwórz rolę (coś w rodzaju „bazy”), w której (między innymi), stwórz odpowiedniego użytkownika (i zasady sudo) do użycia przez ansible
  • utwórz lub dostosuj swoją rolę do SSH, aby zarządzać sshd_config(chciałbym polecić zarządzanie całym plikiem przy użyciu template, ale to zależy od ciebie) i wyłączenie logowania root
  • uzależnij swoją rolę SSH od roli podstawowej, np. używając meta.

W przypadku pierwszej roli (podstawowej) zwykle używam czegoś takiego:

 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

W przypadku konfiguracji SSH użyłbym:

- 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

Zależności ról Ansible są tutaj udokumentowane .

Aby to zrobić, możesz także użyć zamawiania w swoim podręczniku.

Mam grzeczne rzeczy na githubie (z którego wzięto powyższe), jeśli chcesz zobaczyć to w kontekście

iwaseatenbyagrue
źródło
2

Jeśli tworzysz swoje serwery na Linode z modułem Linode można zarejestrowania return valuetego linodezadania i obejmują zadania bootstrap ze stanem sprawdzenie outout zadania Linode. To powinno być idempotentne. Wypróbuj coś takiego:

- 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 zawierałby wtedy wszystkie zadania niezbędne do wyłączenia logowania root ssh i tak dalej.

Henrik Pingel
źródło
-1

Być może można po prostu zmodyfikować ansible_ssh_userw ekwipunku po tym jak bootstrapped hosta?

[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
źródło