{% if ANTIBOT_SESSION_SECRET == "random" +%} set $session_secret {{ random(32) }}; {% else +%} set $session_secret {{ ANTIBOT_SESSION_SECRET }}; {% endif %} set $session_check_addr on; access_by_lua_block { -- disable checks for internal requests if ngx.req.is_internal() then return end -- let's encrypt local use_lets_encrypt = {% if AUTO_LETS_ENCRYPT == "yes" %}true{% else %}false{% endif +%} -- redis local use_redis = {% if USE_REDIS == "yes" %}true{% else %}false{% endif +%} local redis_host = "{{ REDIS_HOST }}" -- external blacklists local use_user_agents = {% if BLOCK_USER_AGENT == "yes" %}true{% else %}false{% endif +%} local use_proxies = {% if BLOCK_PROXIES == "yes" %}true{% else %}false{% endif +%} local use_abusers = {% if BLOCK_ABUSERS == "yes" %}true{% else %}false{% endif +%} local use_tor_exit_nodes = {% if BLOCK_TOR_EXIT_NODE == "yes" %}true{% else %}false{% endif +%} local use_referrers = {% if BLOCK_REFERRER == "yes" %}true{% else %}false{% endif +%} -- countries local use_country = {% if WHITELIST_COUNTRY != "" or BLACKLIST_COUNTRY != "" %}true{% else %}false{% endif +%} -- antibot local use_antibot_cookie = {% if USE_ANTIBOT == "cookie" %}true{% else %}false{% endif +%} local use_antibot_javascript = {% if USE_ANTIBOT == "javascript" %}true{% else %}false{% endif +%} local use_antibot_captcha = {% if USE_ANTIBOT == "captcha" %}true{% else %}false{% endif +%} local use_antibot_recaptcha = {% if USE_ANTIBOT == "recaptcha" %}true{% else %}false{% endif +%} -- resolvers local dns_resolvers = {% raw %}{{% endraw %}{% if DNS_RESOLVERS != "" %}{% set elements = DNS_RESOLVERS.split(" ") %}{% for i in range(0, elements|length) %}"{{ elements[i] }}"{% if i < elements|length-1 %},{% endif %}{% endfor %}{% endif %}{% raw %}}{% endraw +%} -- whitelist local use_whitelist_ip = {% if USE_WHITELIST_IP == "yes" %}true{% else %}false{% endif +%} local use_whitelist_reverse = {% if USE_WHITELIST_REVERSE == "yes" %}true{% else %}false{% endif +%} local whitelist_ip_list = {% raw %}{{% endraw %}{% if WHITELIST_IP_LIST != "" %}{% set elements = WHITELIST_IP_LIST.split(" ") %}{% for i in range(0, elements|length) %}"{{ elements[i] }}"{% if i < elements|length-1 %},{% endif %}{% endfor %}{% endif %}{% raw %}}{% endraw +%} local whitelist_reverse_list = {% raw %}{{% endraw %}{% if WHITELIST_REVERSE_LIST != "" %}{% set elements = WHITELIST_REVERSE_LIST.split(" ") %}{% for i in range(0, elements|length) %}"{{ elements[i] }}"{% if i < elements|length-1 %},{% endif %}{% endfor %}{% endif %}{% raw %}}{% endraw +%} -- blacklist local use_blacklist_ip = {% if USE_BLACKLIST_IP == "yes" %}true{% else %}false{% endif +%} local use_blacklist_reverse = {% if USE_BLACKLIST_REVERSE == "yes" %}true{% else %}false{% endif +%} local blacklist_ip_list = {% raw %}{{% endraw %}{% if BLACKLIST_IP_LIST != "" %}{% set elements = BLACKLIST_IP_LIST.split(" ") %}{% for i in range(0, elements|length) %}"{{ elements[i] }}"{% if i < elements|length-1 %},{% endif %}{% endfor %}{% endif %}{% raw %}}{% endraw +%} local blacklist_reverse_list = {% raw %}{{% endraw %}{% if BLACKLIST_REVERSE_LIST != "" %}{% set elements = BLACKLIST_REVERSE_LIST.split(" ") %}{% for i in range(0, elements|length) %}"{{ elements[i] }}"{% if i < elements|length-1 %},{% endif %}{% endfor %}{% endif %}{% raw %}}{% endraw +%} -- dnsbl local use_dnsbl = {% if USE_DNSBL == "yes" %}true{% else %}false{% endif +%} local dnsbl_list = {% raw %}{{% endraw %}{% if DNSBL_LIST != "" %}{% set elements = DNSBL_LIST.split(" ") %}{% for i in range(0, elements|length) %}"{{ elements[i] }}"{% if i < elements|length-1 %},{% endif %}{% endfor %}{% endif %}{% raw %}}{% endraw +%} -- bad behavior local use_bad_behavior = {% if USE_BAD_BEHAVIOR == "yes" %}true{% else %}false{% endif +%} -- include LUA code local whitelist = require "whitelist" local blacklist = require "blacklist" local dnsbl = require "dnsbl" local cookie = require "cookie" local javascript = require "javascript" local captcha = require "captcha" local recaptcha = require "recaptcha" local iputils = require "resty.iputils" local behavior = require "behavior" local logger = require "logger" local redis = require "resty.redis" -- user variables local antibot_uri = "{{ ANTIBOT_URI }}" local whitelist_user_agent = {% raw %}{{% endraw %}{% if WHITELIST_USER_AGENT != "" %}{% set elements = WHITELIST_USER_AGENT.split(" ") %}{% for i in range(0, elements|length) %}"{{ elements[i] }}"{% if i < elements|length-1 %},{% endif %}{% endfor %}{% endif %}{% raw %}}{% endraw +%} local whitelist_uri = {% raw %}{{% endraw %}{% if WHITELIST_URI != "" %}{% set elements = WHITELIST_URI.split(" ") %}{% for i in range(0, elements|length) %}"{{ elements[i] }}"{% if i < elements|length-1 %},{% endif %}{% endfor %}{% endif %}{% raw %}}{% endraw +%} -- check if already in whitelist cache if use_whitelist_ip and whitelist.ip_cached_ok() then ngx.exit(ngx.OK) end if use_whitelist_reverse and whitelist.reverse_cached_ok() then ngx.exit(ngx.OK) end -- check if already in blacklist cache if use_blacklist_ip and blacklist.ip_cached_ko() then ngx.exit(ngx.HTTP_FORBIDDEN) end if use_blacklist_reverse and blacklist.reverse_cached_ko() then ngx.exit(ngx.HTTP_FORBIDDEN) end -- check if already in dnsbl cache if use_dnsbl and dnsbl.cached_ko() then ngx.exit(ngx.HTTP_FORBIDDEN) end -- check if IP is whitelisted (only if not in cache) if use_whitelist_ip and not whitelist.ip_cached() then if whitelist.check_ip(whitelist_ip_list) then ngx.exit(ngx.OK) end end -- check if reverse is whitelisted (only if not in cache) if use_whitelist_reverse and not whitelist.reverse_cached() then if whitelist.check_reverse(whitelist_reverse_list) then ngx.exit(ngx.OK) end end -- check if URI is whitelisted for k, v in pairs(whitelist_uri) do if ngx.var.request_uri == v then logger.log(ngx.NOTICE, "WHITELIST", "URI " .. v .. " is whitelisted") ngx.exit(ngx.OK) end end -- check if it's certbot if use_lets_encrypt and string.match(ngx.var.request_uri, "^/%.well%-known/acme%-challenge/[A-Za-z0-9%-%_]+$") then logger.log(ngx.INFO, "LETSENCRYPT", "got a visit from Let's Encrypt") ngx.exit(ngx.OK) end -- check if IP is blacklisted (only if not in cache) if use_blacklist_ip and not blacklist.ip_cached() then if blacklist.check_ip(blacklist_ip_list) then ngx.exit(ngx.HTTP_FORBIDDEN) end end -- check if reverse is blacklisted (only if not in cache) if use_blacklist_reverse and not blacklist.reverse_cached() then if blacklist.check_reverse(blacklist_reverse_list, dns_resolvers) then ngx.exit(ngx.HTTP_FORBIDDEN) end end -- check if IP is banned because of "bad behavior" if use_bad_behavior and behavior.is_banned() then logger.log(ngx.WARN, "BEHAVIOR", "IP " .. ngx.var.remote_addr .. " is banned because of bad behavior") ngx.exit(ngx.HTTP_FORBIDDEN) end -- our redis client local redis_client = nil if use_redis then redis_client = redis:new() local ok, err = redis_client:connect(redis_host, 6379) if not ok then redis_client = nil logger.log(ngx.ERR, "REDIS", "Can't connect to the Redis service " .. redis_host) end end -- check if IP is in proxies list if use_proxies then local value, flags = ngx.shared.proxies_data:get(iputils.ip2bin(ngx.var.remote_addr)) if value ~= nil then logger.log(ngx.WARN, "PROXIES", "IP " .. ngx.var.remote_addr .. " is in proxies list") ngx.exit(ngx.HTTP_FORBIDDEN) end end -- check if IP is in abusers list if use_abusers then local value, flags = ngx.shared.abusers_data:get(iputils.ip2bin(ngx.var.remote_addr)) if value ~= nil then logger.log(ngx.WARN, "ABUSERS", "IP " .. ngx.var.remote_addr .. " is in abusers list") ngx.exit(ngx.HTTP_FORBIDDEN) end end -- check if IP is in TOR exit nodes list if use_tor_exit_nodes then local value, flags = ngx.shared.tor_exit_nodes_data:get(iputils.ip2bin(ngx.var.remote_addr)) if value ~= nil then logger.log(ngx.WARN, "TOR", "IP " .. ngx.var.remote_addr .. " is in TOR exit nodes list") ngx.exit(ngx.HTTP_FORBIDDEN) end end -- check if user-agent is allowed if use_user_agents and ngx.var.http_user_agent ~= nil then local whitelisted = false for k, v in pairs(whitelist_user_agent) do if string.match(ngx.var.http_user_agent, v) then logger.log(ngx.NOTICE, "WHITELIST", "User-Agent " .. ngx.var.http_user_agent .. " is whitelisted") whitelisted = true break end end if not whitelisted then local value, flags = ngx.shared.user_agents_cache:get(ngx.var.http_user_agent) if value == nil then local patterns = ngx.shared.user_agents_data:get_keys(0) for i, pattern in ipairs(patterns) do if string.match(ngx.var.http_user_agent, pattern) then value = "ko" ngx.shared.user_agents_cache:set(ngx.var.http_user_agent, "ko", 86400) break end end if value == nil then value = "ok" ngx.shared.user_agents_cache:set(ngx.var.http_user_agent, "ok", 86400) end end if value == "ko" then logger.log(ngx.WARN, "USER-AGENT", "User-Agent " .. ngx.var.http_user_agent .. " is blacklisted") ngx.exit(ngx.HTTP_FORBIDDEN) end end end -- check if referrer is allowed if use_referrer and ngx.var.http_referer ~= nil then local value, flags = ngx.shared.referrers_cache:get(ngx.var.http_referer) if value == nil then local patterns = ngx.shared.referrers_data:get_keys(0) for i, pattern in ipairs(patterns) do if string.match(ngx.var.http_referer, pattern) then value = "ko" ngx.shared.referrers_cache:set(ngx.var.http_referer, "ko", 86400) break end end if value == nil then value = "ok" ngx.shared.referrers_cache:set(ngx.var.http_referer, "ok", 86400) end end if value == "ko" then logger.log(ngx.WARN, "REFERRER", "Referrer " .. ngx.var.http_referer .. " is blacklisted") ngx.exit(ngx.HTTP_FORBIDDEN) end end -- check if country is allowed if use_country and ngx.var.allowed_country == "no" then logger.log(ngx.WARN, "COUNTRY", "Country of " .. ngx.var.remote_addr .. " is blacklisted") ngx.exit(ngx.HTTP_FORBIDDEN) end -- check if IP is in DNSBLs (only if not in cache) if use_dnsbl and not dnsbl.cached() then if dnsbl.check(dnsbl_list, dns_resolvers) then 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 if ngx.var.request_uri ~= antibot_uri then cookie.set({uri = ngx.var.request_uri}) return ngx.redirect(antibot_uri) end logger.log(ngx.WARN, "ANTIBOT", "cookie fail for " .. ngx.var.remote_addr) return ngx.exit(ngx.HTTP_FORBIDDEN) else if ngx.var.request_uri == antibot_uri then return ngx.redirect(cookie.get("uri")) end end end -- javascript check if use_antibot_javascript and ngx.var.uri ~= "/favicon.ico" then if not cookie.is_set("javascript") then if ngx.var.request_uri ~= antibot_uri then cookie.set({uri = ngx.var.request_uri, challenge = javascript.get_challenge()}) return ngx.redirect(antibot_uri) end end end -- captcha check if use_antibot_captcha and ngx.var.uri ~= "/favicon.ico" then if not cookie.is_set("captcha") then if ngx.var.request_uri ~= antibot_uri then cookie.set({uri = ngx.var.request_uri}) return ngx.redirect(antibot_uri) end end end -- recaptcha check if use_antibot_recaptcha and ngx.var.uri ~= "/favicon.ico" then if not cookie.is_set("recaptcha") then if ngx.var.request_uri ~= antibot_uri then cookie.set({uri = ngx.var.request_uri}) return ngx.redirect(antibot_uri) end end end -- plugins check local plugins, flags = ngx.shared.plugins_data:get("plugins") if plugins ~= nil then for plugin_id in string.gmatch(plugins, "%w+") do local plugin = require(plugin_id .. "/" .. plugin_id) plugin.check() end end ngx.exit(ngx.OK) } {% if USE_ANTIBOT == "javascript" +%} include {{ NGINX_PREFIX }}antibot-javascript.conf; {% elif USE_ANTIBOT == "captcha" +%} include {{ NGINX_PREFIX }}antibot-captcha.conf; {% elif USE_ANTIBOT == "recaptcha" +%} include {{ NGINX_PREFIX }}antibot-recaptcha.conf; {% endif %}