nginx反向代理https内部定向到http报302的问题及解决

 更新时间:2023年12月22日 15:19:59   作者:shihuc  
这篇文章主要介绍了nginx反向代理https内部定向到http报302的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

环境信息

Linux:Linux i-8emt1zr1 2.6.32-573.el6.x86_64 #1 SMP Wed Jul 1 18:23:37 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux

nginx:nginx version: openresty/1.9.3.2

Tomcat:Server version: Apache Tomcat/7.0.64

1. 问题描述

我们开发的客服系统,因为消息的到来,有的谷歌浏览器(V62)不支持http的消息提醒,要求https,故而,我们的系统,要将系统改造成https模式,另外,我们的系统,也有必要转化为https,为后续推广做准备。

2. 系统架构

LB+nginx+tomcat集群

3. 当前配置情况

SSL证书配置在LB上,nginx和tomcat服务器上,任然采用http协议通讯。

即LB在接收到客户浏览器https请求消息后,将转发给LB下挂载的nginx上,都是以http的方式转发,nginx对这些请求进行反向代理,代理到后面的tomcat服务器上。

4. 遇到的问题

客服系统,有权限控制,基于tomcat的web应用,用户登录后,执行redirect跳转到指定的服务页面。

就是这个跳转,遇到了问题,redirect在这里都被当做http跳转了。

登录前的样子:

登录后的样子:

问题主要发生在Tomcat7上,验证过tomcat8,是不存在问题的。

5. 如何解决

针对Tomcat7的这个问题,思路很简单,重点是解决redirect的时候,通知客户端浏览器以正确的scheme(https还是http)进行再次发起请求。

问题是, nginx这个时候收到的请求是来自LB的http请求了,怎么弄?其实是有办法的,可以利用HttpRequest中的referer字段,这个字段的含义,自行科普吧。

将referer的请求scheme信息,用来作为当前请求的scheme,如此可以保证所有的请求都是同一个scheme,不会因为redirect而遗漏信息。

nginx里面相应的配置如下:

location /CSS/websocket {
            proxy_pass http://css_ws_svr;
            proxy_set_header Host $host;
            proxy_set_header Remote_Addr $remote_addr;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }

        location /CSS {
            proxy_pass http://css_svr;
            proxy_set_header Host $host;
            proxy_set_header Remote_Addr $remote_addr;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            set $mscheme $scheme;
            if ($http_referer ~* ^https.*) {
                set $mscheme "https";
            }
            proxy_set_header X-Forwarded-Proto $mscheme;
        }

如上配置,经过nginx反向代理后的HttpServletRequest中header部分就带上了字段X-Forwarded-Proto。

另外一方面,就是tomcat里面,要做一个配置,让tomcat在解析请求和做重定向的时候,知道用什么协议。

主要的配置在server.xml里面的Engine下,定义一个Value元素。

具体配置如下:

<Engine name="Catalina" defaultHost="localhost">

      
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

        <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>

        <Context path="/CSS" docBase="/home/tomcat/app/cssv2"/>
      </Host>
    </Engine>

这个配置里面,重点是protocolHeader字段,意思就是说,当protocolHeader字段的值为protocolHeaderHttpsValue的https的时候,认为是安全连接,否则就是http的非安全连接。

对应的代码逻辑,可以看org.apache.catalina.valves.RemoteIpValve这个类的源码

public void invoke(org.apache.catalina.connector.Request request, Response response)
 throws IOException, ServletException
{
......
if (protocolHeader != null) {
    String protocolHeaderValue = request.getHeader(protocolHeader);
    if (protocolHeaderValue != null)
    {

        if (protocolHeaderHttpsValue.equalsIgnoreCase(protocolHeaderValue)) {
            request.setSecure(true);
            
            request.getCoyoteRequest().scheme().setString("https");
        
            setPorts(request, httpsServerPort);
        } else {
            request.setSecure(false);
                
            request.getCoyoteRequest().scheme().setString("http");
                
            setPorts(request, httpServerPort);
        }
    }
}
......
}

经过上面的分析和配置修改,最终很灵活的实现https和http同时工作。

搞定这个问题,重点还是要对Http协议工作的流程有所了解,才能很容易的找到解决问题的思路。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • nginx中重定向的实现

    nginx中重定向的实现

    本文主要介绍了Nginx中location匹配和rewrite重定向的规则与应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-03-03
  • Nginx access.log日志详解及统计分析小结

    Nginx access.log日志详解及统计分析小结

    nginx有一个非常灵活的日志记录模式,本文主要介绍了Nginx access.log日志详解及统计分析小结,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • Nginx配置并开启WebDAV服务的完整指南

    Nginx配置并开启WebDAV服务的完整指南

    本文主要介绍了Nginx上配置并开启WebDAV服务的完整指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • 在Ubuntu20.04上安装Kubernetes集群

    在Ubuntu20.04上安装Kubernetes集群

    容器化为开发人员提供了很大的灵活性,最常用的容器化应用程序之一是 Docker,在容器上部署服务的主要原因之一是它们灵活、轻量级并且在部署在数百台机器上时易于扩展,但是,谁来管理所有这些容器?这就是 Kubernetes 发挥作用的地方
    2023-12-12
  • Nginx访问日志access_log配置及信息详解(推荐)

    Nginx访问日志access_log配置及信息详解(推荐)

    当你设置日志级别成debug,如果你在调试一个在线的高流量网站的话,你的错误日志可能会记录每个请求的很多消息,这样会变得毫无意义,下面小编给大家介绍Nginx访问日志access_log配置及信息详解,感兴趣的朋友跟随小编一起看看吧
    2024-04-04
  • Nginx+Lua脚本+Redis 实现自动封禁访问频率过高IP

    Nginx+Lua脚本+Redis 实现自动封禁访问频率过高IP

    本文主要介绍了如何使用OpenResty+Lua进行动态封禁IP的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-10-10
  • 一文带你搞懂Nginx中的配置文件

    一文带你搞懂Nginx中的配置文件

    Nginx(发音为“engine-x”)是一款高性能的 Web 服务器、反向代理服务器和负载均衡器,广泛应用于全球各类网站和应用中,下面就跟随小编一起来了解下如何配置 Nginx 以满足不同的需求吧
    2025-01-01
  • Nginx反向代理解决跨域详细代码示例

    Nginx反向代理解决跨域详细代码示例

    Nginx作为反向代理服务器,能够在前端轻松解决跨域问题,无需后端配合,这篇文章主要介绍了Nginx反向代理解决跨域的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-06-06
  • Kubernetes中Nginx服务启动失败排查流程分析(Error: ImagePullBackOff)

    Kubernetes中Nginx服务启动失败排查流程分析(Error: ImagePullBackOff)

    这篇文章主要介绍了Kubernetes中Nginx服务启动失败排查流程(Error: ImagePullBackOff),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Nginx搭建支持WebDAV协议的私有云存储网关的实现步骤

    Nginx搭建支持WebDAV协议的私有云存储网关的实现步骤

    本文主要介绍了Nginx搭建支持WebDAV协议的私有云存储网关的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-04-04

最新评论