Heim >Datenbank >Redis >So verwenden Sie Lua für die Nginx-Redis-Zugriffskontrolle

So verwenden Sie Lua für die Nginx-Redis-Zugriffskontrolle

王林
王林nach vorne
2023-06-02 16:31:15937Durchsuche

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

1. Anforderungsanalyse

1. Nginx verfügt über viele Möglichkeiten, die Zugriffskontrolle zu handhaben, und es gibt viele Implementierungseffekte, wie z. B. Zugriffs-IP-Bereich, Zugriffsinhaltsbeschränkungen, Zugriffsfrequenzbeschränkungen usw.

2. Die Verwendung von Nginx+Lua+Redis zur Zugriffsbeschränkung berücksichtigt hauptsächlich die Notwendigkeit einer schnellen Zugriffskontrolle in Umgebungen mit hoher Parallelität.

3. Der Prozess der Nginx-Verarbeitung von Anfragen ist in 11 Phasen unterteilt:

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

In openresty finden Sie:

set_by_lua,access_by_lua,content_by_lua,rewrite_by_lua等方法。

Dann sollte die Zugriffskontrolle die Zugriffsphase sein.

Lösung

Nach normalem logischen Denken würden wir uns folgende Zugangskontrolllösung vorstellen:

1. Erkennen, ob es verboten ist? =》Ja, ob das Verbot abgelaufen ist: Ja, den Datensatz löschen, 200 zurückgeben, normaler Zugriff; =》Nein, 200 zurückgeben, normaler Zugriff

2 1 Verarbeitung

3. Überprüfen Sie, ob die Zugriffshäufigkeit das Limit überschreitet, und 403 wird zurückgegeben. Dies ist eine einfache Lösung Die Zugriffssperrzeit wird durch den Algorithmus importiert und die konkave Kurve nimmt jedes Mal zu.

Implementierungsmethode

Fügen Sie zunächst die vhost-Konfigurationsdatei für nginx hinzu. Der Teil vhost.conf lautet wie folgt:

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

Nachdem wir uns auf die Implementierung von v2ex.com bezogen haben, haben wir festgestellt, dass dies eine einfache Methode ist Die String-Speicherlösung reicht aus. Da die Lösung ausreicht, wurde Redis als Speichermethode ausgewählt. Die Schlüssel sind:

Benutzeranmeldedatensatz: Benutzer:127.0.0.1:Zeit (Unix-Zeitstempel)

Zugriffsbeschränkungen: Block:127.0.0.1

Zuerst eine Verbindung zu Redis herstellen:

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

Nach unserem logischen Plan, zweitens Der erste Der nächste Schritt besteht darin, zu prüfen, ob der Block: 127.0.0.1 abgelaufen ist. Andernfalls wird 200 zurückgegeben :

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
}

Als nächstes prüfen wir, ob die Zugriffshäufigkeit überschritten wurde. Wenn sie zu hoch ist, wird sie auf die schwarze Liste gesetzt. Der Weg, dies zu erreichen, besteht darin, festzustellen, ob der Wert von user:127.0.0.1:time überschritten wird der 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

Denken Sie zum Schluss daran, für jeden Besuch eine Zeit festzulegen. Selbsterhöhend, Benutzer:127.0.0.1:Zeit:

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

Führen Sie dann mehrere Tests durch, erzwingen Sie die Aktualisierung des Browsers und stellen Sie nach einer Weile fest, dass 403 angezeigt wird wird zurückgegeben, ok, fertig.

Das obige ist der detaillierte Inhalt vonSo verwenden Sie Lua für die Nginx-Redis-Zugriffskontrolle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen