前言

最近在折腾公司以前开发的系统。

这套系统状况是直接启动的tomcat,然后防火墙关闭,直接用ip+端口号的方式来访问,现在要做访问控制,tomcat也可以实现,但我实在是看不下去这样丑丑的网址,所以决定采用nginx反向代理tomcat,并启用ssl


报错

域名:dashboard.domain.com

浏览器访问后开发者模式看到的报错信息:

Mixed Content: The page at 'https://dashboard.domain.com/wire' was loaded over HTTPS, but requested an insecure stylesheet 'http://dashboard.domain.com/static/css/flickity.css'. This request has been blocked; the content must be served over HTTPS.

查询后发现这是因为在https网页中请求http数据而被浏览器拦截。

参考链接:https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content?hl=zh-cn

谷歌给出的思路是检查代码,修正http,如果还不行的话,对html代码进行修改,将http的请求转为https请求。

根据我的测试,有三种方法去解决这个问题,但是推荐第一种检查代码的方式,其他的两种只能解决部分,仍然会有其他的错误。


解决

推荐:检查代码

我比较好奇,我们已经对静态的jscss做了nginx静态请求,理论上可以排除tomcat的影响,而且针对http的请求会301重定向至https,竟然还有http的请求,那只能是代码里就是指定的http,查询到代码中这些http请求的代码都是相对路径:

<script type="text/javascript" src="./static/js/jquery-1.11.3.min.js" ></script>
<script type="text/javascript" src="./static/js/echarts.min.js" ></script>
<script type="text/javascript" src="./static/js/china.js" ></script>
<link rel="stylesheet" href="./static/css/pagination.css" />

这是属于标准写法之一。

这时候发现在<head>中有一段代码<base href="<%=basePath%>">,这是jsp网页中设置基链的代码,<%=basePath%>会获得目前的访问地址,比如现在获得的是http://dashboard.domain.com:80。

这里是对basePath的定义:

String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";

所以问题就出在request.getScheme()获取到的一直是http,我们的拓扑是nginx反向代理tomcat,对于tomcat来说,来访者一直都是nginx,而且是http的,这里就需要我们将对nginxtomcat进行分别配置。


NGINX端

需要在配置文件中添加如下参数

location / {
        proxy_pass http://dashboard;
        proxy_redirect off;
        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 $scheme;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

其中的重点是 proxy_set_header X-Forwarded-Proto $scheme;


TOMCAT端

需要在配置文件中添加如下参数

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

然后分别重启nginxtomcat即可解决问题。


不推荐:修改文件或修改NGINX配置文件

修改文件

在访问的网页源代码中,使用一个<meta>元素在文档的<head>部分中嵌入指令

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

实际测试中可行,解决部分问题,但是仍有部分代码仍然报错。


修改NGINX配置文件

将刚刚的对网页文件的修改使用nginx来做,省去每一个文件都需修改的麻烦,但是实测此种方法的弊端与修改网页相同,均有部分代码报错。

location / {
    add_header Content-Security-Policy upgrade-insecure-requests;
    ……省略
}

后记

nginx在做反向代理服务器时,配置参数以及与其他中间件的对接是需要好好查看的,没有系统去阅览过总会在使用中踩坑。

Nginx完整配置

upstream dashboard {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name dashboard.domain.com;
    return 301 https://$host$request_uri; //将http访问301错误指向https
}

server {
    listen 443 ssl;
    server_name dashboard.domain.com;
    
    ssl on;
    ssl_certificate /etc/nginx/ssl/dashboard/fullchain.cer;
    ssl_certificate_key /etc/nginx/ssl/dashboard/dashboard.domain.com.key;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:20m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;
    location / {
        proxy_pass http://dashboard;
        proxy_redirect off;
        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 $scheme;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        allow 8.8.8.8; //仅允许这个ip访问,不符合则返回403错误
        deny all; //禁止其他所有ip访问
        error_page 403 /403.html;
            location = /403.html {
                root /usr/share/nginx/html;
                allow all;
            }
        }
    location ~ .*\.(js|css)?$ {
        root /usr/local/tomcat/webapps/dashboard;
        expires 1h;
    }
    location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
        root /usr/local/tomcat/webapps/dashboard;
        expires 30d;
    }
}
Last modification:May 7th, 2019 at 03:13 pm