When implementing security measures on a web application, we often need to enforce HTTPS for sensitive paths while keeping other sections accessible via HTTP. This is particularly common when:
- Implementing user account sections (/user/*) with HTTPS
- Maintaining public content sections with HTTP
- Optimizing performance for non-sensitive content
Here's the recommended server block configuration that avoids conditional statements (if) and potential redirect loops:
server {
listen 80;
server_name example.com;
# HTTPS enforcement for /user path
location /user {
return 301 https://$host$request_uri;
}
# All other paths remain HTTP
location / {
# Your regular HTTP configuration
try_files $uri $uri/ =404;
}
}
server {
listen 443 ssl;
server_name example.com;
# SSL configuration here
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Only allow HTTPS for /user path
location / {
return 301 http://$host$request_uri;
}
location /user {
# Your secure content configuration
try_files $uri $uri/ =404;
}
}
For more complex scenarios, consider these variations:
Multiple Protected Paths
location ~ ^/(user|account|settings) {
return 301 https://$host$request_uri;
}
Preserving Query Strings
location /user {
return 301 https://$host$request_uri$is_args$args;
}
The 301 redirect is cached by browsers, reducing subsequent redirect overhead. For production environments:
- Always test redirect chains
- Monitor for mixed content warnings
- Consider HSTS headers for the secure paths
Watch out for these potential problems:
- Redirect loops - ensure your HTTPS server block doesn't redirect back
- Cookie security - set Secure flag for cookies in /user section
- Mixed content - ensure assets in /user section are loaded via HTTPS
When implementing security measures on a website, we often need granular control over SSL enforcement. A common scenario is requiring HTTPS only for sensitive sections (like /user
paths) while allowing standard HTTP for other content. This approach balances security and performance.
Many developers initially try using if
statements in Nginx configurations, but this can lead to:
- Performance overhead
- Unexpected behavior in complex scenarios
- Potential redirect loops
Here's the recommended server block configuration that cleanly handles path-specific SSL requirements:
server {
listen 80;
server_name example.com;
# Force SSL for /user paths
location /user {
return 301 https://$host$request_uri;
}
# All other paths remain HTTP
location / {
# Your regular HTTP configuration
root /var/www/html;
index index.html;
}
}
server {
listen 443 ssl;
server_name example.com;
# SSL configuration
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Handle SSL-protected paths
location /user {
# Your secure content configuration
root /var/www/secure;
try_files $uri $uri/ =404;
}
# Redirect non-/user paths back to HTTP
location / {
return 301 http://$host$request_uri;
}
}
1. Separate Server Blocks: Maintain distinct blocks for HTTP (port 80) and HTTPS (port 443) traffic
2. Path-Specific Directives: Use location
blocks to target specific URL paths
3. Bidirectional Redirection:
- HTTP → HTTPS for protected paths
- HTTPS → HTTP for non-protected paths
For more complex setups with multiple protected paths:
# HTTP server block
server {
listen 80;
# Multiple protected paths
location ~ ^/(user|account|checkout) {
return 301 https://$host$request_uri;
}
# Static content exception
location ~* \.(jpg|png|css|js)$ {
expires 30d;
}
}
# HTTPS server block
server {
listen 443 ssl;
location ~ ^/(user|account|checkout) {
# Additional security headers
add_header Strict-Transport-Security "max-age=31536000" always;
# Application-specific configuration
proxy_pass http://backend_app;
}
}
1. Use return 301
instead of rewrite
for permanent redirects
2. Consider caching static assets even on non-SSL paths
Redirect Loops: Ensure your SSL server block doesn't accidentally catch non-SSL paths
Mixed Content Warnings: Verify all resources in SSL-protected paths use HTTPS URLs
Cookie Security: Set Secure
flag for cookies used in protected areas