How to Redirect Wildcard Subdomains to HTTPS in Nginx (SSL/TLS Best Practices)


1 views

When implementing HTTPS redirection for wildcard subdomains (*.example.com) in Nginx, many developers encounter an unexpected behavior where the asterisk symbol gets URL-encoded in the redirect destination (e.g., https://%2A.example.com). This occurs because Nginx processes the wildcard character literally during rewrite operations.

The solution involves using Nginx's $host variable instead of $server_name to preserve the actual requested subdomain:

server {
    listen 80;
    server_name ~^(.*)\.example\.com$;
    return 301 https://$host$request_uri;
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

1. The regex pattern ~^(.*)\.example\.com$ matches any subdomain while capturing the dynamic part
2. $host automatically contains the original requested hostname
3. HTTP status code 301 ensures permanent redirect for SEO benefits
4. The separate block for the apex domain maintains clean URL handling

For environments requiring additional security headers:

server {
    listen 443 ssl http2;
    server_name ~^(.*)\.example\.com$;
    
    ssl_certificate /path/to/wildcard.crt;
    ssl_certificate_key /path/to/wildcard.key;
    
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    
    # Your regular configuration...
}

After implementing, verify with:

curl -I http://test.example.com
curl -I http://dev.example.com
curl -I http://example.com

All should return 301 redirects to their HTTPS counterparts without URL encoding artifacts.


When setting up HTTPS redirection for wildcard subdomains (*.mydomain.com) in Nginx, many developers encounter an issue where the redirect improperly includes the wildcard character (%2A) in the destination URL. This happens because Nginx processes the wildcard literally when using the $server_name variable.

Here's the correct way to handle wildcard subdomain redirects in Nginx:

server {
    listen 80;
    server_name ~^(.*)\.mydomain\.com$;
    
    # Capture the subdomain and use it in redirect
    return 301 https://$1.mydomain.com$request_uri;
}

server {
    listen 80;
    server_name mydomain.com;
    
    # Redirect base domain
    return 301 https://mydomain.com$request_uri;
}

The solution uses regular expression capture groups in the server_name directive:

  • ~^(.*)\.mydomain\.com$ - Matches any subdomain and captures it in $1
  • $1 - Contains the captured subdomain (without the wildcard character)
  • return 301 - More efficient than rewrite for simple redirects

For a production environment with both wildcard and specific subdomains:

# HTTP to HTTPS redirect for all subdomains
server {
    listen 80;
    server_name ~^(.*)\.example\.com$ example.com;
    
    if ($host ~* ^(.*)\.example\.com$) {
        return 301 https://$1.example.com$request_uri;
    }
    
    return 301 https://example.com$request_uri;
}

# HTTPS server configuration
server {
    listen 443 ssl;
    server_name ~^(.*)\.example\.com$ example.com;
    
    ssl_certificate /path/to/wildcard.crt;
    ssl_certificate_key /path/to/wildcard.key;
    
    # Rest of your SSL configuration...
}

Using regular expressions in server_name directives has a slight performance impact. For high-traffic sites, consider:

  • Using separate server blocks for frequently accessed subdomains
  • Implementing caching for the redirect rules
  • Testing with nginx -t after configuration changes

If redirects aren't working as expected:

  1. Verify your DNS wildcard record (*.domain.com) points to the server
  2. Check Nginx error logs: tail -f /var/log/nginx/error.log
  3. Test with curl: curl -I http://test.example.com
  4. Ensure your SSL certificate includes both the wildcard and base domain