Ansible for Windows:WinRM HTTPS设置

时间:2017-11-24 14:18:48

标签: python ssl https ansible winrm

我想要对一些Windows主机运行一些Ansible手册。我已经按照各种Ansible指南设置了WinRM并且它们运行良好,但默认设置非常不安全,我想要更多的生产准备。但是,如何执行此操作的说明非常稀疏。到目前为止,我已经完成了以下工作:

在我的Windows框中:

  1. 使用提供的ConfigureRemotingForAnsible.ps1脚本启用WinRM
  2. 配置目标计算机以使用HTTPS / 5986上的有效证书,而不是上述脚本生成的自签名证书
  3. 在WinRM中的目标计算机上启用了Kerberos和CredSSP身份验证方法。我的一些角色步骤要求CredSSP可靠地工作。
  4. 到目前为止,Windows端似乎运行良好。然而,让Ansible连接正在成为一场噩梦。我无法弄清楚如何让Ansible信任目标上的HTTPS证书,尽管添加它。在我的Centos 7'推箱'上,我做了以下工作:

    1. 使用pywinrm,requests_kerberos和requests_credssp modules安装Ansible和pip
    2. 将我的CA证书添加到/ etc / pki / tls / certs和/ etc / pki / ca-cert
    3. 将我的广告资源设置为以下内容:
    4.   

      ansible_user=ADMINISTRATOR@DOMAIN.COM

           

      ansible_password =密码1

           

      ansible_port = 5986

           

      ansible_connection = WinRM的

           

      ansible_winrm_scheme = HTTPS

           

      /#ansible_winrm_server_cert_validation = ignore

           

      ansible_winrm_transport = CredSSP的

      启用认证验证后,连接失败,并显示以下错误:

      fatal: [host.domain.com]: 
      UNREACHABLE! => {
      "changed": false, 
      "msg": "credssp: HTTPSConnectionPool(host='host.domain.com', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(\"bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)\",),))", 
      "unreachable": true}
      

      关闭证书验证后,它可以正常工作。

      所以我的问题是:我如何让Ansible信任我的CA证书?

3 个答案:

答案 0 :(得分:0)

在ansible控制主机上运行:

python -c "import ssl; print(ssl.get_default_verify_paths())"
通过这种方式,您将看到python期望找到证书的位置

确保CA信任证书是pem编码的 问候

答案 1 :(得分:0)

这对我有用。

https://dodgydudes.se/validate-ca-certificate-in-ansible-connecting-with-winrm/

ansible_winrm_ca_trust_path:/ etc / ssl / certs #TLS 1.2

ansible_winrm_transport:ntlm

答案 2 :(得分:0)

这并不简单。问题是有3个不同的小组并不想玩:

  1. Ansible:不想对OpenSSL或Windows详细信息负责
  2. OpenSSL:不想用作证书颁发机构
  3. Microsoft:除了Windows工具外,您不希望使用其他任何工具

首先,您将需要3套OpenSSL证书/密钥:自签名证书颁发机构(CA),服务器winRM HTTPS和目标用户。

CA证书/密钥没有什么神奇之处;它可以通过以下方式生成:

openssl req -new -out caroot.req -keyout caroot.key -days 730 ...
openssl x509 -req -in caroot.req -extensions v3_ca -signkey caroot.key -out cacert.pem -days 730

这些OpenSSL命令还有许多其他选项,这些选项可能(也可能不会)在您的特定环境中起作用。这是“不想对OpenSSL负责”的例子之一。

第二,您将需要WinRM HTTPS证书/密钥。首先,您必须生成服务器证书。生成证书的关键细节是,证书上的“通用名称”属性必须与任何HTTPS证书一样与目标主机名匹配。

openssl req -new -out server.req -keyout server.key -days 730 -nodes ...

现在,这是棘手的部分。您不能按原样签名密钥;签名过程必须向证书添加几个其他属性,否则它将不起作用。创建一个文本文件,我将使用以下两行将其称为“ attributes.txt”:

subjectAltName=DNS:hostname.mycompany.com,DNS:hostname
extendedKeyUsage=serverAuth

第一行'subjectAltName'是必需的,否则Python / OpenSSL客户端将拒绝该密钥。您需要用适当的值替换目标主机名。 Windows需要第二行,否则Windows不会将其用于HTTPS服务器。

现在用先前生成的CA对密钥进行签名:

openssl x509 -req -in server.req -out server.pem -days 730 -CA caroot.pem -CAkey caroot.key -extfile attributes.txt

另一个小问题:Windows不会导入服务器密钥,除非您将密钥和证书组合到PKCS#12文件中。可以使用以下命令来完成此操作,该命令将创建一个没有密码的PKCS#12文件:

openssl pkcs12 -export -password pass: -inkey server.key -in server.pem -out windows.pfx

这将生成一个文件“ windows.pfx”,稍后我们将需要它。

厌倦了吗?

接下来,我们需要另一个密钥/证书来进行用户登录。这是假设我们将在系统上使用本地用户,而不是域用户。 (您自己决定这样做。)生成密钥与服务器密钥几乎相同,只是“通信名称”属性(CN)必须与目标用户名匹配。 (在以后的用法中,我称我们的用户为“可翻译”)。

openssl req -new -out winlogin.req -keyout winlogin.key -days 730

此私钥将用作登录密钥,类似于SSH私钥。接下来,我们必须签署要求。与服务器密钥一样,我们需要添加一些扩展属性,否则它将不起作用。我们的“ attributes.txt”文件必须包含以下几行:

subjectAltName=otherName:1.3.6.1.4.1.311.20.2.3;UTF8:ansible@localhost
extendedKeyUsage=clientAuth

“ altNames”中的奇数标识符是Microsoft专有的东西,必须包含“ 用户名 @localhost”。如前所述,我正在使用本地用户“ ansible”。 ExtendedKeyUsage属性是必需的,否则Windows将不允许将密钥用于用户身份验证。最后,我们签署证书:

openssl x509 -req -in winlogin.req -out winlogin.pem -days 730 -CA caroot.pem -CAkey caroot.key -extfile attributes.txt

就这么知道,我在这里开始发疯。我们快到了。最后,将CA证书(caroot.pem),服务器PKCS#12证书/密钥(windows.pfx)和用户证书(winlogin.pem)复制到目标Windows系统中的某个位置。从同一目录运行以下PowerShell脚本。它将创建本地ansible用户,并将所有SSL工件导入其正确的目标位置。抱歉,这不是商业质量代码。这也为该匿名用户提供了一个硬编码的密码,但这无关紧要,并且可以自由更改。如果此操作确实成功运行,并且您能经受住震惊,则可以从Windows服务器中删除文件工件(PFX和PEM文件)。

还请注意,此脚本在末尾添加了防火墙规则。当然,必须针对您的环境进行适当的修改。

# master script to enable winRM via HTTPS and allow certificate-based 
# authentication

# add the local 'ansible' user
$username = "ansible"
$password = ConvertTo-SecureString -string "Ans!b123" -AsPlainText -Force
New-LocalUser -Name $username -AccountNeverExpires -Description "Ansible Remote Management" -Password $password
Add-LocalGroupMember -Member "ansible" -Group "Administrators"
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password

# import the Ansible root CA; certlm should show this in the 
# 'Trusted Root Certification Authorities' folder
$caroot = Import-Certificate -FilePath ".\caroot.pem" -CertStoreLocation "Cert:\LocalMachine\Root"

# import the user cert; certlm should show this in the 'Trusted People' folder
$userkey = Import-Certificate -FilePath ".\winlogin.pem" -CertStoreLocation "Cert:\LocalMachine\TrustedPeople"
New-Item -Path WSMan:\localhost\ClientCertificate -subject "ansible@localhost" -URI "*" -Issuer $caroot.Thumbprint -Credential $credential -Force

# import the server certs - should appear in 'Personal' folder. The PFX file
# must contain both the cert and private key
$srvcert = Get-ChildItem -Path ".\windows.pfx" | Import-PFXCertificate -CertStoreLocation "Cert:\LocalMachine\MY" -Exportable

# Now create the winRM instance
$selector_set = @{Address= "*" Transport = "HTTPS" }

$value_set =  @{CertificateThumbprint = $srvcert.Thumbprint}

New-WSManInstance -ResourceURI "winrm/config/Listener" -SelectorSet $selector_set -ValueSet $value_set
Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -value $true

# add a firewall rule
New-NetFirewallRule -DisplayName "Ansible WinRM" -Direction Inbound -Protocol "TCP" -LocalPort "5986" -Action Allow -RemoteAddress @("192.16.2.3")

好的,现在Windows已经完成,我们应该为Ansible做好准备了。在您的清单中,您将需要以下变量才能应用于Windows系统:

ansible_port: 5986
ansible_connection: winrm
ansible_winrm_ca_trust_path: /path/to/caroot.pem
ansible_winrm_transport: certficate
ansible_winrm_cert_pem: /path/to/winlogin.pem
ansible_winrm_cert_key_pem: /path/to/winlogin.key

此时,Ansible应该使用HTTPS和证书身份验证连接到Windows服务器。我希望我能完成所有步骤,这是前一段时间我设置的。