soul网关-7-waf插件

之前的一篇学习Divide插件的笔记里面分析过插件链,waf插件是插件链上排在sign插件后面的第二个插件。

WafPlugin也继承自AbstractSoulPlugin,但在AbstractSoulPluginexecute方法里面对waf插件与其他插件如divide插件稍有不同。

divide插件在AbstractSoulPluginexecute方法里面的处理过程是:

  • 判断内存缓存中是否有插件数据,没有则执行下一个插件
  • 判断插件数据中是否启用的标志位是否为true,否则执行下一个插件
  • 插件数据中是否有selector列表,没有则报错
  • selector列表中是否有与当前请求匹配的selector,没有则报错
  • 与当前请求匹配的selector是否有rule列表,没有则报错
  • rule列表中是否有与当前请求匹配的rule,没有则报错
  • 执行DividePlugin的doExecute方法

但是waf插件在AbstractSoulPluginexecute方法里面的处理过程是这样的:(总结为,只要waf插件启用了,就会调用WafPlugindoExecute方法)

  • 判断内存缓存中是否有插件数据,没有则执行下一个插件
  • 判断插件数据中是否启用的标志位是否为true,否则执行下一个插件
  • 插件数据中是否有selector列表,没有则执行WafPlugindoExecute方法
  • selector列表中是否有与当前请求匹配的selector,没有则执行WafPlugindoExecute方法
  • 与当前请求匹配的selector是否有rule列表,没有则执行WafPlugindoExecute方法
  • rule列表中是否有与当前请求匹配的rule,没有则执行WafPlugindoExecute方法
  • 执行WafPlugindoExecute方法

看下WafPlugindoExecute方法里面具体进行了哪些判断:

  • 如果waf插件的selector和rule都是空
    • 官网文档上写到*“如果配置的model是black,即只有匹配的流量才会执行拒绝策略,不匹配的,直接会跳过”*。此时因为selector和rule是空,未匹配任何流量,直接执行下一个插件
    • 官网文档上写到*”当 module 设置为 mixed 模式的时候,所有的流量都会通过 waf插件,针对不同的匹配流量,用户可以设置是拒绝,还是通过。“*。此时因为selector和rule是空,未匹配任何流量,所以拒绝该请求,响应值为403
  • 如果rule不为空,且rule里面的handle是空,直接执行下一个插件
    • 相当于selector和rule虽然匹配到了这个请求,但因为未配置任何的拦截策略,所以跳过
  • 如果rule的handle不为空,且配置的拦截策略是REJECT
    • 那么拒绝该请求,响应值为拒绝策略中自定义的statusCode
  • 否则配置的拦截策略是ALLOW,即允许请求通过。则执行下一个插件
    @Override
    protected Mono doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
        WafConfig wafConfig = Singleton.INST.get(WafConfig.class);
        if (Objects.isNull(selector) && Objects.isNull(rule)) {
            if (WafModelEnum.BLACK.getName().equals(wafConfig.getModel())) {
                return chain.execute(exchange);
            }
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            Object error = SoulResultWrap.error(403, 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);
        }
        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);
        }
        return chain.execute(exchange);
    }

下面来实际操作一下,在soul-admin管理后台,为waf插件配置selector和rule

soul网关-7-waf插件_第1张图片
soul网关-7-waf插件_第2张图片

soul-admin管理后台,启用waf插件

soul网关-7-waf插件_第3张图片

在浏览器里面访问http://localhost:9195/http/order/findById?id=1,发现被禁止了。符合上方的分析。

在这里插入图片描述

修改rule的handle拦截策略为allow,再在浏览器里面访问http://localhost:9195/http/order/findById?id=1,发现顺利通过了。也符合上方的分析。

soul网关-7-waf插件_第4张图片


上面的rule里面是对uri进行匹配,也可以根据ip来进行匹配

如下图所示,将rule里面的handle改成根据IP来匹配,匹配到之后就REJECT

soul网关-7-waf插件_第5张图片

看一下浏览器里面http://127.0.0.1:9195/http/order/findById?id=1,可以看到被禁止了

在这里插入图片描述

本次学习了soul网关的waf插件,结合前面已经学习过的selector和rule的概念,可以比较快地了解waf插件的机制。

你可能感兴趣的:(Java,网关)