Skip to content

david-garcia-garcia/iischef

Repository files navigation

Build status

IIS Chef

A set of C# based Cmdlets for powershell aimed at supporting Internet Information Services based deployments, including basic Let's Encrypt certificate renewal support targeted at a very specific scenario: using Central Certificate Store with load balanced web heads.

Chef is licensed under GNU v3

How to get it

...

Using the console

Download, extract and import the CMDLET

Use the following commands to install the Chef cmdlets system wide:

$ZipFilePath = Join-Path -Path $env:TEMP -ChildPath "chef_cmdlet.zip"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest "https://ci.appveyor.com/api/projects/david-garcia-garcia/iischef/artifacts/iischef.cmdlet.zip?branch=1.x" -OutFile $ZipFilePath
$Destination = Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell\Modules\iischef"
New-Item -Path $Destination -ItemType Directory -Force | Out-Null
Expand-Archive -Path $ZipFilePath -DestinationPath $Destination -Force
Remove-Item -Path $ZipFilePath -Force

Quick Start

Make sure you have the required IIS componentes installed.

# Enable central certificate store if not enabled
Enable-WindowsOptionalFeature -FeatureName "IIS-CertProvider" -Online;
# Url rewrite an iis-arr
choco install urlrewrite -y;
choco install iis-arr -y;

Then run these commands for the initial setup.

# Setup the Central Certificate Store (required, even if it is already setup, so that the PrivateKey can be knwon)
Invoke-IISChefSetupCcs -PrivateKeyPassword "myprivatekeypassword" -Username "account" -Password "accountpwd"
# Setup the challenge site, run this on all webheads that serve the hostname/s
Invoke-IISChefSetupAcmeChallenge -SharedPath "\\SAMBASHARE\acme"
# Start provisioning certificates
Invoke-IISChefGetCert -Hostname "www.mydomain.com" -Provider Acme -RegistrationMail "myemail@mycompany.com"

Command Reference

Invoke-IISChefSetupCcs

Enables and configures Central Certificate Store on the current computer. This command stores vital information that is needed by other commands such as the private key password for the certificates. Most of the arguments are optional when running after the initial setup as these values get stored, but are needed for the initial setup.

Before performing a provisioning attempt, the command does some validations including DNS and challenge accessibility to avoid consuming failed renewal attempts from the ACME API. If a failure happens, a lock is placed for the Hostname that lasts for 72 hours.

string CertStoreLocation (optional)

Specifies the physical path to the central certificate store. The path is either a local path such as D:\CertStore, or a UNC path such as \\CertStoreServer\CertStore. Be warned, if your networking is not stable, having the CCS on a shared SAMBA drive can lead to issues when IIS reads the certificate, resulting in temporary glitches where IIS does not have the certificates.

string UserName (optional)

Specifies the name of the user account that is used to access the central certificate store. When run for the first time this command will create a local user iis_ccs_store.

string Password (optional)

Specifies the password of the user account that is used to access the central certificate store. When run for the first time this command will create a local user iis_ccs_store with autogenerated random credentials.

string PrivateKeyPassword (optional)

Specifies a password for the private key if one exists. If specified, this password is the same for all keys. The password can be $Null.

SwitchParameter RegenerateStoreAccount

Use this parameter to recreate the default local account used to access the certificate store. You can only set this flag if the currently configured account is the default account (iis_ccs_store) or you specify explicitly that as a username through the -Username argument.

SwitchParameter InstallLetsEncryptChainToCertUser

Will try to add to the Let's Encrypt intermediate certificates to the account used for CCS. This is not needed for CCS to work, but servers as a fix to this issue:

Examples

Setup CCS using the default autogenerated identity:

# This will configure CCS to store certificates at c:\certificates, using as identity a local windows account
Invoke-IISChefSetupCcs -CertStoreLocation "c:\certficates" -PrivateKeyPassword "myprivatekeypassword"

Setup CCS with a custom identity:

# This will configure CCS to store certificates using a custom domain user and a remote SAMBA share
Invoke-IISChefSetupCcs -CertStoreLocation "\\REMOTESERVER\certficates" -PrivateKeyPassword "myprivatekeypassword" -UserName "user@domain.loc" -Password "passwordfortheuser"

Invoke-IISChefSetupAcmeChallenge

In order to support challenge validation, this tool registers a web site in IIS and a server level proxy rewrite rule using IIS Url Rewrite and IIS ARR. This commands sets up this proxy site.

The proxy listens to all incoming requests that start with the .well-known/acme-challenge path, and redirect them to the specific site. If the site is setup to use shared storage, the challenge can be validated across al webheads. At the time of this writing, tools such as Certify The Web - ACME for Windows, simple free certificates for IIS and more, powered by Let's Encrypt and other ACME CAs or win-acme will not allow you to have unattended renewal in load balanced scenarios where the challenges need to be available in all web-heads.

string SharedPath (optional)

The path where the challenge site will be pointing to. If not specified, default's to a "shared" directory inside the currently configured Central Certificate Store Path.

SwitchParameter VerboseOut (optional)

Enable verbose output.

Examples

Setup challenge site on a shared drive

Import-Module WebAdministration
# Setup the site
Invoke-IISChefSetupAcmeChallenge -SharedPath "\\SAMBASHARE\acme"
# Chances are that the share might need a special identity, set it up
Set-ItemProperty IIS:\AppPools\__acmechallenge -name processModel -value @{userName="user_name";password="password";identitytype=3}

Setup challenge site on the default site

# This will set it on a "shared" subdirectory in the current central certificate store path
Invoke-IISChefSetupAcmeChallenge

Invoke-IISChefCcsChangePrivateKeyPassword

Use this command to update the private key password for the certificates in the central certificate store. Iterates all the PFX files, and those that can be opened using the provided Existing password, are updated to the New password.

string Existing (required)

The password protecting the existing certificates. Allows $null or empty strings to represent certificates not protected by any password.

string New (optional)

The new password for the private keys. If not specified, the one that has been set for CCS through the Invoke-IISChefSetupCcs command will be used.

Examples

# Updates any PFX file in the CCS where the -Existing password works to the -New password, in this case the one stored in the CCS.
Invoke-IISChefCcsChangePrivateKeyPassword -Existing "oldpfxpasswod"
# Updates any PFX file in the CCS where the -Existing password works to the -New password, in this case the one stored in the CCS.
Invoke-IISChefCcsChangePrivateKeyPassword -Existing "oldpfxpasswod" -New "newpassword"

Invoke-IISChefGetCert

Provision a PFX certificate for a Hostname, and place it in the Central Certificate Store. Make sure you have previously configured CCS using the Invoke-IISChefSetupCcs command.

string Hostname

The hostname that the certificate should be provisioned for.

int? RenewThresholdDays

Default is 20. Number minimum of days before expiration for a certificate to be renewed. If a certificate exists in the CCS for the requested hostname and the threshold has not been reached, no provisioning attempt will be made unless you use the -Force option.

string RegistrationMail

Required to setup the registrar in the Let's Encrypt API.

CertProvider Provider

One of:

  • SelfSigned
  • Acme
  • AcmeStaging

SwitchParameter Force

Use this parameter to skip all checks, and force a certificate provisioning attempt.

SwitchParameter DisableDnsValidation

By default the hostname DNS records are checked before attempting certificate provisioning.

Examples

Introspect all SSL bindings configured in IIS, and renew all certificates that expire in less than 20 days using the ACME provider.

# Ensure the IISAdministration module is imported
Import-Module IISAdministration;

# Iterate through all sites in IIS
Get-IISSite | ForEach-Object {
    $siteName = $_.Name
    $siteState = $_.State

    # Proceed only if the site is not in a stopped state
    if ($siteState -ne 'Stopped') {
        # Iterate through each binding of the current site
        $_.Bindings | ForEach-Object {
            $binding = $_

            # Check if the binding is HTTPS
            if ($binding.Protocol -eq 'https') {
                # Extract the domain name from the binding information
                $domainName = $binding.BindingInformation.Split(':')[2]

                # Check if the domain name is not empty and does not contain a wildcard
                if (![string]::IsNullOrWhiteSpace($domainName)) {
                    # Check if the domain name does not contain an asterisk
                    if (-not $domainName.Contains("*")) {
                        Invoke-IISChefGetCert -HostName $domainName -Provider Acme -RegistrationMail "tecnologia@mycompany.com" -RenewThresholdDays 20 -VerboseOut
                    }
                }
            }
        }
    }
}

Invoke-IISChefSyncCertsToSite

Given a website, introspects all available PFX certificates in the CCS and adds HTTPS bindings to support ALL those certificates. This command only adds, it does not remove. This command is aimed at single site containerized applications, helping to synchronize SSL bindings in the site with actually available SSL certificates.

string SiteName

The name of the site where the SSL bindings will be created to reflect the available certificates in CCS.

Use this command to insert or update environment variables for application pools (at the pool level). In containerized scenarios environment variables are set at the process level in the entry point, this is a reasonable way of propagating the environment variables you need to the actual application pool.

string Pool (required)

The name of the application pool.

Hashtable Env

Key-value pairs that represent the environment variables.

Examples

Invoke-IISChefPoolEnvUpsert -Pool "DefaultApplicationPool" -Env @{ "KEY1" = "VALUE1"; "KEY2" = "VALUE2"}

Invoke-IISChefCcsCleanup

Deletes all certificates in the CCS that are currently not in use (that is, there is no binding in IIS that justifies the use of that certificate) and that have expired more than -ExpireThreshold days ago.

int ExpireThreshold (optional) (default=30)

Only certificates that expired more than ExpireThreshold days ago, and are not in use by any IIS bindings, will be deleted.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published