remote API - ban IP from distributed DB
This commit is contained in:
@@ -4,6 +4,7 @@ local dataloader = require "dataloader"
|
||||
local logger = require "logger"
|
||||
local cjson = require "cjson"
|
||||
local remoteapi = require "remoteapi"
|
||||
local iputils = require "resty.iputils"
|
||||
|
||||
local use_redis = {% if USE_REDIS == "yes" %}true{% else %}false{% endif +%}
|
||||
|
||||
@@ -15,6 +16,30 @@ local use_referrers = {% if has_value("BLOCK_REFERRER", "yes") %}true{% else %}
|
||||
|
||||
local use_remote_api = {% if has_value("USE_REMOTE_API", "yes") %}true{% else %}false{% endif +%}
|
||||
|
||||
|
||||
-- Load reserved IPs
|
||||
local reserved_ips = {
|
||||
"0.0.0.0/8",
|
||||
"10.0.0.0/8",
|
||||
"100.64.0.0/10",
|
||||
"127.0.0.0/8",
|
||||
"169.254.0.0/16",
|
||||
"172.16.0.0/12",
|
||||
"192.0.0.0/24",
|
||||
"192.0.2.0/24",
|
||||
"192.88.99.0/24",
|
||||
"192.168.0.0/16",
|
||||
"198.18.0.0/15",
|
||||
"198.51.100.0/24",
|
||||
"203.0.113.0/24",
|
||||
"224.0.0.0/4",
|
||||
"233.252.0.0/24",
|
||||
"240.0.0.0/4",
|
||||
"255.255.255.255/32"
|
||||
}
|
||||
ngx.shared.reserved_ips:safe_set("cidrs", iputils.parse_cidrs(reserved_ips), 0)
|
||||
|
||||
-- Load blacklists
|
||||
if not use_redis then
|
||||
if use_proxies then
|
||||
dataloader.load_ip("/etc/nginx/proxies.list", ngx.shared.proxies_data)
|
||||
@@ -87,19 +112,33 @@ if use_remote_api then
|
||||
f:close()
|
||||
|
||||
-- Save machine ID
|
||||
local id = "empty"
|
||||
local f = io.open("/etc/nginx/machine.id", "r")
|
||||
if f == nil then
|
||||
id = "empty"
|
||||
logger.log(ngx.ERR, "REMOTE API", "USE_REMOTE_API is set to yes but machine ID is not generated - communication with {{ REMOTE_API_SERVER }} won't work")
|
||||
else
|
||||
id = f:read("*all"):gsub("[\r\n]", "")
|
||||
logger.log(ngx.ERR, "REMOTE API", "*NOT AN ERROR* Machine ID = " .. id)
|
||||
logger.log(ngx.ERR, "REMOTE API", "*NOT AN ERROR* Using existing machine ID (" .. id .. ")")
|
||||
f:close()
|
||||
end
|
||||
ngx.shared.remote_api:set("id", id, 0)
|
||||
|
||||
-- TODO : ping (blocking socket)
|
||||
-- TODO : load database
|
||||
-- Ping the remote API
|
||||
local ping = "ko"
|
||||
if id ~= "empty" then
|
||||
if remoteapi.ping2() then
|
||||
ping = "ok"
|
||||
logger.log(ngx.ERR, "REMOTE API", "*NOT AN ERROR* Successfully requested the remote API")
|
||||
else
|
||||
logger.log(ngx.ERR, "REMOTE API", "Can't contact the remote API, feature will be disabled")
|
||||
end
|
||||
end
|
||||
ngx.shared.remote_api:set("ping", ping, 0)
|
||||
|
||||
-- Load the database
|
||||
if ping ~= "ko" then
|
||||
dataloader.load_ip("/etc/nginx/remote-api.db", ngx.shared.remote_api_db)
|
||||
end
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
@@ -91,7 +91,9 @@ http {
|
||||
{% if has_value("USE_BAD_BEHAVIOR", "yes") %}lua_shared_dict behavior_ban 10m;{% endif +%}
|
||||
{% if has_value("USE_BAD_BEHAVIOR", "yes") %}lua_shared_dict behavior_count 10m;{% endif +%}
|
||||
lua_shared_dict plugins_data 10m;
|
||||
lua_shared_dict reserved_ips 1m;
|
||||
{% if has_value("USE_REMOTE_API", "yes") %}lua_shared_dict remote_api 1m;{% endif +%}
|
||||
{% if has_value("USE_REMOTE_API", "yes") %}lua_shared_dict remote_api_db 10m;{% endif +%}
|
||||
|
||||
# shared memory zone for limit_req
|
||||
{% if has_value("USE_LIMIT_REQ", "yes") %}limit_req_zone $binary_remote_addr$uri zone=limit:{{ LIMIT_REQ_CACHE }} rate={{ LIMIT_REQ_RATE }};{% endif +%}
|
||||
|
||||
@@ -20,8 +20,9 @@ end
|
||||
-- remote API
|
||||
local use_remote_api = {% if USE_REMOTE_API == "yes" %}true{% else %}false{% endif +%}
|
||||
local remoteapi = require "remoteapi"
|
||||
local iputils = require "resty.iputils"
|
||||
|
||||
if use_remote_api and ngx.shared.remote_api:get("id") ~= "empty" then
|
||||
if use_remote_api and not iputils.ip_in_cidrs(ngx.var.remote_addr, ngx.shared.reserved_ips:get("data")) and ngx.shared.remote_api:get("id") ~= "empty" and ngx.shared.remote_api:get("ping") ~= "ko" then
|
||||
if ngx.status == ngx.HTTP_FORBIDDEN then
|
||||
local reason = "other"
|
||||
if use_bad_behavior and new_bad_behavior_ban then
|
||||
@@ -34,16 +35,13 @@ if use_remote_api and ngx.shared.remote_api:get("id") ~= "empty" then
|
||||
local remoteapi = require "remoteapi"
|
||||
local logger = require "logger"
|
||||
local res, data = remoteapi.ip(ip, reason)
|
||||
-- TODO : find a way to log ?
|
||||
-- if res then
|
||||
-- logger.log(ngx.ERR, "REMOTE API", "Successfully reported ip " .. ngx.var.remote_addr)
|
||||
-- else
|
||||
-- logger.log(ngx.ERR, "REMOTE API", "Error while reporting ip " .. ngx.var.remote_addr .. " : " .. data)
|
||||
-- end
|
||||
-- TODO : find a way to log
|
||||
end
|
||||
local ok, err = ngx.timer.at(0, report_ip, ngx.var.remote_addr, reason)
|
||||
if not ok then
|
||||
logger.log(ngx.ERR, "REMOTE API", "Error while creating report timer " .. err)
|
||||
else
|
||||
logger.log(ngx.NOTICE, "REMOTE API", "Reporting " .. ngx.var.remote_addr .. "(reason: " .. reason .. ") to the remote API")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -57,6 +57,9 @@ local dnsbl_list = {% raw %}{{% endraw %}{% if DNSBL_LIST != "" %}{% set elemen
|
||||
-- bad behavior
|
||||
local use_bad_behavior = {% if USE_BAD_BEHAVIOR == "yes" %}true{% else %}false{% endif +%}
|
||||
|
||||
-- remote API
|
||||
local use_remote_api = {% if USE_REMOTE_API == "yes" %}true{% else %}false{% endif +%}
|
||||
|
||||
-- include LUA code
|
||||
local whitelist = require "whitelist"
|
||||
local blacklist = require "blacklist"
|
||||
@@ -224,6 +227,15 @@ if use_dnsbl and not dnsbl.cached() then
|
||||
end
|
||||
end
|
||||
|
||||
-- check if IP is in distributed DB
|
||||
if use_remote_api then
|
||||
local checker = checker:new("remote-api-db", ngx.shared.remote_api_db, redis_client, "simple")
|
||||
if checker:check(iputils.ip2bin(ngx.var.remote_addr)) then
|
||||
logger.log(ngx.WARN, "REMOTE API", "IP " .. ngx.var.remote_addr .. " is in the distributed DB")
|
||||
ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||
end
|
||||
end
|
||||
|
||||
-- cookie check
|
||||
if use_antibot_cookie and ngx.var.uri ~= "/favicon.ico" then
|
||||
if not cookie.is_set("uri") then
|
||||
|
||||
Reference in New Issue
Block a user