含connection: local指令时,如何让Ansible使用SSH跳板机?
当设置
connection: local时让Ansible通过SSH跳板机访问SNMP设备的方案 核心问题原因
当你设置connection: local时,所有任务都会在控制机本地执行。community.general.snmp_facts模块会直接从控制机向目标设备发送SNMP请求,而如果目标设备只能通过SSH跳板机访问,控制机和目标设备之间没有直接网络通路,自然无法通信。其他能正常工作的模块,大概率是通过SSH连接到跳板机再执行操作(比如利用ansible_ssh_common_args配置跳板),和SNMP模块的工作方式本质不同。
解决方案
方法1:使用sshuttle做全局流量转发
sshuttle可以把控制机的指定流量通过SSH跳板机转发,相当于搭建临时VPN:
- 在控制机安装sshuttle:
pip install sshuttle # 也可用系统包管理器,比如apt install sshuttle - 运行sshuttle转发目标网段的SNMP流量(假设目标设备网段是
192.168.100.0/24,跳板机用户为jump_user、地址为jump_host):sshuttle -r jump_user@jump_host 192.168.100.0/24 - 保持sshuttle会话运行,直接执行原Ansible playbook即可,无需修改playbook内容。
方法2:动态建立SSH端口转发
通过Ansible先建立本地端口到目标设备SNMP端口(默认161)的转发,再让snmp_facts模块访问本地转发端口:
修改playbook如下:
- name: snmp hosts: all gather_facts: false connection: local serial: 1 tasks: - name: 建立SSH端口转发到目标设备SNMP端口 command: > ssh -f -N -L {{ 10000 + inventory_hostname | hash('md5') | int(base=16) % 1000 }}:{{ inventory_hostname }}:161 jump_user@jump_host args: creates: /tmp/ssh_snmp_{{ inventory_hostname }}.lock register: port_forward vars: # 生成唯一本地端口避免冲突 local_snmp_port: "{{ 10000 + inventory_hostname | hash('md5') | int(base=16) % 1000 }}" - name: 生成端口转发锁文件 file: path: /tmp/ssh_snmp_{{ inventory_hostname }}.lock state: touch when: port_forward.changed - name: 通过转发端口获取SNMP facts community.general.snmp_facts: host: localhost port: "{{ local_snmp_port }}" version: v2c community: public vars: ansible_python_interpreter: /var/local/meteor/ansible/.venv/bin/python local_snmp_port: "{{ 10000 + inventory_hostname | hash('md5') | int(base=16) % 1000 }}" - name: 清理端口转发进程 command: pkill -f "ssh -f -N -L {{ local_snmp_port }}:{{ inventory_hostname }}:161" args: removes: /tmp/ssh_snmp_{{ inventory_hostname }}.lock register: kill_forward ignore_errors: true vars: local_snmp_port: "{{ 10000 + inventory_hostname | hash('md5') | int(base=16) % 1000 }}" - name: 删除锁文件 file: path: /tmp/ssh_snmp_{{ inventory_hostname }}.lock state: absent when: kill_forward.changed
方法3:在跳板机上执行SNMP请求
放弃connection: local,改为让任务在跳板机上执行,SNMP请求从跳板机发出,天然能访问目标设备:
修改playbook配置如下:
- name: snmp hosts: all gather_facts: false connection: ssh # 配置通过跳板机连接目标设备 ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p jump_user@jump_host"' serial: 1 tasks: - name: Gather facts with SNMP version 2 community.general.snmp_facts: host: '{{ inventory_hostname }}' version: v2c community: public vars: ansible_python_interpreter: /var/local/meteor/ansible/.venv/bin/python
注意:需要跳板机提前安装SNMP相关依赖(比如
python3-pysnmp),且跳板机能访问目标设备的SNMP端口。
内容的提问来源于stack exchange,提问作者rogeriojlle
相关产品推荐
相关产品推荐

