使用SSL的Nginx子域重定向不起作用

时间:2018-11-27 14:18:15

标签: docker ssl nginx docker-compose

我有一个域 example.com 。我想在其子域上运行多个应用程序,并在其子域上启用https。

我已经使用certbot为 *。example.com example.com 域创建证书。

有三个应用程序可以处理来自不同子域的请求。

  1. 应用程序 app1 处理来自子域 abc.example.com 的请求。
  2. 应用程序 app2 处理来自 [some_name] .example.com 格式的子域的请求。
  3. 应用程序 app3 处理仅来自 example.com 的请求。

我面临以下问题。

  1. 当我尝试从浏览器访问域 abc.example.com 时,它会重定向到 www.abc.example.com ,该域会给出无效的证书错误。
  2. 对服务器名称使用正则表达式会导致所有请求都重定向到 app1
  3. 当我尝试通过浏览器访问域 example.com 时,它将重定向到 www.www.abc.example.com ,这是一个无效的域。

我不确定这是什么问题。服务器名称是正则表达式吗? 另外,还有其他更好的方法可用于这种情况吗? 任何帮助表示赞赏。

注意: 这些应用程序作为docker容器托管在同一docker网络中。


以下是nginx conf文件。

server {
  listen 80;
  listen [::]:80;
  charset utf-8;
  access_log off;
  server_name example.com;

  location / {
    rewrite ^ https://$host$request_uri? permanent;
  }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;

  server_tokens off;
  ssl on;

  ssl_certificate /etc/letsencrypt/live/example.com-0001/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com-0001/privkey.pem;

  ssl_buffer_size 8k;

  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;

  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8;

  return 301 https://www.example.com$request_uri;
}


server {
  server_name www.example.com;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_tokens off;

  ssl on;

  ssl_buffer_size 8k;
  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8 8.8.4.4;

  ssl_certificate /etc/letsencrypt/live/example.com-0001/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com-0001/privkey.pem;

  location / {
    proxy_pass http://app3:80;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

server {
  listen 80;
  listen [::]:80;
  charset utf-8;
  access_log off;
  server_name abc.example.com;

  location / {
     rewrite ^ https://$host$request_uri? permanent;
  }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name abc.example.com;

  server_tokens off;
  ssl on;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  ssl_buffer_size 8k;

  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;

  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8;

  location / {
    proxy_pass http://app1:80;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

server {
  listen 80;
  listen [::]:80;
  charset utf-8;
  access_log off;
  server_name ~^(?!abc|www).+\.example\.com$ ~^www\.(?!abc|www).+\.example\.com$;

  location / {
    rewrite ^ https://$host$request_uri? permanent;
  }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name ~^(?!abc|www).+\.example\.com$ ~^www\.(?!abc|www).+\.example\.com$;

  server_tokens off;
  ssl on;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  ssl_buffer_size 8k;

  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;

  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8;

  location / {
    proxy_pass http://app2:80;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

1 个答案:

答案 0 :(得分:1)

由于 @Steffen Ullrich 的线索,我终于完成了这项工作。

我删除了所有重定向到 www.example.com www。*。example.com 的重定向。

具体来说,以下服务器块。

server {
  server_name www.example.com;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_tokens off;

  ssl on;

  ssl_buffer_size 8k;
  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8 8.8.4.4;

  ssl_certificate /etc/letsencrypt/live/example.com-0001/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com-0001/privkey.pem;

  location / {
    proxy_pass http://app3:80;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

此外,我将通配符服务器名称的正则表达式从~^(?!abc|www).+\.example\.com$ ~^www\.(?!abc|www).+\.example\.com$更改为~^(?!api|www)\w+\.example\.com$