Sign inSign up

titansec/openwaf

By titansec

•Updated over 6 years ago

The first all-round open source Web security protection system, more protection than others

Image
5

4.9K

titansec/openwaf repository overview

⁠Name

OpenWAF

第一个全方位开源的Web应用防护系统(WAF),更全面的防护功能,更多样的防护策略

⁠Table of Contents

⁠Version

This document describes OpenWAF v0.0.6 released on 26 Dec 2017.

Docker Version

  1. titansec/openwaf:0.0.1.161130_beta
      SHA: 596dee9d2b9ce44d59dc445141f72b3607f9fbe6
      https://github.com/titansec/OpenWAF/tree/596dee9d2b9ce44d59dc445141f72b3607f9fbe6⁠
  2. titansec/openwaf:0.0.3.170103_beta
      SHA: 28ce1556250301f26f31b46d9cd9dde5a3b3f03f
      https://github.com/titansec/OpenWAF/tree/28ce1556250301f26f31b46d9cd9dde5a3b3f03f⁠
  3. titansec/openwaf:v0.0.4
      SHA: cdef1e0eac4f12c374feb6ac3c3c465610daaf6c
      https://github.com/titansec/OpenWAF/tree/cdef1e0eac4f12c374feb6ac3c3c465610daaf6c⁠
  4. titansec/openwaf:v0.0.5(titansec/openwaf:latest)
      https://github.com/titansec/OpenWAF/tree/f9a3a6cfb8b75b1f4af9f44477a5b64337a7da47⁠

⁠Synopsis

    #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

Back to TOC⁠

⁠Description

OpenWAF是第一个全方位开源的Web应用防护系统(WAF),他基于nginx_lua API分析HTTP请求信息。OpenWAF由行为分析引擎和规则引擎两大功能引擎构成。其中规则引擎主要对单个请求进行分析,行为分析引擎主要负责跨请求信息追踪。

规则引擎的启发来自modsecurity⁠及freewaf(lua-resty-waf)⁠,将ModSecurity的规则机制用lua实现。基于规则引擎可以进行协议规范,自动工具,注入攻击,跨站攻击,信息泄露,异常请求等安全防护,支持动态添加规则,及时修补漏洞。

行为分析引擎包含基于频率的模糊识别,防恶意爬虫,人机识别等防探测模块,防CSRF,防CC,防提权,文件上传防护等防攻击模块,cookie防篡改,防盗链,自定义响应头,攻击响应页面等防信息泄露模块。

除了两大引擎之外,还包含统计,日志,攻击响应页面,接入规则等基础模块。除了已有的功能模块,OpenWAF还支持动态修改配置, 动态添加第三方模块,使得在不重启引擎中断业务的条件下,升级防护。

OpenWAF支持将上述功能封装为策略,不同的web application应用不同的策略来防护。将来还会打造云平台,策略还可分享供他人参考。

基础模块如下:

功能模块如下:

详细配置文档及示例请看上述各模块文档

Back to TOC⁠

⁠Installation

请看 OpenWAF 安装文档⁠

Back to TOC⁠

⁠Community

⁠English Mailing List

The OpenWAF-en⁠ mailing list is for English speakers.

⁠Chinese Mailing List

The OpenWAF-cn⁠ mailing list is for Chinese speakers.

⁠Personal QQ Mail

[email protected]⁠

⁠QQ Group

579790127

Back to TOC⁠

⁠Bugs and Patches

Please submit bug reports, wishlists, or patches by

  1. creating a ticket on the GitHub Issue Tracker⁠,
  2. or posting to the OpenWAF community⁠.

Back to TOC⁠

⁠TODO

    1. 上传人机识别模块
    1. 上传防盗链模块
    1. 上传cookie防篡改模块
    1. 上传基于频率的模糊识别防探测模块
    1. 上传WebShell上传防护模块
    1. 上传防CSRF模块
    1. 放开动态配置规则引擎API
    1. 放开动态配置行为分析引擎API

MORE⁠

Back to TOC⁠

⁠Changes

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

Back to TOC⁠

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.

Back to TOC⁠

⁠Modules Configuration Directives

Back to TOC⁠

⁠twaf_access_rule

{
    "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
            }
        ]
    }
}

⁠rules

syntax: "rules": table

default: none

context: twaf_access_rule

table类型,接入规则,顺序匹配

⁠client_ssl

syntax: "client_ssl": true|false

default: false

context: twaf_access_rule

客户端认证开关,与ngx_ssl组成双向认证,默认false
PS: 当前客户端认证不生效  

⁠client_ssl_cert

syntax: "client_ssl_cert": "path"

default: none

context: twaf_access_rule

string类型,客户端认证所需PEM证书地址,目前仅支持绝对地址

⁠ngx_ssl

syntax: "ngx_ssl": true|false

default: false

context: twaf_access_rule

boolean类型,服务器端(nginx)认证开关,与client_ssl组成双向认证,默认关闭

⁠ngx_ssl_cert

syntax: "ngx_ssl_cert": "path"

default: none

context: twaf_access_rule

string类型,服务器端(nginx)认证所需PEM证书地址,目前仅支持绝对地址

⁠ngx_ssl_key

syntax: "ngx_ssl_key": "path"

default: none

context: twaf_access_rule

string类型,服务器端(nginx)认证所需PEM私钥地址,目前仅支持绝对地址

⁠host

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"

⁠port

syntax: "port": number

default: 80

context: twaf_access_rule

number类型,端口号

⁠path

syntax: "path": "regex"

default: none

context: twaf_access_rule

string类型,路径,正则匹配

例如:

    "path": "/"
    "path": "/images"
    "path": "/[a|b]test"

⁠server_ssl

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;
    	    }
    	}
    }

⁠forward

syntax: "forward": "upstream_uuid"

default: none

context: twaf_access_rule

string类型,forward表示后端服务器的uuid,即upstream的名称

    #如:forward值为test
    upstream test {
        server 1.1.1.1;
    }

⁠forward_addr

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;
    }

⁠forward_port

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;
    }

⁠uuid

syntax: "uuid": "string"

default: none

context: twaf_access_rule

string类型,接入规则的唯一标识

⁠policy

syntax: "policy": "policy_uuid"

default: none

context: twaf_access_rule

string类型,满足此接入规则的请求,所使用安全策略的uuid

Back to twaf_access_rule⁠

Back to TOC⁠

{
    "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", ""]
    }
}

⁠state

syntax: "state": true|false|"$dynamic_state"

default: false

context: twaf_anti_hotlink

当前模块暂未开源

⁠log_state

syntax: "log_state": true|false|"$dynamic_state"

default: true

context: twaf_anti_hotlink

⁠ct_state

syntax: "ct_state": true|false|"$dynamic_state"

default: false

context: twaf_anti_hotlink

⁠event_id

syntax: "event_id": "string"

default: "110001"

context: twaf_anti_hotlink

⁠event_severity

syntax: "event_severity": "string"

default: "medium"

context: twaf_anti_hotlink

⁠action

syntax: "action": "string"

default: "DENY"

context: twaf_anti_hotlink

⁠action_meta

syntax: "action_meta": "string"|number

default: 403

context: twaf_anti_hotlink

⁠mode

syntax: "mode": "string"

default: "referer"

context: twaf_anti_hotlink

⁠allow_noreferer

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模式下生效

⁠uri_ext

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"

Back to twaf_anti_hotlink⁠

Back to TOC⁠

⁠twaf_anti_mal_crawler

{
    "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
}

⁠state

syntax: state true|false|$dynamic_state

default: false

context: twaf_anti_mal_crawler

模块开关,默认false(关闭),支持动态开关

Back to MCD⁠

⁠log_state

syntax: log_state true|false|$dynamic_state

default: true

context: twaf_anti_mal_crawler

安全日志开关, 默认true(记录),支持动态开关

Back to MCD⁠

⁠dict_state

syntax: dict_state true|false

default: false

context: twaf_anti_mal_crawler

shared_dict 开关。当 dict_state 为 true,某 IP 被此模块拦截,会被记录在内存中,在 timeout 时间内访问会被拦截(且重置timeout)

Back to MCD⁠

⁠shared_dict_name

syntax: shared_dict_name

default: nil

context: twaf_anti_mal_crawler

shared_dict 名称。对应 nginx 中的配置项,不可轻易修改

若为空,则值为 "twaf_global" 下的 "dict_name"

Back to MCD⁠

⁠shared_dict_key

syntax: shared_dict_key |

default: remote_addr

context: twaf_anti_mal_crawler

shared_dict 键值。支持数组

Back to MCD⁠

⁠timeout

syntax: timeout

default: 300

context: twaf_anti_mal_crawler

shared_dict 保存状态有效时长(单位秒)

Back to MCD⁠

⁠timer_flush_expired

syntax: timeout

default: 200

context: twaf_anti_mal_crawler

shared_dict 清除过期信息的间隔时间(单位秒),若为空,则值为 "twaf_global" 下的 "timer_flush_expired"

Back to MCD⁠

syntax: cookie_state true|false|$dynamic_state

default: true

context: twaf_anti_mal_crawler

是否发送cookie,默认true(发送),支持动态开关

Back to MCD⁠

syntax: crawler_cookie_name

default: "TWAF_crawler"

context: twaf_anti_mal_crawler

爬虫 cookie 名称

Back to MCD⁠

syntax: mal_cookie_name

default: TWAF_mcrawler

context: twaf_anti_mal_crawler

恶意爬虫cookie名称

Back to MCD⁠

⁠force_scan_robots_state

syntax: force_scan_robots_state true|false

default: true

context: twaf_anti_mal_crawler

页面注入诱捕路径的开关

某些扫描工具不会去访问 /robots.txt,因此在他访问的页面中插入禁爬目录的暗链

Back to MCD⁠

⁠force_scan_times

syntax: force_scan_times

default: 3

context: twaf_anti_mal_crawler

注入诱捕路径的页面数

Back to MCD⁠

⁠trap_uri

syntax: trap_uri

default: /abc/abc.html

context: twaf_anti_mal_crawler

诱捕路径,访问此路径,被标识为恶意爬虫

Back to MCD⁠

⁠trap_args

syntax: trap_args

default: id=1

context: twaf_anti_mal_crawler

诱捕参数。携带此参数访问诱捕路径,不会标识为攻击

Back to MCD⁠

Back to twaf_anti_mal_crawler⁠

Back to TOC⁠

⁠twaf_reqstat

    "twaf_reqstat": {
        "state":true,
        "safe_state":true,
        "access_state":true,
        "upstream_state":true,
        "shared_dict_name":"twaf_reqshm"
    }

⁠state

syntax: state true|false|$dynamic_state

default: true

context: twaf_reqstat

统计模块开关,支持动态开关,默认开启

⁠access_state

syntax: access_state true|false|$dynamic_state

default: true

context: twaf_reqstat

访问信息统计开关,支持动态开关,默认开启

⁠safe_state

syntax: safe_state true|false|$dynamic_state

default: true

context: twaf_reqstat

安全信息统计开关,支持动态开关,默认开启

⁠upstream_state

syntax: upstream_state true|false|$dynamic_state

default: true

context: twaf_reqstat

转发信息统计开关,支持动态开关,默认开启

⁠shared_dict_name

syntax: shared_dict_name string

default: openwaf_reqshm

context: twaf_reqstat

指定shared_dict名称,在这之前需在nginx配置文件中配置lua_shared_dict⁠

默认shared_dict名称为openwaf_reqshm

Back to twaf_reqstat⁠

Back to TOC⁠

⁠twaf_log

"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":{}             -- 安全日志格式
}

⁠access_log_state

syntax: "access_log_state": true|false

default: false

context: twaf_log

访问日志开关,默认关闭

⁠security_log_state

syntax: "security_log_state": true|false

default: true

context: twaf_log

安全事件日志开关,默认开启

⁠sock_type

syntax: "sock_type": tcp|udp

default: udp

context: twaf_log

日志传输协议,默认udp

⁠content_type

syntax: "content_type": JSON|INFLUXDB

default: JSON

context: twaf_log

日志格式,默认JSON

⁠host

syntax: "host": string

default: "127.0.0.1"

context: twaf_log

日志接收服务器的ip地址

⁠port

syntax: "port": number

default: 60055

context: twaf_log

日志接收服务器的端口号

⁠flush_limit

syntax: "flush_limit": number

default: 0

context: twaf_log

缓冲区大小,当存储的日志大于阈值才发送,默认值为0,即立即发送日志

⁠size_limit

syntax: "size_limit": number

default: 200

context: twaf_log

控制日志中每一项的字符上限,如'raw_header'或请求体响应体,可能会使udp日志报错

⁠drop_limit

syntax: "drop_limit": number

default: 65507

context: twaf_log

缓冲上限,达到此值,丢弃当前日志,发送缓存并清空缓存,当sock_type为udp时,drop_limit值最大为65507(65508会报错message too long)

⁠max_retry_times

syntax: "max_retry_times": number

default: 5

context: twaf_log

最大容错次数

⁠ssl

syntax: "ssl": true|false

default: false

context: twaf_log

是否开启ssl协议,默认false

⁠access_log

syntax: "access_log": table

default: false

context: twaf_log

访问日志格式

⁠security_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",
  

Tag summary

Content type

Image

Digest

Size

329.2 MB

Last updated

over 6 years ago

docker pull titansec/openwaf