Это непросто. Проблема в том, что есть 3 разные группы, которые на самом деле не хотят играть:
- Ansible: не хочет нести ответственность за детали OpenSSL или Windows
- OpenSSL: не хочет использоваться в качестве центра сертификации
- 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, который нам понадобится позже.
Еще не скучно?
Далее нам понадобится еще один ключ / сертификат для входа пользователя. Предполагается, что мы будем использовать локального пользователя в системе, а не пользователя домена. (Вы сами по себе.) Генерация ключа почти такая же, как и для ключа сервера, за исключением того, что атрибут 'commom name' (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 из того же каталога. Он создаст локального доступного пользователя и импортирует все артефакты SSL в их надлежащие целевые местоположения. Извините, если это не коммерческий код. Здесь также есть жестко запрограммированный пароль для доступного пользователя, но он не имеет значения и может быть свободно изменен. Если это действительно работает успешно и вы переживете шок, файловые артефакты (файлы PFX и PEM) можно удалить с сервера Windows.
Также обратите внимание, что этот сценарий добавляет в конце правило брандмауэра. Это, конечно, нужно будет соответствующим образом изменить для вашей среды.
# 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 должен подключиться к серверу Windows, используя HTTPS и проверку подлинности сертификата. Надеюсь, я выполнил все шаги, это было довольно давно.
person
CrankyElderGod
schedule
16.12.2020