nginx lua 无法在重写前设置 headers
nginx lua not able to set headers before rewrite
我的 redis 服务器中有一组 IP 地址要被阻止。现在当客户端发出请求时,
- 请求必须被nginx拦截
- 检查remote_addr是否属于被屏蔽的ip
- 如果ip被封了加一个header
- 然后使用 request_uri.
重定向到实际的 IP 地址
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)
出于测试目的,我将 127.0.0.1 键添加到 redis,值为 1。因此,应该使用附加的 header 命中重定向 uri。我面临的问题是无论我使用 ngx.header 还是 ngx.req.set_header Ip-Status header 都不会发送到重定向请求和结束 api 没有收到它。
例如,如果我在浏览器中点击 http://localhost:9080/hello,
请求headers
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"
回复headers
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"
重定向的 uri 是 http://localhost:9080/hello,
请求headers
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"
回复headers
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"
我能够在原始请求的 header 响应中看到 Ip-Status header,但在请求中看不到 headers 重定向的 uri。关于如何将 header 发送到重定向的 uri 的任何帮助都将非常有帮助。
我是 nginx 和 lua 的新手。提问是因为我找不到任何相应的问题,如果问题已经被问到,我深表歉意。
浏览器重定向到重定向的 uri,nginx 无法控制 headers。所以,我删除了
ngx.redirect(redirect_host..ngx.var.request_uri)
从 src/ip_check.lua 更改 nginx.conf 进行代理调用,我能够观察到 api 能够接收额外的 header.
已修改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;
}
}
}
修改后的 nginx.conf 将向 $backend_host$request_uri 发出请求,浏览器将不知道所做的重定向.因此,在进行代理调用时,将发送 ngx.req.set_header 设置的 header。所以,
ngx.header[header_ip_status_key] = header_ip_status_value
也可以从 src/ip_check.lua.
中删除
我的 redis 服务器中有一组 IP 地址要被阻止。现在当客户端发出请求时,
- 请求必须被nginx拦截
- 检查remote_addr是否属于被屏蔽的ip
- 如果ip被封了加一个header
- 然后使用 request_uri. 重定向到实际的 IP 地址
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)
出于测试目的,我将 127.0.0.1 键添加到 redis,值为 1。因此,应该使用附加的 header 命中重定向 uri。我面临的问题是无论我使用 ngx.header 还是 ngx.req.set_header Ip-Status header 都不会发送到重定向请求和结束 api 没有收到它。
例如,如果我在浏览器中点击 http://localhost:9080/hello,
请求headers
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"
回复headers
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"
重定向的 uri 是 http://localhost:9080/hello,
请求headers
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"
回复headers
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"
我能够在原始请求的 header 响应中看到 Ip-Status header,但在请求中看不到 headers 重定向的 uri。关于如何将 header 发送到重定向的 uri 的任何帮助都将非常有帮助。
我是 nginx 和 lua 的新手。提问是因为我找不到任何相应的问题,如果问题已经被问到,我深表歉意。
浏览器重定向到重定向的 uri,nginx 无法控制 headers。所以,我删除了
ngx.redirect(redirect_host..ngx.var.request_uri)
从 src/ip_check.lua 更改 nginx.conf 进行代理调用,我能够观察到 api 能够接收额外的 header.
已修改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;
}
}
}
修改后的 nginx.conf 将向 $backend_host$request_uri 发出请求,浏览器将不知道所做的重定向.因此,在进行代理调用时,将发送 ngx.req.set_header 设置的 header。所以,
ngx.header[header_ip_status_key] = header_ip_status_value
也可以从 src/ip_check.lua.
中删除