Nginx安全与NginxSession共享

  1. Nginx跨域问题,分别向两台服务器上传下面的两个页面,其中第一个页面调用第二个页面中的内容:

    a.jsp中的内容:

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>177节点</title>
    </head>
    <script src="https://code.jquery.com/jquery-2.2.4.js" integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" crossorigin="anonymous"></script>
      
    <script type="text/javascript">
    	$(document).ready(function() {
    		$.ajax({
    			type: "get",
    			url: "http://www.kangswx/b.jsp",
    			dataType: "text",
    			success: function(data) {
    				debugger;
    				alert("获取178结果:" + data);
    			},
    			error: function(e) {
    				debugger;
    				alert('失败:' + e);
    			}
    		});
    
    	});
    </script>
    
    <body>
        我是177节点
    </body>
    </html>
    

    b.jsp中的内容:

    <%
    response.setContentType("application/json;charset=utf-8");
    out.print("{'status':'200', 'message':'178节点NGINX1'}");
    %>
    

    此时若直接访问 http://192.168.18.177:8080/a.jsp,回报如下的错误(跨域问题):No ‘Access-Control-Allow-Origin’ header is present on the requested resource。

    需要在Nginx的配置文件中做如下的修改:

    upstream serveraaalist{
    	server 192.168.18.177:8080;
    }
    
    upstream serverbbblist{
    	server 192.168.18.178:8080;
    }
    
    location /a {
    	proxy_pass http://serveraaalist/a;
    }
    location /b {
    	proxy_pass http://serverbbblist/b;
    }
    

    在a.jsp中掉用b.jsp的时候,需要通过域名调用 http://www.kangswx/b.jsp

    此时访问 http://www.kangswx.com/a.jsp 就能正常获取b中的数据。

  2. 盗链:

    ​ 客户端向服务端发起请求的时候,为了减少网络宽带,提高响应速度,服务器一般不会把所有的资源都完整的返回给客户端,比如在请求一个网页时,首先会传回该网页的文本内容,当客户端浏览器发现有图片需要加载的时候,会再次向服务器发起请求获取图片资源,服务器再将图片资源返回给客户端,在这个过程中,如果该服务器只包含网页文本内容,并没有相关的要从本地服务器加载图片资源,而是去其他网站加载图片资源,只就是盗链。

  3. 防止盗链:

    ​ HTTP协议中的请求头部的Referer头域和采用URL的格式表示访问当前网页或者文件的源地址。通过Referer头,就可以检测到访问目标资源的源地址。当发现Referer头不是我们自己网站的内的URL,就采用阻止措施,实施防盗链。但是,Referer是可以被篡改的,因此应该方法不能够完全防止盗链。

  4. Nginx防盗链:Nginx配置有个valid_referers指令,用来获取Referer头中值,根据该值的情况给Nginx全局变量invalid_referer赋值,如果Referer头中没有符合的valid_referes指令配置的值,invalid_referer全局变量就会被赋值为1。

  5. valid_referers指令语法格式:

    格式:valid_referers none | blocked | server_names | string……;

    none: 检测Referer头域不存在的情况;

    blocked: 检测Referer头域值被防火墙或代理服务器删除或伪装的情况;

    server_name:设置一个或多个URL, 用于Referer头域值是否属于URL中的某个值, URL支持通配符;

  6. Nginx防盗链配置方式,在原有location下面,新加一个新的location,如下

    location ~ .*\.(jpg|jpeg|png|gif|icon|rar|zip|swf)$ {
        valid_referers blocked http://www.kangswx.com www.kangswx.com;
        if ($invalid_referer) {
        	return 403;  # 资源不可用
        }
    }
    
  7. Nginx防御DDOS攻击:限制请求次数,设置Nginx的连接请求在一个真实用户请求的合理范围内。

  8. Nginx防御DDOS攻击的配置方式

    1. 在配置文件server的上面添加如下的内容

      limit_req_zone $binary_remote_addr zone=one:10m rate=2r/s;
      
    2. 在location中加入

      limit_req zone=one;
      
  9. 参数说明

    $binary_remote_addr二进制远程地址
    zone=one:10m定义zone名字叫one,并为这个zone分配10M内存,用来存储会话(二进制远程地址),1m内存可以保存16000会话
    rate=10r/s;限制频率为每秒10个请求
    burst=5允许超过频率限制的请求数不多于5个,假设1、2、3、4秒请求为每秒9个,那么第5秒内请求15个是允许的,反之,如果第一秒内请求15个,会将5个请求放到第二秒,第二秒内超过10的请求直接503,类似多秒内平均速率限制。
    nodelay超过的请求不被延迟处理,设置后15个请求在1秒内处理。
  10. 此时当请求数量超限的时候,页面会报如下的错误

  1. Nginx解决session共享有四种方案:

    1. 使用Nginx的负载均衡中的ip_hash配置(不推荐);
    2. 使用数据库同步session(不推荐);
    3. 使用cookie同步session(不推荐);
    4. 使用redis存放session数据
  2. 运行SpringBoot的jar文件:

    nohup java -jar springboot-session-8081.jar &
    
  3. 模拟session不共享示例代码,新建一个SpringBoot项目,新建一个测试controller,代码如下:

    package com.kangswx.springbootsession.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    @RestController
    public class SessionController {
    
        //开放的端口号
        @Value("${server.port}")
        private String port;
    
        @GetMapping("/setSession")
        public String setSession(HttpServletRequest request, String key, String value) {
            HttpSession session = request.getSession();
            session.setAttribute(key, value);
            String rs = "setSession  Server Port:" + port + " Value:" + value;
            System.out.println(rs);
            return rs;
        }
    
        @GetMapping("/getSession")
        public String getSession(HttpServletRequest request, String key) {
            HttpSession session = null;
            String value = null;
            try {
                session = request.getSession(false);
                if (session != null)
                    value = (String)session.getAttribute(key);
            } catch (Exception e) {
                e.printStackTrace();
            }
            String rs = "getSession  Server Port:" + port + " Value:" + value;
            System.out.println(rs);
            return rs;
        }
    
    }
    
  4. 分别上传到 192.168.18.177 和 192.168.18.178 两台服务器,并且在Nginx中将上述两台服务器配置好,启动SpringBoot项目(192.168.18.177开放的端口的8081,192.168.18.178开放的端口为8082):

    首先向某个服务器中写入session:

    再多次获取session的时候,就会出现session不共享的问题:

  5. SpringBoot解决session共享问题:

    1. 在之前的项目中添加相关依赖的maven坐标:

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
      
      <dependency>
          <groupId>org.springframework.session</groupId>
          <artifactId>spring-session-data-redis</artifactId>
      </dependency>
      
    2. 在SpringBoot项目的配置文件中加入下面的配置项:

      spring:
        redis:
          host: 192.168.18.177
          port: 6379
          password: redis
          database: 2
      
        #将session存储在Redis中,实现session共享的问题
        session:
          store-type: redis
      
    3. 将项目分别打成对应的jar包并上传到服务器,再进行上面的测试,就会发现session不共享的问题完美解决。

    4. 代码可见 SpringBoot解决session共享

    5. 安装Redis可参考 Centos7安装Redis5

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值