Создайте пользователя без полномочий root и отключите корневой SSH в Ansible

9

Я пытаюсь написать Ansible playbook для загрузки моих серверов. По умолчанию в Linode я могу войти только как root с паролем, поэтому моя playbook входит как root, создает пользователя без полномочий root с ключом SSH и отключает root и пароль SSH.

Это проблема, потому что теперь я не могу запустить эту книгу снова, так как root-вход отключен! Я хотел бы, чтобы playbook был идемпотентом и не должен добавлять и удалять хосты после их начальной загрузки.

JonathanR
источник
1
Вы можете найти вдохновение здесь .
Константин Суворов

Ответы:

5

Мне нравится делать это так:

- 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

Я пытаюсь подключиться к удаленному хосту с моим пользователем. Если это невозможно (при первом запуске), я подключаюсь от имени пользователя root и создаю пользователя ansible вместе с его authorized_keysфайлом и sudoправами.

При последующих запусках работает подключение как ANSIBLE user, поэтому блок задач можно пропустить.

После того, как удаленный хост загружен, я могу продолжить с пользователем ansible и become:

- hosts: all
  remote_user: ansible
  become: yes
  roles:
    - ...
Михаил Троянек
источник
Изменяете ли вы вручную remote_userсвою книгу после первого запуска? Это не идемпотент. Я надеюсь, что что-то упустил.
Deefour
1
Вы делаете, я ничего не меняю вручную. Два примера кода представляют две разные пьесы (возможно, это помогает представить их как вызываемые bootstrap.ymlи site.yml, где site.ymlвключает в себя bootstrap.ymlпрежде всего). Если первая задача bootstrap.ymlтерпит неудачу, все другие задачи этой игры пропускаются и site.ymlвступают во владение.
Майкл Троянек
копировать-вставить фрагмент кода, но анзибль скачет , что блок задач: "skip_reason": "Conditional result was False". Запуск спектакля с -vvvшоу возвращает ssh-вызов"msg": "non-zero return code", "rc": 255,
Рафа
Я исправил изменение whenсостояния:when: not "OK" in check_ansible_user.stdout
Рафа
2

Я бы сделал следующее:

  • создайте роль (что-то вроде 'base'), в которой вы (помимо всего прочего) создадите подходящего пользователя (и правила sudo) для использования в ansible
  • создать или адаптировать свою роль для SSH, управлять sshd_config(я бы порекомендовал вам управлять всем файлом, используя template, но это зависит от вас), и отключить root-логины
  • сделайте вашу роль SSH зависимой от базовой роли, например, с помощью meta.

Для первой роли (основной) я склонен использовать что-то вроде:

 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

Для конфигурации SSH я бы использовал:

- 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

Ролевые зависимости Ansible описаны здесь .

Вы также можете просто использовать порядок в вашей книге игр, чтобы сделать это.

У меня есть кое- что на github (из которого взято выше), если вы хотите увидеть это в контексте

iwaseatenbyagrue
источник
2

Если вы создаете свои сервера на Linode с модулем Linode можно зарегистрировать return valueв linodeзадаче и включает в себя задачу начальной загрузки со условием проверки на Outout задачи Linode. Это должно быть идемпотентом. Попробуйте что-то вроде этого:

- 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 будет содержать все задачи, необходимые для отключения входа root ssh и так далее.

Хенрик Пингел
источник
-1

Может быть, вы могли бы просто изменить ansible_ssh_userв инвентаре после того, как вы загрузили хост?

[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
источник