Tips & Tricks
Mathieu Morrissette

Hello everyone! As a certified OSCP security specialist here at Devolutions, I have the privilege of testing the security of our code, and our solutions to ensure that you have the most secure experience when using our products. Besides that, I also work with developers to write safer code, I keep up with trends at security conferences and during breaks, I like to play the Star Wars pinball machines in the break room. As a huge Star Wars fan, the office here at Devolutions makes me feel right at home.

[TUTORIAL] How to Enhance Your IIS Server Security with Client Certificates

Certificates are easily deployed in a Active Directory (AD) infrastructure but using them to manage accesses, especially to websites hosted on an Internet Information Services (IIS) server can be challenging due to the lack of good documentation on the Internet. This is why I created this tutorial that can also be used as a small cheat sheet.

Since this feature is part of the Transport Layer Security (TLS) standard most servers such as IIS, Apache, Nginx support this feature natively. Popular browsers (Internet Explorer, Chrome, Firefox, etc.) also support this feature natively.

This tutorial will teach you how to configure this feature on a Internet Information Services (IIS) server.

Why should I use this feature?

This feature adds a layer of authentication in front of all of your web sites or can be configured to a subset of your web sites. This feature is especially useful to increase security to highly sensitive web sites. TLS is generally used to guarantee the connection to a server is secure. It is however also possible for a server to validate that only specific clients (eg. browsers) can connect to it.

Is it really secure?

This form of authentication algorithm is enforced mathematically with asymmetric cryptography. TLS (formerly known as SSL) client authentication has been part of the Transport Layer Protocol for a long time and is an industry proven standard for secure communications.

This feature is also often used for compliance in a large organization that need to make sure that only authorized users can access internal websites.

Requirements

Here is what you need for this tutorial:

  • A Certificate Authority certificate
  • A Server certificate
  • One or more Client certificate(s) (for users)

Before You Begin

If you need to generate the certificates, please view my previous blog post. After that is done, complete the following:

  1. Install the ca.crt (public key) file in the following IIS server certificate store:
    Local ComputerTrusted Root Certification Authorities

  2. You will need to merge the server.crt (public key) and server.key (private key) files into a single file named server.pfx with the following command line:

    openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt
    

    You will be prompted to enter a password; make sure you use a strong one.

    Install the resulting server.pfx file in the following IIS server certificate store:
    Local ComputerPersonal

  3. Each client that will access the server needs a certificate. Just like the server certificate above, both the public key (.crt) and private key (.key) will need to be merged into a single .pfx file. The .pfx file will need to be installed on the user’s computer in the following store:
    Current UserPersonal

I’ve tried to simplify this tutorial into easy to follow steps. I also show how to do it manually and also via PowerShell scripts. Take care to modify the scripts to match your environment.

How to Configure IIS

Step 1 - Enabling the required features

Enable IIS Client Certificate Mapping Authentication in the windows features dialog in the Internet Information ServicesWorld Wide Web ServicesSecurity section. (View Image 1)

The Windows features dialog can be opened using the following shortcut:

WIN + R -> optionalfeatures

On a Windows Server, you can enable this feature in the server configuration manager.

It can also be enabled using the following PowerShell command :

Enable-WindowsOptionalFeature -Online -FeatureName IIS-IISCertificateMappingAuthentication

Image 1 - Enabling IIS Client Certificate Mapping Authentication
Image 1 - Enabling IIS Client Certificate Mapping Authentication

Step 2 - Configure a HTTPS binding

Configure your SSL certificate in the Site binding dialog in the IIS Manager. To open the Side Binding dialog, you must select the website where you want to enable this feature then click on Bindings.... Lastly, you must add a HTTPS binding and select your server certificate. An example is shown below (image 2 and 3):

Default Web SiteBindings…Add…

It can also be done with a few simple PowerShell commands:

# List certificates in the local machine personal store.
Get-ChildItem -Path CERT:LocalMachine/My

Thumbprint                                Subject
----------                                -------
838E34D06C2FB5C80E99E6B6938C4127134B32A5  CN=localhost
6A11EAFFBB6A7E1F3CE11DAE82956D4F2973320E  CN=mathmo.org, O="MathMoOrganisation, Inc.", S=CA, C=US

# Create HTTPS binding if it doesn't exists
New-WebBinding -name "Default Web Site" -Protocol https -Port 443

# Get the bindings
$bindings = Get-WebBinding -Name "Default Web Site"

# Configure the certificate mathmo.org for the bindings
$bindings.AddSslCertificate("6A11EAFFBB6A7E1F3CE11DAE82956D4F2973320E",'My')

Image 2 – Opening the Site Binding Dialog
Image 2 – Opening the Site Binding Dialog

Image 3 - Configuring the Server Certificate for the HTTPS Binding
Image 3 - Configuring the Server Certificate for the HTTPS Binding

Step 3 - Enforce SSL on the website

Make sure that your website requires SSL and requires a client certificate. This can be done by opening the SSL settings. To open the SSL settings you must select your website where you want to enable this feature, filter for the SSL settings, select it and click on Open Feature. In the examples show below (see image 4 and 5) the flow goes like this:

Default Web SiteFilter SSL SettingsSelect SSL SettingsOpen Feature

It can also be done with a PowerShell command:

Set-WebConfiguration -Location "Default Web Site" -Filter "system.webserver/security/access" -Value "Ssl,SslNegotiateCert, SslRequireCert"

Image 4 - Opening the Website SSL Settings
Image 4 - Opening the Website SSL Settings

Image 5 - SSL Settings
Image 5 - SSL Settings

Step 4 - Disable Anonymous Authentication

Make sure that you disable Anonymous authentication on your web site by going into the Authentication settings. In the examples show below (Image 6 and 7):

Default Web SiteAuthenticationOpen Feature

PowerShell command:

Set-WebConfigurationProperty -filter "/system.WebServer/security/authentication/AnonymousAuthentication" -name enabled -value false -location "Default Web Site"

Image 6 - Opening the Authentication Settings
Image 6 - Opening the Authentication Settings

Image 7 - Disabling Anonymous Authentication
Image 7 - Disabling Anonymous Authentication

Step 5 - Enable client authentication in IIS

You are now ready to enable the feature on your website!

5.1 - Start by opening your website Configuration Editor.

Image 8 - Configuration Editor
Image 8 - Configuration Editor

5.2 - Go to the system.webServer/security/authentication/iisClientCertificateMapping Authentication section (see image 9).

Image 9 - Section Field
Image 9 - Section Field

5.3 - Here you can choose to enable manyToOneCertificateMappingsEnabled or oneToOneCertificateMappingsEnabled (see image 10).

PowerShell

 # enable certificate mapping authentication for Default Web Site
 Set-WebConfigurationProperty -filter "/system.webServer/security/authentication/iisClientCertificateMappingAuthentication" -name enabled -Value true -location "Default Web Site"
 
 # enable oneToOneCertificateMappings for Default Web Site
 Set-WebConfigurationProperty -filter "/system.webServer/security/authentication/iisClientCertificateMappingAuthentication" -name oneToOneCertificateMappingsEnabled -Value true -location "Default Web Site"

Image 10 - Enabling the Authentication Feature and the oneToOneMappings Sub-Feature
Image 10 - Enabling the Authentication Feature and the oneToOneMappings Sub-Feature

We recommend the oneToOneCertificateMappings, as it requires users to have their own certificate and it is safer. However, manyToOneMappings can also be used. It will reduce the amount of management required, but it is a compromise on the security side of things. Having a single client certificate for a team or a group of users will increase the risk of it being leaked or compromised. The client certificate private key normally must stay on the endpoint where it has been generated.

5.4 - Open the oneToOneMappings Configuration

5.5 - In the dialog you can configure each user with their base64 encoded certificate public key** (instructions on how to obtain it are provided at the end of this article) and their active directory (AD) credentials (see images 11 and 12).

Image 11 - Button to open the oneToOneMappings configuration
Image 11 - Button to open the oneToOneMappings configuration

Image 12 - Configuring a User
Image 12 - Configuring a User

PowerShell

# get the oneToOneMappings collection
$collection = Get-IISConfigSection -SectionPath "system.webServer/security/authentication/iisClientCertificateMappingAuthentication" -Location "Default Web Site" | Get-IISConfigCollection -CollectionName "oneToOneMappings"
 
$username = Read-Host "Username?"
$password = Read-Host "Password?"
$b64CertificatePublicKey = Read-Host "Base64 Certificate Public key?"
 
# create mapping in the oneToOneCertificateMappings
New-IISConfigCollectionElement -ConfigCollection $collection -ConfigAttribute @{"enabled" = "True"; "userName" = $username; "password" = $password; "certificate" =  $b64CertificatePublicKey}

Make sure that the user has read access to the site folder!

5.6 - Close the Collection Editor and Apply the New Configuration Editor Settings (see image 13).

Image 13 - Applying the Changes
Image 13 - Applying the Changes

It is recommended that you restart your website.

Results

If all went well, accessing the website using a popular browser should prompt you a dialog to choose a certificate to authenticate before accessing the server.

Image 14 - TLS Client Authentication Dialog in Google Chrome
Image 14 - TLS Client Authentication Dialog in Google Chrome

Additional Resources:

Note: If you followed this blog to generate self-signed certificates, then the client public key is located in the client1.crt file. The header -----BEGIN CERTIFICATE----- and footer -----END CERTIFICATE----- and line breaks must be removed.

View the example below:

This file client1.crt

-----BEGIN CERTIFICATE-----
MIICUjCCAfegAwIBAgIUbfEfctjOiwDqqBR1vupzjdN4qI0wCgYIKoZIzj0EAwIw
gZ8xCzAJBgNVBAYTAkNBMQswCQYDVQQIDAJRQzESMBAGA1UEBwwJTGF2YWx0cmll
MRkwFwYDVQQKDBBEZXZvbHV0aW9ucyBpbmMuMREwDwYDVQQLDAhTZWN1cml0eTEY
MBYGA1UEAwwPZGV2b2x1dGlvbnMubmV0MScwJQYJKoZIhvcNAQkBFhhzZWN1cml0
eUBkZXZvbHV0aW9ucy5uZXQwHhcNMjAwNjI1MTUwMjMyWhcNMjMwMzIyMTUwMjMy
WjCBlzELMAkGA1UEBhMCQ0ExCzAJBgNVBAgMAlFDMRIwEAYDVQQHDAlMYXZhbHRy
aWUxGTAXBgNVBAoMEERldm9sdXRpb25zIGluYy4xETAPBgNVBAsMCFNlY3VyaXR5
MREwDwYDVQQDDAhKb2huIERvZTEmMCQGCSqGSIb3DQEJARYXSm9obkRvZUBkZXZv
bHV0aW9ucy5uZXQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT/kLSLRnKIdewU
9Ze8KuZbuz7y1PfhTMEfV7ZQ3gRfSxGdRBxftaNFPtxjkmO9hVowyptUR8UvGc9I
a8rRX6NwoxcwFTATBgNVHSUEDDAKBggrBgEFBQcDAjAKBggqhkjOPQQDAgNJADBG
AiEAwvtbZNwzaf1RMvanSGorJwxYSSBiPIUg0YmyfIpG6pwCIQCoE9+V3/2ULCj9
NtzEYsW2uPojMQ3ddr1CpE2m07yIdQ==
-----END CERTIFICATE-----

Should give you the following result:

MIICUjCCAfegAwIBAgIUbfEfctjOiwDqqBR1vupzjdN4qI0wCgYIKoZIzj0EAwIwgZ8xCzAJBgNVBAYTAkNBMQswCQYDVQQIDAJRQzESMBAGA1UEBwwJTGF2YWx0cmllMRkwFwYDVQQKDBBEZXZvbHV0aW9ucyBpbmMuMREwDwYDVQQLDAhTZWN1cml0eTEYMBYGA1UEAwwPZGV2b2x1dGlvbnMubmV0MScwJQYJKoZIhvcNAQkBFhhzZWN1cml0eUBkZXZvbHV0aW9ucy5uZXQwHhcNMjAwNjI1MTUwMjMyWhcNMjMwMzIyMTUwMjMyWjCBlzELMAkGA1UEBhMCQ0ExCzAJBgNVBAgMAlFDMRIwEAYDVQQHDAlMYXZhbHRyaWUxGTAXBgNVBAoMEERldm9sdXRpb25zIGluYy4xETAPBgNVBAsMCFNlY3VyaXR5MREwDwYDVQQDDAhKb2huIERvZTEmMCQGCSqGSIb3DQEJARYXSm9obkRvZUBkZXZvbHV0aW9ucy5uZXQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT/kLSLRnKIdewU9Ze8KuZbuz7y1PfhTMEfV7ZQ3gRfSxGdRBxftaNFPtxjkmO9hVowyptUR8UvGc9Ia8rRX6NwoxcwFTATBgNVHSUEDDAKBggrBgEFBQcDAjAKBggqhkjOPQQDAgNJADBGAiEAwvtbZNwzaf1RMvanSGorJwxYSSBiPIUg0YmyfIpG6pwCIQCoE9+V3/2ULCj9NtzEYsW2uPojMQ3ddr1CpE2m07yIdQ==

I hope this article was helpful to you guys and let me know if you would like me to create a tutorial to enable this feature on Apache, Nginx or other servers!

Related Posts

Read more Tips & Tricks posts