天行健,君子以自强不息;地势坤,君子以厚德载物;

Ansible通过SSH堡垒机管理隔离内网Windows/Linux主机

随VPC网络的使用及自动化运维管理的需求,需要通过堡垒主机连接管理VPC主机。在本文的上下文中,堡垒主机是“放置在内部网络边界上的服务器,并提供从另一个外部网络对该网络的访问”。

《Ansible通过SSH堡垒机管理隔离内网Windows/Linux主机》

由于堡垒主机提供对内部网络的访问,因此必须格外小心,以使该主机免受恶意行为者的侵害。这篇文章的范围不是讨论该主机的加固,而是如何配置Ansible在这样的环境中管理VPC主机。

Ansible对可以直接访问的Windows/Linux主机的管理,可用相关模块直接操作,故不再介绍。

协议

这种情况下使用的主要两个协议是SOCKS和SSH,它们是众所周知的并且很容易理解,因此不再重述。

Linux系统主机

对于使用SSH协议的Linux主机,Ansible是原生态的支持,通过Ansible的SSH参数和SSH的代理命令,可以直接实现:

ansible {Private_Host} -m ping --ssh-common-args='-o ProxyCommand="ssh -v -W %h:%p -i {Bastion_Host_Key} -p {Bastion_Host_Port} {Bastion_Host_User}@{Bastion_Host}"' -u {Private_Host_User} -k

## 相关变量替换为具体值即可

Windows系统主机

当我们谈论代理时,通常会想到一个标准的HTTP代理,它可以将HTTP请求从客户端转发到该代理可以访问的另一台服务器。由于WinRM是HTTP协议,因此我们仍然可以使用HTTP代理路由到Windows主机,但是本指南是关于通过堡垒主机使用SSH的,因此它将忽略HTTP代理。SOCKS代表SOCKet Secure,最新标准是SOCKS5,它将在本指南中使用。

SOCKS协议不会在传输过程中加密或更改您的数据,而是将其与其他协议(例如SSH)一起使用,我们可以确保公共接口上的所有流量都被加密。

一个看起来很基本的概要是:

《Ansible通过SSH堡垒机管理隔离内网Windows/Linux主机》

不同于简单的Ansible通过WinRM直接连接Windows主机,此方案具有多个网络边界,我们需要注意这些边界。这些边界包括:

  • Ansible到SOCKS侦听器
    • SOCKS侦听器端口取决于配置,-D <port>
    • 此数据包含封装在SOCKS数据包中的WinRM有效负载,加密取决于WinRM / HTTP协议
    • 在此演示中,所有这些都在回送接口上运行,但是如果需要,SOCKS / SSH客户端也可以在另一台主机上
  • SOCKS侦听器到SSH客户端
    • 由SSH服务控制的内部通道
  • SSH通道(Ansible主机到堡垒机)
    • SSH流量的发送基于不安全的连接(例如互联网)
    • 所有数据均使用SSH协议加密,并被视为正常的SSH流量
    • 通常,这是通过端口22完成的,但是可以由用户指定
    • 在此演示中,这是通过环回接口上的端口22发送的数据
  • SSH服务器到WinRM侦听器(堡垒机到Windows主机)
    • 堡垒主机充当Ansible控制器,并将WinRM通信发送到Windows主机
    • 对于WinRM,这将通过端口5985(http)或5986(https)完成,但是可以由用户指定
    • WinRM服务将bation主机视为源,并且不了解其背后的SSH / SOCKS实现

Windows主机的所有响应都通过相同的通道发送回去,并且所有内容对于Ansible控制器都是透明的。

PSRP/WinRM

psrp – Run tasks over Microsoft PowerShell Remoting Protocol

winrm – Run tasks over Microsoft’s WinRM

基本上,WinRM是HTTP协议,并使用基于SOAP的API在客户端和服务器之间进行通信。虽然可以并且应该将加密与HTTPS或具有AES256加密的Kerberos一起使用,但是与SSH相比,它的设置和使用并不简单。Windows确实提供了OpenSSH的Win32端口,您现在可以使用它,但是它仍然存在很多问题,并且目前在Ansible中不兼容。

使用PSRP而不使用WinRM的主要原因,是PSRP支持代理配置,而WinRM不支持!

要求

  • Ansible v2.7+
  • pywinrm
  • pypsrp
  • pysocks
pip install ansible pywinrm pypsrp pysocks

配置 SSH 代理

在Ansible管理机上运行

ssh -qfTnNC -o "ControlMaster=auto" -o "ControlPersist=no" -o "StrictHostKeyChecking=no" -i {Bastion_Host_Key} -D 127.0.0.1:7070 -p {Bastion_Host_Port} {Bastion_Host_User}@{Bastion_Host}

## 将相关变量替换为具体值
## SSH相关参数请参考手册
## SSH 代理的可用性监控不在此讨论,可以使用supervisord实现

创建SOCKS代理不仅限于OpenSSH,还有各种可以实现此目标的应用程序。本指南选择了OpenSSH,因为它在使用Ansible方面相当通用。

Ansible连接

设置代理后,最后一步是创建Ansible清单,该清单将使用SSH代理与Windows主机通信。清单的设置方式类似于Ansible直接连接到Windows主机,但添加了ansible_psrp_proxy变量,该变量指向我们的SSH代理服务器。

对于此演示,创建一个包含以下内容的文件 - inventory.ini :

[win]
windows-server
[win:vars]
ansible_ssh_port: '5986'
ansible_connection: 'psrp'
ansible_psrp_protocol: 'https'
ansible_psrp_auth: 'ntlm'
ansible_psrp_cert_validation: 'ignore'
ansible_psrp_proxy: socks5://127.0.0.1:7070

我们将尝试使用新的psrp插件,而不是使用典型的winrm连接插件,该插件提供了一个变量,该变量可以定义供Ansible使用的代理。这也可以使用winrm连接插件来完成,但需要设置全局环境变量,如果每个主机的代理要求不同,则情况会更加混乱。分解代理变量,我们可以看到它分为3部分:<scheme>://<hostname>:<port>;

scheme:设置为socks5或socks5h,前者表示DNS解析是在客户端上完成的,而后者表示解析是在堡垒主机上进行的。

如果您的SOCKS代理服务器需要用户身份验证,则将指定凭据,例如socks5://user:pass@host:port

简单运行ansible命令观察运行状态

ansible -i inventory.ini win -m win_ping -u {Windows_Host_User} -k
## For AD User
ansible -i inventory.ini win -m win_ping -u {Windows_Host_User}@{Domain} -k

## 将相关变量替换为具体值
## 查看详细状态请用 -vvvv 参数

现在我们可以通过堡垒主机成功将Ansible连接到我们的VPC Windows主机,您可以轻松地看到Ansible正常运行,除了设置了proxy变量。我希望将实际的SOCKS / SSH代理设置为Ansible的一部分,以摆脱该手动操作,这将是一个很好的功能。

点赞

发表评论