英文:
playbook to add ssh-key having passphrase and reuse SSH_AUTH_SOCK, SSH_AGENT_PID
问题
Sure, here is the translated content:
我想要实现什么?使用单个 Ansible playbook,
1. 如果尚未运行,请启动 ssh-agent(在本地主机上)。
2. 添加带有密码保护的 ssh 密钥。
3. 连接到远程机器运行任务
---
- name: 设置 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: 启动 ssh-agent 并获取 SSH_AUTH_SOCK 和 SSH_AGENT_PID 环境变量
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: 保存到 env_vars
set_fact:
env_vars: "{{ env_vars_stdout.stdout }}"
- name: 添加 {{ansible_ssh_private_key_file}} 到 ssh-agent
environment: "{{ env_vars }}"
expect:
command: ssh-add {{ ansible_ssh_private_key_file }}
responses:
passphrase: "{{ ansible_ssh_pass }}"
- name: 主要任务
hosts: all
gather_facts: false
environment: "{{ hostvars['localhost']['env_vars'] }}"
vars_files:
- ../vars.yml
vars:
ansible_user: "{{username}}"
tasks:
- name: 进行 ping 测试
shell: ping -c 20 -w 50 fb.me
请注意,翻译的内容只包括 Ansible playbook 的部分,不包括问题的回答部分。
英文:
What do I want to achieve? Using a single Ansible playbook,
- start ssh-agent if not running (on localhost).
- add ssh-key (that is passphrase protected).
- connect to remote machines to run tasks
---
- 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
It throws an error for the ping test, as destination hosts are unreachable with msg "Failed to connect to the host via ssh".
I know this is quite a hacky way, adding the key through ssh-agent in the terminal session would have been straightforward. But anyway to achieve this?
答案1
得分: 1
以下是您提供的内容的翻译:
我认为这里的问题在于,根据文档,enviroment关键字有助于设置远程环境。也就是说,到那时应该已经建立了到远程主机的SSH连接。
为了更改用于连接到remote_host的参数,我们需要使用ansible_ssh_common_args
变量。您可以在ssh_config中使用IdentityAgent
选项来指定SSH代理套接字。
我已经向您的解决方案添加了一些语句。
---
- name: 设置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: 启动ssh-agent并检索SSH_AUTH_SOCK和SSH_AGENT_PID环境变量
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: 保存到env_vars
set_fact:
env_vars: "{{ env_vars_stdout.stdout }}"
ssh_auth_sock: "{{ env_vars_stdout.stdout | from_json | json_query('SSH_AUTH_SOCK') }}" # 安装jmespath如果尚未安装
- name: 将{{ansible_ssh_private_key_file}}添加到ssh-agent
environment: "{{ env_vars }}"
expect:
command: ssh-add {{ ansible_ssh_private_key_file }}
responses:
passphrase: "{{ ansible_ssh_pass }}"
- name: 主要工作
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: 进行ping测试
shell: ping -c 20 -w 50 fb.me
当您运行作业时,我们可以传递-vvv
选项,以查看我们的代理是否确实在与remote_host建立连接时使用。
我在输出中看到了类似以下内容:
<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
您可以看到在与remote_host建立连接时传递了IdentityAgent
选项以及其他选项。
如果这对您有帮助,请告诉我。 1: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_environment.html 2: https://man7.org/linux/man-pages/man5/ssh_config.5.html
英文:
I think the issue here is that, the enviroment keyword, as per the doc, helps in setting the remote environment. i.e. by then the SSH connection to the remote host should have been made.
In order to change the arguments, which are used to connect to the remote_host, we need to use the ansible_ssh_common_args
variable. You can use the IdentityAgent
option, in the ssh_config, to specify the SSH Agent socket.
I have added a couple of statements to your solution.
---
- 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
When you run the job, we can pass the -vvv
option to, see that, our agent is actually being used when making a connection to the remote_host
I saw something like below, in the output
<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
You could see the IdentityAgent
option being passed along with the other options, when making a connection to the remote_host.
Please let me know if this does not work for you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论