Ansible SSH 设置手册

最佳做法是将 Ansible 与 SSH 密钥一起使用,以创建到服务器的 SSH 连接。这确实需要事先进行一些额外的设置,以确保 Ansible 可以单独通过 SSH 密钥访问服务器。由于我最近经常这样做,因此我决定将设置步骤打包到 Ansible 剧本中。

当您第一次设置 Linux 服务器时,您会发现您通常被授予 root 访问权限,并且事后配置它是由您决定的,以便拥有具有正确访问权限的管理员用户。有了这个 root 用户,我们将使用 Ansible 登录到主机,创建一个新用户,设置 SSH 密钥访问,然后更改 sudoers 文件,以便新用户可以执行 Ansible 任务。

假设我们要配置的主机的 IP 地址为 10.0.0.1,我们可以创建一个如下所示的清单文件。

[hosts]
10.0.0.1 ansible_connection=ssh ansible_ssh_user=root ansible_ssh_pass=myrootpassword

由于我们没有 SSH 密钥访问权限,我们需要告诉 Ansible 使用替代方法。ansible_ssh_user 参数告诉 Ansible 以哪个用户登录,ansible_ssh_pass 告诉 Ansible 用户密码是什么。

那些对 Ansible 有所了解的人可能想知道为什么要使用 ansible_ssh_pass 参数而不是命令行上的 --ask-pass 标志将密码传递给 Ansilbe。原因是 --ask-pass 只会接受一个密码并将其传递给所有主机。如果您的清单文件中的每个主机都具有相同的 root 密码,这很好,但我猜这可能不是这种情况。这里的想法是,您可以花一些时间来设置虚拟机,然后将它们插入此设置手册中,以使它们达到最低水平以进行 Ansible 配置。完成后,您可以继续使用其他剧本来相应地配置 Ansible 主机。

为了使用 ansible_ssh_pass 参数,您首先需要安装 sshpass 程序。这允许您将密码发送到 SSH 命令,并且 Ansible 利用此程序将密码发送到它自己的连接。如果你在 Ubuntu 上,你可以像这样安装 sshpass。

sudo apt-get install sshpass

如果您现在尝试与 Ansible 连接,即使密码正确,您也可能会收到身份验证失败消息。这是因为您的本地系统试图询问您是否要存储您正在连接的主机的密钥检查,这妨碍了 Ansible 尝试连接。要禁用主机密钥检查,您需要创建一个名为ansible.cfg(在与您的清单文件相同的文件夹中)的文件并添加以下内容。

[defaults]
host_key_checking=false

该ansible.cfg文件由 Ansible 自动选取并用于设置某些 Ansible 配置选项。在这种情况下,我们将关闭主机密钥检查并允许 Ansible 连接到主机,而无需询问是否应将主机密钥添加到已知主机列表中。

在设置 playbook 之前,您首先需要创建一个用于设置连接的 ssh 密钥。这可以通过 ssh-keygen 命令以通常的方式完成。创建后,将密钥放入与 Ansible 脚本相同的目录中。请记住不要将它们提交到任何源代码控制系统中,特别是如果它们是公共存储库。

在此之后,您就可以创建一个设置手册,将 ssh 密钥放在服务器上。该剧本将使用hosts.ini上面创建的文件中的连接详细信息运行。本剧本将执行以下操作。

  • 在远程主机上创建一个用户。这个用户的名字在剧本的顶部被定义为一个变量。

  • 为创建的用户设置密码。这主要是为了使此用途在服务器上具有完整的存在,并且还可用于在将命令移植回 Ansible playbook 之前测试服务器上的命令。同样,密码是使用剧本顶部的变量设置的。

  • 使用authorized_key Ansible 模块复制公共ssh 密钥(与Ansible 项目保存在同一文件夹中)并将其放在服务器上的.ssh/authorized_keys 文件中。在此步骤之后,可以单独使用 ssh 密钥连接到服务器。不过还有一步要做。

  • 最后一步是允许“ansibleremote”用户在远程主机上完成“sudo”操作,而无需输入密码。我们通过在 /etc/sudoers 文件中添加一行来做到这一点。

这是完整的设置手册。

---
- hosts: all
  user: root
  vars: 
    createuser: 'ansibleremote'
    createpassword: 'myamazingpassword'
  tasks:
  - name: Setup | create user
    command: useradd -m {{ createuser }} creates=/home/{{ createuser }}
    sudo: true
 
  - name: Setup | set user password
    shell: usermod -p $(echo '{{ createpassword }}' | openssl passwd -1 -stdin) {{ createuser }}
    sudo: true
 
  - name: Setup | authorized key upload
    authorized_key: user={{ createuser }}
      key="{{ lookup('file', 'mypublickey.pub') }}"
      path='/home/{{ createuser }}/.ssh/authorized_keys'
      manage_dir=no
    sudo: true
 
  - name: Sudoers | update sudoers file and validate
    lineinfile: "dest=/etc/sudoers
      insertafter=EOF
      line='{{ createuser }} ALL=(ALL) NOPASSWD: ALL'
      regexp='{{ createuser }} ALL=(ALL) NOPASSWD: ALL'
      state=present"
    sudo: true

您可以使用以下命令运行此设置剧本。

ansible-playbook --inventory-file=hosts.ini setup.yml

完成后,您现在可以使用“ansibleremote”用户运行其他 Ansible 剧本并使用安全 ssh 密钥在主机上完成操作。有几种使用 ssh 密钥连接的方法,但一种方法是通过hosts.ini以下方式在您的文件中引用它。

[default]
10.0.0.1 ansible_ssh_user=ansibleremote ansible_ssh_private_key_file=privatekey