How to Setup, Manage, and Maintain WSUS: Part 7 – SSL Setup for WSUS and Why You Should Care!

by | Last updated 2024.01.12 | Published on 2018.06.01 | Guides, WSUS

We can go on explaining why you should switch over your WSUS Server to SSL so that you can mitigate Man-In-The-Middle (MITM) attacks, but sometimes it is better to show you.

The following video is worth the watch as they explain exactly how relatively easy it is to take over a network by just having access to it with a WSUS Server that does not have SSL Enabled.

From Blackhat USA 2015 – WSUSpect – Compromising The Windows Enterprise Via Windows Update

Please, everyone, mitigate this risk and switch your WSUS to SSL. This does NOT mean that you can turn off HTTP as communication between clients and the WSUS server use both HTTP and HTTPS much like FTP uses port 20 (data) and 21 (command channel).

Emin Atac, a PowerShell MVP, posted a simple PowerShell method of switching your WSUS Server to use SSL with a self-signed Certificate which we have re-posted here with some modifications for streamlining. We have also broken this out into 2 groups – a self-signed certificate script and an internal CA certificate script. The self-signed certificate method contains 8 steps and 7 of them can be copy/pasted or run as a single step. If you have your own Internal CA, it is best to use your CA to request the certificate and import it into your certificate store on the WSUS server then run the script.

Self-Signed Certificate PowerShell Conversion to HTTPS for WSUS

PowerShell Example – Do not copy/paste this into a script. Instead run it line by line on the PowerShell console so that you can adjust based on your needs. If you need to deploy it to multiple systems, after confirming your commands, then you can take those and build it into a deployment script.

# 1. Create a self-signed certificate using the FQDN
    # Setup the stage dynamically for the $FQDN based on if the system is a member of a domain or is just in a workgroup.
    $DNSHostName = (Get-CimInstance win32_computersystem -Verbose:$False).DNSHostName
    $DNSDomainName = $( if ((Get-CimInstance -Class Win32_ComputerSystem -Verbose:$False).PartOfDomain -eq 'True') { (Get-CimInstance win32_computersystem -Verbose:$False).Domain } )
    $FQDN = "$DNSHostName$( if ((Get-CimInstance -Class Win32_ComputerSystem -Verbose:$False).PartOfDomain -eq 'True') { ".$DNSDomainName" } )".ToLower()
    # Create the hash table for splatting
    $SelfSignedHT = @{
     DnsName = $FQDN
     CertStoreLocation = "Cert:\LocalMachine\My"
    }
    # Create the self-signed certificate and set a variable to hold the object
    $SelfSignedWSUSCertificate = New-SelfSignedCertificate @SelfSignedHT
 
# 2. Export its public key to the local user's Documents folder
    Export-Certificate -Cert $SelfSignedWSUSCertificate -Type CERT -FilePath "$([Environment]::GetFolderPath("MyDocuments"))\SelfSignedWSUSCertificate.cer"
     
# 3. Import the public key in the Trusted Root Certificate Authorities store
    Import-Certificate -FilePath "$([Environment]::GetFolderPath("MyDocuments"))\SelfSignedWSUSCertificate.cer" -CertStoreLocation Cert:\LocalMachine\Root
 
# 4. Select this certificate in the SSL bindings
    Get-WebBinding -Protocol https
    $SelfSignedWSUSCertificate | New-Item IIS:\SslBindings\0.0.0.0!8531
 
# 5. Require SSL for the following virtual roots only:
    'SimpleAuthWebService','DSSAuthWebService',
    'ServerSyncWebService','APIRemoting30',
    'ClientWebService' | ForEach-Object {
        Set-WebConfigurationProperty -Filter 'system.webserver/security/access' -Location "WSUS Administration/$($_)" -Name sslFlags -Value 8
    }
 
# 6. Switch WSUS to SSL
    & 'C:\Program Files\Update Services\Tools\WsusUtil.exe' configuressl $($FQDN)
 
# 7. Change your GPO to point to the new URL
    if ($(Get-WindowsFeature -Name GPMC).installed -eq $False) { Install-WindowsFeature GPMC }
    Import-Module -Name GroupPolicy
    $WindowsUpdateKey = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate'
    $WindowsUpdateURI = 'https://{0}:8531' -f $($FQDN)
    Get-GPO -All | Foreach-Object { 
        if ($_ | Get-GPRegistryValue -Key $WindowsUpdateKey -ValueName WUServer -EA 0) {
            $_ | Set-GPRegistryValue -Key $WindowsUpdateKey -ValueName WUServer       -Value $WindowsUpdateURI -Type String
            $_ | Set-GPRegistryValue -Key $WindowsUpdateKey -ValueName WUStatusServer -Value $WindowsUpdateURI -Type String
            # If you are NOT storing updates locally computers install from Microsoft Update - DO NOT set the UpdateServiceUrlAlternate URI
            if ($(Get-WsusServer).GetConfiguration().HostBinariesOnMicrosoftUpdate -eq $False) {
                $_ | Set-GPRegistryValue -Key $WindowsUpdateKey -ValueName UpdateServiceUrlAlternate -Value $WindowsUpdateURI -Type String
            }
        }
    }

The last step is to distribute the public key of your self-signed certificate to your clients so that they trust your self-signed certificate. You’ll need to edit your GPO that targets clients and import your SelfSignedWSUSCertificate.cer file located in your Documents folder into ‘Computer Configuration / Policies / Windows Settings / Security Settings / Public Key Policies / Trusted Root Certificate Authorities’

Import_Self_Signed_WSUS_Certificate

Internal CA Certificate PowerShell Conversion to HTTPS for WSUS

This assumes you have already requested and received the certificate and it is installed on the WSUS server.

PowerShell Example – Do not copy/paste this into a script. Instead run it line by line on the PowerShell console so that you can adjust based on your needs. If you need to deploy it to multiple systems, after confirming your commands, then you can take those and build it into a deployment script.

# 1. Get the certificate from the certificate store and add the object into a variable
    # Setup the stage dynamically for the $FQDN based on if the system is a member of a domain or is just in a workgroup.
    $DNSHostName = (Get-CimInstance win32_computersystem -Verbose:$False).DNSHostName
    $DNSDomainName = $( if ((Get-CimInstance -Class Win32_ComputerSystem -Verbose:$False).PartOfDomain -eq 'True') { (Get-CimInstance win32_computersystem -Verbose:$False).Domain } )
    $FQDN = "$DNSHostName$( if ((Get-CimInstance -Class Win32_ComputerSystem -Verbose:$False).PartOfDomain -eq 'True') { ".$DNSDomainName" } )"
    $CA_WSUSCertificate = Get-ChildItem -Path Cert:\LocalMachine\My -SSLServerAuthentication | Where-Object { $_.Subject -ilike "*$($FQDN.ToLower())*" }
    if ($CA_WSUSCertificate.Count -gt 1) { Write-Output "There are too many certificates with the FQDN '$FQDN'. You will have to select only one for this variable or you will end up getting all errors trying to set the binding."}
 
# 2. Select this certificate in the SSL bindings
    Get-WebBinding -Protocol https
    $CA_WSUSCertificate | New-Item IIS:\SslBindings\0.0.0.0!8531
 
# 3. Require SSL for the following virtual roots only:
    'SimpleAuthWebService','DSSAuthWebService',
    'ServerSyncWebService','APIRemoting30',
    'ClientWebService' | ForEach-Object {
        Set-WebConfigurationProperty -Filter 'system.webserver/security/access' -Location "WSUS Administration/$($_)" -Name sslFlags -Value 8
    }
 
# 4. Switch WSUS to SSL
    & 'C:\Program Files\Update Services\Tools\WsusUtil.exe' configuressl $($FQDN)
 
# 5. Change your GPO to point to the new URL
    if ($(Get-WindowsFeature -Name GPMC).installed -eq $False) { Install-WindowsFeature GPMC }
    Import-Module -Name GroupPolicy
    $WindowsUpdateKey = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate'
    $WindowsUpdateURI = 'https://{0}:8531' -f $($FQDN)
    Get-GPO -All | Foreach-Object { 
        if ($_ | Get-GPRegistryValue -Key $WindowsUpdateKey -ValueName WUServer -EA 0) {
            $_ | Set-GPRegistryValue -Key $WindowsUpdateKey -ValueName WUServer       -Value $WindowsUpdateURI -Type String
            $_ | Set-GPRegistryValue -Key $WindowsUpdateKey -ValueName WUStatusServer -Value $WindowsUpdateURI -Type String
            # If you are NOT storing updates locally computers install from Microsoft Update - DO NOT set the UpdateServiceUrlAlternate URI
            if ($(Get-WsusServer).GetConfiguration().HostBinariesOnMicrosoftUpdate -eq $False) {
                $_ | Set-GPRegistryValue -Key $WindowsUpdateKey -ValueName UpdateServiceUrlAlternate -Value $WindowsUpdateURI -Type String
            }
        }
    }

As you have already distributed your internal RootCA certificate, you are finished.

RemoteApp and Desktop Connections

RemoteApp and Desktop Connections

How Do I Add RemoteApp Connections? Ever get sick of trying to find the right way of mass-adding a RemoteApp connection feed to a large amount of computers? There are a few ways: manually (YUCK!), and automatically using a GPO: User Configuration > Policies >...

WSUS Permissions – WsusContent, Registry, and IIS

WSUS Permissions – WsusContent, Registry, and IIS

If you Google WSUS Permissions, you may end up getting a boatload of links to support help on TechNet, Spiceworks, ExpertsExchange, Microsoft Docs, or other blogs around the Internet. Most of the links are only for specific parts - maybe the WsusContent folder, maybe...