日志
屏蔽user-agent并屏蔽日志
1 2 3 4 5 6 7 8 |
if ($http_user_agent ~* (^badbot/useragent$)) { rewrite (.*) /badbot break; } location = /badbot { access_log off; return 403; } |
不屏蔽user-agent(允许其访问),但屏蔽日志
1 2 3 4 5 6 7 |
server { set $is_spider 1; if ($http_user_agent ~* "bot|spider|Bot|Disqus|WebIndex|YunGuanCe") { set $is_spider 0; } access_log /var/log/nginx/access.log combined if=$is_spider; } |
按uri屏蔽日志(可以和上面的按user-agent用同一个变量来同时过滤uri和user-agent)
1 2 3 4 5 6 7 8 9 10 11 |
map $request $loggable { ~/favicon.ico 0; ~/images/* 0; ~/js/* 0; ~/css/* 0; default 1; } server { access_log /var/log/nginx/access.log combined if=$loggable; } |
Header
按mime type设置缓存时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
map $sent_http_content_type $cacheable_types { "text/css" "max-age=14400"; "text/plain" "max-age=86400"; "image/jpeg" "max-age=86400"; "image/png" "max-age=86400"; "image/gif" "max-age=86400"; "image/x-icon" "max-age=86400"; "application/x-7z-compressed" "max-age=864000"; "application/x-javascript" "max-age=86400"; "application/json" "max-age=86400"; "application/x-bittorrent" "max-age=864000"; default ""; } server { location / { root "/var/www/html/"; add_header "Cache-Control" $cacheable_types; } } |
防攻击
简单的无状态cookie challenge(需要lua-nginx-module)
crawlers块中可以手动填写要屏蔽的IP
将其中的s改成随机字符串+时间戳可以变成有状态版本(需使用redis/memcached/shared memory存储生成的随机字符串)
将set-cookie改成通过js生成cookie可以变成javascript challenge,注意要在js里加上浏览器上下文判断,如var cookie=location.protocol?cookie:””; 或者DOM操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
geo $crawlers{ 1.2.3.0/24 1; 4.5.6.7 1; default 0; } server { location ~ \.php { set $_c 0; if ($http_user_agent ~* "bad.guy/123") { set $_c 1; } if ($crawlers){ set $_c 1; } if ($_c){ access_log off; access_by_lua_block { local expires = 90 local s = ngx.time() local cob = tonumber(ngx.var.cookie_cob) if cob == nil then cob=0 end local coa = ngx.md5("saltsalt" .. ngx.var.remote_addr .. "saltsalt" .. cob) if s - cob > expires or ngx.var.cookie_coa ~= coa then coa = ngx.md5("saltsalt" .. ngx.var.remote_addr .. "saltsalt" .. s) ngx.header["Set-Cookie"] = {"coa=" .. coa .."; path=/; domain=.example.com; HttpOnly", "cob=" .. s.."; path=/; domain=.example.com; HttpOnly"} ngx.header["Content-Type"] = "text/html" ngx.say("<meta http-equiv ='refresh' content='0'>"); ngx.exit(200) end } } # fastcgi_pass } } |
其他
植入cookie
需要注意的是使用ngx.time()产生秒级的时间,用来做随机数种子可能会冲突,因此建议加上另外的随机变量(如下面的例子用的是客户端的ip) 可以使用ngx.now()产生毫秒精度时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
local modname = "util" local _M = { _VERSION = '0.01' } local mt = { __index = _M } function _M.random_str(l, seed, r) local s = r or 'abcdefghijklmnhopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=+-' local ret ='' -- os.time() is precise to second math.randomseed(os.time() * 1000 + ngx.crc32_short(seed or "")) for i=1 ,l do local pos = math.random(1, string.len(s)) ret = ret .. string.sub(s, pos, pos) end return ret end function _M.plant_cookie(k, h) local ck = require "resty.cookie" local cookie, err = ck:new() if not cookie then ngx.log(ngx.ERR, "ERROR PLANTING COOKIE", err) return end local _, err = cookie:get(k) if _ then return end local ok, err = cookie:set({ key = k, value = _M.random_str(32, ngx.var.remote_addr, '0123456789abcdef'), path = "/", domain = h or ngx.var.http_host, httponly = true, expires= 'Thu, 31-Dec-37 23:55:55 GMT', max_age = 2147483647 }) end return _M |
1 2 3 4 5 6 |
location / { access_by_lua ' local _ = require("util") _.plant_cookie("cookie_name",".example.come") '; } |
爸爸 我来前排跪舔
好厉害的样子呀!!
[害羞]
nginx: [emerg] unknown “crawlers” variable$crawlers ???
哈哈这个变量用来手动屏蔽IP,比如geo $crawlers{ 1.2.3.0/24 1; 4.5.6.7 1; default 0;}
多谢提醒
是不是逻辑有问题啊,如果没有cookie就会不停的请求访问。
反正都在nginx层,没什么压力,你可以加个limit_req_rate
最近碰到个好奇葩的问题啊,大佬有没有碰到过Nginx 经常不处理请求详细http://bbs.csdn.net/topics/392008066
贴下日志嘛
没啥日志,nginx一些缓存文件未找到的日志2016/08/23 22:08:57 [crit] 29891#0: unlink() “/tmp/wpcache/8/84/61ea03f64ead57389493cea88df29848” failed (2: No such file or directory)PHP无错误日志
简化了下配置文件,去除memcahed缓存,去除pagespeed优化。问题依旧 更新后配置文件 http://bbs.csdn.net/topics/392008066
哦我想起来我的博客之前也有这猫饼,感觉是php的opcache配置有问题
应该不是吧,抽风期间我连静态文件都没法访问。
硬盘爆炸了
有可能,看了下,并没有。附上几张图抽风时服务器监控图。http://ww4.sinaimg.cn/large/ec76730dgw1f74aave54ej20wg0don1j.jpg一个是CPU资源,抽风时没处理请求 负载0,,抽风完毕后等待的请求一股脑冲进来 负载飙升。然后是最重要的连接数,抽风时连接数太不正常了。关于磁盘与网络http://ww1.sinaimg.cn/large/ec76730dgw1f74acj1vudj20wk06lac0.jpg
看图没看懂,20:44开始抽风?难道有人在cc你
不,只是ngixn炸了。抽风时不处理请求=负载0,,抽风完毕后抽风时期等待的请求一股脑冲进来=负载飙升。这就是负载坐过山车一样
我怎么感觉和nginx没关系
啊…..我一直认为是nginx的问题,其他东西还能阻止访问静态文件么?
在抽风时试着重启PHP,竟然。。。管用…竟然是后端的问题。
那好像和我博客之前一样,感觉你可以把opcache扔了(?
我扔了试试吧….(WHT?什么原理
感觉扔的东西越来越多了….memcached也一用PHP就出问题
不知道,我一个一个丢的丢到opcache那就没问题了诶不对我是php7,你用的是7不
对呀对呀
有毒,不如回家卖红薯