Удаленное управление Windows
В отличие от узлов Linux/Unix, которые по умолчанию используют SSH, узлы Windows настроены для работы с WinRM. В этом разделе описано, как настроить и использовать WinRM с Ansible.
- Что такое WinRM?
- Учетные записи без прав администратора
- Шифрование WinRM
- Проверка сертификата HTTPS
- Ограничения WinRM
- Устранение неполадок WinRM
Что такое WinRM?
WinRM — это протокол управления, используемый Windows для удаленного взаимодействия с другим сервером. Это протокол на основе SOAP, который использует HTTP/HTTPS и включен во все современные операционные системы Windows. Начиная с Windows Server 2012 WinRM включен по умолчанию, однако в некоторых случаях для использования WinRM с Ansible требуется дополнительная настройка.
Ansible может использовать WinRM через плагины подключения psrp или winrm. Для этих плагинов требуются собственные зависимости Python, которые не входят в пакет Ansible и должны устанавливаться отдельно.
Если вы выбрали инструкции по установке pipx, эти зависимости можно установить, выполнив следующую команду:
pipx inject ansible "pypsrp<=1.0.0" # for psrp pipx inject ansible "pywinrm>=0.4.0" # for winrm
Или, если вы выбрали инструкции по установке pip:
pip3 install "pypsrp<=1.0.0" # for psrp pip3 install "pywinrm>=0.4.0" # for winrm
Предупреждение
Использование плагинов подключения winrm или psrp в Ansible на MacOS в последних выпусках обычно приводит к сбою. Это известная проблема, возникающая глубоко в стеке Python, и Ansible не может ее исправить. На данный момент единственный обходной путь — задать переменную среды OBJC_DISABLE_INITIALIZE_FORK_SAFETY=yes, no_proxy=* и не использовать аутентификацию Kerberos.
Настройка WinRM
Прежде чем Ansible сможет подключиться через WinRM, на узле Windows должен быть настроен прослушиватель WinRM. Этот прослушиватель будет ожидать подключения на настроенном порту и принимать входящие запросы WinRM.
В этом руководстве подробно описано, как просматривать, добавлять и удалять прослушиватели. Чтобы настроить прослушиватель HTTP с параметрами по умолчанию, можно выполнить следующий фрагмент PowerShell:
# Enables the WinRM service and sets up the HTTP listener
Enable-PSRemoting -Force
# Opens port 5985 for all profiles
$firewallParams = @{
Action = 'Allow'
Description = 'Inbound rule for Windows Remote Management via WS-Management. [TCP 5985]'
Direction = 'Inbound'
DisplayName = 'Windows Remote Management (HTTP-In)'
LocalPort = 5985
Profile = 'Any'
Protocol = 'TCP'
}
New-NetFirewallRule @firewallParams
# Allows local user accounts to be used with WinRM
# This can be ignored if using domain accounts
$tokenFilterParams = @{
Path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
Name = 'LocalAccountTokenFilterPolicy'
Value = 1
PropertyType = 'DWORD'
Force = $true
}
New-ItemProperty @tokenFilterParams
Чтобы также добавить прослушиватель HTTPS с самоподписанным сертификатом, выполните следующую команду:
# Create self signed certificate
$certParams = @{
CertStoreLocation = 'Cert:\LocalMachine\My'
DnsName = $env:COMPUTERNAME
NotAfter = (Get-Date).AddYears(1)
Provider = 'Microsoft Software Key Storage Provider'
Subject = "CN=$env:COMPUTERNAME"
}
$cert = New-SelfSignedCertificate @certParams
# Create HTTPS listener
$httpsParams = @{
Path = 'WSMan:\localhost\Listener'
Address = '*'
CertificateThumbprint = $cert.Thumbprint
Enabled = $true
Port = 5986
Transport = 'HTTPS'
Force = $true
}
New-Item @httpsParams
# Opens port 5986 for all profiles
$firewallParams = @{
Action = 'Allow'
Description = 'Inbound rule for Windows Remote Management via WS-Management. [TCP 5986]'
Direction = 'Inbound'
DisplayName = 'Windows Remote Management (HTTPS-In)'
LocalPort = 5986
Profile = 'Any'
Protocol = 'TCP'
}
New-NetFirewallRule @firewallParams
Предупреждение
Приведенные выше сценарии предназначены только для демонстрации, и перед выполнением в рабочей среде их следует проверить. Некоторые изменения, например открытие порта брандмауэра для всех входящих подключений, разрешение использования локальных учетных записей с WinRM и применение самоподписанных сертификатов, могут быть неприемлемы для отдельных сред.
Просмотр прослушивателей
Чтобы просмотреть текущие прослушиватели, работающие в службе WinRM:
winrm enumerate winrm/config/Listener
Будет выведено примерно следующее:
Listener
Address = *
Transport = HTTP
Port = 5985
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0.2.15%6, fe80::5efe:192.168.56.155%8, fe80::
ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7
Listener
Address = *
Transport = HTTPS
Port = 5986
Hostname = SERVER2016
Enabled = true
URLPrefix = wsman
CertificateThumbprint = E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE
ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0.2.15%6, fe80::5efe:192.168.56.155%8, fe80::
ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7
В приведенном выше примере настроены два прослушивателя WinRM. Один прослушивает порт 5985 по HTTP, другой — порт 5986 по HTTPS. Ниже приведены некоторые важные параметры, которые полезно понимать:
-
Transport: указывает, работает ли прослушиватель по HTTP или HTTPS -
Port: порт, который прослушивается; по умолчанию для HTTP используется5985, а для HTTPS —5986 -
CertificateThumbprint: для HTTPS это отпечаток сертификата, используемого для подключения TLS
Чтобы просмотреть сведения о сертификате, указанном в CertificateThumbprint, можно выполнить следующую команду PowerShell:
$thumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" Get-Item -Path "Cert:\LocalMachine\My\$thumbprint" | Select-Object *
Создание прослушивателя
Прослушиватель HTTP можно создать с помощью командлета Enable-PSRemoting, но для создания прослушивателя HTTP вручную можно также воспользоваться следующим кодом PowerShell.
$listenerParams = @{
Path = 'WSMan:\localhost\Listener'
Address = '*'
Enabled = $true
Port = 5985
Transport = 'HTTP'
Force = $true
}
New-Item @listenerParams
Создание прослушивателя HTTPS выполняется аналогично, но теперь Port равен 5986, а значение CertificateThumbprint необходимо задать. В качестве сертификата можно использовать самоподписанный сертификат или сертификат центра сертификации. Создание сертификата выходит за рамки этого раздела.
$listenerParams = @{
Path = 'WSMan:\localhost\Listener'
Address = '*'
CertificateThumbprint = 'E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE'
Enabled = $true
Port = 5986
Transport = 'HTTPS'
Force = $true
}
New-Item @listenerParams
Значение CertificateThumbprint должно быть задано как отпечаток сертификата, установленного в хранилище сертификатов LocalMachine\My.
Для параметра Address можно задать одно из трех значений:
-
*— привязка ко всем адресам -
IP:...— привязка к адресу IPv4 или IPv6, указанному в... -
MAC:32-a3-58-90-be-cc— привязка к адаптеру с указанным MAC-адресом
Удаление прослушивателя
Следующий код удаляет все прослушиватели или один указанный прослушиватель:
# Removes all listeners
Remove-Item -Path WSMan:\localhost\Listener\* -Recurse -Force
# Removes only HTTP listeners
Get-ChildItem -Path WSMan:\localhost\Listener |
Where-Object Keys -contains "Transport=HTTP" |
Remove-Item -Recurse -Force
# Removes only HTTPS listeners
Get-ChildItem -Path WSMan:\localhost\Listener |
Where-Object Keys -contains "Transport=HTTPS" |
Remove-Item -Recurse -Force
Аутентификация WinRM
В WinRM предусмотрено несколько вариантов аутентификации пользователей на узле Windows. У каждого варианта есть свои преимущества и недостатки, поэтому важно понимать, когда его следует использовать, а когда нет.
В следующей таблице приведен общий обзор вариантов:
Вариант | Локальные учетные записи | Учетные записи Active Directory | Делегирование учетных данных | Шифрование HTTP |
|---|---|---|---|---|
Базовая | Да | Нет | Нет | Нет |
Сертификат | Да | Нет | Нет | Нет |
Kerberos | Нет | Да | Да | Да |
NTLM | Да | Да | Нет | Да |
CredSSP | Да | Да | Да | Да |
Варианты аутентификации Basic и NTLM не следует использовать с прослушивателем HTTP, поскольку они не обеспечивают шифрование или используют очень слабое шифрование. Плагин подключения psrp также поддерживает вариант аутентификации Negotiate: он сначала попытается использовать Kerberos, а затем, если это не удастся, перейдет к NTLM. В плагине подключения winrm необходимо указать либо kerberos, либо ntlm.
Для указания протокола аутентификации можно использовать следующие переменные:
# For psrp ansible_psrp_auth: basic|certificate|negotiate|kerberos|ntlm|credssp # For winrm ansible_winrm_transport: basic|certificate|kerberos|ntlm|credssp
Для WinRM рекомендуется использовать аутентификацию Kerberos по HTTP в доменной среде или Basic/NTLM по HTTPS для локальных учетных записей. CredSSP следует использовать только в случае крайней необходимости, поскольку использование неограниченного делегирования может представлять угрозу безопасности.
Базовая
Базовая аутентификация — один из самых простых вариантов, но также и самый небезопасный. Это связано с тем, что имя пользователя и пароль просто кодируются в Base64. Если защищенный канал не используется (например, HTTPS), любой сможет их декодировать. Базовую аутентификацию можно использовать только для локальных учетных записей, но не для доменных.
В следующем примере показаны переменные узла, настроенные для базовой аутентификации:
ansible_user: LocalUsername ansible_password: Password # psrp ansible_connection: psrp ansible_psrp_auth: basic # winrm ansible_connection: winrm ansible_winrm_transport: basic
Базовая аутентификация по умолчанию не включена на узле Windows, но ее можно включить, выполнив в PowerShell следующую команду:
Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true
Сертификат
Дополнительные сведения о настройке и использовании аутентификации по сертификату см. в разделе Аутентификация WinRM по сертификату.
NTLM
NTLM — это старый механизм аутентификации Microsoft, который поддерживает как локальные, так и доменные учетные записи. NTLM включен по умолчанию в службе WinRM, поэтому перед его использованием дополнительная настройка не требуется.
NTLM — самый простой в использовании протокол аутентификации, и он безопаснее аутентификации Basic. В доменной среде вместо NTLM следует использовать Kerberos.
Kerberos имеет несколько преимуществ перед NTLM:
- NTLM — старый протокол, не поддерживающий более новые протоколы шифрования.
- Аутентификация NTLM выполняется медленнее, поскольку на этапе аутентификации требуется больше обменов данными с узлом.
- В отличие от Kerberos, NTLM не поддерживает делегирование учетных данных.
В этом примере показаны переменные узла, настроенные для аутентификации NTLM:
ansible_user: LocalUsername ansible_password: Password # psrp ansible_connection: psrp ansible_psrp_auth: negotiate # or ntlm to only use NTLM # winrm ansible_connection: winrm ansible_winrm_transport: ntlm
Kerberos и Negotiate
Kerberos — рекомендуемый вариант аутентификации для доменной среды. Kerberos поддерживает такие возможности, как делегирование учетных данных и шифрование сообщений по HTTP, и является одним из наиболее безопасных вариантов, доступных в WinRM.
Для корректной работы Kerberos на узле Ansible требуется выполнить дополнительную настройку. Дополнительные сведения о настройке, использовании и устранении неполадок аутентификации Kerberos см. в разделе Аутентификация Kerberos.
В следующем примере показаны переменные узла, настроенные для аутентификации Kerberos:
ansible_user: username@MY.DOMAIN.COM ansible_password: Password # psrp ansible_connection: psrp ansible_psrp_auth: negotiate # or kerberos to disable ntlm fallback # winrm ansible_connection: winrm ansible_winrm_transport: kerberos
CredSSP
CredSSP — более новый протокол аутентификации, поддерживающий делегирование учетных данных. Для этого после успешной аутентификации имя пользователя и пароль шифруются и отправляются серверу с помощью протокола CredSSP.
Поскольку имя пользователя и пароль отправляются на сервер для аутентификации с двойным переходом, убедитесь, что узлы, с которыми взаимодействует узел Windows, не скомпрометированы и являются доверенными.
CredSSP можно использовать как для локальных, так и для доменных учетных записей; он также поддерживает шифрование сообщений по HTTP.
Чтобы использовать аутентификацию CredSSP, настройте переменные узла следующим образом:
ansible_user: Username ansible_password: Password # psrp ansible_connection: psrp ansible_psrp_auth: credssp # winrm ansible_connection: winrm ansible_winrm_transport: credssp
Аутентификация CredSSP по умолчанию не включена на узле Windows, но ее можно включить, выполнив в PowerShell следующую команду:
Enable-WSManCredSSP -Role Server -Force
Для CredSSP требуются дополнительные библиотеки Python, которые можно установить с помощью pipx:
pipx inject "pypsrp[credssp]<=1.0.0" # for psrp pipx inject "pywinrm[credssp]>=0.4.0" # for winrm
Или, если вы выбрали инструкции по установке pip:
pip3 install "pypsrp[credssp]<=1.0.0" # for psrp pip3 install "pywinrm[credssp]>=0.4.0" # for winrm
CredSSP устанавливает TLS-подключение, чтобы защитить токены аутентификации и последующие сообщения, передаваемые по этому подключению. По умолчанию используется самоподписанный сертификат, автоматически созданный Windows. При использовании CredSSP через HTTPS по-прежнему необходимо проверять сертификат HTTPS, используемый прослушивателем WinRM, однако проверка сертификата CredSSP не выполняется. CredSSP можно настроить на использование другого сертификата, задав параметр CertificateThumbprint в конфигурации службы WinRM.
# Note the value $thumprint will be different in each situation, this needs # to be set based on the cert that is used. $thumbprint = "7C8DCBD5427AFEE6560F4AF524E325915F51172C" # Set the thumbprint value Set-Item -Path WSMan:\localhost\Service\CertificateThumbprint -Value $thumbprint
Учетные записи без прав администратора
По умолчанию WinRM разрешает подключения только учетным записям из локальной группы Administrators. Это можно изменить, выполнив следующую команду:
winrm configSDDL default
Откроется редактор ACL, в котором можно добавить пользователей или группы. Для выполнения команд через WinRM у пользователей и групп должны быть включены как минимум разрешения Read и Execute.
Хотя с WinRM можно использовать учетные записи без прав администратора, для большинства типичных задач администрирования сервера требуется определенный уровень административного доступа, поэтому возможности такого подхода обычно ограничены.
Шифрование WinRM
По умолчанию WinRM не работает через незашифрованный канал. Согласно протоколу WinRM, канал считается зашифрованным, если используется TLS поверх HTTP (HTTPS) или шифрование на уровне сообщений. Рекомендуется использовать WinRM с TLS: этот вариант работает со всеми способами аутентификации, но требует создания сертификата и его настройки для прослушивателя WinRM.
В доменной среде ADCS может создать сертификат для узла, выданный самим доменом.
Если использовать HTTPS невозможно, HTTP можно использовать, когда выбран вариант аутентификации NTLM, Kerberos или CredSSP. Эти протоколы шифруют данные WinRM собственным способом перед отправкой на сервер. При работе через HTTPS шифрование на уровне сообщений не используется, поскольку вместо него применяется более безопасный протокол TLS. Если требуется одновременно шифрование транспортного уровня и сообщений, можно задать следующие переменные узла:
# psrp ansible_psrp_message_encryption: always # winrm ansible_winrm_message_encryption: always
Примечание
Для шифрования сообщений по HTTP требуется pywinrm>=0.3.0.
В крайнем случае можно отключить требование шифрования на узле Windows. Это следует делать только для разработки и отладки, поскольку любые данные, отправленные из Ansible, могут быть просмотрены или изменены, а любой пользователь в той же сети может полностью перехватить удаленный сеанс. Чтобы отключить требование шифрования:
Set-Item -Path WSMan:\localhost\Service\AllowUnencrypted -Value $true
Примечание
Не отключайте проверку шифрования без крайней необходимости. Это может позволить другим пользователям сети перехватывать конфиденциальные данные, например учетные данные и файлы.
Проверка сертификата HTTPS
В рамках протокола TLS сертификат проверяется, чтобы убедиться, что узел соответствует субъекту сертификата, а клиент доверяет издателю сертификата сервера. Если используется самоподписанный сертификат, клиент не будет ему доверять и подключение завершится с ошибкой. Чтобы обойти эту проверку, задайте следующие переменные узла в зависимости от используемого плагина подключения:
ansible_psrp_cert_validation: ignoreansible_winrm_server_cert_validation: ignore
В доменной среде для настройки прослушивателя HTTPS часто используют службу сертификатов Active Directory (AD CS). AD CS создает подписанные сертификаты на основе запроса на подпись сертификата (CSR). Если для прослушивателя WinRM HTTPS используется сертификат, подписанный другим центром, например AD CS, Ansible можно настроить на доверие этому издателю в ходе согласования TLS.
Чтобы Ansible доверял центру сертификации (CA), например AD CS, сертификат издателя CA можно экспортировать в формате PEM. Затем этот сертификат можно скопировать на управляющий узел Ansible и использовать для проверки сертификатов, то есть в качестве цепочки CA.
Цепочка CA может содержать один или несколько сертификатов издателей, каждый из которых указывается на новой строке. Чтобы использовать пользовательскую цепочку CA для проверки, задайте следующую переменную узла в зависимости от используемого плагина подключения, указав путь к файлу в формате PEM с цепочкой CA:
ansible_psrp_ca_certansible_winrm_ca_trust_path
Если эта переменная не задана, вместо нее используется цепочка CA по умолчанию, расположенная в каталоге установки пакета Python certifi. В некоторых дистрибутивах Linux базовая библиотека Python requests может быть настроена так, чтобы плагины подключения psrp и winrm использовали системное хранилище сертификатов вместо certifi. В этом случае цепочка CA будет совпадать с системным хранилищем сертификатов.
Ограничения WinRM
Из-за особенностей конструкции протокола WinRM при его использовании возникают некоторые ограничения, которые могут создавать проблемы при написании плейбуков Ansible. К ним относятся:
- Для большинства типов аутентификации учетные данные не делегируются, что приводит к ошибкам аутентификации при обращении к сетевым ресурсам или установке некоторых программ.
- При работе через WinRM блокируются многие вызовы API Центра обновления Windows.
- Некоторые программы не устанавливаются через WinRM из-за отсутствия делегирования учетных данных или потому, что обращаются к запрещенным API Windows, например WUA через WinRM.
- Команды WinRM выполняются в неинтерактивном сеансе, что может препятствовать запуску некоторых команд или исполняемых файлов.
- Нельзя запустить процесс, взаимодействующий с
DPAPI, который используется некоторыми программами установки (например, Microsoft SQL Server).
Некоторые из этих ограничений можно смягчить одним из следующих способов:
- Настроить метод аутентификации на использование
credsspилиkerberosс включенным делегированием учетных данных - Использовать
become, чтобы обойти все ограничения WinRM и выполнить команду так, как если бы она выполнялась локально. В отличие от использования механизма аутентификации, напримерcredssp, этот способ также снимает ограничения неинтерактивного режима и ограничения API, такие как WUA и DPAPI - Использовать запланированную задачу для выполнения команды, которую можно создать с помощью модуля
win_scheduled_task. Как иbecome, этот способ обходит все ограничения WinRM, но позволяет выполнять только команды, а не модули.
Устранение неполадок WinRM
WinRM имеет широкий набор параметров конфигурации, из-за чего его настройка довольно сложна. Поэтому ошибки, отображаемые Ansible, на самом деле могут быть связаны с настройкой узла.
Чтобы выявить проблему на узле, выполните следующую команду с другого узла Windows и проверьте подключение к целевому узлу Windows.
- Проверка HTTP:
# winrm
winrs -r:http://server:5985/wsman -u:Username -p:Password ipconfig
# psrp
Invoke-Command -ComputerName server { ipconfig } -Credential username
- Проверка HTTPS:
# winrm
winrs -r:https://server:5986/wsman -u:Username -p:Password -ssl ipconfig
# psrp
Invoke-Command -UseSSL -ComputerName server { ipconfig } -Credential username
# psrp ignoring certs
$sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
Invoke-Command -UseSSL -ComputerName server { ipconfig } -Credential username -SessionOption $sessionOption
Чтобы проверить, разрешается ли имя целевого узла на управляющем узле Ansible, выполните одну из следующих команд:
dig +search server # May fail if the Windows firewall is set to block ICMP pings # but will show the hostname if resolvable. ping server
Чтобы проверить, прослушивает ли служба WinRM соединения и не блокирует ли подключение брандмауэр, можно использовать nc для проверки подключения через порт WinRM:
# HTTP port > nc -zv server 5985 Connection to server port 5985 [tcp/wsman] succeeded! # HTTPS port > nc -zv server 5986 Connection to server port 5986 [tcp/wsmans] succeeded!
Чтобы проверить, настроен ли прослушиватель HTTPS в WinRM и работает ли он, используйте openssl s_client для проверки подключения и просмотра сведений о сертификате:
echo '' | openssl s_client -connect server:5986
Примечание
Команда openssl s_client использует системное хранилище доверенных сертификатов для проверки сертификата, которое может отличаться от хранилища, используемого в Ansible. Дополнительные сведения см. в разделе Проверка сертификата HTTPS.
См. также
- Плейбуки Ansible
-
Введение в плейбуки
- Советы и рекомендации по Ansible
-
Советы и рекомендации по работе с плейбуками
- Список модулей Windows
-
Список модулей для Windows, реализованных на PowerShell
- Общение
-
Есть вопросы? Нужна помощь? Хотите поделиться идеями? Посетите руководство по общению сообщества Ansible
© 2012–2018 Michael DeHaan
© 2018–2025 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/projects/ansible/latest/os_guide/windows_winrm.html