我拥有的:
- 指向主机服务器的域名*.posmete.com。
- 运行 ubuntu 18.04 的主机服务器(Google 云实例)
- (主机服务器内部)名为“proxy”的 LXC 容器 1 运行 ubuntu 18.04 和 nginx 1.17 作为反向代理
- (主机服务器内部)名为“web1”的 LXC 容器 2 运行 ubuntu 18.04 和 nginx 1.17 和 php7.4-fpm 以及 MySQL 8.0
两个带有 proxy_protocol=true 的 lxc 代理设备
igorkovalenko@xprs-tst:~$ lxc config device show proxy
myport80:
connect: tcp:127.0.0.1:80
listen: tcp:0.0.0.0:80
proxy_protocol: "true"
type: proxy
myport443:
connect: tcp:127.0.0.1:443
listen: tcp:0.0.0.0:443
proxy_protocol: "true"
type: proxy
我的容器列表:
igorkovalenko@xprs-tst:~$ lxc list
+-------+---------+----------------------+----------------------------------------------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+----------------------+----------------------------------------------+-----------+-----------+
| proxy | RUNNING | 10.130.126.23 (eth0) | fd42:f63:4839:fedc:216:3eff:fe26:523b (eth0) | CONTAINER | 0 |
+-------+---------+----------------------+----------------------------------------------+-----------+-----------+
| web1 | RUNNING | 10.130.126.41 (eth0) | fd42:f63:4839:fedc:216:3eff:fe18:2fa3 (eth0) | CONTAINER | 0 |
+-------+---------+----------------------+----------------------------------------------+-----------+-----------+
我的 Nginx 反向代理配置(代理容器)
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwared-For $proxy_add_x_forwarded_for;
proxy_ssl_session_reuse on;
proxy_ssl_server_name on;
upstream backend {
server web1:443;
}
server {
server_name web1.posmete.com;
location / {
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto https;
# proxy_ssl_session_reuse off;
# proxy_ssl_server_name on;
# proxy_ssl_protocols TLSv1.2;
# proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;
# proxy_ssl_certificate /etc/letsencrypt/live/web1.posmete.com/fullchain.pem;
# proxy_ssl_certificate_key /etc/letsencrypt/live/web1.posmete.com/privkey.pem;
proxy_pass https://backend;
# proxy_redirect http:// https://;
}
real_ip_header proxy_protocol;
set_real_ip_from 127.0.0.1;
listen [::]:443 ssl proxy_protocol; # managed by Certbot
listen 443 ssl proxy_protocol; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/web1.posmete.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/web1.posmete.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = web1.posmete.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 proxy_protocol;
listen [::]:80 proxy_protocol;
server_name web1.posmete.com;
return 404; # managed by Certbot
}
我的 Nginx Web 服务器配置(web1 容器)
server {
# listen 80;
listen 443;
server_name web1.posmete.com;
root /usr/share/nginx/html;
index index.php;
location = /50x.html {
root /usr/share/nginx/html;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~* \.php$ {
if ($uri !~ "^/uploads/") {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
location ~ /\.ht {
deny all;
}
}
我想要实现的目标:
我正在尝试通过 https 连接使用 Wordpress 安装脚本在 lxc 容器“web1”内安装 Wordpress。
我遇到过什么问题:
web1.posmete.com 502 错误网关
来自代理服务器日志的错误:
2020/03/24 15:20:44 [error] 4199#4199: *42 SSL_do_handshake() failed (SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number) while SSL handshaking to upstream, client: 169.197.108.42, server: web1.posmete.com, request: "GET /remote/login HTTP/1.1", upstream: "https://10.130.126.41:443/remote/login", host: "35.198.175.173"
2020/03/24 15:20:44 [warn] 4199#4199: *42 upstream server temporarily disabled while SSL handshaking to upstream, client: 169.197.108.42, server: web1.posmete.com, request: "GET /remote/login HTTP/1.1", upstream: "https://10.130.126.41:443/remote/login", host: "35.198.175.173"
2020/03/24 15:20:44 [error] 4199#4199: *42 connect() failed (111: Connection refused) while connecting to upstream, client: 169.197.108.42, server: web1.posmete.com, request: "GET /remote/login HTTP/1.1", upstream: "https://[fd42:f63:4839:fedc:216:3eff:fe18:2fa3]:443/remote/login", host: "35.198.175.173"
2020/03/24 15:20:44 [warn] 4199#4199: *42 upstream server temporarily disabled while connecting to upstream, client: 169.197.108.42, server: web1.posmete.com, request: "GET /remote/login HTTP/1.1", upstream: "https://[fd42:f63:4839:fedc:216:3eff:fe18:2fa3]:443/remote/login", host: "35.198.175.173"
2020/03/24 15:20:49 [info] 4199#4199: *42 client 127.0.0.1 closed keepalive connection
来自 Web 服务器日志的错误:
10.130.126.23 - - [24/Mar/2020:15:20:44 +0000] "\x16\x03\x01\x00\xCD\x01\x00\x00\xC9\x03\x03\xB6j\x9Ef\x90\x08\x90O\x8A-VYw\xD8\x09rn\xD1\x10\xB1m\xCF\x0E\xDE\x95\x83]e\xC6J\x14\x06\x00\x008\xC0,\xC00\x00\x9F\xCC\xA9\xCC\xA8\xCC\xAA\xC0+\xC0/\x00\x9E\xC0$\xC0(\x00k\xC0#\xC0'\x00g\xC0" 400 157 "-" "-" "-"
我尝试了几乎所有通过互联网提供的说明,但仍然出现 502 错误。只有一个解决方案产生了积极效果 - 那就是将 SSL 证书从代理复制到 Web。但我想避免这种情况,并使用 certbot 从一个地方管理证书。
因此,基本上通过 HTTP 一切正常,但通过 https 出现 502 错误
答案1
如果不复制私钥和证书,握手就无法完成:
TLS(版本 1.3)握手由一条ClientHello
消息发起,该消息的响应预期为ServerHello
、EncryptedExtensions
、Certificate
和消息。该消息包含证书,而消息包含使用私钥计算的签名。因此,如果不复制私钥和证书,握手就无法完成。CertificateVerify
Certificate
CertificateVerify
您需要复制。
当您考虑 SSL/TLS 的属性时,重复的需要应该变得直观,因为 SSL/TLS 用于服务器身份验证(这需要私钥,否则无法实现身份验证)。
或者,您可以使用两个不同的私钥和证书。如果您可以接受,我会详细说明。