nginx naxsi 模块

nginx naxsi 模块

git地址:https://github.com/nbs-system/naxsi

背景

上周项目组的伙伴在灰度访问项目时,发现发送不了消息了。排查各个请求发现有请求被ng拦截了。

于是找到ng拦截日志,路径在ng配置的error日志中,默认在nginx根目录下的log目录下的error.log

如下:

2018/08/03 16:45:43 [error] 25994#0: *4783 NAXSI_FMT: ip=118.249.55.30&server=livechat-touch-client_test&uri=/ad/test/livechat-touch-client/chat/829/gipyojle/xhr_send&learning=0&vers=0.53-1&total_processed=56&total_blocked=11&block=1&zone0=BODY&id0=11&var_name0=, client: 118.249.55.30, server: localhost, request: "POST /ad/test/livechat-touch-client/chat/829/gipyojle/xhr_send?t=1533285944041 HTTP/1.1", host: "livechat-touch-client_test", referrer: "https://shop.10086.cn/ad/test/livechat-touch-client/pub-page/liveChatTouchHome.html?tenantId=1000091&code=BS&channelType=1012"

归纳下naxsi错误日志解释

  • ip : Client's ip(访客IP)
  • server : Requested Hostname (as seen in http header Host)(服务名称,这里为ng的location)
  • uri: Requested URI (without arguments, stops at ?)(请求地址)
  • learning: tells if naxsi was in learning mode (0/1)(学习模式是否开启)
  • vers : Naxsi version, only since 0.51(naxsi版本)
  • total_processed: Total number of requests processed by nginx's worker (ng处理工作进程)
  • total_blocked: Total number of requests blocked by (naxsi) nginx's worker(naxsi拦截进程)
  • zoneN: Zone in which match happened (see "Zones" in the table below)(规则匹配发生的区域,包括:arg|body|head)
  • idN: The rule id that matched(匹配的拦截规则号)
  • ** var_nameN: Variable name in which match happened (optional)(拦截规则匹配时的参数名)**
  • cscoreN : named score tag
  • scoreN : associated named score value 得分(每一项naxsi规则都有对应的得分)

那么我们就知道这个日志表明:该uri请求违反了id=11的naxsi规则,被拦截了。那么id=11的规则是什么呢?让我们了解下naxsi定义的规则,配置在ng的http中规则文件:

include       /interactive/openresty18800/nginx/conf/naxsi_conf/naxsi_core.rules;

naxsi 核心规则(节选)

##################################
## INTERNAL RULES IDS:1-999 ##
##################################
#@MainRule "msg:weird request, unable to parse" id:1;
#@MainRule "msg:request too big, stored on disk and not parsed" id:2;
#@MainRule "msg:invalid hex encoding, null bytes" id:10;
#@MainRule "msg:unknown content-type" id:11;
#@MainRule "msg:invalid formatted url" id:12;
#@MainRule "msg:invalid POST format" id:13;
#@MainRule "msg:invalid POST boundary" id:14;

##################################
## SQL Injections IDs:1000-1099 ##
##################################
MainRule "rx:select|union|update|delete|insert|table|from|ascii|hex|unhex|drop" "msg:sql keywords" "mz:BODY|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1000;
MainRule "str:\"" "msg:double quote" "mz:BODY|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8,$XSS:8" id:1001;
MainRule "str:0x" "msg:0x, possible hex encoding" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:2" id:1002;
image
  1. 其中:(基本上都是http级别MainRule的规则)

     location level (BasicRule)
     http level (MainRule)
    
  2. ID 0-999为naxsi的内部规则,如不在白名单中,则自动生效。 其余为自定义规则,naxsi已经帮我们默认配置了大多数情况下都可适用的规则,一般来说是比较全面的,我们也可以参考。

  3. 匹配规则

    rx:foo|bar : will match foo or bar
    str:foo|bar : will match foo|bar
    【下述需要第三方插件-后续有需要再研究】
    d:libinj_xss : will match if libinjection says it's XSS (>= 0.55rc2)
    d:libinj_sql : will match if libinjection says it's SQLi (>= 0.55rc2)

  4. 得分

     s: 前缀
     $LABEL 区分标示  可自定义,如:footer。
     score  得分  可自定义,如4
     
     得分示例:s:$FOOTER:4  则表示匹配此规则,则得分为4.  结合CheckRule,根据标示和得分定义拦截配置。
    
     CheckRules示例: CheckRule "$FOOTER >= 4" BLOCK  
    
     标示当规则匹配$FOOTER得分大于等于4时,则拦截。配置为上述拦截规则,则表示出现拦截,得分即为4,则符合拦截规则。
     更多CheckRules,参考:https://github.com/nbs-system/naxsi/wiki/checkrules-bnf
    

5、匹配区域

    字符匹配:
    
        ARGS: GET args
        HEADERS: HTTP Headers
        BODY: POST args (and RAW_BODY)
        URL: The URL itself (before '?')
    
        
        $ARGS_VAR:string: named GET argument
        $HEADERS_VAR:string : named HTTP header
        $BODY_VAR:string: named POST argument
    
    正则匹配:
        
        $HEADERS_VAR_X:regex: regex matching a named HTTP header (>= 0.52)
        $ARGS_VAR_X:regex: regex matching the name of a GET argument (>= 0.52)
        $BODY_VAR_X:regex: regex matching the name of a POST argument (>= 0.52)
    
    可制定匹配的URL,同样包括字符匹配和正则匹配
        
        $URL:string: restricted to this url
        $URL_X:regex: restricted to url matching regex (>= 0.52)

那么 @MainRule "msg:unknown content-type" id:11; 就是请求违反的规则,不知名的内容类型。从浏览器此请求header看,它的content-type为text/plain.

对比生产其他ng配置,发现其在naxsi的白名单中放过了id11,故可正常运行。 那么,我们再灰度环境配置中,增加此白名单即可解决。 让我们来看看,如何配置naxsi的白名单。

naxsi 白名单配置

image

其中wl 单独匹配放过某项规则,如:

  • wl:0 : Whitelist all rules 代表放过所有规则
  • wl:42 : Whitelist rule #42 代表放过id=42的规则
  • wl:42,41,43 : Whitelist rules 42, 41 and 43 代表放过id=42/41/43规则
  • wl:-42 : Whitelist all user rules (>= 1000), excepting rule 42 代表放过所有规则除了42规则

mz:MATCHZONE 配合wl规则,制定对应匹配区域规则,区域包括: URL, ARGS, HEADERS, BODY.

示例:url为/foo 请求放过BODY请求中参数名中的规则1310,1311

BasicRule id:1310,1311 "mz:$URL:/foo|BODY|NAME";

备注:增加|NAME标示对应目标为参数名,而非参数值。

更多示例,可参考

https://github.com/nbs-system/naxsi/wiki/whitelists-examples

附录-nginx增加naxis配置

nginx安装,增加naxis配置:

 wget http://nginx.org/download/nginx-x.x.xx.tar.gz
 wget https://github.com/nbs-system/naxsi/archive/x.xx.x.tar.gz
 tar xvzf nginx-x.x.xx.tar.gz 
 tar xvzf naxsi-x.xx.tar.gz
 cd nginx-x.x.xx/

 ./configure --add-module=../naxsi-x.xx/naxsi_src/ [add/remove your favorite/usual options]
 make
 make install

nginx配置:

#Only for nginx's version with modular support
load_module /../modules/ngx_http_naxsi_module.so;
events {
 ...
}
http {
 include /tmp/naxsi_ut/naxsi_core.rules;  #引用核心规则
 ...
 server {
  listen ...;
  server_name  ...;
  location / {
   #Enable naxsi
   SecRulesEnabled;
   #Enable learning mode
   LearningMode;
   #Define where blocked requests go
   DeniedUrl "/50x.html"; 
   #CheckRules, determining when naxsi needs to take action
   CheckRule "$SQL >= 8" BLOCK;
   CheckRule "$RFI >= 8" BLOCK;
   CheckRule "$TRAVERSAL >= 4" BLOCK;
   CheckRule "$EVADE >= 4" BLOCK;
   CheckRule "$XSS >= 8" BLOCK;
   #naxsi logs goes there
   error_log /.../foo.log;
   ...
  }
  error_page   500 502 503 504  /50x.html;
  #This is where the blocked requests are going
  location = /50x.html {
  return 418; #I'm a teapot \o/
  }
 }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容