Maison > base de données > Redis > le corps du texte

Comment utiliser Lua pour le contrôle d'accès Nginx Redis

王林
Libérer: 2023-06-02 16:31:15
avant
921 Les gens l'ont consulté

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

1. Analyse des exigences

1. Nginx dispose de nombreuses façons de gérer le contrôle d'accès, et il existe de nombreux effets de mise en œuvre, tels que la plage IP d'accès, les restrictions de contenu d'accès, les restrictions de fréquence d'accès, etc.

2. L'utilisation de Nginx+Lua+Redis pour la restriction d'accès prend principalement en compte la nécessité d'un contrôle d'accès rapide dans les environnements à forte concurrence.

3. Le processus de traitement des requêtes Nginx est divisé en 11 étapes, qui sont :

post-read、server-rewrite、find-config、rewrite、post-rewrite、 preaccess、access、post-access、try-files、content、log.
Copier après la connexion

Dans openresty, vous pouvez trouver :

set_by_lua,access_by_lua,content_by_lua,rewrite_by_lua等方法。
Copier après la connexion

Ensuite, le contrôle d'accès devrait être l'étape d'accès.

Solution

Selon la pensée logique normale, la solution de contrôle d'accès à laquelle nous penserions est la suivante :

1. Détecter si c'est interdit ? =》Oui, si l'interdiction a expiré : Oui, effacer l'enregistrement, renvoyer 200, accès normal ; Non, renvoyer 403 =》Non, renvoyer 200, accès normal

2. 1 traitement

3. Vérifiez si la fréquence d'accès dépasse la limite. Si elle dépasse la limite, un enregistrement interdit sera ajouté et 403 sera renvoyé

C'est une solution simple. le temps d'interdiction d'accès est importé via l'algorithme et la courbe concave augmente à chaque fois.

Méthode d'implémentation

Ajoutez d'abord le fichier de configuration vhost pour nginx. La partie vhost.conf est la suivante :

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来处理访问控制   }
}
Copier après la connexion

Access_by_redis.lua

Après avoir fait référence à l'implémentation de v2ex.com, nous avons constaté qu'en utilisant un simple La solution de stockage de chaînes est suffisante. C'était suffisant, c'est pourquoi Redis a été choisi comme méthode de stockage. Les clés sont :

Enregistrement de connexion utilisateur : utilisateur :127.0.0.1 :heure (horodatage unix)

Restrictions d'accès : bloc :127.0.0.1

Connectez-vous d'abord à 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
Copier après la connexion

Selon notre plan logique, deuxièmement Le premier L'étape consiste à vérifier si c'est interdit. Ensuite, nous vérifierons le bloc : 127.0.0.1. Si les données sont recherchées, vérifiez si le délai n'a pas expiré, 403 sera renvoyé directement. :

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
}
Copier après la connexion

Ensuite, nous vérifierons si la fréquence d'accès a été dépassée. Si elle est trop élevée, elle sera mise sur liste noire. La façon d'y parvenir est de détecter si la valeur de user:127.0.0.1:time dépasse. le standard :

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
Copier après la connexion

Enfin, pensez à prévoir un temps pour chaque visite Auto-augmentation, 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
Copier après la connexion

Ensuite, testez, forcez le rafraîchissement du navigateur plusieurs fois, et constatez qu'au bout d'un moment, 403 est renvoyé, ok, c'est fait.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal