mRuby 使用 ngx_mruby 打造简易 WAF

046569 · 2016年04月22日 · 最后由 hammer 回复于 2016年04月25日 · 8529 次阅读

mruby 是什么?

简单的说就是符合 ISO 标准的轻量级 ( 嵌入式 ) 版本的 Ruby .没错,可以拿来直接操作树莓派。

ngx_mruby 是什么?

看名字就知道了,将 mruby 作为模块整合进了 Nginx .类似的还有 ngx_lua .

mruby / ngx_mruby 的优势?

  • 高度可定制
  • 运行快速
  • 内存管理高效

WAF 有什么用?

WAF => Web Application Firewall ,可以用来屏蔽常见的网站漏洞攻击。

如何安装?

Debian wheezy 可以使用这个脚本一键安装。

要点:

  • memory + swap > 2 G .
  • 会同步编译安装 Nginx 1.9,有洁癖者自行更改。
  • 编译前检查 build_config.rb,注释不需要的组件 ( mrbgems ).

来点实际的?

最近客户碰到个蛋疼骇客,盯着他千疮百孔的DedeCMS不放。由于网站已经经过 N 次开发,阿里云默认的网站防火墙无法识别,短期内又无法升级修补,防护迫在眉睫。对手尝试注入,挂马,失败后又来采集。封了他几次 IP ,人家锲而不舍,搞来一堆肉鸡玩起了 CC .不堪其扰,最后通过定制 WAF 解决。

我裤子都脱了,你就给我看这个?

男人太快真心不 xing 福。

首先设定 Nginx 配置文件。

# Nginx.conf
location /m {
    mruby_content_handler '/root/hello.rb';
}

其次写过滤规则吧,推荐的方法是计算阈值。比如某一 IP 尝试扫描后台风险值 + 1 ,三秒内连续访问超过五次风险值 + 3 ,总计 5 分以上拖入黑名单。注意不要忘记设定白名单.数据库推荐使用 Redis .

# 初始化
def initialize
  @db  = Redis.new('127.0.0.1', 6379)
  @req = Nginx::Request.new
  @ip  = Nginx::Connection.new.remote_ip
end
# 加入黑名单
def add_black_list(msg)
  @db.set "#{@ip}_ban", '1'
  @db.expire "#{@ip}_ban", 10
  err_msg "ban #{@ip}! #{msg}"
end
# 重定向
def redirect(time, score, threshold)
  if score > threshold
    add_black_list("#{score} > #{threshold}")
    clear_time time
    FALSE_BACKEND
  else
    TRUE_BACKEND
  end
end
# 过滤流程示意
def filter
  return TRUE_BACKEND if white_list?
  return FALSE_BACKEND if black_list?
  if bad_ua?
    add_black_list('UA banned!')
    return FALSE_BACKEND
  end
  redirect 5, incr_time(5), 4
  redirect 60, incr_time(60), 30
end

再次写测试吧,怎么写你懂的。不懂去学嘛,不想学就手动测吧,累死你丫的。^_^

最后部署上看看效果,随时调整规则。补充下,最好做个网站后台,便于编辑规则和观察效果。

思路很好,可是为什么是过了期的 Wheezy 呢……

rack-attack

#1 楼 @msg7086 阿里云才支持 wheezy 不久... 国内厂商的镜像更新之慢,无力吐槽。

#2 楼 @rei 看到 sinatra news 推荐这个,还没仔细看 😢

ngx_mruby 跟 OpenResty 比起来还是差非常多,比如 OpenResty 内部连 Redis 使用的是完全异步的 cosocket,不会阻塞 nginx 主线程,而上次我看的时候,ngx_mruby 里面嵌入的 mruby 还是直接用了 hiredis,这样一旦跟 redis 的连接出点什么问题整个 nginx worker 线程都阻塞住了 -_- 对于 WAF 来说,这不是件好事。

我也觉得用 Ruby 写代码会比用 Lua 要爽,但是现阶段来说,想在生产环境跑的话还是不要用 ngx_mruby,优化部分差太远了。当然,要是自己没事写着玩就是另一回事了

推荐用 OpenResty, lua 性能也要更高

需要 登录 后方可回复, 如果你还没有账号请 注册新账号