【Nginx】Openresty增加waf配置

Carson發表於2017-05-10

1. Ngx lua waf 說明

防止sql注入,本地包含,部分溢位,fuzzing測試,xss,SSRF等web攻擊
防止svn/備份之類檔案洩漏
防止ApacheBench之類壓力測試工具的攻擊
遮蔽常見的掃描黑客工具,掃描器
遮蔽異常的網路請求
遮蔽圖片附件類目錄php執行許可權
防止webshell上傳

2. 下載 waf

使用git

git clone https://github.com/loveshell/…

使用wget

wget https://github.com/loveshell/…

3. 安裝

下載解壓後,將整 ngx_lua_waf 放到 nginx conf 目錄中,並命名為 waf;

4. 配置

nginx安裝路徑假設為:/usr/local/nginx/conf/ ;以下都將以此配置為例進行說明

4.1. 在nginx.conf的http段新增

lua_package_path "/usr/local/nginx/conf/waf/?.lua";
lua_shared_dict limit 10m;
init_by_lua_file  /usr/local/nginx/conf/waf/init.lua;
access_by_lua_file /usr/local/nginx/conf/waf/waf.lua;

4.2. 配置config.lua

--配置waf規則目錄
RulePath = "/usr/local/nginx/conf/waf/wafconf/"

--修改失敗提示
html=[[{"retcode":"21000","messages":"請求失敗,請稍後再試","body":{}}]]

--開啟cc攻擊,需要在nginx.conf http 段配置lua_shared_dict
CCDeny="on"

-- 設定cc攻擊頻率,單位為秒 (如:同一個ip請求同一個地址,每秒最多請求50次)
CCrate = "50/1"

4.3. 其他詳細配置說明

    RulePath = "/usr/local/nginx/conf/waf/wafconf/"
    --規則存放目錄

    attacklog = "off"
    --是否開啟攻擊資訊記錄,需要配置logdir

    logdir = "/usr/local/nginx/logs/hack/"
    --log儲存目錄,該目錄需要使用者自己新建,切需要nginx使用者的可寫許可權

    UrlDeny="on"
    --是否攔截url訪問

    Redirect="on"
    --是否攔截後重定向

    CookieMatch = "on"
    --是否攔截cookie攻擊

    postMatch = "on"
    --是否攔截post攻擊

    whiteModule = "on"
    --是否開啟URL白名單

    black_fileExt={"php","jsp"}
    --填寫不允許上傳檔案字尾型別

    ipWhitelist={"127.0.0.1"}
    --ip白名單,多個ip用逗號分隔

    ipBlocklist={"1.0.0.1"}
    --ip黑名單,多個ip用逗號分隔

    CCDeny="on"
    --是否開啟攔截cc攻擊(需要nginx.conf的http段增加lua_shared_dict limit 10m;)

    CCrate = "100/60"
    --設定cc攻擊頻率,單位為秒.
    --預設1分鐘同一個IP只能請求同一個地址100次

    html=[[Please go away~~]]
    --警告內容,可在中括號內自定義

5 修改 waf/init.lua 檔案

替換sys_html 函式:

function say_html()
    if Redirect then
        ngx.header.content_type = "text/html;charset=UTF-8"
        ngx.status = ngx.HTTP_FORBIDDEN
        ngx.say(html)
        ngx.exit(ngx.status)
    end
end

替換denycc 函式:

function denycc()
    if CCDeny then
        local uri=ngx.var.uri
        CCcount=tonumber(string.match(CCrate,`(.*)/`))
        CCseconds=tonumber(string.match(CCrate,`/(.*)`))
        local token = getClientIp()..uri
        local limit = ngx.shared.limit
        local req,_=limit:get(token)
        if req then
            if req > CCcount then
                ngx.header.content_type = "application/json;charset=UTF-8"
                local ret={returncode=`22000`,messages=`請求拒絕,請稍後再試`,body={}}
                --ngx.header[`Content-Type`]="text/html;charset=UTF-8"
                ngx.say(json.encode(ret))
                ngx.exit(200)
                return true
            else
                 limit:incr(token,1)
            end
        else
            limit:set(token,1,CCseconds)
        end
    end
    return false
end

6. 啟用waf

然後重啟nginx,或reload 即可:
/user/local/nginx/sbin/nginx -s reload

7. 測試

curl http://www.test.cn/test/index?id=../etc/passwd

返回:{"retcode":"21000","messages":"請求失敗,請稍後再試","body":{}} 說明生效

相關文章