1、问题
某些IP(如21.78.41.6、21.78.41.161)一直向本系统发送无效报文,导致error.log出现大量无用报错日志,如何屏蔽?
2、解决方案
使用map完成对IP打标记(需要过滤的标记为1,放行的标记为0),之后再error_log使用if来让之前的标记生效。
3、具体配置
http {#1、定义IP过滤规则:#匹配到21.78.41.6、21.78.41.161时,标记为1;#其他IP,标记为0#这里用一个自定义变量来记录这个规则#$disable_error_log的值,当$remote_addr为21.78.41.6和21.78.41.161时,标记为1,其他时候标记为0map $remote_addr $disable_error_log {default 0;21.78.41.6 1;21.78.41.161 1;}#2、动态设置error日志:根据$disable_error_logerror_log /var/log/nginx/error.log error if=$disable_error_log;# /var/log/nginx/error.log:正常error日志路径# error:日志级别# if=$disable_error_log:条件判断:=1时生效(不记录为日志),=0时正常记录 }
4、说明
1、map
map是nginx配置文件中特有的指令,专门用于实现“变量映射”功能:根据一个变量的取值,来定义另一个变量的结果。类似键值对、K-V对的逻辑
使用位置
map仅存在于Nginx的配置语法中(如nginx.conf),与Linux系统命令、Shell脚本、编程语言、函数均无关系,它只是nginx本身的一项功能。
作用
人为定义一个“映射关系表”,让Nginx在处理请求时,可以根据某个输入变量(如客户端IP $remote_addr、请求域名 $host等)的取值,自动生成另一个输出变量(该变量为用户自定义变量,仅作用于该配置文件内)
用法
map $系统变量A $自定义变量B {K1 V1;K2 V2;...default 0; }
解释:
当系统变量A取值为K1时,变量B的值置为V1;
当A取值为K2时,B的值置为V2;
……
当A没匹配到前边的K1、K2、……时,B置为0。
例子
map $remote_addr $tag{default 0;21.78.41.6 1;192.168.1.0/24 1;10.0.0.5 1; }
上边这段的含义是:
当客户端IP($remote_addr)匹配到21.78.41.6、192.168.1.0/24、10.0.0.5中的任何一个时,就把自定义变量$tag的值置为1,其他时候都将$tag置为1;
所以在我们一开始的例子中:
map $remote_addr $disable_error_log {default 0;21.78.41.6 1;21.78.41.161 1;}
含义就是:
disable_error_log的值:当$remote_addr为21.78.41.6和21.78.41.161时,标记为1,其他时候标记为0
2、if
error_log、access_log支持一种使用if进行条件判断的轻量级句法:
用法
error_log 路径 级别 if=$变量; access_log 路径 级别 if=$变量;
解释
当变量值为0时,该条日志计入到log文件中;其他情况均过滤掉不计入。
所以在一开始的例子中:
#2、动态设置error日志:根据$disable_error_logerror_log /var/log/nginx/error.log error if=$disable_error_log;
就是根据之前的自定义变量$disable_error_log的值来决定是否将该条日志录入log文件。当$disable_error_log为1,也就是根据map规则当客户端IP为21.78.41.6、161时,日志会被过滤掉,从而实现了一开始的排除某些IP的日志的目的。