nginx配置问题
给docker部署的应用(一个开源的项目管理系统redmine)的nginx反代理配置又又访问异常了。
- 详情:在会议室的笔记本电脑上访问xxx.xxx.xxx死后无法访问,提示 “400 Bad Request . The plain HTTP request was sent to HTTPS port”, 但是在其他电脑上(其他三台上都可以正常访问)
- 怪现象:另外一台主机开始使用火狐浏览器也是一样的情况,但是它换了浏览器后,可以访问,登录后却异常了,报告重定向问题
- 后续:已经解决了
配置改动
参考博客 Nginx报错“The plain HTTP request was sent to HTTPS port”问题解决办法-CSDN博客
原文如下:
java redirect重定向https跳转http问题,如果https访问nginx通过nginx proxy_pass到http的tomcat服务正常能够访问,但是java redirect就跳转到http,导致报错“400 Bad Request: The plain HTTP request was sent to HTTPS port”。
实现流程是根据nginx的不同执行阶段,来完成Location http到https。
1)proxy_pass执行前,先设置了request head host 为https外网访问的域名+端口
2)proxy_pass执行后,tomcat结果返回response
3)proxy_redirect修改response中的location中的协议http为https外网访问的协议。
注:java redirect重定向主要是通过访问tomcat服务的请求head项来决定的,默认是http协议,域名是通过读取host地址,默认host中不包括访问端口。
所以原配置做了如下修改:
1、在 proxy_pass http xxx 后面添加了proxy_redirect http:// https://;
2、删除了原来的 proxy_redirect off;
最后重启服务
修改前后配置对比
修改前
server {
listen 80;
server_name xxx.xxx.xxx;
if ($host = 'xxx.xxx.xxx'){
return 301 https://xxx.xxx.xxx$request_uri;
}
}
server {
listen 443 ssl;
server_name xxx.xxx.xxx;
index index.php index.html index.htm;
client_max_body_size 8192M;
client_body_buffer_size 128k;
ssl_certificate xxx.pem;
ssl_certificate_key xxx_key.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://192.168.xxx.xxx:xxxx; # 转发规则
client_max_body_size 100m;
proxy_redirect off;
#下面这一步一定要加上端口号,否则如果使用非443端口,网站在ajax请求之后会跳转到错误的页面(会不带端口号)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
#下面这一行配置也要加上,否则ajax请求之后会跳转到错误的页面(https会变成http)
proxy_set_header X-Forwarded-Proto $scheme;
index index.html index.htm;
}
}
修改后
server {
listen 80;
server_name xxx.xxx.xxx;
if ($host = 'xxx.xxx.xxx'){
return 301 https://xxx.xxx.xxx$request_uri;
}
}
server {
listen 443 ssl;
# ssl on;
server_name xxx.xxx.xxx;
index index.php index.html index.htm;
client_max_body_size 8192M;
client_body_buffer_size 128k;
ssl_certificate xxx.pem;
ssl_certificate_key xxx_key.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://192.168.xxx.xxx:xxxx; # 转发规则
proxy_redirect http:// https://;
# client_max_body_size 100m;
# proxy_redirect off;
#下面这一步一定要加上端口号,否则如果使用非443端口,网站在ajax请求之后会跳转到错误的页面(会不带端口号)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
#下面这一行配置也要加上,否则ajax请求之后会跳转到错误的页面(https会变成http)
proxy_set_header X-Forwarded-Proto $scheme;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}