LoginSignup
16
5

More than 5 years have passed since last update.

OpenResty(nginx-luaフレームワーク)とRedisでアクセス制限システムの試作

Last updated at Posted at 2016-12-11

この記事は リクルートライフスタイルアドベントカレンダー2016 の11日目です。
ホットペッパービューティーでゆるふわエンジニアをしています。しゃぜです。
割りと最近入社したばっかりです。

さて、今回は前から試そうと思って暇がなくてサボっていた、OpenRestyで少し遊んでみました。

はじめに

  • OpenRestyとredisを利用して、簡易的なアクセス制御システムを試作してみます。
  • 同じIPアドレスから一定回数のアクセスが合った場合にBANするというものです。
    • 今回は雑に、30秒以内に10アクセス以上あった場合「アクセスしすぎですよ」というメッセージを表示してみます。
    • お仕事の場合だと、404を返すとか、そういう感じになるかとは思います。
  • 今回は同じEC2インスタンス(ubuntu)上で、nginxとredis-serverを動かしています。
    • そのEC2にEIPを付与して、そのまま外からアクセスできるような状態です。

redisの導入と起動

sudo apt-get install redis-server -y
sudo service redis-server start

Ubuntu 16.04.1 LTS に OpenRestyの導入(nginx含む)

sudo apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl make wget gcc -y
cd /usr/local
wget https://openresty.org/download/openresty-1.11.2.2.tar.gz
tar xvfz openresty-1.11.2.2.tar.gz
cd openresty-1.11.2.2
./configure --prefix=/usr/local
make
sudo make install

nginxの操作

  • 起動
    • sudo /usr/local/nginx/sbin/nginx
  • 再読込
    • sudo /usr/local/nginx/sbin/nginx -s reload
  • 停止
    • sudo /usr/local/nginx/sbin/nginx -s stop

nginxの設定

  • location /のところを、sample.luaを見るようにしています。

/usr/local/nginx/conf/nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        location / {
                default_type 'text/html';
                content_by_lua_file /usr/local/luafiles/sample.lua;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

luaスクリプト配置用のディレクトリをつくります。

sudo mkdir /usr/local/luafiles

アクセス制御用のlua scriptの実装

では、実際に、lua scriptを配置してみます。
実装イメージはこんな感じです。
/usr/local/luafiles/sample.lua

local redis = require "resty.redis"
local redisObject = redis:new()
redisObject:set_timeout(3000)

local ok, err = redisObject:connect("127.0.0.1",6379)
if not ok then
  ngx.say("connection error",err)
  return
end

redisObject:incr(ngx.var.remote_addr)
redisObject:expire(ngx.var.remote_addr,30)

local counter = redisObject:get(ngx.var.remote_addr)
if tonumber(counter) > 10 then
  ngx.say("アクセスしすぎですよ")
else
  ngx.say("ようこそ")
end

動作

nginxに対して、同一IPアドレスから、30秒以内に10回アクセスすると、「アクセスしすぎですよ」というメッセージがでるようになりました。

まとめ

  • 今回は手抜きでパッケージ入れましたが、お仕事で使う時は、nginxや、redisの最新版を使うようにしたいですね。
  • luaのエラーハンドリングなどは雑なので、あくまでもサンプルということでご容赦を。
    • redisのexpireの仕組みからすると厳密な30sになっていないとかいろいろありますが。。。
  • お仕事で使う際はいろいろ要件とかありそうですが、導入の敷居は低いなぁと感じました。気軽に活用できるのではないでしょうか。

ではではーε≡≡ヘ( ´Д`)ノ

16
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
5