2016-05-05 10 views
0

Ich habe eine Reihe von IP-Adresse in meinem Redis-Server blockiert werden. Nun, wenn ein Client eine Anfrage stellt,nginx lua nicht in der Lage, Header vor dem Neuschreiben

  1. muss der Antrag
  2. Prüfung durch nginx abgefangen werden, wenn die remote_addr zum blockierten ip gehört
  3. einen Header hinzufügen, wenn die IP blockiert
  4. dann umleiten zu die tatsächliche IP-Adresse mit der request_uri.

nginx.conf

worker_processes 1; 

events { 
    worker_connections 1024; 
} 

http { 
    include  mime.types; 
    default_type application/octet-stream; 

    sendfile  on; 

    keepalive_timeout 65; 

    lua_shared_dict ip_status 1m; 

    server { 
     listen  9080; 
     server_name localhost; 
     location ~ .* { 
      rewrite_by_lua_file src/ip_check.lua; 
     } 
    } 
} 

src/ip_check.lua

-- redis configuration 
local redis_host    = "127.0.0.1" 
local redis_port    = 6379 -- connection timeouts for redis in ms. 
local redis_max_idle_timeout = 10000 
local redis_pool_size   = 2  -- don't set this too high! 
local redis_timeout    = 200 

-- check a set with this key for blacklist entries 
local redis_key   = ngx.var.remote_addr 
local ip_status   = ngx.shared.ip_status 
local status_unblocked = "0" 
local status_blocked = "1" 
-- cache lookups for this many seconds 
local cache_ttl   = 1800 

local redirect_host    = "http://192.168.12.103:8080/Spring4MVCHelloWorld1" 
local header_ip_status_key  = "Ip-Status" 
-- value of the header to be sent when the client ip address is blocked 
local header_ip_status_value = "block" 
local add_header    = status_unblocked 

-- lookup the value in the cache 
local cache_result = ip_status:get(redis_key) 
if cache_result then 
    if cache_result == status_blocked then 
    add_header = status_blocked 
    end 
else 
    -- lookup against redis 
    local resty = require "resty.redis" 
    local redis = resty:new() 
    redis:set_timeout(redis_timeout) 

    local connected, err = redis:connect(redis_host, redis_port) 
    if not connected then 
    ngx.log(ngx.ERR, "ip_check: could not connect to redis @"..redis_host..":"..redis_port.." - "..err) 
    else 
    ngx.log(ngx.ALERT, "ip_check: found connect to redis @"..redis_host..":"..redis_port.." - successful") 

    local result, err = redis:get(redis_key) 
    if not result then 
     ngx.log(ngx.ERR, "ip_check: lookup failed for "..ngx.var.remote_addr.." - "..err) 
    else 
     if result == status_blocked then 
     add_header = status_blocked 
     end 

     -- cache the result from redis 
     ip_status:set(ip, add_header, cache_ttl) 
    end 

    redis:set_keepalive(redis_max_idle_timeout, redis_pool_size) 
    end 
end 

ngx.log(ngx.ALERT, "ip_check: "..header_ip_status_key.." of "..ngx.var.remote_addr.." is "..add_header) 
if add_header == status_blocked then 
    ngx.header[header_ip_status_key] = header_ip_status_value 
    ngx.req.set_header(header_ip_status_key, header_ip_status_value) 
end 

ngx.redirect(redirect_host..ngx.var.request_uri) 

Für Testzwecke hinzugefügt i 127.0.0.1 Taste 1 mit dem Wert Redis die Umleitung So uri sollte mit dem zusätzlichen Header getroffen werden. Das Problem, das ich gegenüberstelle, ist egal, was ich ngx.header oder ngx.req.set_header die Ip-Status Header nicht an die Weiterleitung Anfrage gesendet und das Ende API erhält es nicht.

Zum Beispiel, wenn ich http://localhost:9080/hello im Browser getroffen,

Anfrage Header

Host:"localhost:9080" 
User-Agent:"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0" 
Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" 
Accept-Language:"en-US,en;q=0.5" 
Accept-Encoding:"gzip, deflate" 
Connection:"keep-alive" 

Response-Header

Connection:"keep-alive" 
Content-Length:"166" 
Content-Type:"text/html" 
Date:"Thu, 05 May 2016 08:06:33 GMT" 
Location:"http://192.168.12.103:8080/Spring4MVCHelloWorld1/hello" 
Server:"openresty/1.9.7.2" 
ip-status:"block" 

Die umgeleitet uri ist http://localhost:9080/hello,

Anfrage Header

Host:"192.168.12.103:8080" 
User-Agent:"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0" 
Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" 
Accept-Language:"en-US,en;q=0.5" 
Accept-Encoding:"gzip, deflate" 
Cookie:"JSESSIONID=4834843FE0E76170E429028E096A66E5" 
Connection:"keep-alive" 

Response-Header

Content-Language:"en-US" 
Content-Length:"166" 
Content-Type:"text/html;charset=UTF-8" 
Date:"Thu, 05 May 2016 08:06:33 GMT" 
Server:"Apache-Coyote/1.1" 

Ich bin in der Lage Ip Status Header in Antwort-Header der ursprünglichen Anfrage aber nicht in den Request-Header des umgeleiteten uri zu sehen. Jede Hilfe, wie man Header an das umgeleitete URI sendet, wird sehr hilfreich sein.

Ich bin neu in Nginx und Lua. Fragen, weil ich keine entsprechenden Fragen entschuldigen konnte, wenn die Frage bereits gestellt wurde.

+0

Anfragen werden vom Browser gesendet. Sie haben keine Kontrolle über die Header, die gesendet werden. –

+0

@AlexeyTen danke für den Vorschlag. Das hat geholfen zu verstehen, was zu tun ist. –

Antwort

0

Es ist der Browser, der auf die umgeleitete URI umleitet und Nginx haben keine Kontrolle über die Header. Also, ich entfernt

ngx.redirect(redirect_host..ngx.var.request_uri) 

vom src/ip_check.lua und geändert nginx.conf einen Proxy-Anruf zu tätigen, und ich war in der Lage zu beobachten, dass die api Lage war, die zusätzlichen Header zu empfangen. Diese modifizierte nginx.conf wird eine Anfrage an $ backend_host $ request_uri und Browser machen wird keine Kenntnis der gemacht Umleitungen

nginx.conf

worker_processes 1; 

events { 
    worker_connections 1024; 
} 

http { 
    include  mime.types; 
    default_type application/octet-stream; 

    sendfile  on; 
    keepalive_timeout 65; 
    lua_shared_dict ip_status 1m; 

    server { 
     listen  9080; 
     server_name localhost; 
     location ~ .* { 
      set $backend_host "http://192.168.12.103:8080/Spring4MVCHelloWorld1"; 
      access_by_lua_file src/ip_check.lua; 
      proxy_pass $backend_host$request_uri; 
     } 
    } 
} 

Modified. Daher werden die Header von ngx.req festgelegt.set_header wird gesendet, wenn der Proxy-Aufruf erfolgt. Also

ngx.header[header_ip_status_key] = header_ip_status_value 

kann auch aus src/ip_check.lua entfernt werden.