首页 > 解决方案 > SNI 不工作?多个 ssl 反向代理 nginx

问题描述

我想用 ssl 配置两个反向代理,代理传递给不同的应用程序

https://api.example.com --> http://app:8080
https://pg.example.com --> http://pgadmin:80

给定以下 nginx 配置,两个子域都重定向到第一个 443-server 配置 ( app)。访问 443 端口时会出现问题。从 80 到 433 的重定向对两者都适用。但是当我浏览https://pg.example.com它时,它会传递给app而不是pgadmin.

server {
        listen 80;
        listen [::]:80;
        server_name api.example.com pg.example.com;

        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }

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

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

        server_tokens off;

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

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

        location / {
                proxy_pass http://app:8080;
                add_header X-Frame-Options "SAMEORIGIN" always;
                add_header X-XSS-Protection "1; mode=block" always;
                add_header X-Content-Type-Options "nosniff" always;
                add_header Referrer-Policy "no-referrer-when-downgrade" always;
                add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
                # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
                # enable strict transport security only if you understand the implications
        }
}

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

        server_tokens off;

        # note that api.example.com certificate has pg.example.com as alias
        ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

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

        location / {
                proxy_set_header X-Scheme $scheme;
                proxy_set_header Host $host;
                proxy_pass http://pgadmin:80;
                proxy_redirect off;

                add_header X-Frame-Options "SAMEORIGIN" always;
                add_header X-XSS-Protection "1; mode=block" always;
                add_header X-Content-Type-Options "nosniff" always;
                add_header Referrer-Policy "no-referrer-when-downgrade" always;
                add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
                # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
                # enable strict transport security only if you understand the implications
        }
}

感觉像 SNI 不工作左右..?!但它在 nginx 中启用:

nginx -V
nginx version: nginx/1.17.10
built by gcc 9.2.0 (Alpine 9.2.0) 
built with OpenSSL 1.1.1d  10 Sep 2019 (running with OpenSSL 1.1.1g  21 Apr 2020)
TLS SNI support enabled

让两个反向代理工作我缺少什么?

编辑:当我删除 (on 443) 的server块时,server_name api.example.com;另一个 ( pg.example.com:443) 确实按预期工作。然后api.example.com:443显示相同的pgadmin上游)。

标签: nginx

解决方案


我认为最简单的方法是将第一个服务器块分成两个服务器块。

例如:

server {
    listen 80;
    listen [::]:80;
    server_name api.example.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

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

server {
    listen 80;
    listen [::]:80;
    server_name pg.example.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

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

我希望这会有所帮助,但我不能保证此配置与 certbot 一起正常工作。


推荐阅读