Skip to content

Commit 84ea443

Browse files
committed
Adds WinRM certificate auth scripts
1 parent 27eb395 commit 84ea443

4 files changed

+213
-7
lines changed

SetupClientWinRMCertificateAuth.ps1

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
$ErrorActionPreference = "Stop"
2+
3+
# Setup the WinRM client in an elevated command prompt
4+
#& winrm set winrm/config/client `@`{TrustedHosts=`"*`"`}
5+
#& winrm set winrm/config/client/auth `@`{Certificate=`"true`"`}
6+
7+
$remote_host = "192.168.209.134"
8+
$host_cacert_path = "C:\temp\ca_winrm.pem"
9+
$client_cert_pfx = "c:\temp\cert.pfx"
10+
$client_cert_pfx_password = "Passw0rd"
11+
12+
# Get the user's personal certificate store
13+
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
14+
[System.Security.Cryptography.X509Certificates.StoreName]::My,
15+
[System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser)
16+
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
17+
18+
# Get the user's Trusted Root CA store
19+
$castore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
20+
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
21+
[System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser)
22+
$castore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
23+
24+
# Import the client cert and its CA cert
25+
$coll = new-object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
26+
$coll.Import($client_cert_pfx, $client_cert_pfx_password,
27+
([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::UserKeySet -bor
28+
[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet))
29+
30+
foreach($cert in $coll) {
31+
# TODO: handle intermediate CAs
32+
if ($cert.Subject -eq $cert.Issuer) {
33+
$castore.Add($cert)
34+
}
35+
else {
36+
$store.Add($cert)
37+
}
38+
}
39+
40+
# Import the server's cert CA cert.
41+
# This is necessary only due to a New-PSSession bug as the PSSessionOption.SkipCACheck setting is ignored
42+
$host_cacert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($host_cacert_path)
43+
$castore.Add($host_cacert)
44+
45+
# Open a remote PowerShell session using certificate authentication
46+
$opt = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
47+
$session = New-PSSession -ComputerName $remote_host -UseSSL -CertificateThumbprint $clientcert.Thumbprint -SessionOption $opt
48+
Enter-PSSession $session

SetupWinRMAccess.ps1

+13-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ function SetAdminOnlyACL($path) {
1616
{
1717
$sidObj = New-Object System.Security.Principal.SecurityIdentifier($sid)
1818
$account = $sidObj.Translate( [System.Security.Principal.NTAccount])
19-
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule ($account, $fsRights, $inheritanceFlags, $propagationFlags, $aceType)
19+
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule (
20+
$account, $fsRights, $inheritanceFlags, $propagationFlags, $aceType)
2021
$acl.AddAccessRule($ace)
2122
}
2223

@@ -41,12 +42,10 @@ mkdir crl
4142

4243
$ca_conf_file="ca.cnf"
4344
$openssl_conf_file="openssl.cnf"
44-
$server_ext_conf_file="server_ext.cnf"
4545

4646
$conf_base_url="https://raw.github.com/cloudbase/unattended-setup-scripts/master/"
4747

4848
(new-object System.Net.WebClient).DownloadFile($conf_base_url + $ca_conf_file, "$ca_dir\$ca_conf_file")
49-
(new-object System.Net.WebClient).DownloadFile($conf_base_url + $server_ext_conf_file, "$ca_dir\$server_ext_conf_file")
5049
(new-object System.Net.WebClient).DownloadFile($conf_base_url + $openssl_conf_file, "$ca_dir\$openssl_conf_file")
5150

5251
$ENV:PATH+=";C:\OpenSSL-Win32\bin"
@@ -60,19 +59,26 @@ openssl req -newkey rsa:2048 -nodes -sha1 -keyout private\cert.key -keyform PEM
6059
if ($LastExitCode) { throw "openssl failed to create server certificate request" }
6160

6261
$ENV:OPENSSL_CONF="$ca_dir\ca.cnf"
63-
openssl ca -batch -notext -in certs\cert.req -out certs\cert.pem -extensions v3_req_server -extensions v3_req_server
62+
openssl ca -batch -notext -in certs\cert.req -out certs\cert.pem -extensions v3_req_server
6463
if ($LastExitCode) { throw "openssl CA failed to sign server certificate request" }
6564

6665
# Import CA certificate
6766
$cacert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("$ca_dir\certs\ca.pem")
68-
$castore = New-Object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::Root, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
67+
$castore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
68+
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
69+
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
6970
$castore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
7071
$castore.Add($cacert)
7172

7273
# Import server certificate
7374
openssl pkcs12 -export -in certs\cert.pem -inkey private\cert.key -out certs\cert.pfx -password pass:Passw0rd
74-
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("$ca_dir\certs\cert.pfx", "Passw0rd", ([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet))
75-
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::My, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
75+
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(
76+
"$ca_dir\certs\cert.pfx", "Passw0rd",
77+
([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor
78+
[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet))
79+
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
80+
[System.Security.Cryptography.X509Certificates.StoreName]::My,
81+
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
7682
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
7783
$store.Add($cert)
7884
del certs\cert.pfx

SetupWinRMCertificateAuth.ps1

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
$ErrorActionPreference = "Stop"
2+
3+
$username = "Administrator"
4+
$password = "Passw0rd"
5+
6+
$client_cert_path = z:\Downloads\ca_test\certs\cert.pem"
7+
$client_ca_cert_path = "z:\Downloads\ca_test\certs\ca.pem"
8+
9+
# Enable certificate authentication
10+
& winrm set winrm/config/service/auth `@`{Certificate=`"true`"`}
11+
12+
# Import the client cert's CA cert
13+
$cacert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($client_ca_cert_path)
14+
$castore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
15+
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
16+
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
17+
$castore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
18+
$castore.Add($cacert)
19+
20+
# Import the client cert into TrustedPeople
21+
$clientcert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($client_cert_path)
22+
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
23+
[System.Security.Cryptography.X509Certificates.StoreName]::TrustedPeople,
24+
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
25+
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
26+
$store.Add($clientcert)
27+
28+
$secure_password = ConvertTo-SecureString $password -AsPlainText -Force
29+
# For domain auth just replace $ENV:COMPUTERNAME with the domain name
30+
$cred = New-Object System.Management.Automation.PSCredential "$ENV:COMPUTERNAME\$username", $secure_password
31+
32+
# Get the UPN from the cert extension
33+
$clientcert.Extensions[1].Format($false) -match ".*=(.*)"
34+
$upn = $Matches[1]
35+
36+
New-Item -Path WSMan:\localhost\ClientCertificate -Issuer $cacert.Thumbprint -Subject $upn -Uri * -Credential $cred -Force

generate_winrm_client_cert.sh

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/bin/bash
2+
set -e
3+
4+
USER_NAME=user$RANDOM
5+
6+
UPN=$USER_NAME@localhost
7+
PFX_FILE=`pwd`/cert.pfx
8+
PFX_PASSWORD=Passw0rd
9+
10+
CA_DIR=`mktemp -d -t openssl`
11+
12+
pushd .
13+
cd $CA_DIR
14+
15+
mkdir private
16+
chmod 700 private
17+
mkdir certs
18+
mkdir crl
19+
20+
cat > ca.cnf << EOF
21+
[ ca ]
22+
default_ca = mypersonalca
23+
24+
[ mypersonalca ]
25+
dir = $CA_DIR
26+
certs = \$dir/certs
27+
crl_dir = \$dir/crl
28+
database = \$dir/index.txt
29+
new_certs_dir = \$dir/certs
30+
certificate = \$dir/certs/ca.pem
31+
serial = \$dir/serial
32+
crl = \$dir/crl/crl.pem
33+
private_key = \$dir/private/ca.key
34+
RANDFILE = \$dir/private/.rand
35+
x509_extensions = usr_cert
36+
default_days = 3650
37+
default_crl_days= 30
38+
default_md = sha1
39+
preserve = no
40+
policy = mypolicy
41+
x509_extensions = certificate_extensions
42+
43+
[ mypolicy ]
44+
commonName = supplied
45+
stateOrProvinceName = supplied
46+
countryName = supplied
47+
emailAddress = supplied
48+
organizationName = supplied
49+
organizationalUnitName = optional
50+
51+
[ certificate_extensions ]
52+
basicConstraints = CA:false
53+
54+
[ req ]
55+
default_keyfile = $CA_DIR/private/ca.key
56+
default_md = sha1
57+
prompt = no
58+
subjectKeyIdentifier=hash
59+
authorityKeyIdentifier=keyid:always,issuer
60+
string_mask = utf8only
61+
basicConstraints = CA:true
62+
distinguished_name = root_ca_distinguished_name
63+
x509_extensions = root_ca_extensions
64+
65+
[ root_ca_distinguished_name ]
66+
commonName = WinRM CA
67+
stateOrProvinceName = Timis
68+
countryName = RO
69+
emailAddress = [email protected]
70+
organizationName = WinRM CA
71+
72+
[ root_ca_extensions ]
73+
basicConstraints = CA:true
74+
75+
[v3_req_server]
76+
extendedKeyUsage = serverAuth
77+
EOF
78+
79+
cat > openssl.cnf << EOF
80+
distinguished_name = req_distinguished_name
81+
[req_distinguished_name]
82+
[v3_req]
83+
[v3_req_server]
84+
extendedKeyUsage = serverAuth
85+
[v3_ca]
86+
EOF
87+
88+
touch index.txt
89+
echo 01 > serial
90+
91+
export OPENSSL_CONF=ca.cnf
92+
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -out certs/ca.pem -outform PEM -keyout private/ca.key
93+
94+
export OPENSSL_CONF=openssl.cnf
95+
openssl req -newkey rsa:2048 -nodes -sha1 -keyout private/cert.key -keyform PEM -out certs/cert.req -outform PEM -subj \
96+
"/C=US/ST=Timis/L=Timisoara/[email protected]/organizationName=IT/CN=$USER_NAME"
97+
98+
EXT_CONF_FILE=`mktemp -t openssl`
99+
100+
cat > $EXT_CONF_FILE << EOF
101+
[v3_req_client]
102+
extendedKeyUsage = clientAuth
103+
subjectAltName = otherName:1.3.6.1.4.1.311.20.2.3;UTF8:$UPN
104+
EOF
105+
106+
export OPENSSL_CONF=ca.cnf
107+
openssl ca -batch -notext -in certs/cert.req -out certs/cert.pem -extensions v3_req_client -extfile $EXT_CONF_FILE
108+
109+
rm $EXT_CONF_FILE
110+
111+
# Export the certificate, including the CA chain, into cert.pfx
112+
openssl pkcs12 -export -in certs/cert.pem -inkey private/cert.key -chain -CAfile certs/ca.pem -out $PFX_FILE -password pass:$PFX_PASSWORD
113+
114+
popd
115+
rm -rf $CA_DIR
116+

0 commit comments

Comments
 (0)