0
# Authentication & Security
1
2
Support for multiple authentication methods and secure communication protocols with message-level encryption capabilities. PyWinRM provides comprehensive security features for remote Windows management across different network environments and security requirements.
3
4
## Capabilities
5
6
### Authentication Methods
7
8
PyWinRM supports multiple authentication mechanisms for different deployment scenarios and security requirements.
9
10
```python { .api }
11
# Supported authentication types
12
FEATURE_SUPPORTED_AUTHTYPES = [
13
"basic", "certificate", "ntlm", "kerberos",
14
"plaintext", "ssl", "credssp"
15
]
16
17
# Feature flags for client capability detection
18
FEATURE_READ_TIMEOUT = True
19
FEATURE_OPERATION_TIMEOUT = True
20
FEATURE_PROXY_SUPPORT = True
21
```
22
23
### Transport Security Configuration
24
25
Configure transport-level security including certificates, validation, and encryption options.
26
27
```python { .api }
28
class Transport:
29
def __init__(
30
self,
31
endpoint: str,
32
username: str | None = None,
33
password: str | None = None,
34
realm: None = None,
35
service: str = "HTTP",
36
keytab: None = None,
37
ca_trust_path: Literal["legacy_requests"] | str = "legacy_requests",
38
cert_pem: str | None = None,
39
cert_key_pem: str | None = None,
40
read_timeout_sec: int | None = None,
41
server_cert_validation: Literal["validate", "ignore"] = "validate",
42
kerberos_delegation: bool | str = False,
43
kerberos_hostname_override: str | None = None,
44
auth_method: Literal["auto", "basic", "certificate", "ntlm", "kerberos", "credssp", "plaintext", "ssl"] = "auto",
45
message_encryption: Literal["auto", "always", "never"] = "auto",
46
credssp_disable_tlsv1_2: bool = False,
47
credssp_auth_mechanism: Literal["auto", "ntlm", "kerberos"] = "auto",
48
credssp_minimum_version: int = 2,
49
send_cbt: bool = True,
50
proxy: Literal["legacy_requests"] | str | None = "legacy_requests"
51
):
52
"""
53
Configure transport-level security and authentication.
54
55
Parameters:
56
- endpoint: WinRM webservice endpoint URL
57
- username: authentication username
58
- password: authentication password
59
- realm: realm parameter (currently unused)
60
- service: service name for Kerberos authentication (default: "HTTP")
61
- keytab: keytab parameter (currently unused)
62
- ca_trust_path: CA certificate trust path or "legacy_requests" for env vars
63
- cert_pem: client certificate file path (PEM format)
64
- cert_key_pem: client certificate private key file path (PEM format)
65
- read_timeout_sec: HTTP connection/read timeout in seconds
66
- server_cert_validation: certificate validation mode ("validate" or "ignore")
67
- kerberos_delegation: enable Kerberos delegation for multi-hop scenarios
68
- kerberos_hostname_override: override hostname for Kerberos SPN
69
- auth_method: authentication method to use
70
- message_encryption: message-level encryption policy
71
- credssp_disable_tlsv1_2: disable TLS 1.2 for CredSSP compatibility
72
- credssp_auth_mechanism: CredSSP authentication mechanism
73
- credssp_minimum_version: minimum CredSSP version
74
- send_cbt: send Channel Binding Tokens for enhanced security
75
- proxy: proxy configuration
76
"""
77
78
def build_session(self) -> requests.Session:
79
"""
80
Create and configure a requests.Session object.
81
82
Sets up proxy configuration, SSL verification, authentication,
83
and message encryption if required.
84
85
Returns:
86
Configured requests.Session object ready for WinRM communication
87
"""
88
89
def setup_encryption(self, session: requests.Session) -> None:
90
"""
91
Set up message encryption for the transport.
92
93
Sends an initial blank message to initialize security context
94
and creates an Encryption instance for the session.
95
96
Parameters:
97
- session: requests.Session to configure encryption for
98
"""
99
100
def close_session(self) -> None:
101
"""
102
Close the current session if it exists.
103
104
Sets the session attribute to None and cleans up resources.
105
"""
106
107
def send_message(self, message: str | bytes) -> bytes:
108
"""
109
Send WinRM message and return response.
110
111
Handles both encrypted and unencrypted messages.
112
Converts string messages to bytes automatically.
113
114
Parameters:
115
- message: WinRM message as string or bytes
116
117
Returns:
118
Response content as bytes
119
"""
120
```
121
122
### Message Encryption
123
124
Message-level encryption for secure communication over potentially untrusted networks.
125
126
```python { .api }
127
class Encryption:
128
"""Message-level encryption for WinRM communication."""
129
130
# Constants
131
SIXTEN_KB = 16384 # 16KB chunk size for large message encryption
132
MIME_BOUNDARY = b"--Encrypted Boundary" # MIME boundary for encrypted messages
133
134
def __init__(self, session: requests.Session, protocol: str):
135
"""
136
Initialize message encryption for supported protocols.
137
138
Supported protocols:
139
- "ntlm": NTLM with SPNEGO session encryption
140
- "kerberos": Kerberos with SPNEGO session encryption
141
- "credssp": CredSSP with session encryption
142
143
Parameters:
144
- session: HTTP session with established authentication context
145
- protocol: encryption protocol type
146
147
Raises:
148
- WinRMError: if protocol is not supported for encryption
149
"""
150
151
def prepare_encrypted_request(
152
self,
153
session: requests.Session,
154
endpoint: str | bytes,
155
message: bytes
156
) -> requests.PreparedRequest:
157
"""
158
Prepare HTTP request with encrypted message payload.
159
160
Handles both single-part and multi-part encryption based on message size.
161
For CredSSP messages larger than 16KB, uses multipart/x-multi-encrypted.
162
163
Parameters:
164
- session: requests.Session to prepare request with
165
- endpoint: target endpoint URL
166
- message: unencrypted message bytes to send
167
168
Returns:
169
Prepared request with encrypted body and appropriate headers
170
"""
171
172
def parse_encrypted_response(self, response: requests.Response) -> bytes:
173
"""
174
Parse and decrypt encrypted response from WinRM service.
175
176
Automatically detects if response is encrypted based on Content-Type
177
header and decrypts accordingly.
178
179
Parameters:
180
- response: HTTP response from WinRM service
181
182
Returns:
183
Decrypted response message bytes
184
"""
185
```
186
187
## Authentication Configuration Examples
188
189
### Basic Authentication
190
191
Simple username/password authentication over HTTP or HTTPS.
192
193
```python
194
import winrm
195
196
# HTTP Basic (not recommended for production)
197
s = winrm.Session(
198
'http://windows-host:5985/wsman',
199
auth=('username', 'password'),
200
transport='basic'
201
)
202
203
# HTTPS Basic (recommended)
204
s = winrm.Session(
205
'https://windows-host:5986/wsman',
206
auth=('username', 'password'),
207
transport='ssl'
208
)
209
```
210
211
### NTLM Authentication
212
213
Windows NTLM authentication with optional message encryption.
214
215
```python
216
# NTLM with message encryption (recommended)
217
s = winrm.Session(
218
'windows-host.domain.com',
219
auth=('domain\\username', 'password'),
220
transport='ntlm',
221
message_encryption='always'
222
)
223
224
# NTLM without encryption (faster, less secure)
225
s = winrm.Session(
226
'windows-host.domain.com',
227
auth=('domain\\username', 'password'),
228
transport='ntlm',
229
message_encryption='never'
230
)
231
```
232
233
### Kerberos Authentication
234
235
Domain-based Kerberos authentication with delegation support.
236
237
```python
238
# Standard Kerberos authentication
239
s = winrm.Session(
240
'windows-host.domain.com',
241
auth=('user@DOMAIN.COM', 'password'),
242
transport='kerberos'
243
)
244
245
# Kerberos with delegation (for multi-hop scenarios)
246
s = winrm.Session(
247
'windows-host.domain.com',
248
auth=('user@DOMAIN.COM', 'password'),
249
transport='kerberos',
250
kerberos_delegation=True,
251
kerberos_hostname_override='custom-host.domain.com'
252
)
253
```
254
255
### CredSSP Authentication
256
257
CredSSP with credential delegation for accessing network resources.
258
259
```python
260
# CredSSP authentication (requires pywinrm[credssp])
261
s = winrm.Session(
262
'windows-host.domain.com',
263
auth=('domain\\username', 'password'),
264
transport='credssp',
265
message_encryption='always'
266
)
267
268
# CredSSP with TLS compatibility options
269
s = winrm.Session(
270
'windows-host.domain.com',
271
auth=('domain\\username', 'password'),
272
transport='credssp',
273
credssp_disable_tlsv1_2=True # For older systems
274
)
275
```
276
277
### Certificate Authentication
278
279
Client certificate-based authentication for PKI environments.
280
281
```python
282
# Certificate authentication
283
s = winrm.Session(
284
'https://windows-host:5986/wsman',
285
auth=('username', 'password'), # May still be required
286
transport='certificate',
287
cert_pem='/path/to/client.crt',
288
cert_key_pem='/path/to/client.key',
289
server_cert_validation='validate',
290
ca_trust_path='/path/to/ca-bundle.crt'
291
)
292
293
# Certificate auth with custom CA trust
294
s = winrm.Session(
295
'https://windows-host:5986/wsman',
296
auth=('username', 'password'),
297
transport='certificate',
298
cert_pem='/path/to/client.pem',
299
cert_key_pem='/path/to/client.key',
300
ca_trust_path='/etc/ssl/certs/custom-ca.pem'
301
)
302
```
303
304
## Certificate Validation Options
305
306
### Production Configuration
307
308
```python
309
# Strict certificate validation (production)
310
s = winrm.Session(
311
'https://windows-host.domain.com:5986/wsman',
312
auth=('user', 'password'),
313
transport='ssl',
314
server_cert_validation='validate',
315
ca_trust_path='/etc/ssl/certs/ca-certificates.crt'
316
)
317
```
318
319
### Development/Testing Configuration
320
321
```python
322
# Disabled certificate validation (development only)
323
import urllib3
324
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
325
326
s = winrm.Session(
327
'https://windows-host:5986/wsman',
328
auth=('user', 'password'),
329
transport='ssl',
330
server_cert_validation='ignore' # NOT for production
331
)
332
```
333
334
## Proxy Configuration
335
336
### Proxy Support
337
338
```python
339
# Explicit proxy configuration
340
s = winrm.Session(
341
'windows-host',
342
auth=('user', 'password'),
343
proxy='http://proxy.company.com:8080'
344
)
345
346
# Proxy with authentication
347
s = winrm.Session(
348
'windows-host',
349
auth=('user', 'password'),
350
proxy='http://proxyuser:proxypass@proxy.company.com:8080'
351
)
352
353
# Disable proxy completely
354
s = winrm.Session(
355
'windows-host',
356
auth=('user', 'password'),
357
proxy=None
358
)
359
360
# Use environment variables (default)
361
s = winrm.Session(
362
'windows-host',
363
auth=('user', 'password'),
364
proxy='legacy_requests' # Uses HTTP_PROXY, HTTPS_PROXY env vars
365
)
366
```
367
368
## Security Best Practices
369
370
### Secure Configuration Example
371
372
```python
373
import winrm
374
import os
375
376
def create_secure_session(hostname, username, password):
377
"""Create WinRM session with security best practices."""
378
379
# Use HTTPS transport with NTLM
380
session = winrm.Session(
381
f'https://{hostname}:5986/wsman',
382
auth=(username, password),
383
transport='ntlm',
384
385
# Security settings
386
message_encryption='always',
387
server_cert_validation='validate',
388
ca_trust_path='/etc/ssl/certs/ca-certificates.crt',
389
send_cbt=True,
390
391
# Timeout settings
392
read_timeout_sec=60,
393
operation_timeout_sec=30
394
)
395
396
return session
397
398
# Usage with environment variables for credentials
399
hostname = os.environ['WINRM_HOST']
400
username = os.environ['WINRM_USERNAME']
401
password = os.environ['WINRM_PASSWORD']
402
403
s = create_secure_session(hostname, username, password)
404
```
405
406
### Authentication Method Selection
407
408
```python
409
def select_auth_method(hostname, username, password, domain=None):
410
"""Select appropriate authentication method based on environment."""
411
412
# Domain environment - prefer Kerberos
413
if domain and '@' in username:
414
return winrm.Session(
415
hostname,
416
auth=(username, password),
417
transport='kerberos',
418
message_encryption='auto'
419
)
420
421
# Domain environment - NTLM fallback
422
elif domain:
423
return winrm.Session(
424
hostname,
425
auth=(f'{domain}\\{username}', password),
426
transport='ntlm',
427
message_encryption='always'
428
)
429
430
# Local account - SSL Basic
431
else:
432
return winrm.Session(
433
f'https://{hostname}:5986/wsman',
434
auth=(username, password),
435
transport='ssl',
436
server_cert_validation='validate'
437
)
438
439
# Usage
440
s = select_auth_method('windows-host.domain.com', 'user', 'password', 'DOMAIN')
441
```
442
443
## Security Considerations
444
445
- **Transport Security**: Always use HTTPS (`ssl` transport) or message encryption (`ntlm`, `kerberos`, `credssp`) in production
446
- **Certificate Validation**: Never disable certificate validation in production environments
447
- **Credential Management**: Use environment variables or secure credential stores, never hardcode passwords
448
- **Network Security**: Consider firewall rules, network segmentation, and VPN requirements
449
- **Timeout Configuration**: Set appropriate timeouts to prevent resource exhaustion
450
- **Audit Logging**: Enable WinRM audit logging on target systems for security monitoring