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

Nginx代理Docker中Angular应用的SSL与路由问题排查

解决方案

1. 修复外部Nginx代理配置

问题核心是内部Nginx返回的301重定向暴露了内部端口和HTTP协议,加上HSTS强制转HTTPS导致访问非SSL端口出错。修改外部Nginx的/test location块:

# 先处理不带斜杠的请求,直接重定向到带斜杠的HTTPS地址
location = /test {
    return 301 https://$host/test/;
}

location /test/ {
    proxy_pass http://project1/test/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Host $host;
    proxy_set_header Connection $http_upgrade;
    proxy_cache_bypass $http_upgrade;
    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 https;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Port $server_port;
    # 禁止内部Nginx的重定向修改地址
    proxy_redirect off;
}

2. 调整内部Angular的Nginx配置

确保内部Nginx正确处理路由,同时传递外部请求的头部信息给Angular:

server {
    listen 3000;
    listen [::]:3000;

    root /var/www/nginx;
    server_tokens off;

    location /test/ {
        try_files $uri $uri/ /test/index.html;
        # 传递外部协议、域名、端口给Angular
        add_header X-Forwarded-Proto $http_x_forwarded_proto;
        add_header X-Forwarded-Host $http_x_forwarded_host;
        add_header X-Forwarded-Port $http_x_forwarded_port;
    }
}

3. 配置Angular应用的Base Href

构建Angular时指定正确的基础路径,避免生成带内部端口的链接:

ng build --base-href "/test/"

原提问内容

我正尝试配置Nginx以加密通往Docker服务的外部流量,计划搭建一个带有Let's Encrypt SSL证书、监听外部IP的代理,将请求路由至Docker容器内的不同服务器。目前已完成外部Nginx服务器的安全配置,测试表明静态文件可正常访问,SSL功能运行良好。

但在将路径路由至部署Angular应用的非SSL Nginx服务器时,遇到了一些问题:

  • 请求末尾带斜杠/的URL时,访问正常;
  • 请求不带斜杠的URL时,出现如下错误:
    curl: (35) OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version number
    
  • Angular路由与当前配置冲突,Web应用内视图间的跳转链接会混淆内部端口与外部域名。

外部SSL加密Nginx服务器配置:

# web.conf
upstream project1 {
  server nginx:3000;
}

server {
  listen 443 default_server ssl http2;
  listen [::]:443 ssl http2;

  ssl_certificate /etc/letsencrypt/live/my.domain.some/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/my.domain.some/privkey.pem;

  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

  # Extra config
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; always";
  add_header X-Frame-Options SAMEORIGIN;
  add_header X-Content-Type-Options nosniff;
  add_header X-XSS-Protection "1; mode=block";

  server_name my.domain.some;

  location / {
    root /var/www/nginx;
  }

  location /test {
    proxy_pass http://project1;
    proxy_http_version 1.1;
    proxy_set_header    Upgrade         $http_upgrade;
    proxy_set_header    Host            $host;
    proxy_set_header    Connection      'upgrade';
    proxy_cache_bypass  $http_upgrade;
    # Extra config
    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;
    proxy_set_header    X-Forwarded-Proto   https;
    proxy_set_header    X-Forwarded-Host    $host;
    proxy_set_header    X-Forwarded-Port    $server_port;
  }

}

Angular项目部署的Nginx实例配置:

server {
  listen 3000;
  listen [::]:3000;

  root /var/www/nginx;

  server_tokens off;

  location /test {
    alias /var/www/nginx;
    autoindex off;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
  }
}

执行curl -v -L https://my.domain.some/test(无末尾斜杠)的返回报错:

*   Trying 111.111.111.111:443...
* Connected to my.domain.some (111.111.111.111) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Request CERT (13):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=my.domain.some
*  start date: May  5 13:49:51 2023 GMT
*  expire date: Aug  3 13:49:50 2023 GMT
*  subjectAltName: host "my.domain.some" matched cert's "my.domain.some"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /test]
* h2h3 [:scheme: https]
* h2h3 [:authority: my.domain.some]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x55a78c81e680)
> GET /test HTTP/2
> Host: my.domain.some
> user-agent: curl/7.88.1
> accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/2 301 
< server: nginx/1.15.12
< date: Mon, 03 Jul 2023 15:42:05 GMT
< content-type: text/html
< content-length: 162
< location: http://my.domain.some:3000/test/
< strict-transport-security: max-age=31536000; includeSubDomains; always
< x-frame-options: SAMEORIGIN
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< 
* Ignoring the response-body
* Connection #0 to host my.domain.some left intact
* Clear auth, redirects to port from 443 to 3000
* Issue another request to this URL: 'http://my.domain.some:3000/test/'
* Switched from HTTP to HTTPS due to HSTS => https://my.domain.some:3000/test/
*   Trying 111.111.111.111:3000...
* Connected to my.domain.some (111.111.111.111) port 3000 (#1)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version number
* Closing connection 1
curl: (35) OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version number

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 01:59:52