ホームページ  >  記事  >  データベース  >  nginx redisアクセス制御にluaを使用する方法

nginx redisアクセス制御にluaを使用する方法

王林
王林転載
2023-06-02 16:31:15865ブラウズ

怎么使用lua进行nginx redis访问控制

1. 要件分析

\1. Nginx がアクセス制御を処理するには多くの方法があり、実装による影響も数多くあります。アクセス IP セグメント, アクセスコンテンツ制限、アクセス頻度制限など。

\2. アクセス制限に Nginx Lua Redis を使用する場合、主に同時実行性の高い環境での高速アクセス制御の必要性が考慮されます。

\3. Nginx のリクエスト処理プロセスは、次の 11 段階に分かれています:

post-read、server-rewrite、find-config、rewrite、post-rewrite、 preaccess、access、post-access、try-files、content、log.

openresty では、次のことがわかります:

set_by_lua,access_by_lua,content_by_lua,rewrite_by_lua等方法。

次に、アクセス制御は次のとおりです。になります、アクセス段階です。

ソリューション

通常の論理的思考によれば、私たちが考えるアクセス制御ソリューションは次のとおりです:

1. 禁止されているかどうかを検出しますか? =>>はい、禁止期限が切れているかどうか: はい、レコードをクリア、200 を返す、通常のアクセス; いいえ、403 を返す; =>>いいえ、200 を返す、通常のアクセス

2. 各訪問、ユーザーの訪問を訪問します。頻度 1 の処理

3. アクセス頻度が制限を超えているかどうかを確認し、制限を超えている場合は禁止レコードを追加して 403

これは簡単な解決策です。分岐を追加することもできます出てアクセス禁止時間が経過するとアルゴリズムがインポートされ、その度に凹曲線が増加します。

実装方法

まずnginx用のvhost設定ファイルを追加します vhost.conf部分は以下の通りです:

lua_package_path "/usr/local/openresty/lualib/?.lua;;";#告诉openresty库地址lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
error_log /usr/local/openresty/nginx/logs/openresty.debug.log debug;

server {
   listen 8080 default;
   server_name www.ttlsa.com;    
   root  /www/openresty;

   location /login {
       default_type 'text/html';
       access_by_lua_file "/usr/local/openresty/nginx/lua/access_by_redis.lua";#通过lua来处理访问控制   }
}

#Access_by_redis.lua# #v2ex.com の実装を参照した結果、単純な文字列ストレージ ソリューションを使用するだけで十分であることがわかり、ストレージ方法として Redis を選択しました。キーは次のとおりです:

ユーザー ログイン レコード: user:127.0.0.1:time (unix タイムスタンプ)

アクセス制限: block:127.0.0.1

最初に Redis に接続します :

local red = redis:new()function M:redis()
red:set_timeout(1000)local ok, err = red:connect("127.0.0.1", 6379)if not ok then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
end

私たちの論理計画によると、2 番目のステップは、それが禁止されているかどうかを検出することです。次に、ブロック:127.0.0.1 を検出します。データが検索された場合は、時間が経過しているかどうかを確認します。有効期限が切れていない場合は 403 が返されます。それ以外の場合は直接 200 を返します:

function M:check1()local time=os.time() --system timelocal res, err = red:get("block:"..ngx.var.remote_addr)if not res then -- redis error
 ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis get data error  endif type(res) == "string" then --if red not null then type(red)==string
 if tonumber(res) >= tonumber(time) then  --check if forbidden expired
  ngx.exit(ngx.HTTP_FORBIDDEN)
  --ngx.say("forbidden")
 end
end
}

次のステップでは、アクセス頻度が高すぎるかどうかを確認します。高すぎる場合は、ブラックリストに登録されます。

実装方法は user:127.0.0.1 :time の値が標準を超えているかどうかを検出することです:

function M:check2()local time=os.time() --system timelocal res, err = red:get("user:"..ngx.var.remote_addr..":"..time)if not res then -- redis error
 ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis get data error
endif type(res) == "string" then if tonumber(res) >= 10 then -- attack, 10 times request/s
  red:del("block:"..self.ip)
  red:set("block:"..self.ip, tonumber(time)+5*60 ) --set block time
  ngx.exit(ngx.HTTP_FORBIDDEN)
 end
end
end

最後に、各アクセスの時間を忘れずに増やしてください user:127.0.0.1:time:

function M:add()local time=os.time() --system time
ok, err = red:incr("user:"..ngx.var.remote_addr..":"..time)if not ok then ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis get data error
end
end

それでは、試しに、ブラウザを数回スワイプして、しばらくすると 403 が返されることがわかりました。

以上がnginx redisアクセス制御にluaを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。