美文网首页
Ansible Certificate认证

Ansible Certificate认证

作者: A二十一画 | 来源:发表于2023-05-30 13:48 被阅读0次

    Ansible Certificate认证

    Ansible在对Windows主机控制时,不同于Linux主机通过SSH协议进行密码和秘钥认证,在对Windows主机进行控制时最常见的使用Windows用户名和密码通过NTLM进行认证,但是在需求环境中,当平台将Windows主机分配给用户之后,会出现用户自行修改密码的情况。

    为了避免这种情况,可以通过Certificate证书认证,在《Ansible官方文档》中提供了以下五种认证方式

    202305311017355.png

    此文档只描述通过Certificate进行认证。

    需要注意的是Certificate并不能通过域用户进行认证,如果通过域用户可使用NTLM或者Kerberos进行认证。

    环境要求

    Windows主机
    -- Powershell >= 3.0
    -- .NET >= 4.0
    -- 激活WinRM服务

    Ansible主机
    -- 安装Ansible
    -- 安装pywinrm模块

    开启WinRM基于证书认证

    Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true
    

    创建本地用户账户

    相关的ps1脚本可以使用Windows PowerShell ISE进行编辑运行

    使用基于证书认证的WinRM,需要将证书映射到本地用户上,可以直接映射到本地用户上,但是需求环境每个主机本地用户是不经相同,所以最好是创建一个特定的用户用于Ansible管理。

    以下脚本可以创建一个名为ansibleuser的本地用户账户,并设置其密码为An@passw0rd,始终处于活跃状态密码不过期。

    $UserAccountName = 'ansibleuser'
    $UserAccountPassword = (ConvertTo-SecureString -String 'An@passw0rd' -AsPlainText -Force)
    if (-not (Get-LocalUser -Name $UserAccountName -ErrorAction Ignore)) {
        $newUserParams = @{
            Name                 = $UserAccountName
            AccountNeverExpires  = $true
            PasswordNeverExpires = $true
            Password             = $UserAccountPassword
        }
        $null = New-LocalUser @newUserParams
    }
    

    创建证书

    创建证书可以通过以下两种方式进行生成
    1、在使用Openssl进行生成
    2、在PowerShell使用New-SelfSignedCertificate进行生成

    Openssl生成证书

    在一台安装了Openssl的Linux主机上创建以下Shell脚本

    ## This is the public key generated from the Ansible server using:
    cat > openssl.conf << EOL
    distinguished_name = req_distinguished_name
    [req_distinguished_name]
    [v3_req_client]
    extendedKeyUsage = clientAuth
    subjectAltName = otherName:1.3.6.1.4.1.311.20.2.3;UTF8:ansibletestuser@localhost
    EOL
    export OPENSSL_CONF=openssl.conf
    openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -out cert.pem -outform PEM -keyout cert_key.pem -subj "/CN=ansibleuser" -extensions v3_req_client
    rm openssl.conf 
    

    然后执行此脚本,在脚本所在目录会生成一对公/密钥(cert_key.pem/cert.pem)

    New-SelfSignedCertificate生成证书

    $username = "ansibleuser"
    $output_path = "C:\temp"
    
    # Instead of generating a file, the cert will be added to the personal
    # LocalComputer folder in the certificate store
    $cert = New-SelfSignedCertificate -Type Custom `
        -Subject "CN=$username" `
        -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2","2.5.29.17={text}upn=$username@localhost") `
        -KeyUsage DigitalSignature,KeyEncipherment `
        -KeyAlgorithm RSA `
        -KeyLength 2048
    
    # Export the public key
    $pem_output = @()
    $pem_output += "-----BEGIN CERTIFICATE-----"
    $pem_output += [System.Convert]::ToBase64String($cert.RawData) -replace ".{64}", "$&`n"
    $pem_output += "-----END CERTIFICATE-----"
    [System.IO.File]::WriteAllLines("$output_path\cert.pem", $pem_output)
    
    # Export the private key in a PFX file
    [System.IO.File]::WriteAllBytes("$output_path\cert.pfx", $cert.Export("Pfx"))
    

    会在C:\temp下生成秘钥对,但是生成的秘钥是pfx格式的,所以需要Anisble在使用的时候需要通过Openssl使用以下命令进行转化为.pem,其中passin/passout为创建证书时使用密码,但是以上脚本中为加密,所以密码为空。

    openssl pkcs12 -in cert.pfx -nocerts -nodes -out cert_key.pem -passin pass: -passout pass:
    

    导入证书

    生成证书之后[若是使用Openssl生成,将其公钥上传到Windows的C盘],需要使用以下命令将其证书导入到受信任的根证书颁发机构和受信任的人证书存储区

    $pubKeyFilePath = 'C:\cert.pem'
    
    $null = Import-Certificate -FilePath $pubKeyFilePath -CertStoreLocation 'Cert:\LocalMachine\Root'
    $null = Import-Certificate -FilePath $pubKeyFilePath -CertStoreLocation 'Cert:\LocalMachine\TrustedPeople'
    

    创建服务器证书

    使用以下命令将创建自签证书存储到LocalMachine\My

    $hostname = hostname
    $serverCert = New-SelfSignedCertificate -DnsName $hostName -CertStoreLocation 'Cert:\LocalMachine\My'
    

    证书映射本地用户

    将证书映射到本地用户,是为了确保当Ansible通过证书连接到windows主机时,它将以本地用户身份执行所有指令,这样可以使用Ansible连接windows进行执行命令是都是通过ansibleuser用户进行操作

    $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserAccountName, $UserAccountPassword
    
    $ansibleCert = Get-ChildItem -Path 'Cert:\LocalMachine\Root' | Where-Object {$_.Subject -eq 'CN=ansibleuser'}
    
    $params = @{
        Path = 'WSMan:\localhost\ClientCertificate'
        Subject = "$UserAccountName@localhost"
        URI = '*'
        Issuer = $ansibleCert.Thumbprint
      Credential = $credential
        Force = $true
    }
    New-Item @params
    

    设置LocalAccountTokenFilterPolicy

    LocalAccountTokenFilterPolicy是用于控制过滤本地管理员组中所有本地用户的远程连接访问令牌的策略。当此参数设置为1时,则策略允许使用明文凭据或密码哈希,从本地管理员组的任何成员获得高完整性访问令牌的远程连接。

    $newItemParams = @{
        Path         = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
        Name         = 'LocalAccountTokenFilterPolicy'
        Value        = 1
        PropertyType = 'DWORD'
        Force        = $true
    }
    $null = New-ItemProperty @newItemParams
    

    将本地用户账户加入到管理员组

    Get-LocalUser -Name $UserAccountName | Add-LocalGroupMember -Group 'Administrators'
    

    至此全部的配置完成,在Ansible的hosts文件中配置以下内容,测试是否可正常使用

    ansible_connection: winrm
    ansible_winrm_cert_pem: /path/to/certificate/public/cert.pem
    ansible_winrm_cert_key_pem: /path/to/certificate/private/cert_key.pem
    ansible_winrm_transport: certificate
    

    相关文章

      网友评论

          本文标题:Ansible Certificate认证

          本文链接:https://www.haomeiwen.com/subject/bgteedtx.html