The first all-round open source Web security protection system, more protection than others
4.9K
OpenWAF
第一个全方位开源的Web应用防护系统(WAF),更全面的防护功能,更多样的防护策略
This document describes OpenWAF v0.0.6 released on 26 Dec 2017.
Docker Version
#nginx.conf
lua_package_path '/twaf/?.lua;;';
init_by_lua_file /twaf/app/twaf_init.lua;
lua_shared_dict twaf_shm 50m;
upstream test {
server 0.0.0.1; #just an invalid address as a place holder
balancer_by_lua_file twaf_balancer.lua;
}
server {
listen 443 ssl;
server_name _;
ssl_certificate_by_lua_file twaf_ssl_cert.lua;
rewrite_by_lua_file /twaf/app/twaf_rewrite.lua;
access_by_lua_file /twaf/app/twaf_access.lua;
header_filter_by_lua_file /twaf/app/twaf_header_filter.lua;
body_filter_by_lua_file /twaf/app/twaf_body_filter.lua
log_by_lua_file /twaf/app/twaf_log.lua;
set $twaf_https 1;
set $twaf_upstream_server "";
ssl_certificate nginx.crt;
ssl_certificate_key nginx.key;
location / {
lua_need_request_body on;
proxy_pass $twaf_upstream_server;
}
}
server {
listen 80;
server_name _;
rewrite_by_lua_file /twaf/app/twaf_rewrite.lua;
access_by_lua_file /twaf/app/twaf_access.lua;
header_filter_by_lua_file /twaf/app/twaf_header_filter.lua;
body_filter_by_lua_file /twaf/app/twaf_body_filter.lua
log_by_lua_file /twaf/app/twaf_log.lua;
set $twaf_upstream_server "";
location / {
lua_need_request_body on;
proxy_pass $twaf_upstream_server;
}
}
#default_config-json
#main_safe_policy-json
OpenWAF是第一个全方位开源的Web应用防护系统(WAF),他基于nginx_lua API分析HTTP请求信息。OpenWAF由行为分析引擎和规则引擎两大功能引擎构成。其中规则引擎主要对单个请求进行分析,行为分析引擎主要负责跨请求信息追踪。
规则引擎的启发来自modsecurity及freewaf(lua-resty-waf),将ModSecurity的规则机制用lua实现。基于规则引擎可以进行协议规范,自动工具,注入攻击,跨站攻击,信息泄露,异常请求等安全防护,支持动态添加规则,及时修补漏洞。
行为分析引擎包含基于频率的模糊识别,防恶意爬虫,人机识别等防探测模块,防CSRF,防CC,防提权,文件上传防护等防攻击模块,cookie防篡改,防盗链,自定义响应头,攻击响应页面等防信息泄露模块。
除了两大引擎之外,还包含统计,日志,攻击响应页面,接入规则等基础模块。除了已有的功能模块,OpenWAF还支持动态修改配置, 动态添加第三方模块,使得在不重启引擎中断业务的条件下,升级防护。
OpenWAF支持将上述功能封装为策略,不同的web application应用不同的策略来防护。将来还会打造云平台,策略还可分享供他人参考。
基础模块如下:
功能模块如下:
详细配置文档及示例请看上述各模块文档
The OpenWAF-en mailing list is for English speakers.
The OpenWAF-cn mailing list is for Chinese speakers.
579790127
Please submit bug reports, wishlists, or patches by
Time: 2017/03/20
Version: v0.0.4
1. New Module - twaf_anti_cc
Anti http flood
Time: 2017/01/03
Version: v0.0.3.170103_beta
1. New Module - twaf_anti_mal_crawler
Distinguish malicious crawler and some scan tools
Time: 2016/12/05
Version: v0.0.2.161205_beta
1. New Module - twaf_attack_response
Return custom response page When the request is rejected by OpenWAF
2. Api - api/stat[/policy_uuid]
Show statistical infomation
Time: 2016/12/05
Version: v0.0.1.161130_beta
1. Docker
build OpenWAF with docker
Time: 2016/12/05
Version: v0.0.1.161012_beta
1. log module
Send tcp/udp log
2. reqstat module
Statistics of request infomation
3. access rule
Publish applications
4. rule engine
Access Control
This module is licensed under the BSD license.
Copyright (C) 2016-2016, by Jian "Miracle" Qi (齐健) [email protected], Titan Co.Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
"twaf_access_rule": {
"rules": [ -- 注意先后顺序
{
"client_ssl": false, -- 客户端认证的开关,与ngx_ssl组成双向认证
"client_ssl_cert": "path", -- 客户端认证所需PEM证书地址
"ngx_ssl": false, -- nginx认证的开关
"ngx_ssl_cert": "path", -- nginx认证所需PEM证书地址
"ngx_ssl_key": "path", -- nginx认证所需PEM私钥地址
"host": "^1\\.1\\.1\\.1$", -- 域名,正则匹配
"port": 80, -- 端口号(缺省80)
"path": "\/", -- 路径,正则匹配
"server_ssl": false, -- 后端服务器ssl开关
"forward": "server_5", -- 后端服务器upstream名称
"forward_addr": "1.1.1.2", -- 后端服务器ip地址
"forward_port": "8080", -- 后端服务器端口号(缺省80)
"uuid": "access_567b067ff2060", -- 用来标记此规则的uuid
"policy": "policy_uuid" -- 安全策略ID
}
]
}
}
syntax: "rules": table
default: none
context: twaf_access_rule
table类型,接入规则,顺序匹配
syntax: "client_ssl": true|false
default: false
context: twaf_access_rule
客户端认证开关,与ngx_ssl组成双向认证,默认false
PS: 当前客户端认证不生效
syntax: "client_ssl_cert": "path"
default: none
context: twaf_access_rule
string类型,客户端认证所需PEM证书地址,目前仅支持绝对地址
syntax: "ngx_ssl": true|false
default: false
context: twaf_access_rule
boolean类型,服务器端(nginx)认证开关,与client_ssl组成双向认证,默认关闭
syntax: "ngx_ssl_cert": "path"
default: none
context: twaf_access_rule
string类型,服务器端(nginx)认证所需PEM证书地址,目前仅支持绝对地址
syntax: "ngx_ssl_key": "path"
default: none
context: twaf_access_rule
string类型,服务器端(nginx)认证所需PEM私钥地址,目前仅支持绝对地址
syntax: "host": "ip|domain name regex"
default: none
context: twaf_access_rule
string类型,域名,正则匹配(匹配时,忽略大小写)
例如:
"host": "^1\\.1\\.1\\.1$"
"host": "test\\.com"
"host": "^.*\\.com$"
"host": "www.baidu.com"
syntax: "port": number
default: 80
context: twaf_access_rule
number类型,端口号
syntax: "path": "regex"
default: none
context: twaf_access_rule
string类型,路径,正则匹配
例如:
"path": "/"
"path": "/images"
"path": "/[a|b]test"
syntax: "server_ssl": true|false
default: false
context: twaf_access_rule
boolean类型,OpenWAF向后端服务器连接的ssl开关
例如:
upstream test {
server 1.1.1.1;
}
http {
server {
listen 80;
server_name _;
location / {
#server_ssl为true,相当于proxy_pass后为https
proxy_pass https://test;
#server_ssl为false,相当于proxy_pass后为http
#proxy_pass http://test;
}
}
}
syntax: "forward": "upstream_uuid"
default: none
context: twaf_access_rule
string类型,forward表示后端服务器的uuid,即upstream的名称
#如:forward值为test
upstream test {
server 1.1.1.1;
}
syntax: "forward_addr": "ip"
default: none
context: twaf_access_rule
string类型,forward_addr表示后端服务器的ip地址(TODO:支持域名)
upstream test {
#如:forward_addr值为1.1.1.1
server 1.1.1.1;
}
syntax: "forward_port": port
default: 80
context: twaf_access_rule
number类型,forward_port表示后端服务器端口号,默认80
upstream test {
#如:forward_port值为50001
server 1.1.1.1:50001;
}
syntax: "uuid": "string"
default: none
context: twaf_access_rule
string类型,接入规则的唯一标识
syntax: "policy": "policy_uuid"
default: none
context: twaf_access_rule
string类型,满足此接入规则的请求,所使用安全策略的uuid
{
"twaf_anti_hotlink":{
"state":false,
"log_state":true,
"event_id":"110001",
"event_severity":"medium",
"ct_state":false,
"action_meta":403,
"action":"DENY",
"mode":"referer",
"allow_noreferer":true,
"cookie_name":"TWAF_AH",
"uri_ext":["javascript", "css", "html", ""]
}
}
syntax: "state": true|false|"$dynamic_state"
default: false
context: twaf_anti_hotlink
当前模块暂未开源
syntax: "log_state": true|false|"$dynamic_state"
default: true
context: twaf_anti_hotlink
syntax: "ct_state": true|false|"$dynamic_state"
default: false
context: twaf_anti_hotlink
syntax: "event_id": "string"
default: "110001"
context: twaf_anti_hotlink
syntax: "event_severity": "string"
default: "medium"
context: twaf_anti_hotlink
syntax: "action": "string"
default: "DENY"
context: twaf_anti_hotlink
syntax: "action_meta": "string"|number
default: 403
context: twaf_anti_hotlink
syntax: "mode": "string"
default: "referer"
context: twaf_anti_hotlink
syntax: "allow_noreferer": true|false
default: true
context: twaf_anti_hotlink
syntax: "cookie_name": "string"
default: TWAF_AH
context: twaf_anti_hotlink
cookie_name表示盗链模块发送COOKIE的名称,默认"TWAF_AH"
此配置只有mode为cookie模式下生效
syntax: "uri_ext": array|exten|"all"
default: none
context: twaf_anti_hotlink
uri_ext表示对哪些资源进行盗链防护
#对html类型资源进行盗链防护
"uri_ext": "html"
#对未知类型资源进行盗链防护,nginx无法解析出资源类型时为空字符串
"uri_ext": ""
#对html、css及未知类型资源进行盗链防护
"uri_ext": ["html", "css", ""]
#对所有资源进行盗链防护
"uri_ext": "all"
{
"state": false, -- 模块开关,支持 true,false
"log_state":true, -- 日志开关
"dict_state": false, -- shared_dict 开关
"shared_dict_name":"twaf_anti_mal_crawler", -- shared_dict 名称,若为空,则值为 "twaf_global" 下的 "dict_name"
"shared_dict_key": "remote_addr", -- shared_dict 键值
"timeout":300, -- shared_dict 保存状态有效时长(单位秒)
"timer_flush_expired":200, -- shared_dict 清除过期信息的间隔时间(单位秒),若为空,则值为 "twaf_global" 下的 "timer_flush_expired"
"cookie_state":true, -- cookie机制开关
"crawler_cookie_name":"TWAF_crawler", -- 爬虫cookie名称
"mal_cookie_name":"TWAF_mcrawler", -- 恶意爬虫cookie名称
"force_scan_robots_state":true, -- 页面注入诱捕路径的开关
"force_scan_times": 3, -- 注入诱捕路径的页面个数
"trap_uri":"/abc/abc.html", -- 诱捕路径
"trap_args":"id=1", -- 诱捕参数
"action":"DENY", -- 执行动作,支持 "ALLOW", "DENY", "REDIRECT", "ROBOT", "RESET_CONNECTION", "PASS" 等
"action_meta": 403 -- 执行动作的附属信息,若 action 为 DENY,action_meta为响应码,若 action 为 REDIRECT,action_meta 为重定向 url
}
syntax: state true|false|$dynamic_state
default: false
context: twaf_anti_mal_crawler
模块开关,默认false(关闭),支持动态开关
syntax: log_state true|false|$dynamic_state
default: true
context: twaf_anti_mal_crawler
安全日志开关, 默认true(记录),支持动态开关
syntax: dict_state true|false
default: false
context: twaf_anti_mal_crawler
shared_dict 开关。当 dict_state 为 true,某 IP 被此模块拦截,会被记录在内存中,在 timeout 时间内访问会被拦截(且重置timeout)
syntax: shared_dict_name
default: nil
context: twaf_anti_mal_crawler
shared_dict 名称。对应 nginx 中的配置项,不可轻易修改
若为空,则值为 "twaf_global" 下的 "dict_name"
syntax: shared_dict_key |
default: remote_addr
context: twaf_anti_mal_crawler
shared_dict 键值。支持数组
syntax: timeout
default: 300
context: twaf_anti_mal_crawler
shared_dict 保存状态有效时长(单位秒)
syntax: timeout
default: 200
context: twaf_anti_mal_crawler
shared_dict 清除过期信息的间隔时间(单位秒),若为空,则值为 "twaf_global" 下的 "timer_flush_expired"
syntax: cookie_state true|false|$dynamic_state
default: true
context: twaf_anti_mal_crawler
是否发送cookie,默认true(发送),支持动态开关
syntax: crawler_cookie_name
default: "TWAF_crawler"
context: twaf_anti_mal_crawler
爬虫 cookie 名称
syntax: mal_cookie_name
default: TWAF_mcrawler
context: twaf_anti_mal_crawler
恶意爬虫cookie名称
syntax: force_scan_robots_state true|false
default: true
context: twaf_anti_mal_crawler
页面注入诱捕路径的开关
某些扫描工具不会去访问 /robots.txt,因此在他访问的页面中插入禁爬目录的暗链
syntax: force_scan_times
default: 3
context: twaf_anti_mal_crawler
注入诱捕路径的页面数
syntax: trap_uri
default: /abc/abc.html
context: twaf_anti_mal_crawler
诱捕路径,访问此路径,被标识为恶意爬虫
syntax: trap_args
default: id=1
context: twaf_anti_mal_crawler
诱捕参数。携带此参数访问诱捕路径,不会标识为攻击
Back to twaf_anti_mal_crawler
"twaf_reqstat": {
"state":true,
"safe_state":true,
"access_state":true,
"upstream_state":true,
"shared_dict_name":"twaf_reqshm"
}
syntax: state true|false|$dynamic_state
default: true
context: twaf_reqstat
统计模块开关,支持动态开关,默认开启
syntax: access_state true|false|$dynamic_state
default: true
context: twaf_reqstat
访问信息统计开关,支持动态开关,默认开启
syntax: safe_state true|false|$dynamic_state
default: true
context: twaf_reqstat
安全信息统计开关,支持动态开关,默认开启
syntax: upstream_state true|false|$dynamic_state
default: true
context: twaf_reqstat
转发信息统计开关,支持动态开关,默认开启
syntax: shared_dict_name string
default: openwaf_reqshm
context: twaf_reqstat
指定shared_dict名称,在这之前需在nginx配置文件中配置lua_shared_dict
默认shared_dict名称为openwaf_reqshm
"twaf_log": {
"access_log_state":false, -- 访问日志开关
"security_log_state":true, -- 安全日志开关
"sock_type":"udp", -- 支持tcp和udp两种协议
"content_type":"JSON", -- 支持JSON和INFLUXDB两种日志格式
"host":"127.0.0.1", -- 日志服务器地址
"port":60055, -- 日志服务器端口号
"flush_limit":0, -- 缓冲,当存储的日志大于阈值才发送
"size_limit": 200, -- 控制日志中每一项的字符上限,如'raw_header'或请求体响应体,可能会使udp日志报错
"drop_limit":65507, -- 缓冲上限,达到此值,丢弃当前日志,发送缓存并清空缓存,当sock_type为udp时,drop_limit值最大为65507(65508会报错message too long)
"max_retry_times":5, -- 最大容错次数
"ssl":false, -- 是否开启ssl协议
"access_log":{} -- 访问日志格式
"security_log":{} -- 安全日志格式
}
syntax: "access_log_state": true|false
default: false
context: twaf_log
访问日志开关,默认关闭
syntax: "security_log_state": true|false
default: true
context: twaf_log
安全事件日志开关,默认开启
syntax: "sock_type": tcp|udp
default: udp
context: twaf_log
日志传输协议,默认udp
syntax: "content_type": JSON|INFLUXDB
default: JSON
context: twaf_log
日志格式,默认JSON
syntax: "host": string
default: "127.0.0.1"
context: twaf_log
日志接收服务器的ip地址
syntax: "port": number
default: 60055
context: twaf_log
日志接收服务器的端口号
syntax: "flush_limit": number
default: 0
context: twaf_log
缓冲区大小,当存储的日志大于阈值才发送,默认值为0,即立即发送日志
syntax: "size_limit": number
default: 200
context: twaf_log
控制日志中每一项的字符上限,如'raw_header'或请求体响应体,可能会使udp日志报错
syntax: "drop_limit": number
default: 65507
context: twaf_log
缓冲上限,达到此值,丢弃当前日志,发送缓存并清空缓存,当sock_type为udp时,drop_limit值最大为65507(65508会报错message too long)
syntax: "max_retry_times": number
default: 5
context: twaf_log
最大容错次数
syntax: "ssl": true|false
default: false
context: twaf_log
是否开启ssl协议,默认false
syntax: "access_log": table
default: false
context: twaf_log
访问日志格式
syntax: "security_log": table
default: false
context: twaf_log
安全事件日志格式
若content_type为JSON,则日志格式为
[
variable_key_1,
variable_key_2,
...
]
若content_type为INFLUXDB,则日志格式为
{
"db":MEASUREMENT名称,
"tags":[variable_key_1, variable_key_2, ...],
"fileds"[variable_key_1, variable_key_2, ...],
"time":true|false
}
变量名称详见规则引擎模块twaf_secrules
#日志格式举例
#JSON格式
"security_log": [
"remote_addr",
"remote_port",
"userid",
"dev_uuid",
"original_dst_addr",
"original_dst_port",
"remote_user",
"time_local",
"msec",
"request_method",
"request_uri",
"request_protocol",
"status",
"bytes_sent",
"http_referer",
"http_user_agent",
"gzip_ratio",
"http_host",
"raw_header"
]
#INFLUXDB格式
"security_log": {
"db":"test", -- MEASUREMENT名称
"tags":[], -- tags keys
"fileds":[ -- fileds keys
"remote_addr",
"remote_port",
"userid",
"dev_uuid",
"original_dst_addr",
"original_dst_port",
"remote_user",
Content type
Image
Digest
Size
329.2 MB
Last updated
over 6 years ago
docker pull titansec/openwaf