方法一:命令行模式
使用 Ansible 时,如何配置,可以直接穿过跳板机到内网地址呢?
基本原来都是源自于ssh命令,好好读懂ssh ProxyCommand 问题迎刃而解。
大致的过程如下面的图示:
+-------------+ +----------+ +--------------+
| 开发环境机器A | <---> | 跳板机B | <--> | 生产环境机器B |
+-------------+ +----------+ +--------------+
我们可以通过 ssh 命令的 ProxyCommand 选项来解决以上问题。
通过 ProxyCommand 选项,机器 A 能够灵活使用任意代理机制与机器 C 上的 SSH Server 端口建立连接,接着机器 A 上的 SSH Client 再与该连接进行数据交互,从而机器 A 上的 SSH Client 与机器 C 上的 SSH Server 之间建立了与一般直接 SSH 连接不太一样的间接 SSH 连接。
不过由于间接 SSH 连接的透明性,逻辑上可认为机器 A 上的 SSH Client 与机器 C 上的 SSH Server 建立了直接 SSH 连接。
![](https://i-blog.csdnimg.cn/blog_migrate/0c67327b9710e7982111482a19938ea5.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2e852f1a4f53c6ae083aa99d153c7f99.png)
原理
ssh 命令自提供的代理机制,在机器 A 上另外单独建立与 B 的 SSH 连接,该 SSH 连接的 B 端侧与机器 C 上的 SSH Server 端口建立连接,该 SSH 连接的 A 端侧与机器 A 上的 SSH Client建立连接。
测试环境
A-本机:192.22.9.23
B-跳板机:192.22.9.21
C-目标机:192.22.4.46
条件:A->B的互信
测试步骤
测试 1
A–>B:root 用户的互信
C:root 的登录信息
# ansible all -m ping --ssh-common-args='-o ProxyCommand="ssh -W %h:%p -q root@192.22.9.21"'
192.22.4.46 | SUCCESS => {
"changed": false,
"ping": "pong"
}
可以成功穿过跳板机。
测试 2
A–>B:一般用户(luke)的互信
C:root 的登录信息
# ansible all -m ping --ssh-common-args='-o ProxyCommand="ssh -W %h:%p -q luke@192.22.9.21"'
192.22.4.46 | SUCCESS => {
"changed": false,
"ping": "pong"
}
跳板机普通用户,访问目标机器的 root 目录
# ansible all --ssh-common-args='-o ProxyCommand="ssh -W %h:%p -q luke@192.22.9.21"' -m command -a 'ls /root/'
192.22.4.46 | CHANGED | rc=0 >>
1115.txt
anaconda-ks.cfg
deploytelegraf
deploytelegraf.tar.gz
epic-brook.18.11.20.01.tar.gz
epic-josh-threshold.0.1.26.tar.gz
images.tar.gz
metric.tar.gz
python-httplib2-0.9.2-1.el7.noarch.rpm
restates
sensu-1.6.1-1.el7.x86_64.rpm
sshpass-1.06-2.el7.x86_64.rpm
test1115.txt
tl.txt
结论
访问权限取决于目标机器的登录用户。
测试 3
A–>B:一般用户(luke)的互信
C:一般用户(luke)的登录信息
# ansible all -m ping --ssh-common-args='-o ProxyCommand="ssh -W %h:%p -q luke@192.22.9.21"'
192.22.4.46 | SUCCESS => {
"changed": false,
"ping": "pong"
}
# ansible all --ssh-common-args='-o ProxyCommand="ssh -W %h:%p -q luke@192.22.9.21"' -m command -a 'pwd'
192.22.4.46 | CHANGED | rc=0 >>
/home/luke
跳板机普通用户,目标机普通用户,无法访问 root
# ansible all --ssh-common-args='-o ProxyCommand="ssh -W %h:%p -q luke@192.22.9.21"' -m command -a 'ls /root/'
192.22.4.46 | FAILED | rc=2 >>
ls: cannot open directory /root/: Permission deniednon-zero return code
目标机器的普通用户无法访问 root 权限的路径。
测试 4
A–>B:root 用户的互信
C:luke 的登录信息
# ansible all --ssh-common-args='-o ProxyCommand="ssh -W %h:%p -q root@192.22.9.21"' -m command -a 'pwd'
192.22.4.46 | CHANGED | rc=0 >>
/home/luke
总结
1、若要使用跳板机功能,需要本机和跳板机的互信,任一用户的互信都可以。
2、目标机器的操作权限,取决于目标机器的登录用户信息,与跳板机的登录信息无关。
3、穿过跳板机,无法保证所有的 Ansible 功能都支持,特别是一些复杂的功能,如 synchronize 模块。后续需要用的模块需要一一测试。
方法二:更改ansible.cfg模式
创建/etc/ansible/ansible-bastion.cfg,然后改变ssh_args control_path 默认参数
# cat /etc/ansible/ansible-bastion.cfg
# diff ansible.cfg ansible-bastion.cfg
375a376,377
> ssh_args = -F /etc/ansible/ssh.cfg #ssh_args 参数更新
> #ssh_args = -F /root/.ssh/config.bak
382a385
> control_path = ~/.ssh/mux-%r@%h:%p # control_path参数更新
创建/etc/ansible/ssh.cfg
# 创建/etc/ansible/ssh.cfg
Host 118.178.xxx.xxx
HostName 118.178.xxx.xxx
ProxyCommand none
BatchMode yes
User root
Host 172.16.*
ProxyCommand ssh 118.178.xxx.xxx -W %h:%p
ControlPath /tmp/%r@%h:%p
Host *
StrictHostKeyChecking no
ControlMaster auto
ControlPath /tmp/%r@%h:%p
ControlPersist 15m
改变ansible 默认读取的变量文件
export ANSIBLE_CONFIG=/etc/ansible/ansible-bastion.cfg
编辑 hosts2 文件
# cat hosts2
[bastion]
118.178.xxx.xxx
[app_servers]
172.16.0.125
172.16.0.121
运行ping 模块测试一下
ansible app_servers -i hosts2 -m ping -v -u root
# ansible app_servers -i hosts2 -m ping -v -u root
Using /etc/ansible/ansible-bastion.cfg as config file
172.16.0.125 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
172.16.0.121 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
参考:ansible-jump-server.htmlansible-bastion-host-proxycommand-e6946c945d30