IIS SNI Wildcard SSL Configuration: Solving Conflicts Between Wildcard and Specific Certificates on Same Server


2 views

When configuring IIS with both wildcard SSL certificates (e.g., *.domain.com) and specific certificates (domain2.com, domain3.com) on the same IP address, administrators often encounter routing conflicts where the wildcard binding intercepts all HTTPS traffic regardless of SNI settings.

The root cause lies in how HTTP.sys processes SSL bindings before IIS receives the request. In Windows Server 2012+ with IIS 8+, the binding precedence works as follows:

1. Exact hostname matches (SNI enabled)
2. IP address matches
3. Port matches
4. Wildcard hostname matches (*)

However, in Azure Cloud Services with single IP constraints, we lose the IP-based differentiation layer.

Here's the working configuration sequence:

  1. First create SNI bindings for specific domains:
New-WebBinding -Name "Site2" -Protocol "https" -HostHeader "domain2.com" -Port 443 -SslFlags 1
New-WebBinding -Name "Site3" -Protocol "https" -HostHeader "domain3.com" -Port 443 -SslFlags 1
  1. Then configure the wildcard binding:
New-WebBinding -Name "WildcardSite" -Protocol "https" -HostHeader "*" -Port 443

If encountering HTTP 503 errors:

# Check URL reservations
netsh http show urlacl

# Remove conflicting reservation
netsh http delete urlacl url=https://IP:443/

For Azure Cloud Services with single IP limitation:

  • Use non-standard SSL ports (e.g., 8443) for SNI sites
  • Implement ARR (Application Request Routing) as reverse proxy
  • Consider Azure App Service instead of Cloud Services

To validate your SSL bindings:

Get-ChildItem IIS:\SslBindings | 
Where-Object { $_.Port -eq 443 } | 
Select-Object IPAddress, Port, Host, CertificateHash, SslFlags |
Format-Table -AutoSize

When configuring IIS to handle both wildcard certificates (*.domain.com) and specific certificates (domain2.com) on the same server, we encounter a fundamental limitation in how HTTP.sys processes SSL requests. The core issue stems from IIS's URL resolution order:

1. Exact hostname matches (domain2.com:443)
2. Blank hostname matches (:443) 
3. Weak wildcard matches (*.domain.com:443)

The HTTP.sys driver evaluates SSL bindings before host headers become available. This creates a chicken-and-egg problem where:

  • SNI provides the hostname during TLS handshake
  • IIS must select certificate before seeing HTTP headers
  • Wildcard bindings often "steal" requests meant for specific domains

In Azure Cloud Services (Web Roles), we face additional limitations:

// Azure limitations
- Single VIP per deployment
- No ARR (Application Request Routing) available
- No Server Name Indication (SNI) for Classic Cloud Services

Here's the correct binding sequence for IIS Manager:

  1. Create SNI binding for domain2.com (port 443)
  2. Add wildcard binding for *.domain.com (port 443)
  3. Verify URL ACLs with netsh:
netsh http show urlacl
netsh http delete urlacl url=https://IP:443/

When URL ACL conflicts persist, we can implement port-based separation:

// web.config excerpt
<system.webServer>
    <security>
        <access sslFlags="Sni" />
    </security>
    <bindings>
        <binding protocol="https" bindingInformation="*:443:domain2.com" />
        <binding protocol="https" bindingInformation="*:8443" />
    </bindings>
</system.webServer>

When encountering "Service Unavailable" errors, check these critical components:

Component Verification Command
HTTP.sys registration netsh http show servicestate
Certificate bindings netsh http show sslcert
Application Pool appcmd list apppool /state:Started

For automated configuration in Azure deployments:

# Configure SNI binding
New-WebBinding -Name "Site1" -Protocol "https" -Port 443 -HostHeader "domain2.com" -SslFlags 1

# Remove conflicting URL reservation
netsh http delete urlacl url=https://+:443/

# Verify binding precedence
Get-WebBinding -Name "Site1" | Where-Object {$_.Protocol -eq "https"} | 
    Select-Object -Property protocol,bindingInformation,sslFlags

For production environments, consider these architectural patterns:

  • Frontend IIS instance handling SSL termination
  • Backend servers with HTTP-only communication
  • Azure Application Gateway for advanced routing
  • Let's Encrypt wildcard certificates via DNS-01 challenge