diff --git a/Dockerfile b/Dockerfile index 9da743e..90785d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ COPY scripts/ /opt/scripts COPY misc/*.mmdb /etc/nginx/geoip.mmdb COPY fail2ban/ /opt/fail2ban -RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban && \ +RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav && \ chmod +x /opt/entrypoint.sh /opt/scripts/* && \ mkdir /www && \ adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx diff --git a/confs/modsecurity-clamav.conf b/confs/modsecurity-clamav.conf new file mode 100644 index 0000000..3c2999d --- /dev/null +++ b/confs/modsecurity-clamav.conf @@ -0,0 +1,2 @@ +SecRule FILES_TMPNAMES "@inspectFile /opt/scripts/clamav.sh" \ +"phase:2,t:none,block,msg:'Virus found in uploaded file',id:'399999'" diff --git a/confs/modsecurity-rules.conf b/confs/modsecurity-rules.conf index bdfc18f..1e10122 100644 --- a/confs/modsecurity-rules.conf +++ b/confs/modsecurity-rules.conf @@ -54,6 +54,9 @@ SecAuditLogRelevantStatus "^(?:5|4(?!04))" SecAuditLogType Serial SecAuditLog /var/log/modsec_audit.log +# scan uploaded files with clamv +%USE_CLAMAV_UPLOAD%" + # include custom rules %MODSECURITY_INCLUDE_CUSTOM_RULES% diff --git a/entrypoint.sh b/entrypoint.sh index a93714c..8a2f6a8 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -2,6 +2,25 @@ echo "[*] Starting bunkerized-nginx ..." +# trap SIGTERM and SIGINT +function trap_exit() { + echo "[*] Catched stop operation" + echo "[*] Stopping crond ..." + pkill -TERM crond + if [ "$USE_PHP" = "yes" ] ; then + echo "[*] Stopping php ..." + pkill -TERM php-fpm7 + fi + if [ "$USE_FAIL2BAN" = "yes" ] ; then + echo "[*] Stopping fail2ban" + fail2ban-client stop > /dev/null + fi + echo "[*] Stopping nginx ..." + /usr/sbin/nginx -s stop + pkill -TERM tail +} +trap "trap_exit" TERM INT + # replace pattern in file function replace_in_file() { # escape slashes @@ -69,6 +88,9 @@ FAIL2BAN_STATUS_CODES="${FAIL2BAN_STATUS_CODES-400|401|403|404|405|444}" FAIL2BAN_BANTIME="${FAIL2BAN_BANTIME-3600}" FAIL2BAN_FINDTIME="${FAIL2BAN_FINDTIME-60}" FAIL2BAN_MAXRETRY="${FAIL2BAN_MAXRETRY-10}" +USE_CLAMAV_UPLOAD="${USE_CLAMAV_UPLOAD-yes}" +USE_CLAMAV_SCAN="${USE_CLAMAV_SCAN-yes}" +CLAMAV_SCAN_REMOVE="${CLAMAV_SCAN_REMOVE-yes}" # install additional modules if needed if [ "$ADDITIONAL_MODULES" != "" ] ; then @@ -303,6 +325,25 @@ else replace_in_file "/etc/nginx/server.conf" "%USE_FAIL2BAN%" "" fi +# clamav setup +if [ "$USE_CLAMAV_UPLOAD" = "yes" ] || [ "$USE_CLAMAV_SCAN" = "yes" ] ; then + echo "[*] Updating clamav ..." + freshclam > /dev/null 2>&1 + echo "0 0 * * * /usr/bin/freshclam > /dev/null 2>&1" >> /etc/crontabs/root +fi +if [ "$USE_CLAMAV_UPLOAD" = "yes" ] ; then + replace_in_file "/etc/nginx/modsecurity-rules.conf" "%USE_CLAMAV_UPLOAD%" "include /etc/nginx/modsecurity-clamav.conf" +else + replace_in_file "/etc/nginx/modsecurity-rules.conf" "%USE_CLAMAV_UPLOAD%" "" +fi +if [ "$USE_CLAMAV_SCAN" = "yes" ] ; then + if [ "$USE_CLAMAV_SCAN_REMOVE" = "yes" ] ; then + echo "0 */1 * * * /usr/bin/clamscan -r -i --no-summary --remove / >> /var/log/clamav.log 2> /dev/null" >> /etc/crontabs/root + else + echo "0 */1 * * * /usr/bin/clamscan -r -i --no-summary / >> /var/log/clamav.log 2> /dev/null" >> /etc/crontabs/root + fi +fi + # edit access if needed if [ "$WRITE_ACCESS" = "yes" ] ; then chown -R root:nginx /www @@ -320,16 +361,18 @@ fi crond # start nginx -/usr/sbin/nginx echo "[*] Running nginx ..." +/usr/sbin/nginx +# start fail2ban if [ "$USE_FAIL2BAN" = "yes" ] ; then - fail2ban-server + fail2ban-server > /dev/null fi # display logs -exec tail -f /var/log/access.log +tail -f /var/log/access.log & +wait $! -# try to gracefully stop nginx -echo "[*] Stopping nginx ..." -/usr/sbin/nginx -s stop +# sigterm trapped +echo "[*] bunkerized-nginx stopped" +exit 0 diff --git a/scripts/clamav.sh b/scripts/clamav.sh new file mode 100644 index 0000000..39f66ec --- /dev/null +++ b/scripts/clamav.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +output=$(clamscan -i --no-summary "$1" 2> /dev/null) + +if echo "$output" | grep -q ".* FOUND$" ; then + echo "0 clamscan: $output" +else + echo "1 clamscan: ok" +fi diff --git a/scripts/exit-nodes.sh b/scripts/exit-nodes.sh index 03c78ed..1a650ce 100644 --- a/scripts/exit-nodes.sh +++ b/scripts/exit-nodes.sh @@ -1,6 +1,6 @@ #!/bin/sh -BLACKLIST=$(curl "https://iplists.firehol.org/files/tor_exits.ipset") +BLACKLIST=$(curl -s "https://iplists.firehol.org/files/tor_exits.ipset") DATA="" for ip in $BLACKLIST ; do DATA="${DATA}deny ${ip};\n" diff --git a/scripts/user-agents.sh b/scripts/user-agents.sh index 7e8e784..5a8c4e1 100755 --- a/scripts/user-agents.sh +++ b/scripts/user-agents.sh @@ -9,7 +9,7 @@ function replace_in_file() { sed -i "s/$pattern/$replace/g" "$1" } -BLACKLIST="$(curl https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list)" +BLACKLIST="$(curl -s https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list)" DATA="" IFS=$'\n' for ua in $BLACKLIST ; do