LMLPHP后院

Nginx SSL 代理设置完整示例技术

maybe yes 发表于 2020-02-15 21:05

当服务器发展到一定时候,搬迁是个很头疼的问题,于是代理应运而生。本文完整的反向代理配置全过程,其实就是负载均衡。

先生成证书相关文件

openssl genrsa 2048 > ca-key.pem // .key
openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca-cert.pem // .csr 证书
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem
openssl rsa -in server-key.pem -out server-key.pem // 去除密码
openssl x509 -req -in server-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem // .cert
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pem
openssl rsa -in client-key.pem -out client-key.pem // .key
openssl x509 -req -in client-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem

以上命令也有更加简介的写法。

代理端 nginx 配置

upstream test.macbook {
        server test.macbook:8443;
}

server {
        listen 80;
        server_name test.upstream.local;
        error_log /var/log/nginx/test.upstream.local.error.log;
        charset utf-8;

        proxy_ssl_certificate /etc/nginx/certs/client-cert.pem;
        proxy_ssl_certificate_key /etc/nginx/certs/client-key.pem;
        proxy_ssl_trusted_certificate /etc/nginx/certs/ca-cert.pem;
        proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        proxy_ssl_ciphers HIGH:!aNULL:!MD5;

        #proxy_ssl_verify on;
        proxy_ssl_verify_depth 2;
        proxy_ssl_session_reuse on;

        location / {
                proxy_pass https://test.macbook;
        }
        location ~ \.php$ {
                proxy_http_version 1.1;
                proxy_set_header Connection "";
                proxy_pass https://test.macbook;
        }
}

服务端 nginx 配置

server {
        listen 8443 ssl;
        server_name test.macbook;
        charset utf-8;
        root /srv/www/test;
        index index.html index.php;

        ssl_certificate /usr/local/etc/nginx/certs/server-cert.pem;
        ssl_certificate_key /usr/local/etc/nginx/certs/server-key.pem;
        ssl_client_certificate /usr/local/etc/nginx/certs/ca-cert.pem;
        ssl_verify_client optional;

        location / {
                try_files $uri $uri/ /index.php/$uri?$query_string;
        }
        location ~ ^\/index\.php {
                #rewrite ^/(.*) /index.php/$1 break;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_split_path_info ^(.+\.php)(.*)$;
                include fastcgi_params;
        }
        location ~ \.php$ {
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_split_path_info ^(.+\.php)(.*)$;
                include fastcgi_params;
        }

server 可以多加几个,在业务端实现分流,就可以实现负载均衡了。

遇到的一些问题

1.

2020/02/15 15:07:49 [error] 6113#6113: *36 SSL_do_handshake() failed (SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number) while SSL handshaking to upstream, client: 127.0.0.1, server: test.upstream.local, request: "GET /test HTTP/1.1", upstream: "https://192.168.3.19:8443/test", host: "test.upstream.local"

2.

2020/02/15 15:24:01 [error] 6610#6610: *41 upstream SSL certificate does not match "test.macbook" while SSL handshaking to upstream, client: 127.0.0.1, server: test.upstream.local, request: "GET /test HTTP/1.1", upstream: "https://192.168.3.19:8443/test", host: "test.upstream.local"

第一个错误是配置错误导致,比如忘记在端口 8443 后面加上 ssl,这样自然就是访问错误了。第二个错误是生成证书的时候域名填写和配置的虚拟主机名称不一致导致,解决办法就是 proxy_ssl_verify on 这一行注释掉就好了。

参考官方文档

https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/

https://docs.nginx.com/nginx/admin-guide/security-controls/securing-http-traffic-upstream/

2020-04-02 19:37:23 1585827443 0.012523