playbook 添加具有密码短语的 ssh 密钥并重用 SSH_AUTH_SOCK、SSH_AGENT_PID

问题描述 投票:0回答:2

我想实现什么目标?使用单个 Ansible 剧本,

  1. 如果未运行(在本地主机上),则启动 ssh-agent。
  2. 添加 ssh-key(受密码保护)。
  3. 连接到远程机器来运行任务
    ---
    - name: setup ssh-agent
      hosts: localhost
      gather_facts: false
      vars_files:
        - ../vars.yml
      vars:
        ansible_ssh_private_key_file: "{{ lookup('env', 'HOME') }}/.ssh/{{sshkeyname}}"
        ansible_ssh_pass: "{{sshpassphrs}}"
      tasks:
        - name: Start ssh-agent and Retrieve the SSH_AUTH_SOCK and SSH_AGENT_PID environment variables
          shell: |
              eval $(ssh-agent -s) > /dev/null
              echo '{"SSH_AUTH_SOCK":"'$SSH_AUTH_SOCK'","SSH_AGENT_PID":"'$SSH_AGENT_PID'"}'
          register: env_vars_stdout
        - name: save to env_vars
          set_fact:
            env_vars: "{{ env_vars_stdout.stdout }}"
        - name: add {{ansible_ssh_private_key_file}} to ssh-agent
          environment: "{{ env_vars }}"
          expect:
            command: ssh-add {{ ansible_ssh_private_key_file }}
            responses:
              passphrase: "{{ ansible_ssh_pass }}"
    - name: main jobs
      hosts: all
      gather_facts: false
      environment: "{{ hostvars['localhost']['env_vars'] }}"
      vars_files:
        - ../vars.yml
      vars:
        ansible_user: "{{username}}"
      tasks:
        - name: Do a ping test
          shell: ping -c 20 -w 50 fb.me

它会引发 ping 测试错误,因为无法访问目标主机,并显示消息“无法通过 ssh 连接到主机”。

我知道这是一种相当狡猾的方法,在终端会话中通过 ssh-agent 添加密钥会很简单。但无论如何要实现这个目标吗?

ssh ansible ansible-2.x ssh-agent
2个回答
1
投票

我认为这里的问题是,根据文档,enviroment关键字有助于设置远程环境。即到那时应该已经建立了与远程主机的 SSH 连接。

为了更改用于连接到远程主机的参数,我们需要使用

ansible_ssh_common_args
变量。您可以使用
ssh_config
中的 IdentityAgent 选项来指定 SSH 代理套接字。

我在您的解决方案中添加了一些语句。

 ---
    - name: setup ssh-agent
      hosts: localhost
      gather_facts: false
      vars_files:
        - ../vars.yml
      vars:
        ansible_ssh_private_key_file: "{{ lookup('env', 'HOME') }}/.ssh/{{sshkeyname}}"
        ansible_ssh_pass: "{{sshpassphrs}}"
      tasks:
        - name: Start ssh-agent and Retrieve the SSH_AUTH_SOCK and SSH_AGENT_PID environment variables
          shell: |
              eval $(ssh-agent -s) > /dev/null
              echo '{"SSH_AUTH_SOCK":"'$SSH_AUTH_SOCK'","SSH_AGENT_PID":"'$SSH_AGENT_PID'"}'
          register: env_vars_stdout
        - name: save to env_vars
          set_fact:
            env_vars: "{{ env_vars_stdout.stdout }}"
            ssh_auth_sock: "{{ env_vars_stdout.stdout | from_json | json_query('SSH_AUTH_SOCK') }}" # install jmespath if not already present
        - name: add {{ansible_ssh_private_key_file}} to ssh-agent
          environment: "{{ env_vars }}"
          expect:
            command: ssh-add {{ ansible_ssh_private_key_file }}
            responses:
              passphrase: "{{ ansible_ssh_pass }}"
    - name: main jobs
      hosts: all
      gather_facts: false
      environment: "{{ hostvars['localhost']['env_vars'] }}"
      vars_files:
        - ../vars.yml
      vars:
        ansible_user: "{{username}}"
        ansible_ssh_common_args: "-o 'IdentityAgent={{ hostvars['localhost']['ssh_auth_sock'] }}'"
      tasks:
        - name: Do a ping test
          shell: ping -c 20 -w 50 fb.me

当您运行作业时,我们可以将

-vvv
选项传递给,看看我们的代理在连接到远程主机时实际上正在使用

我在输出中看到了类似下面的内容

<remote.host> SSH: EXEC ssh -C -o IdentityAgent=/var/folders/1s/rwv4vb6n01ld3sxfzqp5svtm0000gn/T//ssh-KGeKsXlC8bGO/agent.14769 -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PasswordAuthentication=no -o 'User="phanirajgoutham"' -o ConnectTimeout=10 remote.host

在连接到远程主机时,您可以看到

IdentityAgent
选项与其他选项一起传递。

如果这对您不起作用,请告诉我。


-1
投票

这必须是公认的答案。拯救了我的一周!

© www.soinside.com 2019 - 2024. All rights reserved.