I'm encountering an issue with WinRM certificate authentication on a Windows Server 2022 CIS STIGs image. The server is running the WinRM service, and I'm trying to connect from an Ubuntu Pro 20.04 FIPS client using pywinrm (v0.5.0). Both certificates are self-signed (ACM PCA) and the CA cert is added to the trusted stores on both Windows and Ubuntu.
On Windows Server 2022:
PS C:\Windows\system32> Get-ChildItem -Path Cert:\CurrentUser\Root | Where-Object { $_.Thumbprint -eq "5A2F4E63BEBEDB186ED84BF722B54207E6664469" } | Select-Object Subject, Thumbprint
Subject Thumbprint
------- ----------
L=TA, CN=example.com, S=TA, OU=RnD, O=Company, C=IL 5A2F4E63BEBEDB186ED84BF722B54207E6664469
PS C:\Windows\system32> winrm enumerate winrm/config/service/certmapping
CertMapping
URI = *
Subject = 50612F90702F2FEF1B777E987B7CD974DC99CE51
Issuer = 5A2F4E63BEBEDB186ED84BF722B54207E6664469
UserName = Administrator
Enabled = true
Password
PS C:\Windows\system32> winrm g winrm/config
Config
MaxEnvelopeSizekb = 500
MaxTimeoutms = 1800000
MaxBatchItems = 32000
MaxProviderRequests = 4294967295
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false [Source="GPO"]
Auth
Basic = false [Source="GPO"]
Digest = false [Source="GPO"]
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = false [Source="GPO"]
Auth
Basic = false [Source="GPO"]
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = true
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = true
CertificateThumbprint
AllowRemoteAccess = true
Winrs
AllowRemoteShellAccess = true
IdleTimeout = 7200000
MaxConcurrentUsers = 2147483647
MaxShellRunTime = 2147483647
MaxProcessesPerShell = 2147483647
MaxMemoryPerShellMB = 1024
MaxShellsPerUser = 2147483647
PS C:\Windows\system32> winrm g winrm/config/service
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = false [Source="GPO"]
Auth
Basic = false [Source="GPO"]
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = true
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = true
CertificateThumbprint = 13F3C1844B7617270D1331BEB02AD347FAB74D9C
AllowRemoteAccess = true
On Ubuntu Pro 20.04:
$ cert_path="/etc/nginx/certs/controller.example.com.crt.pem"
$ thumbprint=$(openssl x509 -in "$cert_path" -noout -fingerprint -sha1 | sed 's/://g' | awk -F= '{print $2}')
$ echo $thumbprint
50612F90702F2FEF1B777E987B7CD974DC99CE51
$ issuer_thumbprint=$(tac /etc/ssl/certs/ca-certificates.crt | awk 'BEGIN {c=0} /END CERTIFICATE/ {c++} {if (c==1) print}' | tac | openssl x509 -in /dev/stdin -noout -fingerprint -sha1 | sed 's/://g' | awk -F= '{print $2}')
$ echo $issuer_thumbprint
5A2F4E63BEBEDB186ED84BF722B54207E6664469
I'm testing the connection using pywinrm with HTTPS and certificate authentication. Here is the command and the error message:
$ python -c "import winrm; winrm.Session('https://winrm.example.com:5986/wsman', auth=(None, None), transport='certificate', cert_key_pem='/etc/nginx/certs/controller.example.com.key.pem', cert_pem='/etc/nginx/certs/controller.example.com.crt.pem', server_cert_validation='validate', ca_trust_path='/etc/ssl/certs/ca-certificates.crt').run_cmd('ipconfig', ['/all']).std_out.decode()"
Traceback (most recent call last):
File "/opt/venv3.11/lib/python3.11/site-packages/winrm/transport.py", line 342, in _send_message_request
response.raise_for_status()
File "/opt/venv3.11/lib/python3.11/site-packages/requests/models.py", line 1024, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: for url: https://winrm.example.com:5986/wsman
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/opt/venv3.11/lib/python3.11/site-packages/winrm/__init__.py", line 44, in run_cmd
shell_id = self.protocol.open_shell()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv3.11/lib/python3.11/site-packages/winrm/protocol.py", line 193, in open_shell
res = self.send_message(xmltodict.unparse(req))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv3.11/lib/python3.11/site-packages/winrm/protocol.py", line 263, in send_message
resp = self.transport.send_message(message)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv3.11/lib/python3.11/site-packages/winrm/transport.py", line 336, in send_message
response = self._send_message_request(session, prepared_request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv3.11/lib/python3.11/site-packages/winrm/transport.py", line 346, in _send_message_request
raise InvalidCredentialsError("the specified credentials were rejected by the server")
winrm.exceptions.InvalidCredentialsError: the specified credentials were rejected by the server
WinRM Service Logs: On the WinRM service, I see the following log entry:
PS C:\Windows\system32> Get-WinEvent -LogName "Microsoft-Windows-WinRM/Operational" -MaxEvents 1 | Format-List *
Message : The authorization of the user failed with error 5
Id : 192
Version : 0
Qualifiers :
Level : 4
Task : 8
Opcode : 0
Keywords : 4611686018427387916
RecordId : 5435
ProviderName : Microsoft-Windows-WinRM
ProviderId : a7975c8f-ac13-49f1-87da-5a984a4ab417
LogName : Microsoft-Windows-WinRM/Operational
ProcessId : 3320
ThreadId : 3744
MachineName : winrm
UserId : S-1-5-20
TimeCreated : 4/8/2025 8:44:41 PM
ActivityId : a3ddc236-a84c-0004-90ed-dda34ca8db01
RelatedActivityId
Please help me understand why do I fail connect using certificate auth option (TLS handshake looks good. also confirmed directly with openssl s_client ... getting verification OK).
Any suggestions / ideas please! Thanks!!
Found the bug...
The CertMapping.Subject should include the actual Subject CN of the client certificate, and not the fingerprint.