Git Product home page Git Product logo

waf's Introduction

Join the chat at https://gitter.im/chengdedeng/waf MIT Licence LICENSE

WAF是使用Java开发的API Gateway,由于WAF构建在开源代理LittleProxy之上,所以说WAF底层使用的是Netty

特性

  1. 安全拦截,支持各种分析检测,支持脚本(沙箱);
  2. 流控/CC防护,支持IP粒度,可扩展;
  3. HTTP代理,支持"hijacking" HTTPS connection using "Man in the Middle" style attack;
  4. URL Rewrite;
  5. HTTP Redirect;
  6. Socks5;
  7. 集中式配置;
  8. 自定义协议转化,HTTP->DUBBO,HTTP->GRPC等(可导入swagger接口文档);

Quick Start

编译:
 mvn package
运行:

由于使用appassembler-maven-plugin 打成了符合JSW规范的包,所以解压target目录下的Zip文件, 然后在bin目录下运行对应平台的脚本,以Linux为例:

bin/waf { console | start | stop | restart | status | dump }
配置:

2.0开始配置分为基础配置和应用配置,基础配置就是Classpath下的waf.properties、admin.properties、application.properties、cluster.properties; 应用配置则需要通过接口进行设置,waf目前还没有一套简易的UI来进行设置,不过集成了swagger,可以通过swagger ui界面来配置。2.0相较于1.0,配置集中化之后的好处在于配置修改 不再需要停机重新加载,规则随时可以添加、禁用删除。配置中心目前zookeeper是稳定的,atomix自研的配置中心目前还不完善,建议别开启atomix的spi实现。尽管没有UI,但是接口做了 详细的校验,大家可以放心设置,不大会出现配置参数设置错误导致的系统崩溃。

架构

HTTP Proxy选择了基于Netty研发的LittleProxy, LittleProxy是LANTERN的维护者发起的开源项目,是一款非常优秀的Java HTTP Proxy. 关于Loadbalance,WAF有两种模式可以供选择,一种基于Proxy Chain,另一种是基于HostResolver.Proxy Chain是把目标机的映射交给 下游的Proxy,而HostResolver则是WAF自身完成映射.需要特别注意的是,Proxy Chain中如果存在多Proxy是不会负载均衡的,只有前一个不可用时才会用下一个.

HttpRequestFilterChainHttpResponseFilterChain 责任链,分别对进来和出去的数据进行拦截分析.Request拦截又分为黑白名单两种,Response拦截主要给输出的数据进行安全加固.在Request的拦截规则方面,我参考了loveshell/ngx_lua_waf.

更多技术详情请移步个人Java版WAF技术细节 HttpProxy研发心得

性能

测试目的

Nginx的性能是有目共睹的,WAF既然作为一个HTTP Proxy,所以需要跟Nginx对比一下,看看性能的差距有多大.

因为目的是要压出中间Proxy的性能极限,所以后端服务性能要非常高,至少要比中间Proxy性能好,所以选用了Nginx模拟后端服务. 为了减少网络开销对测试影响,所有的测试都是在一台机器上完成的.

测试基准:

1.AB->Nginx_Proxy->Nginx_AS

2.AB->WAF->Nginx_AS

3.ab -k -c 100 -n 1000000 目标地址(HTTP长链)

4.ab -c 100 -n 1000000 目标地址(HTTP短链)

JDK版本
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
WAF JVM配置:
wrapper.java.additional.1=-server
wrapper.java.additional.2=-Xms2048m
wrapper.java.additional.3=-Xmx2048m
wrapper.java.additional.4=-Xmn800m
wrapper.java.additional.5=-XX:+UseG1GC
wrapper.java.additional.6=-Xloggc:/tmp/log/gc.log
wrapper.java.additional.7=-XX:+HeapDumpOnOutOfMemoryError
wrapper.java.additional.8=-XX:+PrintGCDetails
wrapper.java.additional.9=-XX:+PrintGCTimeStamps
wrapper.java.additional.10=-XX:+PreserveFramePointer
WAF基础配置:
#on表示waf支持loadbalance,需要配置upstream.properties,与waf.proxy.chain和waf.mitm互斥
waf.lb=on
#设置重试间隔时间,默认10秒
waf.lb.fail_timeout=10
#是否路由到waf下游的proxy,与waf.proxy.lb互斥
waf.chain=off
#waf下游的proxy,多个用","分隔.注意只有前一个不可用,才会用下一个,下游proxy不会负载均衡
waf.chain.servers=127.0.0.1:4321
#是否启用TLS,与waf.mitm互斥
waf.tls=off
#是否HTTPS开启中间人拦截,与waf.tls和waf.proxy.lb互斥
waf.mitm=off
#接收者线程数,如果系统只有一个服务端port需要监听,则BossGroup线程组线程数设置为 1。
#https://stackoverflow.com/questions/22280916/do-we-need-more-than-a-single-thread-for-boss-group
waf.acceptorThreads=1
#处理client请求的工作线程数
waf.clientToProxyWorkerThreads=100
#处理proxy与后端服务器的工作线程数
waf.proxyToServerWorkerThreads=100
#waf服务器端口
waf.serverPort=9091
#是否开启Socks5支持
waf.ss=off
waf.ss.server.host=127.0.0.1
waf.ss.server.port=1080
#The timeout (in seconds) for auto-closing idle connections.
waf.idleConnectionTimeout=70
服务器/虚拟机(测试机)配置:
4  Intel(R) Xeon(R) CPU E5-2640 v2 @ 2.00GHz

结果:

CPU(id基本在10以内)

%Cpu0  : 49.8 us, 33.7 sy,  0.0 ni,  6.1 id,  0.0 wa,  0.0 hi, 10.4 si,  0.0 st
%Cpu1  : 48.0 us, 33.9 sy,  0.0 ni,  7.4 id,  0.0 wa,  0.0 hi, 10.7 si,  0.0 st
%Cpu2  : 49.8 us, 33.0 sy,  0.0 ni,  7.4 id,  0.0 wa,  0.0 hi,  9.8 si,  0.0 st
%Cpu3  : 48.8 us, 31.5 sy,  0.0 ni,  8.5 id,  0.0 wa,  0.0 hi, 11.2 si,  0.0 st

QPS

测试场景 测试条件 QPS
AB->Nginx_AS HTTP长链 64815
AB->Nginx_AS HTTP短链 6174
AB->Nginx_Proxy->Nginx_AS HTTP长链 16924
AB->Nginx_Proxy->Nginx_AS HTTP短链 13137
AB->WAF->Nginx_AS HTTP长链 5566
AB->WAF->Nginx_AS HTTP短链 5559

火焰图:

github不支持火焰图显示,点击下载源文件.

常见问题

  1. 开启TLS or MITM后,会在项目的目录下生成waf_cert证书,TLS会自动下发证书,MITM需要手动加入证书,信任之后就可以正常工作了.
  2. waf.proxy.lbwaf.proxy.mitm,waf.tlswaf.proxy.mitm,waf.proxy.chainwaf.proxy.lb两两之间只能开启其中之一.
  3. 如果只是HTTP或者HTTPS抓包,可以关闭所有的安全拦截.
  4. 如果Gateway前面还有loadbalance,例如Nginx,Nginx->Gateway一定要用HTTP1.1,否者会报upstream prematurely closed connection while reading upstream。出现该问题的原因 可以仔细阅读HttpFilterAdapterImpl.java中方法 proxyToServerRequestSending的注释。

waf's People

Contributors

chengdedeng avatar dependabot[bot] avatar gitter-badger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

waf's Issues

License ?

Hello, under what license is this project released under ? Thank-you.

如何运行?

waf console 报错 java.lang.ClassNotFoundException: javax.servlet.Filter 请指教如何运行 谢谢!

Unimplemented for /waf/config/security/info.yangguo.waf.request.security.ArgsSecurity

启动的时候日志:
org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for /waf/config/security/info.yangguo.waf.request.security.ArgsSecurity

zookeeper是启动的啊,以下是zookeeper日志
2018-09-07 13:44:31,148 [myid:] - INFO [SessionTracker:ZooKeeperServer@354] - Expiring session 0x100003763d00001, timeout of 30000ms exceeded
2018-09-07 13:44:31,149 [myid:] - INFO [ProcessThread(sid:0 cport:2181)::PrepRequestProcessor@487] - Processed session termination for sessionid: 0x100003763d00000
2018-09-07 13:44:31,149 [myid:] - INFO [ProcessThread(sid:0 cport:2181)::PrepRequestProcessor@487] - Processed session termination for sessionid: 0x100003763d00001
2018-09-07 13:44:31,149 [myid:] - INFO [SyncThread:0:FileTxnLog@213] - Creating new log file: log.417
2018-09-07 13:44:32,452 [myid:] - WARN [SyncThread:0:FileTxnLog@378] - fsync-ing the write ahead log in SyncThread:0 took 1301ms which will adversely effect operation latency. See the ZooKeeper troubleshooting guide
2018-09-07 13:44:36,384 [myid:] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@215] - Accepted socket connection from /127.0.0.1:54844
2018-09-07 13:44:36,388 [myid:] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:ZooKeeperServer@948] - Client attempting to establish new session at /127.0.0.1:54844
2018-09-07 13:44:36,392 [myid:] - INFO [SyncThread:0:ZooKeeperServer@693] - Established session 0x1000121f7a80000 with negotiated timeout 40000 for client /127.0.0.1:54844
2018-09-07 13:44:36,447 [myid:] - WARN [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:ZooKeeperServer@755] - Received packet at server of unknown type 15
2018-09-07 13:44:36,448 [myid:] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1040] - Closed socket connection for client /127.0.0.1:54844 which had sessionid 0x1000121f7a80000

windows运行问题

@chengdedeng hi:
打包后在admin权限cmd执行 waf.bat start 提示以下错误:wrapper | The waf service is not installed - 指定的服务未安装。 (0x424) 请问这是什么问题,waf需要安装什么别的依赖吗?
另外,希望作者有更多的相关使用、开发经验分享!

感谢您的开源分享!

为支持多个下游service,需要部署多个waf进程吗?

因为一个waf代理根据host和waf.serverPort,只能找到一个remoteAddress。这样设计就导致,一个下游服务会占用一个waf代理。新增一个下游服务,也需要增加一个waf代理。
为什么不设计成一个waf代理,可以路由到所有下游服务呢?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.