转载

Nginx Https With Tomcat Http

昨天配置了HTTPS了,nginx https代理访问应用的http登录页也确实没有问题的。一切都是那么的完美,然而今天一早有人告诉我:登录失败报错400 Bad Request The plain HTTP request was sent to HTTPS port.

初步定位问题

然后想起有看到过红薯蜀黍的 https://www.oschina.net/question/12_213459 如下:(注:最终版在最后,如果有兴趣可以看看心路历程)

# tomcat server.xml
  <Service name="Catalina">
    <Connector port="9000" protocol="HTTP/1.1"
               connectionTimeout="20000"
               URIEncoding="UTF-8" 
               redirectPort="14443"
               scheme="https" 
               proxyPort="14443" />
  ...
 
    <Engine name="Catalina" defaultHost="localhost">
 
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
 
      <Valve className="org.apache.catalina.valves.RemoteIpValve"
                remoteIpHeader="x-forwarded-for"
                remoteIpProxiesHeader="x-forwarded-by"
                protocolHeader="x-forwarded-proto"
            />
  
# nginx 
    server {
        listen       14443 ssl;
        server_name localhost;
 
        ssl on;
        ssl_certificate      nginx.crt;
        ssl_certificate_key  nginx.key;
 
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  5m;
 
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
 
        location / {
            root   html;
            index  index.html index.htm;
        }
 
        location /omc {
          proxy_set_header Host $http_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_connect_timeout      240;
          proxy_send_timeout         240;
          proxy_read_timeout         240;
  
          proxy_pass http://localhost:9000; #默认连的是http的端口
          proxy_redirect off;
          #proxy_redirect https://$host/ / ;
      }
    }

登录请求确实都是https请求了,但是重定向(302)返回的https的端口丢失了(即被替换为默认的443)。查了很多资料,先弄了一个折中的处理方式,把hostname替换掉,即最后注释的那一行proxy_redirect。

查看的文章多半是http问题和多了端口的问题。我这是少端口了,但是还是有参考价值对proxy_redirect和port_in_redirect多了解一点:

  • nginx 和 Tomcat 集成后发生的重定向问题分析和解决
  • Nginx SSL+tomcat集群,request.getScheme() 取到https正确的协议
  • Nginx + Tomcat + HTTPS 配置原来不需要在 Tomcat 上启用 SSL 支持
  • Setting up NGINX SSL reverse proxy for Tomcat

还有一些没啥卵用,还带点误导性质的,但是还是得把它帖出来(蜜汁尴尬):(注:不是说人家的有错,而是说和上面的Valve结合后不行了)

  • 解决nginx https代理tomcat redirect问题

最终成果

注:nginx/tomcat配置https的方法,请查看前一篇文章。

注2:还有tomcat里面Header是不区分大小写的: org.apache.tomcat.util.http.MimeHeaders.getValue(String)

注3:如果配置proxyPort(而不是Valve的话)取到协议好像不对(没验证),并且配置Valve可以不影响Connector。

# nginx
    server {
        listen       14443 ssl;
        server_name localhost;
 
        ssl on;
        ssl_certificate      nginx.crt;
        ssl_certificate_key  nginx.key;
 
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  5m;
 
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
 
        location / {
            root   html;
            index  index.html index.htm;
        }
 
        location /omc {
        port_in_redirect on;
 
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Port $server_port; # !!自定义port header
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_connect_timeout      240;
        proxy_send_timeout         240;
        proxy_read_timeout         240;
 
        proxy_pass http://localhost:9000;
        #proxy_redirect default;
        proxy_redirect off;
        #proxy_redirect https://$host/ / ;
        }
 
    }
 
# tomcat server.xml
  <Service name="Catalina">
    <Connector port="9000" protocol="HTTP/1.1"
               connectionTimeout="20000"
               URIEncoding="UTF-8"
               redirectPort="8443"
                />
  ...
    <Engine name="Catalina" defaultHost="localhost">
  ...
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
          ...
            <Valve className="org.apache.catalina.valves.RemoteIpValve"
                  portHeader="x-forwarded-port"
                  remoteIpHeader="x-forwarded-for"
                  proxiesHeader="x-forwarded-by"
                  protocolHeader="x-forwarded-proto"
            />

参考:

http://www.winseliu.com/blog/2017/01/20/nginx-https-with-tomcat-http/

http://info.siven.net/posts/d925bb5d.html

原文  https://www.omgdba.com/nginx-https-with-tomcat-http.html
正文到此结束
Loading...