Let’s Encrypt na Windows Server 2016 – PowerShell a ACMESharp #2 – skript PoC

Rychlá a nedokonalá implementace automatizace vystavování nových Let’s Encrypt certifikátů pro Web Application Proxy na Windows Serveru 2016. Samozřejmě předpokládáme již nakonfigurované prostředí (vault, ověřené domény a definované aliasy pro domény)  – např. podle http://www.jan-zak.cz/lets-encrypt-ws2016-powershell-acmesharp/  🙂

Doporučná perioda vystavování je 60 dnů, takže stačí nastavit Task Scheduler na každé dva měsíce a máme vystaráno (samozřejmě dokud se něco nezmění na straně LE).

####################################################################################################
######## This script generates new Let’s Encrypt certificate (vault has to be already configured)
######## Version 1.0 (2016-12-31), PoC only, no errors handling implmented
######## Jan Zak (www.jan-zak.cz)
####################################################################################################

### Get variables ####
$Path2Module="C:\ACME\ACMESharp\0.8.1\ACMESharp.psd1" #Load module file directly instad of "Import-Module ACMESharp"
$DomainAlias="fscloudtestcz" #Already configured alias in ACME vault
$DomainSANAlias="fscloudtestcz","appcloudtestcz","claimappcloudtestcz" #Already configured aliases in ACME vault
$CertificatePwd="Password123"
$CertificatePwdSecure=ConvertTo-SecureString -String $CertificatePwd -Force -AsPlainText
$WorkDir="C:\ACME\Certificates\"
$Date2Name=Get-Date -Format yyyyMMdd_HHmm
$CertificateAlias="fscloudtestcz_cert_" + $Date2Name
$CertificatePath=$WorkDir + $DomainAlias + "_" + $Date2Name + ".pfx"
$CAName="Let's Encrypt Authority X3" #To identify LE certificates during cean-up phase

### Create and submit request ###
Import-Module $Path2Module
New-ACMECertificate $DomainAlias -Generate -AlternativeIdentifierRefs $DomainSANAlias -Alias $CertificateAlias
Submit-ACMECertificate $CertificateAlias
Update-ACMECertificate $CertificateAlias
Get-ACMECertificate $CertificateAlias -ExportPkcs12 $CertificatePath -CertificatePassword $CertificatePwd

### Import certificate into Win Cert Store, delete expired certificates and source .pfx file
Import-PfxCertificate $CertificatePath -Password $CertificatePwdSecure -CertStoreLocation Cert:\LocalMachine\My\ -Exportable
Remove-Item $CertificatePath -Force
Get-ChildItem Cert:\LocalMachine\My |? Issuer -Like "CN=$CAName*" |? NotAfter -LT (Get-Date) |Remove-Item

### Set new certificate as active (example only!)
$NewCertThumbprint=Get-ChildItem Cert:\LocalMachine\My |? Issuer -like "CN=$CAName*" |? NotBefore -GT ((Get-Date).AddMinutes(-120)) |Select-Object Thumbprint
Set-WebApplicationProxySslCertificate -Thumbprint $NewCertThumbprint.Thumbprint #Optional, configures WebApplicationProxy with a new certificate

 

Aktualizace O365/Azure PS modulů

PowerShell 5 umí instalovat moduly přímo z https://www.powershellgallery.com, což se hodí.

PS C:\> Connect-MsolService
WARNING: There is a newer version of the Microsoft Online Services Module.  Your current version
will still work as expected, however the latest version can be downloaded at
https://portal.microsoftonline.com.
PS C:\>  Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpoint...
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable,...
Manifest   1.0        MSOnline                            {Add-MsolForeignGroupToRole, Add-MsolG...
Binary     1.0.0.1    PackageManagement                   {Find-Package, Find-PackageProvider, G...
Script     1.0.0.1    PowerShellGet                       {Find-DscResource, Find-Module, Find-S...
Script     1.1        PSReadline                          {Get-PSReadlineKeyHandler, Get-PSReadl...

PS C:\> Install-Module msonline -Force
PS C:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpoint...
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable,...
Manifest   1.0        MSOnline                            {Add-MsolForeignGroupToRole, Add-MsolG...
Binary     1.0.0.1    PackageManagement                   {Find-Package, Find-PackageProvider, G...
Script     1.0.0.1    PowerShellGet                       {Find-DscResource, Find-Module, Find-S...
Script     1.1        PSReadline                          {Get-PSReadlineKeyHandler, Get-PSReadl...

Update 1: Tak je to špatně. Když se totiž pomocí

(get-item C:\Windows\System32\WindowsPowerShell\v1.0\Modules\MSOnline\Microsoft.Online.Administration.Automation.PSModule.dll).VersionInfo.FileVersion

podíváme na verzi, tak ten update tam prostě tu nejnovější nedá. Upozornění se sice již nezobrazuje, ale podle http://social.technet.microsoft.com/wiki/contents/articles/28552.microsoft-azure-active-directory-powershell-module-version-release-history.aspx jsou k dispozici dokonce dvě novější verze. Bez té se nedá zapnout například DuplicateUPNResiliency nebo DuplicateProxyAddressResiliency (viz. https://azure.microsoft.com/en-us/documentation/articles/active-directory-aadconnectsyncservice-duplicate-attribute-resiliency/).

CSR pro Domain Controller certifikát (offline request)

Poslední dobou často vystavujeme základní certifikáty pro doménové řadiče na certifikačních autoritách které jsou v jiných AD forestech. Možná se někomu bude hodit PowerShell skript, který celý proces generování výrazně usnadní. Výsledná žádost neobsahuje GUID, nicméně to ve většině případů ani moc nevadí 🙂

####################################################################################################
######## This script generates CSR for DC certificate (signed by external CA).
######## Version 1.2 (2016-04-19)
######## Jan Zak (www.jan-zak.cz)
####################################################################################################

#Define variables

$ComputerName=(Get-WmiObject win32_computersystem).DNSHostName
$ComputerDomain=(Get-WmiObject win32_computersystem).Domain
$ComputerFQDN=(Get-WmiObject win32_computersystem).DNSHostName+"."+(Get-WmiObject win32_computersystem).Domain
$DomainNetBIOSName=(Get-ADDomain).NetBIOSName
#$WorkDir=(Get-Location).Path 
$WorkDir=$Env:USERPROFILE + "\Desktop"
$CSRFilePath = $WorkDir + "\" + $ComputerName + ".csr"
$DCRequestINFFileName = $WorkDir + "\" + $ComputerName + ".inf"

Clear-Host

#Verify permissions for access to private keys
$myIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$wp = New-Object Security.Principal.WindowsPrincipal($myIdentity)
if (-not $wp.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
 Write-Host "This script requires administrative privileges, please re-launch with elevated credentials." -ForegroundColor Red -BackgroundColor Yellow
 Start-Sleep 20
 Exit
}


Write-Host "Collecting data for CSR:" -ForegroundColor Green

$CN=if(($result = Read-Host "Press enter to accept $ComputerFQDN as CN or specify a value: ") -eq '') {$ComputerFQDN} else {$result}
$SAN1=if(($result = Read-Host "Press enter to accept $CN as SAN1 or specify a value: ") -eq '') {$CN} else {$result}
$SAN2=if(($result = Read-Host "Press enter to accept $ComputerDomain as SAN2 or specify a value: ") -eq '') {$ComputerDomain} else {$result}
$SAN3=if(($result = Read-Host "Press enter to accept $DomainNetBIOSName as SAN3 or specify a value: ") -eq '') {$DomainNetBIOSName} else {$result}
Write-Host
Write-Host Values to build CSR: -ForegroundColor Green
Write-Host ==================== -ForegroundColor Green
Write-Host CN=$CN
Write-Host DNS=$SAN1
Write-Host DNS=$SAN2
Write-Host DNS=$SAN3
Write-Host
Write-Host Files are going to be stored in $WorkDir\ folder.

write-host -nonewline "Continue? (Y/N) " -ForegroundColor Yellow
$response = read-host
if ( $response -ne "Y" ) { exit }


# Build CSR file

Write-Host "Preparing Server Certificate Request File (CertReq.inf) for $ComputerName `r "

$DCRequestINFFileContent =
@"
[Version]

Signature="$Windows NT$"

[NewRequest]

Subject = "CN=$CN" ; Remove to use an empty Subject name.
;Because SSL/TLS does not require a Subject name when a SAN extension is included, the certificate Subject name can be empty.
;If you are using another protocol, verify the certificate requirements.
;EncipherOnly = FALSE ; Only for Windows Server 2003 and Windows XP. Remove for all other client operating system versions.
Exportable = TRUE ; TRUE = Private key is exportable
KeyLength = 2048 ; Valid key sizes: 1024, 2048, 4096, 8192, 16384
KeySpec = 1 ; Key Exchange – Required for encryption
KeyUsage = 0xA0 ; Digital Signature, Key Encipherment
MachineKeySet = True
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
RequestType = PKCS10 ; or CMC.

[EnhancedKeyUsageExtension]
; If you are using an enterprise CA the EnhancedKeyUsageExtension section can be omitted
OID=1.3.6.1.5.5.7.3.1 ; Server Authentication
OID=1.3.6.1.5.5.7.3.2 ; Client Authentication
OID=1.3.6.1.5.2.3.5 ; KDC Authentication
OID=1.3.6.1.4.1.311.20.2.2 ; Smart Card Logon


[Extensions]
; If your client operating system is Windows Server 2008, Windows Server 2008 R2, Windows Vista, or Windows 7
; SANs can be included in the Extensions section by using the following text format. Note 2.5.29.17 is the OID for a SAN extension.
2.5.29.17 = "{text}"
_continue_ = "dns=$SAN1&"
_continue_ = "dns=$SAN2&"
_continue_ = "dns=$SAN3&"


; If your client operating system is Windows Server 2003, Windows Server 2003 R2, or Windows XP
; SANs can be included in the Extensions section only by adding Base64-encoded text containing the alternative names in ASN.1 format.
; Use the provided script MakeSanExt.vbs to generate a SAN extension in this format.
; RMILNE – the below line is remmed out else we get an error since there are duplicate sections for OID 2.5.29.17
; 2.5.29.17=MCaCEnd3dzAxLmZhYnJpa2FtLmNvbYIQd3d3LmZhYnJpa2FtLmNvbQ

[RequestAttributes]
; If your client operating system is Windows Server 2003, Windows Server 2003 R2, or Windows XP
; and you are using a standalone CA, SANs can be included in the RequestAttributes
; section by using the following text format.
;”SAN="dns=not.server2008r2.com&dns=stillnot.server2008r2.com&dns=meh.2003server.com"
; Multiple alternative names must be separated by an ampersand (&).

;CertificateTemplate = WebServer ; Modify for your environment by using the LDAP common name of the template.

;Required only for enterprise CAs.
"@

Write-Host "Generating Certificate Request file... `r " -ForegroundColor DarkYellow
$DCRequestINFFileContent | out-file -filepath $DCRequestINFFileName -force
certreq -new $DCRequestINFFileName $CSRFilePath
Remove-Item $DCRequestINFFileName -Force

Write-Host "CSR fle created as $CSRFilePath. Use this file to request the DC's server certificate `r " -ForegroundColor Green
Start-Sleep 20
exit

Perfect Forward Secrecy a TLS pro Windows Server

Poslední dobou všichni provádí bezpečnostní audity a panikaří ze špatných známek od https://www.ssllabs.com.

Skvělý PS skript pro snadné získání lepších známek je k dispozici na

https://www.hass.de/content/setup-your-iis-ssl-perfect-forward-secrecy-and-tls-12

Klikači samozřejmě mohou použít neméně skvělý IIS Crypto od  https://www.nartac.com/Products/IISCrypto/