You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单域名多端口配置NGINX SSL,实现不同端口差异化请求处理

Solution for NGINX Multi-Port SSL Configuration with Different Location Logic

Hey there! Let's work through your NGINX config issue step by step. First, we'll fix the existing config problems, then cover the multi-port setup you requested, plus a cleaner alternative that might work better for your use case.

First: Correct Your 8877 Port Server Blocks

Your current API server blocks have a couple of small issues (like missing ssl on the IPv6 listen directive for port 8877). Here's the corrected, working version that uses your existing SSL certificate (single-domain certs fully support multiple ports for the same domain):

# Redirect HTTP (80) to HTTPS (443) for the main website
server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    rewrite ^/(.*) https://example.com/$1 permanent;
}

# Redirect HTTP (8877) to HTTPS (8877) for the API
server {
    listen 8877;
    listen [::]:8877;
    server_name example.com;
    rewrite ^/(.*) https://example.com:8877/$1 permanent;
}

# Main website on HTTPS (443)
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    root /var/www/example;
    index index.html;
    server_name example.com;

    ssl_certificate /root/example.com.crt;
    ssl_certificate_key /root/example.com.key;
    # Modernize SSL protocols (drop outdated, insecure versions)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    location / {
        try_files $uri $uri/ =404;
    }
}

# API on HTTPS (8877) - reverse proxy to NodeJS
server {
    listen 8877 ssl;
    listen [::]:8877 ssl;
    server_name example.com;

    ssl_certificate /root/example.com.crt;
    ssl_certificate_key /root/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    location / {
        proxy_pass http://localhost:1111;
        # Add essential proxy headers so your NodeJS app gets correct client info
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Key Notes for This Multi-Port Setup:

  • Your existing SSL certificate works here because certs are tied to domains, not ports—example.com:8877 is still a valid use for your single-domain certificate.
  • We added full IPv6 support for all ports to cover both IPv4 and IPv6 traffic.
  • Updated SSL protocols to remove TLSv1 and TLSv1.1, which are no longer considered secure.
  • Added proxy headers for your NodeJS app—this ensures your backend can correctly detect the original client's IP address and request protocol.
  • Critical Tip: Move your SSL certificates out of /root if possible. The NGINX process (usually running as www-data) may not have read access to the /root directory. A safer location is /etc/nginx/ssl/, with file permissions set to 600 (read/write only for root).

Better Alternative: Path-Based Routing (No Extra Port Needed)

If you don't strictly require a separate port for your API, using a path prefix (like /api/) is a cleaner, more secure approach. This way, you only use port 443 for both your website and API, reducing your attack surface and simplifying maintenance:

# Redirect all HTTP traffic to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

# Combined website + API on HTTPS (443)
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    root /var/www/example;
    index index.html;
    server_name example.com;

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    # Serve static website content for all non-API paths
    location / {
        try_files $uri $uri/ =404;
    }

    # Reverse proxy all /api/ requests to NodeJS
    location /api/ {
        proxy_pass http://localhost:1111/;  # Trailing slash ensures path is passed correctly to your backend
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Why This Is a Better Approach:

  • Fewer open ports means fewer potential security vulnerabilities.
  • A single HTTPS server block makes your config easier to maintain and debug.
  • Users don't need to remember a custom port for your API—they just use https://example.com/api/.

Final Steps to Validate

After updating your config:

  1. Test for syntax errors with sudo nginx -t.
  2. Reload NGINX to apply changes: sudo systemctl reload nginx.
  3. Verify both your website and API work over HTTPS (use curl or your browser to test endpoints).

内容的提问来源于stack exchange,提问作者Michiel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:04:30