Category Archives

8 Articles

nginx/openresty的一些记录

28   28811 转为繁体

日志

屏蔽user-agent并屏蔽日志

不屏蔽user-agent(允许其访问),但屏蔽日志

按uri屏蔽日志(可以和上面的按user-agent用同一个变量来同时过滤uri和user-agent)

 

Header

按mime type设置缓存时间

防攻击

简单的无状态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操作

这里有个更高级的输验证码的示例

其他

植入cookie

需要注意的是使用ngx.time()产生秒级的时间,用来做随机数种子可能会冲突,因此建议加上另外的随机变量(如下面的例子用的是客户端的ip) 可以使用ngx.now()产生毫秒精度时间

Lua用setmetatable返回默认值为function时的暗坑

0   114331 转为繁体

想在api服务器里实现一个acl的功能,对某些请求(需要登录,需要检查appkey,需要限制频次等)做限制,对某些起始状态(比如登陆)或者终结状态(比如报错)的请求放行。

因为lua里木有switch case,因此通过一个acl_list的table去查找规则,因为需要限制的请求种类比较多,就把rule_check_token当成默认值了,一看是是这么写的:

然而却会在local token= xxxx那一行报stack overflow,想了半天也发现哪里有无限递归,因为query传进来的是http请求的query string解析出的键值对表。

把query打印出来一看,发现竟然是这个模块本身……

仔细看了文档才知道,原来__index后面的值是一个function时,lua会调用这个function去获得不存在的键,并且第一个参数是模块本身(即_M,一个table)。在这个例子里:

  1. 调用一个非默认规则的api
  2. lua调用了rule_check_token
  3. 参数query被传入了_M本身
  4. 运行到local token= xxxx这一行
  5. 这个table里(_M)又没有token这个键
  6. 回到2

所以就死循环了

 

所以要好好看文档

 

解决方法是可以套一个function

 

贴一个打印table的工具,方便调试:

可以打印出如下形式:

使用openresty请自行改写成local function和ngx.say的形式