Manage IIS HTTPS Bindings with Powershell?

Welcome Forums General PowerShell Q&A Manage IIS HTTPS Bindings with Powershell?

This topic contains 5 replies, has 3 voices, and was last updated by

 
Participant
3 months ago.

  • Author
    Posts
  • #161966

    Participant
    Topics: 1
    Replies: 2
    Points: 37
    Rank: Member

    Howdy, I have a few customers using client certificates for HTTPS client authentication (to validate that the channel can be trusted, not to authenticate to the application fully), but for whom the CRL is only published via LDAP... and the LDAP server isn't accessible to their IIS host.

    The following instructions are clear and solve the problem, allowing us to disable certificate checking only on the HTTPS site in question: https://blogs.msdn.microsoft.com/kaushal/2012/10/15/disable-client-certificate-revocation-crl-check-on-iis/

    To recap, the commands are:

    netsh http show sslcert
    
    netsh http delete sslcert ipport=0.0.0.0:443
    
    netsh http add sslcert ipport=0.0.0.0:443 certhash=40db5bb1bf5659a155258d1d007c530fcb8996c2
    appid={4dc3e181-e14b-4a21-b022-59fc669b0914}
    certstorename=My verifyclientcertrevocation=disable

    but they use netsh to edit the bindings, which... doesn't script well inside powershell. ūüôā

    The problem is that the "certhash" and "appid" values can be dynamic (IIS is always that AppID, but the certhash will definitely change on each binding).  So I want to script "list the bindings, capture the hash of the cert used for this binding, and insert it into the last command to create the new binding."

    The IISAdministration 10 cmdlets for powershell include "Get-IISSiteBinding", "Remove-IISSiteBinding", and "new-IISSiteBinding", which appear to be the same commands under the hood as the netsh http commands, so all should be good, right?

    New-IISSiteBinding does not have a parameter for "VerifyClientCertRevocation": https://docs.microsoft.com/en-us/powershell/module/iisadministration/new-iissitebinding?view=win10-ps

    So, anyone have any ideas how I can script this in PowerShell?  FWIW 100% of the systems I need to edit are 2012 R2 or 2016.

  • #162059

    Participant
    Topics: 2
    Replies: 999
    Points: 1,946
    Helping Hand
    Rank: Community Hero

    You can just use netsh for all or parts of what you are doing, and this approach is a common thing when PowerShell does not have something directly in it for X or Y. So, falling back to an older cmdline tool or popping into .Net namespaces is a thing.

    All this does is set this Reg, so you could also use the Registry cmdlets, to set it.

    Registry: HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\SslBindingInfo
    Dword   : DefaultSslCertCheckMode
    Value     : 1

    Value Meaning

    0  Enables the client certificate revocation check
    1  Client certificate is not to be verified for revocation.
    2  Only cached certificate revocation is to be used
    4  The DefaultRevocationFreshnessTime setting is enabled
    0x10000 No usage check is to be performed

    Also of note, With IIS there are 2 new SSL bindings viz. SNI Bindings and CCS Bindings.

  • #162063

    Participant
    Topics: 8
    Replies: 31
    Points: 116
    Helping Hand
    Rank: Participant

    Here's what I use when I build IIS servers.

    New-WebBinding -Name "Default Web Site" -Protocol https
    $Binding = Get-WebBinding -Protocol https
    $Cert = Get-ChildItem -Path Cert:\LocalMachine\My | where FriendlyName -Like "CERTNAMEFILTER"
    $Binding.AddSslCertificate($Cert.GetCertHashString(), "My")

     

     

    • #162092

      Participant
      Topics: 1
      Replies: 2
      Points: 37
      Rank: Member

      @Darwin thanks, but how would I disable certificate checking with your method?  I like it better than random registry keys, if I could figure it out.  The problem with pulling the cert from the local store, rather than the original binding, is that in auto-enroll environments, a computer may have 2 or more certificates in the local store (My lab root CA has 3: 1 for the LDAP cert, one for the CA cert, and one for the CA HTTPS /certsrv website cert.

       

      @postanote The documentation isn't clear Рis this the structure for all bindings, or just the registry key for the default binding?  IE: I can enumerate bindings in the registry and change the key underneath them appropriately?  I won't be able to get on a test box till Friday to look.
      And yes, I could use netsh to *set* the value, but I need to read the correct certificate out, in order to push it back, and netsh doesn't generate output I have been able to successfully capture in powershell variables, so that I can pull the right thumbprint with select-string.

       

      Thanks!

  • #162170

    Participant
    Topics: 8
    Replies: 31
    Points: 116
    Helping Hand
    Rank: Participant

    My code is just applying the cert I got from our corporate CA to the Default Web Site.  If you know the name of the cert (CERTNAMEFILTER in my code), you can apply it to a particular website instead of "Default Web Site."  But I'm not sure how auto-enroll will impact that.

  • #162269

    Participant
    Topics: 1
    Replies: 2
    Points: 37
    Rank: Member

    Autoenroll isn't the only case where you may have problems here, it just is a form of the generic problem "how do you know precisely which certificate to use for any given site, programatically?"

    Here are the certs, and some properties of them, for example, from my lab Windows 2016 DC, which is also my lab's enterprise root CA *and* hosts the certificate autoenrollment HTTPS site.  You'll see there are 2 certs with the same CN Рone of them is the LDAP autoenrolled certificate (Template = Domain Controller), and one is the IIS website autoenrolled certificate (Template = modified Web Server (2003+ version)).

    So, again, in your line 3: how do I know which cert to use?  The advantage of the "netsh http show sslcert" is that I can filter on the IIS binding in question, pull the precise correct thumbprint, and reuse that same thumbprint, without needing to know anything else about the certificate.  The problem is that I can't capture the netsh output.

    In a single test so far, @postanote 's method changes the default behavior when a new binding is created, so I'd need to modify that, then delete the old binding, create the new, and then set the default value *back* to the original, to preserve security on future websites on the same server.

    PS C:\Users\rob-adm> gci cert:\localmachine\my | foreach { 
      if ($_.HasPrivateKey) { 
        Write-Host "`n" $_.Subject;
        foreach ($use in $_.EnhancedKeyUsageList) { 
          write-Host $use ;
        };  
        foreach ($ext in $_.Extensions) { 
          $ext | Select-Object -property *;
        } ;   
      };
    }
    
     CN=dc01.test.corp
    Server Authentication (1.3.6.1.5.5.7.3.1)
    
     CN=test-DC01-CA, DC=test, DC=corp
    
     CN=dc01.test.corp
    Client Authentication (1.3.6.1.5.5.7.3.2)
    Server Authentication (1.3.6.1.5.5.7.3.1)
    
     CN=dc01.test.corp, OU=Domain Controllers, O=TEST, L=New York, S=NY, C=US
    Server Authentication (1.3.6.1.5.5.7.3.1)
    Critical Oid                              RawData
    -------- ---                              -------
       False System.Security.Cryptography.Oid {30, 18, 0, 87...}
       False System.Security.Cryptography.Oid {48, 10, 6, 8...}
        True System.Security.Cryptography.Oid {3, 2, 5, 160}
       False System.Security.Cryptography.Oid {4, 20, 125, 255...}
       False System.Security.Cryptography.Oid {48, 18, 130, 16...}
       False System.Security.Cryptography.Oid {48, 22, 128, 20...}
       False System.Security.Cryptography.Oid {48, 129, 245, 48...}
       False System.Security.Cryptography.Oid {48, 130, 1, 4...}
       False System.Security.Cryptography.Oid {3, 2, 1, 134}
        True System.Security.Cryptography.Oid {48, 3, 1, 1...}
       False System.Security.Cryptography.Oid {4, 20, 127, 193...}
       False System.Security.Cryptography.Oid {2, 1, 0}
       False System.Security.Cryptography.Oid {30, 32, 0, 68...}
       False System.Security.Cryptography.Oid {48, 20, 6, 8...}
        True System.Security.Cryptography.Oid {3, 2, 5, 160}
       False System.Security.Cryptography.Oid {48, 105, 48, 14...}
       False System.Security.Cryptography.Oid {4, 20, 186, 80...}
       False System.Security.Cryptography.Oid {48, 22, 128, 20...}
       False System.Security.Cryptography.Oid {48, 129, 245, 48...}
       False System.Security.Cryptography.Oid {48, 130, 1, 4...}
       False System.Security.Cryptography.Oid {48, 51, 160, 31...}
        True System.Security.Cryptography.Oid {3, 2, 5, 160}
       False System.Security.Cryptography.Oid {48, 10, 6, 8...}
       False System.Security.Cryptography.Oid {48, 105, 48, 14...}
       False System.Security.Cryptography.Oid {30, 18, 0, 87...}
       False System.Security.Cryptography.Oid {4, 20, 7, 227...}
       False System.Security.Cryptography.Oid {48, 22, 128, 20...}
       False System.Security.Cryptography.Oid {48, 129, 245, 48...}
       False System.Security.Cryptography.Oid {48, 130, 1, 4...}

The topic ‘Manage IIS HTTPS Bindings with Powershell?’ is closed to new replies.