【问题标题】:Nginx Load Balancing HTTPs clusterNginx 负载均衡 HTTPs 集群
【发布时间】:2021-04-20 08:50:43
【问题描述】:

我想使用 Nginx 作为 Consul 集群的负载均衡器。 Consul 集群只能通过 TLS 访问。

这里我尝试反向代理单个 Consul 服务器以检查 TLS 证书是否有效

server {
    listen 80;
    listen [::]:80;
    
    location  /consul/ {

        resolver 127.0.0.1;

        proxy_pass https://core-consul-server-1-dev.company.io:8500;

        sub_filter_types text/css application/javascript;
        sub_filter_once off;
        sub_filter /v1/ /consul_v1/;

        proxy_ssl_certificate      /etc/nginx/certs/agent.crt;
        proxy_ssl_certificate_key  /etc/nginx/certs/agent.key;
        proxy_ssl_trusted_certificate  /etc/nginx/certs/ca.crt;
        proxy_ssl_verify        on;
        proxy_ssl_verify_depth  4;      

    }
}

这个配置工作正常,我可以用它来调用它

curl http://core-proxy-server-1-dev.company.io/consul/consul_v1/agent/members

现在我尝试做这样的上游:

upstream consul {
    server core-consul-server-1-dev.company.io:8500;
    server core-consul-server-2-dev.company.io:8500;
}

server {

    listen 80;
    listen [::]:80;
  
    
    location  /consul/ {

        resolver 127.0.0.1;

        proxy_pass https://consul;
        sub_filter_types text/css application/javascript;
        sub_filter_once off;
        sub_filter /v1/ /consul_v1/;
        
        proxy_ssl_certificate      /etc/nginx/certs/agent.crt;
        proxy_ssl_certificate_key  /etc/nginx/certs/agent.key;
        proxy_ssl_trusted_certificate  /etc/nginx/certs/ca.crt;
        proxy_ssl_verify        on;
        proxy_ssl_verify_depth  4;      

    } 
}

当调用与以前相同的 curl 命令时,我收到以下错误:

2021/04/20 08:38:59 [debug] 3364#3364: *1 X509_check_host(): no match
2021/04/20 08:38:59 [error] 3364#3364: *1 upstream SSL certificate does not match "consul" while SSL handshaking to upstream, client: 10.10.xx.xxx, server: , request: "GET /consul/consul_v1/agent/members HTTP/1.1", upstream: "https://10.10.yy.yyy:8500/consul/consul_v1/agent/members", host: "core-proxy-server-1-dev.company.io"

然后我试过这样:

upstream consul_1 {
    server core-consul-server-1-dev.company.io:8500;
}

upstream consul_2 {
    server core-consul-server-2-dev.company.io:8500;
}

map $http_host $backend {
    core-consul-server-1-dev.company.io       consul_1;
    core-consul-server-2-dev.company.io       consul_2;

}

server {

    listen 80;
    listen [::]:80;
  
    
    location  /consul/ {

        resolver 127.0.0.1;

        proxy_pass https://$backend;
        sub_filter_types text/css application/javascript;
        sub_filter_once off;
        sub_filter /v1/ /consul_v1/;
        
        proxy_ssl_certificate      /etc/nginx/certs/agent.crt;
        proxy_ssl_certificate_key  /etc/nginx/certs/agent.key;
        proxy_ssl_trusted_certificate  /etc/nginx/certs/ca.crt;
        proxy_ssl_verify        on;
        proxy_ssl_verify_depth  4;      

    }

}

但也没有运气;

2021/04/20 08:45:05 [error] 3588#3588: *1 invalid URL prefix in "https://", client: 10.10.xx.xxx, server: , request: "GET /consul/consul_v1/agent/members HTTP/1.1", host: "core-proxy-server-1-dev.company.io"

有什么想法吗?有人可以帮我一个吗?

【问题讨论】:

    标签: nginx ssl load-balancing consul nginx-upstreams


    【解决方案1】:

    我想通了。

    在这个变体中:

    upstream consul {
        server core-consul-server-1-dev.company.io:8500;
        server core-consul-server-2-dev.company.io:8500;
    }
    
    server {
    
        listen 80;
        listen [::]:80;
      
        
        location  /consul/ {
    
            resolver 127.0.0.1;
    
            proxy_pass https://consul;
            sub_filter_types text/css application/javascript;
            sub_filter_once off;
            sub_filter /v1/ /consul_v1/;
            
            proxy_ssl_certificate      /etc/nginx/certs/agent.crt;
            proxy_ssl_certificate_key  /etc/nginx/certs/agent.key;
            proxy_ssl_trusted_certificate  /etc/nginx/certs/ca.crt;
            proxy_ssl_verify        on;
            proxy_ssl_verify_depth  4;      
    
        } 
    }
    

    上游名称consul 也应该与我在证书中定义的alt_names 匹配。所以将配置更改为以下配置就可以了:

    upstream core-consul-server-1-dev.company.io{
        server core-consul-server-1-dev.company.io:8500;
        server core-consul-server-2-dev.company.io:8500;
    }
    
    server {
    
        listen 80;
        listen [::]:80;
      
        
        location  /consul/ {
    
            resolver 127.0.0.1;
    
            proxy_pass https://core-consul-server-1-dev.company.io;
            sub_filter_types text/css application/javascript;
            sub_filter_once off;
            sub_filter /v1/ /consul_v1/;
            
            proxy_ssl_certificate      /etc/nginx/certs/agent.crt;
            proxy_ssl_certificate_key  /etc/nginx/certs/agent.key;
            proxy_ssl_trusted_certificate  /etc/nginx/certs/ca.crt;
            proxy_ssl_verify        on;
            proxy_ssl_verify_depth  4;      
    
        } 
    }
    

    我应该稍后在alt_names 中添加一个通用名称,以便我可以将流引用为

    core-consul-server-dev.company.io
    

    【讨论】: