0×01 WAF簡介
WAF全稱是Web Application Firewall, 簡單講就是web防火牆,是對web業務進行防護的一種安全防護手段。其實,現在很多的移動app,也是使用的http協定進行資料交換,也可以理解成web業務,可以對app server進行防護。
主要的web危害,一般指的是OWASP Top 10,比如SQL注入、XSS、CSRF等常見的web危害方法。當然可能不止這些方法,比如社工。輕則用你的服務器打個ddos,重則數據全部被盜,損失公司的信譽和money。
互聯網公司的業務傾向於雲平臺,雲WAF就應運而生,除去考慮硬體WAF的考慮,下麵只講基於互聯網公司的需求,打造一款WAF聯動系統。
0×02 WAF基本組成
大部分互聯網公司的業務,都會使用Nginx做各種各樣的工作,負載均衡、A/B測試、Web閘道等等的功能;另外,加上openresty(nginx + lua)的開發效率和易用性,提高了程式猿開發nginx功能的效率。現在互聯網公司招WAF開發的,一般都會加上nginx lua的要求,可見使用nginx + lua開發WAF,實在是天時地利人和。
現在簡單的說一下WAF系統的組成。WAF系統主要是由三部分組成的:執行前端、後端中心系統及資料庫。
執行前端是WAF的執行引擎,主要是根據規則進行過濾。根據規則匹配的結果,執行相應的動作。
後端中心系統主要是生成規則的邏輯,並與執行前端的nginx進行必要的資料交換。
資料庫就是存放規則和一些配寘及狀態的地方,可以根據實際情況,選擇關係型數據庫或者Nosql。
其中,可以看到後端中心系統相當於WAF的大腦,會根據不同的功能變數名稱或者設備hostname的配寘生成對應的邏輯。當執行前端拉取配寘和規則時,後端中心會把它對應的內容發給執行前端。這裡做成集中式的管理模式,主要是方便統一管理,另外可以監控執行前端的狀態,具體的狀態數據,可以根據實際的情况進行協商,現時是建議json數據走http協定,方便易用。當然,資料傳輸的過程最好還是使用對稱加密加base64 encode。
0×03 WAF細節考慮
一直比較關注cloudflare的雲WAF,基本上WAF規則可以考慮為三類(不考慮長亭科技的sqlchop https://github.com/chaitin/sqlchop,據說有類似的xss要開源)::1️⃣通用的規則,比如sql、xss規則,攔截惡意爬蟲和掃描器等等的非常有效,這種基本上通用的。2️⃣cms規則,就是根據不同的cms,根據相應的漏洞定制的規則,比如php網站,不可能存在java語言的漏洞,具有專一性。3️⃣自定義規則,這就是根據自己的需求,自定義一些規則。根據入侵類型,再細分就會更多了,攔截shell、爬蟲等等的,這裡只是輸了大概。
在github上面,最具參攷的lua waf就屬https://github.com/p0pr0ck5/lua-resty-waf她了,其它的並不是說不好,然而只有這個最接近Modsecurity的邏輯,最突出的有點就是規則的彈性化,最接近Modsecrity的規則。不過,https://github.com/starjun/openstar裡面的很多防禦方法,也是可以借鑒的。
執行前端:
基於p0pr0ck5的WAF,二次修改一下,就可以做成上述的執行前端,但是它是有Bug的,生產環境下需要線下流量測試。主要在這個基礎上,添加拉取配寘和規則的timer就可以了,有些人說用zookeeper什麼的,另外還有用的http來進行配寘更新通知,zookeeper不建議,當你reload的時候,就可以看見很多nginx處於shutting down狀態,就只zookeeper處於keepalive狀態。使用http訪問加共用記憶體,京東的濤哥是這樣做的,也是有些坑,不過timer最簡單,每個worker單獨維護一個配寘,避免了鎖的情况。
另外,收集日誌最好不要用kafka,打火焰圖的時候,明顯cpu時間有點長,用tcp或者http發送最可靠。執行前端大概就是這些內容,記得加上xpcall能把一些小的問題catch到,避免影響請求。
所有的配寘是用json傳輸的,然後轉換成lua的數據格式,使其能正確識別出WAF規則。WAF規則類似如下:
{
"vars": [
{
"parse": {
"values": 1
},
"type": "REQUEST_ARGS"
}
],
"pattern": "select[^A-Za-z].*from\\W|union\\W.*select[^A-Za-z]",
"actions": {
"disrupt": "SCORE",
"nondisrupt": [
{
"action": "setvar",
"data": {
"key": "anomaly_score",
"col": "TX",
"value": 8,
"inc": 1
}
}
]
},
"msg": "SQLInject",
"operator": "REGEX",
"id": 10001
}
確保WAF能够識別出這些規則就可以了,嚴格按照它的格式來,畢竟lua腳本的優勢在這裡體現的一覽無餘。
後端中心系統:
後端中心系統同樣是使用的Openresty(別的我也不會,開個玩笑),設計成類似api閘道,還是那句話好管理。根據不同的功能變數名稱和設備Hostname發送不同的配寘。甚至,可以把所有WAF的邏輯放到這裡,這是lua支持熱加載的功能。這裡是如何做你的WAF的關鍵,主要邏輯還是在這裡。
這裡是一些基本配置涵蓋了:
- WAF基本配置,包括了規則拉取服務配寘、日誌中心配寘及更新組件等配寘。這些基本配置决定了,WAF主要的邏輯處理。
- IP清單,包括了所有黑名單的ip,及對應host或者uri對應的ip,其中,支持配寘生效時間。
- 規則清單,主要是Web入侵規則配寘,包括了default集合及對應host的waf配寘。
基本配置主要是配寘規則拉取服務配寘、日誌中心配寘及更新組件等配寘。這些配寘也可以有由服務端動態生成。
conifg = {
ip_status = "off",
waf_status = "off",
srvhost="127.0.0.1",
srvport=80,
srvuir="/api/get_waf_data",
loghost="127.0.0.1",
logport=80,
loguri="/api/post_waf_log",
deny_code=201,
delay = 10,
}
IP清單,其中有些是全域封禁,有些是針對某些介面,配寘有過期時間的功能。
ip_list = {
global_ip={{"1.1.1.1", 0}, {"2.2.2.2", 123124}, { "3.3.3.3", 0}}
host = {{"1.1.1.1", 123124214}, { "2.2.2.2", 123412412}}
host1_uri1 ={{"1.1.1.1", 0}, { "2.2.2.2", 123412412}}
host2_uri2 = {{"1.1.1.1", 1231241}, {"2.2.2.2", 0}}
},
規則的內容就是上面已經列出的內容了。其中因為要適合配寘的邏輯需要根據根據自己的需求進行修改。
資料庫和Web:
資料庫規則設計:
CREATE TABLE `waf_rules_info` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ruleid` int(10) NOT NULL COMMENT '规则id',
`patterntype` varchar(32) DEFAULT 'REGEX',
`specific` varchar(255) DEFAULT NULL,
`vartype` varchar(255) DEFAULT NULL,
`patternvalue` varchar(255) DEFAULT NULL COMMENT 'base64 封装',
`action` varchar(32) DEFAULT NULL,
`score` int(10) DEFAULT NULL,
`description` varchar(512) DEFAULT NULL COMMENT 'decrption',
`transforms` varchar(512) DEFAULT NULL COMMENT 'json 结构体',
`negated` int(5) DEFAULT '0',
`ruletype` varchar(32) DEFAULT NULL,
`rulephase` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`,`ruleid`),
KEY `rule_id` (`ruleid`)
) ENGINE=MyISAM AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;
這個是最主要的,有些内容暫時沒有設定。
對於web而言,主要還是配合下發配寘,規則方面,我是設定了三層結構:規則->規則組->host。它們只是邏輯上的關係,具體在後面邏輯實現時,會把散列的規則進行分組並根據資料庫的邏輯進行組合,生成對唯一host的配寘。同理,可以設定不同的分組,達到灰度測試的目的。
這是具體規則的web設定,規則配寘增删改規則,規則分組則是對規則分組的增删改操作,規則應用則是對不同host配寘不同的規則分組。這裡說明一下,規則分組是按照XSS、SQLi、灰度等功能分開的,對於host進行不同的配寘。
現時,阿裡雲有自定義的規則,太單一,遠遠比不上cloudflare的設計,而且cloudflare更貼近互聯網公司的需求,最主要的如何讓自定義功能更有彈性,更大限度的支持規則的彈性。
簡簡單單,就說了個大概,如果真的對WAF有研究的話,剩餘的就比較輕鬆了,算是抛磚引玉了。
0×04其它
記得有個作者提到,WAF位置卡位比較好,現在很多CC和掃描器都是在七層防禦的,WAF封禁某些ip和用戶還是比較可靠的,另外很多是cdn過來的請求,只能靠x-forward-for取出來的ip進行封禁,當然它可以偽造,就看資料分析的能力,把真實的ip抓出來。WAF規則p0pr0ck5提供了一些Modsecurity轉譯的,可以參考它實現自己的規則。另外,WAF的效能也很重要,章亦春大神的很多講座ppt有提到的,可以作為參攷。章亦春大神已經創業了,它打造的商業openresty就有WAF的支持。
最後,就先寫這些吧,有問題的可以私信我,後面會引入大資料分析和安全資料挖掘。第一次發文章,歡迎各位大神輕拍。
*本文作者:chengfangang,轉載請注明來自Freebuf.COM