diff --git a/confs/dnsbl.conf b/confs/dnsbl.conf new file mode 100644 index 0000000..3a1911f --- /dev/null +++ b/confs/dnsbl.conf @@ -0,0 +1,84 @@ +access_by_lua_block { + + -- get client IP + local ip = ngx.var.remote_addr + + -- check if IP is in cache + local cached = ngx.shared.dnsblcache:get(ip) + if cached ~= nil then + if cached == "ok" then + ngx.exit(ngx.OK) + else + ngx.exit(ngx.HTTP_FORBIDDEN) + end + end + + -- get the reverse DNS + local rdns = "" + local both = false + local resolver = require "resty.dns.resolver" + local resolvers = {%DNSBL_RESOLVERS%} + local r, err = resolver:new{nameservers=resolvers, retrans=2, timeout=2000} + if not r then + ngx.exit(ngx.OK) + end + local answers, err = r:reverse_query(ip) + if not answers.errcode then + for ak, av in pairs(answers) do + if av.ptrdname then + rdns = av.ptrdname + break + end + end + end + if rdns ~= "" then + local answers, err, tries = r:query(rdns, nil, {}) + for ak, av in pairs(answers) do + if av.address and av.address == ip then + both = true + break + end + end + end + + -- check if it's a legitimate SE crawler + local ips = {"23.21.227.69", "40.88.21.235", "50.16.241.113", "50.16.241.114", "50.16.241.117", "50.16.247.234", "52.204.97.54", "52.5.190.19", "54.197.234.188", "54.208.100.253", "54.208.102.37", "107.21.1.8"} + local domains = {".googlebot.com", ".google.com", ".search.msn.com", ".crawl.yahoot.net", ".crawl.baidu.jp", ".crawl.baidu.com", ".yandex.com", ".yandex.ru", ".yandex.net"} + for k, v in pairs(ips) do + if v == ip then + ngx.shared.dnsblcache:set(ip, "ok", 86400) + ngx.exit(ngx.OK) + end + end + if both and rdns ~= "" then + for k, v in pairs(domains) do + if rdns:sub(-#v) == v then + ngx.shared.dnsblcache:set(ip, "ok", 86400) + ngx.exit(ngx.OK) + end + end + end + + -- dnsbl check + local dnsbls = {%DNSBL_LIST%} + for k, v in pairs(dnsbls) do + local name = resolver.arpa_str(ip) + name = name:gsub("%.in%-addr%.arpa", ""):gsub("%.ip6%.arpa", "") .. "." .. v + local answers, err, tries = r:query(name, nil, {}) + if not answers.errcode then + for ak, av in pairs(answers) do + if av.address then + a,b,c,d = av.address:match("([%d]+).([%d]+).([%d]+).([%d]+)") + if a == "127" then + ngx.shared.dnsblcache:set(ip, "dnsbl", 86400) + ngx.exit(ngx.HTTP_FORBIDDEN) + end + end + end + end + end + + -- legitimate user + ngx.shared.dnsblcache:set(ip, "ok", 86400) + ngx.exit(ngx.OK) +} diff --git a/confs/nginx.conf b/confs/nginx.conf index 92d1168..ebccf45 100644 --- a/confs/nginx.conf +++ b/confs/nginx.conf @@ -67,7 +67,8 @@ http { # lua path lua_package_path "/usr/local/lib/lua/?.lua;;"; - # lua_shared_dict somecache 10m; + %DNSBL_CACHE% + lua_shared_dict dnsblcache 10m; # server config include /etc/nginx/server.conf; diff --git a/confs/server.conf b/confs/server.conf index ad958d2..b401d29 100644 --- a/confs/server.conf +++ b/confs/server.conf @@ -11,6 +11,7 @@ server { { return 405; } + %DNSBL% %AUTH_BASIC% %USE_PHP% %HEADER_SERVER% diff --git a/entrypoint.sh b/entrypoint.sh index 5c9c1ee..2a8b4a8 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -34,6 +34,18 @@ function replace_in_file() { sed -i "s/$pattern/$replace/g" "$1" } +# convert space separated values to LUA +function spaces_to_lua() { + for element in $1 ; do + if [ "$result" = "" ] ; then + result="$element" + else + result="${result}, \"${element}\"" + fi + done + echo "$result" +} + # copy stub confs cp /opt/confs/*.conf /etc/nginx cp -r /opt/confs/owasp-crs /etc/nginx @@ -108,6 +120,10 @@ USE_HTTPS_CUSTOM="${USE_HTTPS_CUSTOM-no}" ROOT_FOLDER="${ROOT_FOLDER-/www}" LOGROTATE_MINSIZE="${LOGROTATE_MINSIZE-10M}" LOGROTATE_MAXAGE="${LOGROTATE_MAXAGE-7}" +USE_DNSBL="${USE_DNSBL-yes}" +DNSBL_CACHE="${DNSBL_CACHE-10m}" +DNSBL_RESOLVERS="${DNSBL_RESOLVERS-8.8.8.8 8.8.4.4}" +DNSBL_LIST="${DNSBL_LIST-bl.blocklist.de problems.dnsbl.sorbs.net sbl.spamhaus.org xbl.spamhaus.org}" # install additional modules if needed if [ "$ADDITIONAL_MODULES" != "" ] ; then @@ -361,6 +377,17 @@ if [ "$USE_AUTH_BASIC" = "yes" ] ; then else replace_in_file "/etc/nginx/server.conf" "%AUTH_BASIC%" "" fi +if [ "$USE_DNSBL" = "yes" ] ; then + replace_in_file "/etc/nginx/nginx.conf" "%DNSBL_CACHE%" "lua_shared_dict dnsblcache $DNSBL_CACHE;" + replace_in_file "/etc/nginx/server.conf" "%DNSBL%" "include /etc/nginx/dnsbl.conf;" + resolvers=$(spaces_to_lua "$DNSBL_RESOLVERS") + list=$(spaces_to_lua "$DNSBL_LIST") + replace_in_file "/etc/nginx/dnsbl.conf" "%DNSBL_RESOLVERS%" "$resolvers" + replace_in_file "/etc/nginx/dnsbl.conf" "%DNSBL_LIST%" "$list" +else + replace_in_file "/etc/nginx/nginx.conf" "%DNSBL_CACHE%" "" + replace_in_file "/etc/nginx/server.conf" "%DNSBL%" "" +fi # fail2ban setup if [ "$USE_FAIL2BAN" = "yes" ] ; then diff --git a/www/403.html b/www/403.html deleted file mode 100644 index c99e414..0000000 --- a/www/403.html +++ /dev/null @@ -1 +0,0 @@ -test 403 diff --git a/www/404.html b/www/404.html deleted file mode 100644 index c29ea80..0000000 --- a/www/404.html +++ /dev/null @@ -1 +0,0 @@ -test 404 diff --git a/www/index.php b/www/index.php deleted file mode 100644 index 798166c..0000000 --- a/www/index.php +++ /dev/null @@ -1,5 +0,0 @@ -