创建非root用户并在Ansible中禁用root SSH


9

我正在尝试编写Ansible剧本来引导我的服务器。默认情况下,在Linode上,我只能以root用户身份使用密码登录,因此我的剧本将以root用户身份登录,使用SSH密钥创建非root用户,并禁用root用户和密码SSH。

这是一个问题,因为由于禁用了root登录,我现在无法再次运行该剧本!我希望剧本具有幂等性,并且不必在引导主机后添加和删除主机。


1
您可能会在这里找到一些灵感。
康斯坦丁·苏沃洛夫

Answers:


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

我尝试与我的ansible用户连接到远程主机。如果这是不可能的(在第一次运行中),我将以root用户身份连接并创建ansible用户及其authorized_keys文件和sudo权限。

在随后的运行中,以敏感用户的身份进行连接会起作用,因此可以跳过任务块。

一旦引导了远程主机,我就可以继续使用ansible用户并执行以下操作become

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

remote_user首次运行后,您是否要在剧本中手动更改?那不是幂等的。我希望我想念一些东西。
Deefour

1
您可以,我不会手动更改任何内容。这两个代码样本代表两个不同的场景(也许有助于想象它们被称为bootstrap.ymlsite.yml,其中site.yml包括bootstrap.yml其他内容)。如果第一个任务bootstrap.yml失败,则该播放的所有其他任务将被跳过并site.yml接管。
Michael Trojanek '18

复制粘贴了代码段,但ansible跳过了该任务块:"skip_reason": "Conditional result was False"。通过运行-vvv放映会显示ssh通话返回"msg": "non-zero return code", "rc": 255,
拉法

我已更改when条件:when: not "OK" in check_ansible_user.stdout
Rafa

2

我将执行以下操作:

  • 创建一个角色(例如“ base”),在其中您(除其他外),创建合适的用户(和sudo规则)以供使用
  • 创建或调整您的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上有一些有趣的内容(从上面可以得出)


2

如果用创建上的Linode服务器的Linode模块,你可以注册return value了的linode任务,包括与条件检查的Linode任务的outout的引导任务。那应该是幂等的。尝试这样的事情:

- 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 然后将包含禁用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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.