zoukankan      html  css  js  c++  java
  • Soul 学习笔记---使用 waf 插件(十九)

    登录 soul-admin,开启 waf 插件。

    官网上的这两句很重要,waf 插件源码的实现也是根据这两句话来的。

    • 当 module 设置为 black 模式的时候,只有匹配的流量才会执行拒绝策略,不匹配的,直接会跳过。
    • 当 module 设置为 mixed 模式的时候,所有的流量都会通过 waf插件,针对不同的匹配流量,用户可以设置是 拒绝,还是通过。

    一开始我选的 black 模式,配置如下。

    请求时,就是这样的。

    接下来看下源码是怎么实现的。

    waf 插件是前置插件,也就是在请求真正 url 之前进行的,在插件链上第三个执行的。执行 waf 插件时,AbstractSoulPlugin 会匹配选择器和规则,匹配成功后,在 WafPlugin 会执行 doExecute 方法。
    但 waf 插件比较特殊一点是,其他插件规则匹配不成功,一般就是走下一个插件了,AbstractSoulPlugin 的 handleSelectorIsNull,handleRuleIsNull 的代码都是这么写的

    	//执行下一个插件
    	protected Mono<Void> handleSelectorIsNull(final String pluginName, final ServerWebExchange exchange, final SoulPluginChain chain) {
            return chain.execute(exchange);
        }
    
        protected Mono<Void> handleRuleIsNull(final String pluginName, final ServerWebExchange exchange, final SoulPluginChain chain) {
            return chain.execute(exchange);
        }
    

    但 wafPlugin 重写了 handleSelectorIsNull 和 handleRuleIsNull 方法,即使匹配不到选择器和规则,只要你 waf 插件开启了,也会走到 wafPlugin 的 doExecute 方法。

        @Override
        protected Mono<Void> handleSelectorIsNull(final String pluginName, final ServerWebExchange exchange, final SoulPluginChain chain) {
            //执行 waf 插件的 doExecute
            return doExecute(exchange, chain, null, null);
        }
    
        @Override
        protected Mono<Void> handleRuleIsNull(final String pluginName, final ServerWebExchange exchange, final SoulPluginChain chain) {
            return doExecute(exchange, chain, null, null);
        }
    

    waf 插件的 doExecute 方法

        protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
            //获取配置的是 black 还是 mixed,这个值是启动 soul-bootstrap 进行数据同步时,调用 WafPluginDataHandler 的 handlerPlugin 方法放进去的
            WafConfig wafConfig = Singleton.INST.get(WafConfig.class);
          	//匹配不到选择器和规则,就走这个逻辑
            if (Objects.isNull(selector) && Objects.isNull(rule)) {
                //这里就和一开始讲的官网上的说明对上了,black模式下,不匹配的直接跳过,走下一个插件
                if (WafModelEnum.BLACK.getName().equals(wafConfig.getModel())) {
                    return chain.execute(exchange);
                }
                //如果是 mixed,匹配不到就是 forbidden
                exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
                Object error = SoulResultWrap.error(HttpStatus.FORBIDDEN.value(), Constants.REJECT_MSG, null);
                return WebFluxResultUtils.result(exchange, error);
            }
            String handle = rule.getHandle();
            WafHandle wafHandle = GsonUtils.getInstance().fromJson(handle, WafHandle.class);
            if (Objects.isNull(wafHandle) || StringUtils.isBlank(wafHandle.getPermission())) {
                log.error("waf handler can not configuration:{}", handle);
                return chain.execute(exchange);
            }
            //我们在规则配置的是 reject 时,这里就按照我们配置的错误码直接返回 response
            if (WafEnum.REJECT.getName().equals(wafHandle.getPermission())) {
                exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
                Object error = SoulResultWrap.error(Integer.parseInt(wafHandle.getStatusCode()), Constants.REJECT_MSG, null);
                return WebFluxResultUtils.result(exchange, error);
            }
            //规则配置的是 allow 的话,直接走下一个插件了,可见 allow 时,配置的状态码也没啥用。
            return chain.execute(exchange);
        }
    

    利用网关的这个 waf 插件,我们就可以对那些非法的请求设置拦截策略。

  • 相关阅读:
    爬虫系列---多线程爬取实例
    爬虫系列---selenium详解
    爬虫系列二(数据清洗--->bs4解析数据)
    爬虫系列二(数据清洗--->xpath解析数据)
    爬虫系列二(数据清洗--->正则表达式)
    爬虫实例系列一(requests)
    selenium PO模式
    setUp和tearDown及setUpClass和tearDownClass的用法及区别
    chromeIEFirefox驱动下载地址
    HTTP通信机制
  • 原文地址:https://www.cnblogs.com/fightingting/p/14468782.html
Copyright © 2011-2022 走看看