SNI不起作用?多个SSL反向代理Nginx

时间:2020-10-11 07:31:15

标签: nginx

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

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

鉴于以下nginx配置,两个子域都重定向到第一个443服务器配置(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

我想让两个反向代理都能工作吗?

编辑: 当我删除server的{​​{1}}块(在443上)时,另一个(server_name api.example.com;)确实可以正常工作。然后pg.example.com:443在上游显示相同的api.example.com:443

2 个答案:

答案 0 :(得分:0)

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

例如:

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一起正常使用。

答案 1 :(得分:0)

找出原因是域sever_name的域拼写错误 pg.example.com:433。因此,sever_name不会匹配,nginx将使用最佳匹配-api.example.com:433

我发现通过为80和443添加默认服务器配置(使它们成为conf文件中的第一个,并且都使用sever_name _),因此我可以确保仅在以下情况下才使用特定的服务器配置: server_name个匹配项。结果是api.example.com:433表现出与以前相同的行为(表明它可以正常工作),而pg.example.com:433则显示了新配置的默认服务器-因此它必须是阻止在server_name中正确匹配的内容。配置。我三遍检查了sever_name,最后看到了错字。

相关问题