Nginx反向代理https报错The plain HTTP request was sent to HTTPS port解决办法
原创
©著作权归作者所有:来自51CTO博客作者青龙小码农的原创作品,请联系作者获取转载授权,否则将追究法律责任
最近通过Nginx反向代理一个网站,配置https,在浏览器输入:https://xxxx.test.com访问出现了“400 Bad Request The plain HTTP request was sent to HTTPS port”错误,如下图:
出现这种报错的主要原因是:
因为HTTP请求被发送到HTTPS端口,这种报错多出现在Nginx既处理HTTP请求又处理HTTPS请求的+是多次重定向导致的情况
正常80端口访问应该是:http://xxxx.test.com:80/login
正常开启HTTPS以后443端口访问应该是:https://xxxx.test.com:443/login
但是此时却变成了: http://xxxx.test.com:443/login,即HTTP请求被发送到HTTPS端口。
简单来说就是:当第一次请求试图通过HTTP访问网站xxxx.test.com,这个请求被重定向到HTTPS。于是Nginx预计使用SSL(443端口)交互,但原来的请求(通过端口80接收,即检查到未登录,需要从/跳转到/login)是普通的HTTP请求,于是会产生错误。
解决方法是在原来的配置上面加两个参数:
proxy_set_header X-Forwarded-Proto https; # X-Forwarded-Proto(XFP)报头是用于识别协议HTTP或HTTPS的,即用户客户端实际连接到代理或负载均衡的标准报头。
proxy_redirect http:// https:// # proxy_redirect 该指令用来修改被代理服务器返回的响应头中的Location头域和“refresh”头域,也就是把http协议改成https协议。
添加以后完整的配置如下:
upstream xxxx.test.com{
#1、轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
#2、weight 指定轮询几率,weight和访问比率成正比
#3、ip_hash 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
#ip_hash
server 127.0.0.1:8808 weight=1;
}
server {
#keepalive_requests 120; #单连接请求上限次数。
listen 80; #监听端口
#访问域名
server_name xxxx.test.com; #监听地址
#charset koi8-r;
#access_log logs/host.access.log main;
client_max_body_size 100m;
location / {
proxy_pass http://xxxx.test.com;
proxy_set_header X-Original-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host xxxx.test.com:$server_port;
# proxy_set_header Host $host:$server_port;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_redirect off;
proxy_connect_timeout 18000;
proxy_send_timeout 18000;
proxy_read_timeout 18000;
#fastcgi_param HTTPS on;
}
add_header X-Cache $upstream_cache_status;
proxy_cache_key $host$uri$is_args$args;
if ($scheme = http) {
return 301 https://$host$uri?$args;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
#https
listen 443 ssl;
server_name xxxx.test.com; #监听地址
ssl_certificate /usr/local/nginx/key/8024886_xxxx.test.com.pem;
ssl_certificate_key /usr/local/nginx/key/8024886_xxxx.test.com.key;
#ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
#访问域名
#charset koi8-r;
#access_log logs/host.access.log main;
client_max_body_size 20m;
location / {
proxy_set_header X-Original-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host xxxx.test.com:$server_port;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://xxxx.test.com;
proxy_redirect http:// https://;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}