Ansible将ssh密钥从一个主机复制到另一个主机

时间:2014-09-02 18:27:59

标签: ssh ansible capistrano3 ansible-playbook

我有两个app服务器,前面有一个loadbalancer,我的系统中有一个数据库服务器。我使用Ansible配置它们。应用程序服务器具有Nginx + Passenger并运行Rails应用程序。将使用capistrano进行部署,但我有一个关于ssh密钥的问题。我的git repo在另一台服务器上,我必须在appservers上生成ssh公钥并将它们添加到Git服务器(To authorized_keys文件)。我怎么能在ansible playbook中做到这一点?

PS:我的app服务器可能超过2个。

enter image description here

6 个答案:

答案 0 :(得分:28)

查看authorized_key module以获取有关如何管理公钥的信息。

我能想到的最直接的解决方案是为您的应用程序生成一个新的密钥对,以便在所有应用程序实例中共享。 这可能会产生安全隐患(您确实在所有实例之间共享密钥!),但它会简化配置过程。

您还需要在每台应用计算机上部署一个部署用户,以便稍后在部署过程中使用。您需要在每个部署用户的authorized_keys上使用您的公钥(或jenkins one)。

草图剧本:

---
- name: ensure app/deploy public key is present on git server
  hosts: gitserver
  tasks:
    - name: ensure app public key
      authorized_key: 
        user: "{{ git_user }}" 
        key: app_keys/id_dsa.pub 
        state: present

- name: provision app servers
  hosts: appservers
  tasks:
    - name: ensure app/deploy user is present
      user: 
        name: "{{ deploy_user }}"
        state: present

    - name: ensure you'll be able to deploy later on
      authorized_key:
        user: "{{ deploy_user }}" 
        key: "{{ path_to_your_public_key }}" 
        state: present

    - name: ensure private key and public one are present
      copy: 
        src: keys/myapp.private 
        dest: "/home/{{ deploy_user }}/.ssh/{{ item }}" 
        mode: 0600
      with_items:
        - app_keys/id_dsa.pub
        - app_keys/id_dsa

答案 1 :(得分:27)

这对我来说很有用,它收集节点上的公共ssh密钥并将其分发到所有节点上。这样他们就可以互相沟通。

- hosts: controllers
  gather_facts: false
  remote_user: root
  tasks:
    - name: fetch all public ssh keys
      shell: cat ~/.ssh/id_rsa.pub
      register: ssh_keys
      tags:
        - ssh

    - name: check keys
      debug: msg="{{ ssh_keys.stdout }}"
      tags:
        - ssh

    - name: deploy keys on all servers
      authorized_key: user=root key="{{ item[0] }}"
      delegate_to: "{{ item[1] }}"
      with_nested:
        - "{{ ssh_keys.stdout }}"
        - "{{groups['controllers']}}"
      tags:
        - ssh

信息:这适用于用户root

答案 2 :(得分:1)

我会创建一个部署用户,该用户仅限于提取对您的回购的访问权限。您可以通过http或there are a few options to do it over ssh允许此操作。

如果您不关心将用户限制为对您的仓库的只读访问权限,那么您可以创建一个普通的ssh用户。创建用户后,您可以使用Ansible将用户的公钥添加到git服务器上的授权密钥文件中,您可以使用authorized key module

设置完成后,您有两个选择:

  1. 如果使用ssh,请使用ssh密钥转发,以便用于运行Ansible任务的用户将其公钥发送到开发服务器。

  2. 暂时转移密钥并使用ssh_opts git module option来使用部署用户的公钥。

答案 3 :(得分:0)

我创建了一个参数化角色,以确保在源远程主机中的源用户中生成ssh密钥对,并将其公钥复制到目标远程主机中的目标用户。

您可以在源和目标主机列表的嵌套循环中调用该角色,如下所示:

---
#****h* ansible/ansible_roles_ssh_authorize_user
# NAME
#   ansible_roles_ssh_authorize_user - Authorizes user via ssh keys
#
# FUNCTION
#
#   Copies user's SSH public key from a source user in a source host
#   to a target user in a target host
#
# INPUTS
#
#   * ssh_authorize_user_source_user
#   * ssh_authorize_user_source_host
#   * ssh_authorize_user_target_user
#   * ssh_authorize_user_target_host
#****
#****h* ansible_roles_ssh_authorize_user/main.yml
# NAME
#   main.yml - Main playbook for role ssh_authorize_user
# HISTORY
#   $Id: $
#****

- assert:
    that:
      - ssh_authorize_user_source_user != ''
      - ssh_authorize_user_source_host != ''
      - ssh_authorize_user_target_user != ''
      - ssh_authorize_user_target_host != ''
  tags:
    - check_vars
- name: Generate SSH Keypair in Source
  user:
    name: "{{ ssh_authorize_user_source_user }}"
    state: present
    ssh_key_comment: "ansible-generated for {{ ssh_authorize_user_source_user }}@{{ ssh_authorize_user_source_host }}"
    generate_ssh_key: yes
  delegate_to: "{{ ssh_authorize_user_source_host }}"
  register: source_user
- name: Install SSH Public Key in Target
  authorized_key:
    user: "{{ ssh_authorize_user_target_user }}"
    key: "{{ source_user.ssh_public_key }}"
  delegate_to: "{{ ssh_authorize_user_target_host }}"
- debug:
    msg: "{{ ssh_authorize_user_source_user }}@{{ ssh_authorize_user_source_host }} authorized to log in to {{ ssh_authorize_user_target_user }}@{{ ssh_authorize_user_target_host }}"

在循环中调用角色:

- name: Authorize User
  include_role:
    name: ssh_authorize_user
  vars:
    ssh_authorize_user_source_user: "{{ git_user }}"
    ssh_authorize_user_source_host: "{{ item[0] }}"
    ssh_authorize_user_target_user: "{{ git_user }}"
    ssh_authorize_user_target_host: "{{ item[1] }}"
  with_nested:
    - "{{ app_server_list }}"
    - "{{ git_server_list }}"

答案 4 :(得分:0)

使用openssh_keypair和authorized_key模块来同时创建和部署密钥,而无需将其保存到您的ansible主机中。

- openssh_keypair:
    group: root
    owner: root
    path: /some/path/in/your/server
    register: ssh_key

- name: Store public key into origin
  delegate_to: central_server_name
  authorized_key:
     key: "{{ssh_key.public_key}}"
     comment: "{{ansible_hostname}}"
     user: any_user_on_central

将在服务器上创建和/或确保SSH密钥将启用SSH与central_server_name的连接。

答案 5 :(得分:0)

我想通过移除 shell 模块并使用 slurp 来贡献这段代码。非常感谢 Jonas Libbrecht 的代码。很有用。

- name: Get ssh keys
  slurp:
    src: /home/nsbl/.ssh/id_ed25519.pub
  register: ssh_keys
  tags:
    - ssh

- name: Check keys
  debug: msg="{{ ssh_keys['content'] | b64decode }}"
  tags:
    - ssh

- name: deploy keys on nodes 1
  authorized_key: 
    user: root 
    key: "{{ item[1]  }}"
  delegate_to: "{{ item[0] }}"
  with_nested:
    - "{{ groups['cluster'] }}"
    - "{{ ssh_keys['content'] | b64decode }}"
  tags:
    - ssh

感谢社区。