Nginx配置:本地网络允许TLSv1,外部仅开放TLSv1.1/1.2
Let's break down how to resolve both your issues—getting the segmented TLS access working and eliminating that duplicate hostname warning on port 443.
Root Causes
First, let's clarify why you're seeing these problems:
- The duplicate hostname warning happens when you have multiple
serverblocks listening on port 443 with the sameserver_name myhostname. Nginx doesn't know which one to prioritize, hence the warning. - The TLS version filtering isn't working likely because your configuration isn't correctly tying the client IP range to the allowed protocols (probably due to misconfigured server blocks or missing conditional logic).
Step 1: Use a map to Define Dynamic TLS Protocols
Instead of creating duplicate server blocks, we'll use an Nginx map directive to dynamically set allowed TLS protocols based on the client's IP. This keeps your configuration clean and avoids duplicate entries.
Add this inside your http block (not inside a server block):
map $remote_addr $custom_ssl_protocols { # Match any IP in the 10.0.0.0/8 range ~^10\. TLSv1 TLSv1.1 TLSv1.2; # Default for all other external clients default TLSv1.1 TLSv1.2; }
This map checks if the client IP starts with 10. (covering the entire 10.0.0.0/8 subnet) and assigns the appropriate TLS protocols.
Step 2: Configure a Single Server Block
Now replace any duplicate server blocks for port 443 with a single block that uses the mapped variable. This eliminates the duplicate hostname warning and applies the correct TLS rules:
server { listen 443 ssl; server_name myhostname; # Your SSL certificate paths (update these to your actual files) ssl_certificate /etc/nginx/ssl/myhostname.crt; ssl_certificate_key /etc/nginx/ssl/myhostname.key; # Use the dynamic TLS protocol variable from our map ssl_protocols $custom_ssl_protocols; # Optional: Add other SSL hardening settings (recommended) ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Your regular site configuration (root, index, locations, etc.) root /var/www/myhostname; index index.html; location / { try_files $uri $uri/ =404; } }
Step 3: Test & Apply the Configuration
- Validate your Nginx configuration to catch any syntax errors:
sudo nginx -t - If the test passes, restart Nginx to apply the changes:
sudo systemctl restart nginx
Step 4: Verify the Setup Works
From a local 10.0.0.0/8 machine: Test if TLSv1 is allowed using
openssl:openssl s_client -connect myhostname:443 -tls1You should see a successful connection (look for "Verify return code: 0 (ok)").
From an external machine: Test TLSv1—this should fail:
openssl s_client -connect myhostname:443 -tls1You'll see an error like "sslv3 alert handshake failure". Then test TLSv1.1 and TLSv1.2 to confirm they work:
openssl s_client -connect myhostname:443 -tls1_1 openssl s_client -connect myhostname:443 -tls1_2
Key Notes
- Make sure you delete any old duplicate
serverblocks listening on 443 formyhostname—leaving them will bring back the warning. - The
mapdirective must be placed in thehttpcontext (outside allserverblocks) for Nginx to recognize it. - If you're using IPv6 alongside IPv4, you'll need to adjust the map to match your local IPv6 range if needed, but your question specifies 10.0.0.0/8 so this isn't required here.
内容的提问来源于stack exchange,提问作者Samson Chung

