banner
moeyy

moeyy

一条有远大理想的咸鱼。
github
mastodon
email

OpenResty(nginx拡張)によるCC攻撃の防止

この記事では、OpenResty を使用して CC 攻撃を防止する方法について説明します。OpenResty の公式ウェブサイトはこちら:http://openresty.org/cn/index.html。以下は CC 攻撃のフローチャートです。
フローチャートに基づいて、CC 攻撃の主な要素は 2 つあります。1 つはリクエスト速度の制限、もう 1 つはユーザーに対して JS リダイレクトコードを送信してリクエストの正当性を検証することです。

依存関係のインストール#

CentOS:#

yum install readline-devel pcre-devel openssl-devel

Ubuntu:#

apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl

luajit のインストール

cd /tmp/
git clone http://luajit.org/git/luajit-2.0.git
cd luajit-2.0/
make && make install
ln -sf luajit-2.0.0-beta10 /usr/local/bin/luajit
ln -sf /usr/local/lib/libluajit-5.1.so.2 /usr/lib/

OpenResty のインストール#

cd /tmp
wget http://agentzh.org/misc/nginx/ngx_openresty-1.2.4.13.tar.gz
tar xzf ngx_openresty-1.2.4.13.tar.gz
cd ngx_openresty-1.2.4.13/
./configure --prefix=/usr/local/openresty --with-luajit
make && make install

nginx の設定#

nginx.conf:

    http{
    [......]
    lua_shared_dict limit 10m;
    lua_shared_dict jsjump 10m;
     
        server {
    #lua_code_cache off;
            listen       80;
            server_name  www.moeyy.cn;
     
            location / {
    default_type  text/html;
    content_by_lua_file "/usr/local/openresty/nginx/conf/lua";
            }
            location @cc {
                internal;
                root   html;
                index  index.html index.htm;
            }
        }
    }

/usr/local/openresty/nginx/conf/lua ファイル:

    local ip = ngx.var.binary_remote_addr
    local limit = ngx.shared.limit
    local req,_=limit:get(ip)
    if req then
            if req > 20 then
                    ngx.exit(503)
            else
                    limit:incr(ip,1)
            end
    else
            limit:set(ip,1,10)
    end
     
    local jsjump = ngx.shared.jsjump
    local uri = ngx.var.request_uri
    local jspara,flags=jsjump:get(ip)
    local args = ngx.req.get_uri_args()
    if jspara then
        if flags then
            ngx.exec("@cc")
        else
                    local p_jskey=''
                    if args["moeyy_anticc"] and type(args["moeyy_anticc"])=='table' then
                             p_jskey=args["moeyy_anticc"][table.getn(args["moeyy_anticc"])]
                    else
                             p_jskey=args["moeyy_anticc"]
                    end
            if p_jskey and p_jskey==tostring(jspara) then
                            jsjump:set(ip,jspara,3600,1)
                            ngx.exec("@cc")
            else
                            local url=''
                            if ngx.var.args then
                                   url=ngx.var.scheme.."://"..ngx.var.host..uri.."&moeyy_anticc="..jspara
                            else
                                   url=ngx.var.scheme.."://"..ngx.var.host..uri.."?moeyy_anticc="..jspara
                            end
                            local jscode="window.location.href='"..url.."';"
                            ngx.say(jscode)
            end
        end
    else
    math.randomseed( os.time() );
        local random=math.random(100000,999999)
        jsjump:set(ip,random,60)
        local url=''
        if ngx.var.args then
            url=ngx.var.scheme.."://"..ngx.var.host..uri.."&moeyy_anticc="..random
        else
            url=ngx.var.scheme.."://"..ngx.var.host..uri.."?moeyy_anticc="..random
        end
        local jscode="window.location.href='"..url.."';"
        ngx.say(jscode)
    end

**lua コードの説明:

  1. 1-12 行目は制限速度の機能を実装しており、5 行目と 10 行目は 10 秒間に 20 回のリクエストまで許可することを意味しています。
  2. 14-48 行目は検証部分です。24 行目の 3600 は検証が合格した後、ホワイトリストの有効期間が 3600 秒(1 時間)であることを示しています。**
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。