You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含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:

  1. 在控制机安装sshuttle:
    pip install sshuttle  # 也可用系统包管理器,比如apt install sshuttle
    
  2. 运行sshuttle转发目标网段的SNMP流量(假设目标设备网段是192.168.100.0/24,跳板机用户为jump_user、地址为jump_host):
    sshuttle -r jump_user@jump_host 192.168.100.0/24
    
  3. 保持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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 08:08:16