diff --git a/.github/workflows/buildimage.yml b/.github/workflows/buildimage.yml index 23fe49ac..72cb262a 100644 --- a/.github/workflows/buildimage.yml +++ b/.github/workflows/buildimage.yml @@ -10,7 +10,9 @@ jobs: matrix: image: - 3.3-apache + - 3.4-apache - 3.3-nginx + - 3.4-nginx steps: - uses: actions/checkout@v1 with: diff --git a/3.3-apache/Dockerfile b/3.3-apache/Dockerfile index 89ed03d6..9748d6b5 100644 --- a/3.3-apache/Dockerfile +++ b/3.3-apache/Dockerfile @@ -2,9 +2,9 @@ FROM owasp/modsecurity:2 LABEL maintainer="Chaim Sanders " -ARG COMMIT=v3.3/dev -ARG BRANCH=v3.3/dev -ARG REPO=SpiderLabs/owasp-modsecurity-crs +ARG COMMIT=v3.3/master +ARG BRANCH=v3.3/master +ARG REPO=coreruleset/coreruleset ENV PARANOIA=1 \ ANOMALY_INBOUND=5 \ diff --git a/3.3-nginx/Dockerfile b/3.3-nginx/Dockerfile index fbfcc4c6..42b748e6 100644 --- a/3.3-nginx/Dockerfile +++ b/3.3-nginx/Dockerfile @@ -2,9 +2,9 @@ FROM owasp/modsecurity:3 LABEL maintainer="Chaim Sanders " -ARG COMMIT=v3.3/dev -ARG BRANCH=v3.3/dev -ARG REPO=SpiderLabs/owasp-modsecurity-crs +ARG COMMIT=v3.3/master +ARG BRANCH=v3.3/master +ARG REPO=coreruleset/coreruleset ENV PARANOIA=1 \ ANOMALY_INBOUND=5 \ diff --git a/3.4-apache/Dockerfile b/3.4-apache/Dockerfile new file mode 100644 index 00000000..01eb0a61 --- /dev/null +++ b/3.4-apache/Dockerfile @@ -0,0 +1,50 @@ +FROM owasp/modsecurity:2 + +LABEL maintainer="Chaim Sanders " + +ARG COMMIT=v3.4/dev +ARG BRANCH=v3.4/dev +ARG REPO=coreruleset/coreruleset + +ENV PARANOIA=1 \ + ANOMALY_INBOUND=5 \ + ANOMALY_OUTBOUND=4 \ + APACHE_TIMEOUT=60 \ + LOGLEVEL=warn \ + ERRORLOG='/proc/self/fd/2' \ + USER=daemon \ + GROUP=daemon \ + SERVERADMIN=root@localhost \ + SERVERNAME=localhost \ + PORT=80 \ + MODSEC_RULE_ENGINE=on \ + MODSEC_REQ_BODY_ACCESS=on \ + MODSEC_REQ_BODY_LIMIT=13107200 \ + MODSEC_REQ_BODY_NOFILES_LIMIT=131072 \ + MODSEC_RESP_BODY_ACCESS=on \ + MODSEC_RESP_BODY_LIMIT=1048576 \ + MODSEC_PCRE_MATCH_LIMIT=100000 \ + MODSEC_PCRE_MATCH_LIMIT_RECURSION=100000 + +COPY src/etc/modsecurity.d/*.conf /etc/modsecurity.d/ +COPY src/opt/modsecurity/activate-rules.sh /opt/modsecurity/ +COPY 3.4-apache/conf/extra/*.conf /usr/local/apache2/conf/extra/ +COPY 3.4-apache/docker-entrypoint.sh / + +RUN apt-get update \ + && apt-get -y install \ + ca-certificates \ + git \ + iproute2 \ + && mkdir /opt/owasp-crs \ + && cd /opt/owasp-crs \ + && git init \ + && git remote add origin https://github.com/${REPO} \ + && git fetch --depth 1 origin ${BRANCH} \ + && git checkout ${COMMIT} \ + && mv -v crs-setup.conf.example crs-setup.conf \ + && ln -sv /opt/owasp-crs /etc/modsecurity.d/ \ + && sed -i -E 's/(Listen) [0-9]+/\1 ${PORT}/g' /usr/local/apache2/conf/httpd.conf + +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["apachectl", "-D", "FOREGROUND"] diff --git a/3.4-apache/conf/extra/httpd-logging-after-modsec.conf b/3.4-apache/conf/extra/httpd-logging-after-modsec.conf new file mode 100644 index 00000000..4b1b8ce7 --- /dev/null +++ b/3.4-apache/conf/extra/httpd-logging-after-modsec.conf @@ -0,0 +1,25 @@ +# === ModSec Timestamps at the End of Each Phase (ids: 90010 - 90019) + +SecAction "id:90010,phase:1,pass,nolog,setvar:TX.ModSecTimestamp1end=%{DURATION}" +SecAction "id:90011,phase:2,pass,nolog,setvar:TX.ModSecTimestamp2end=%{DURATION}" +SecAction "id:90012,phase:3,pass,nolog,setvar:TX.ModSecTimestamp3end=%{DURATION}" +SecAction "id:90013,phase:4,pass,nolog,setvar:TX.ModSecTimestamp4end=%{DURATION}" +SecAction "id:90014,phase:5,pass,nolog,setvar:TX.ModSecTimestamp5end=%{DURATION}" + + +# === ModSec performance calculations and variable export (ids: 90100 - 90199) + +SecAction "id:90100,phase:5,pass,nolog,\ + setvar:TX.perf_modsecinbound=%{PERF_PHASE1},\ + setvar:TX.perf_modsecinbound=+%{PERF_PHASE2},\ + setvar:TX.perf_application=%{TX.ModSecTimestamp3start},\ + setvar:TX.perf_application=-%{TX.ModSecTimestamp2end},\ + setvar:TX.perf_modsecoutbound=%{PERF_PHASE3},\ + setvar:TX.perf_modsecoutbound=+%{PERF_PHASE4},\ + setenv:ModSecTimeIn=%{TX.perf_modsecinbound},\ + setenv:ApplicationTime=%{TX.perf_application},\ + setenv:ModSecTimeOut=%{TX.perf_modsecoutbound},\ + setenv:ModSecAnomalyScoreInPLs=%{tx.anomaly_score_pl1}-%{tx.anomaly_score_pl2}-%{tx.anomaly_score_pl3}-%{tx.anomaly_score_pl4},\ + setenv:ModSecAnomalyScoreOutPLs=%{tx.outbound_anomaly_score_pl1}-%{tx.outbound_anomaly_score_pl2}-%{tx.outbound_anomaly_score_pl3}-%{tx.outbound_anomaly_score_pl4},\ + setenv:ModSecAnomalyScoreIn=%{TX.anomaly_score},\ + setenv:ModSecAnomalyScoreOut=%{TX.outbound_anomaly_score}" diff --git a/3.4-apache/conf/extra/httpd-logging-before-modsec.conf b/3.4-apache/conf/extra/httpd-logging-before-modsec.conf new file mode 100644 index 00000000..7fd07fcd --- /dev/null +++ b/3.4-apache/conf/extra/httpd-logging-before-modsec.conf @@ -0,0 +1,26 @@ +ErrorLog ${ERRORLOG} + +# For more information regarding the values in the extended log format +# and aliases and scripts to extract information please read: +# https://www.netnea.com/cms/apache-tutorial-5_extending-access-log/ +# https://www.netnea.com/cms/apache-tutorial-7_including-modsecurity-core-rules/ + +LoadModule logio_module /usr/local/apache2/modules/mod_logio.so + +LogFormat "%h %{GEOIP_COUNTRY_CODE}e %u [%{%Y-%m-%d %H:%M:%S}t.%{usec_frac}t] \"%r\" %>s %b \ +\"%{Referer}i\" \"%{User-Agent}i\" \"%{Content-Type}i\" %{remote}p %v %A %p %R \ +%{BALANCER_WORKER_ROUTE}e %X \"%{cookie}n\" %{UNIQUE_ID}e %{SSL_PROTOCOL}x %{SSL_CIPHER}x \ +%I %O %{ratio}n%% %D %{ModSecTimeIn}e %{ApplicationTime}e %{ModSecTimeOut}e \ +%{ModSecAnomalyScoreInPLs}e %{ModSecAnomalyScoreOutPLs}e \ +%{ModSecAnomalyScoreIn}e %{ModSecAnomalyScoreOut}e" extended + +CustomLog ${ACCESSLOG} extended + + +# === ModSec timestamps at the start of each phase (ids: 90000 - 90009) + +SecAction "id:90000,phase:1,nolog,pass,setvar:TX.ModSecTimestamp1start=%{DURATION}" +SecAction "id:90001,phase:2,nolog,pass,setvar:TX.ModSecTimestamp2start=%{DURATION}" +SecAction "id:90002,phase:3,nolog,pass,setvar:TX.ModSecTimestamp3start=%{DURATION}" +SecAction "id:90003,phase:4,nolog,pass,setvar:TX.ModSecTimestamp4start=%{DURATION}" +SecAction "id:90004,phase:5,nolog,pass,setvar:TX.ModSecTimestamp5start=%{DURATION}" diff --git a/3.4-apache/conf/extra/httpd-modsecurity.conf b/3.4-apache/conf/extra/httpd-modsecurity.conf new file mode 100644 index 00000000..936a96eb --- /dev/null +++ b/3.4-apache/conf/extra/httpd-modsecurity.conf @@ -0,0 +1,17 @@ +Timeout ${APACHE_TIMEOUT} +LogLevel ${LOGLEVEL} +ErrorLog ${ERRORLOG} +ServerAdmin ${SERVERADMIN} + + + User ${USER} + Group ${GROUP} + + + + RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500 + + +LoadModule security2_module /usr/local/apache2/modules/mod_security2.so + +Include /etc/modsecurity.d/setup.conf diff --git a/3.4-apache/docker-entrypoint.sh b/3.4-apache/docker-entrypoint.sh new file mode 100755 index 00000000..0d07e2d2 --- /dev/null +++ b/3.4-apache/docker-entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +source /opt/modsecurity/activate-rules.sh + +exec "$@" diff --git a/3.4-nginx/Dockerfile b/3.4-nginx/Dockerfile new file mode 100644 index 00000000..13e474fb --- /dev/null +++ b/3.4-nginx/Dockerfile @@ -0,0 +1,50 @@ +FROM owasp/modsecurity:3 + +LABEL maintainer="Chaim Sanders " + +ARG COMMIT=v3.4/dev +ARG BRANCH=v3.4/dev +ARG REPO=coreruleset/coreruleset + +ENV PARANOIA=1 \ + ANOMALY_INBOUND=5 \ + ANOMALY_OUTBOUND=4 \ + NGINX_KEEPALIVE_TIMEOUT=60s \ + ERRORLOG=/var/log/nginx/error.log \ + LOGLEVEL=warn \ + USER=nginx \ + PORT=80 \ + SERVERNAME=locahost \ + WORKER_CONNECTIONS=1024 \ + MODSEC_RULE_ENGINE=on \ + MODSEC_REQ_BODY_ACCESS=on \ + MODSEC_REQ_BODY_LIMIT=13107200 \ + MODSEC_REQ_BODY_NOFILES_LIMIT=131072 \ + MODSEC_RESP_BODY_ACCESS=on \ + MODSEC_RESP_BODY_LIMIT=1048576 \ + MODSEC_PCRE_MATCH_LIMIT=100000 \ + MODSEC_PCRE_MATCH_LIMIT_RECURSION=100000 + +COPY 3.4-nginx/docker-entrypoint.sh / +COPY 3.4-nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf +COPY 3.4-nginx/nginx.conf /etc/nginx/nginx.conf +COPY src/opt/modsecurity/activate-rules.sh /opt/modsecurity/ +COPY src/etc/modsecurity.d/*.conf /etc/modsecurity.d/ + +RUN apt-get update \ + && apt-get -y install \ + ca-certificates \ + git \ + iproute2 \ + moreutils \ + && mkdir /opt/owasp-crs \ + && cd /opt/owasp-crs \ + && git init \ + && git remote add origin https://github.com/${REPO} \ + && git fetch --depth 1 origin ${BRANCH} \ + && git checkout ${COMMIT} \ + && mv -v crs-setup.conf.example crs-setup.conf \ + && ln -sv /opt/owasp-crs /etc/modsecurity.d/ + +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["nginx", "-g", "daemon off;"] diff --git a/3.4-nginx/conf.d/default.conf b/3.4-nginx/conf.d/default.conf new file mode 100644 index 00000000..0904fd50 --- /dev/null +++ b/3.4-nginx/conf.d/default.conf @@ -0,0 +1,14 @@ +server { + listen ${PORT}; + server_name ${SERVERNAME}; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/3.4-nginx/docker-entrypoint.sh b/3.4-nginx/docker-entrypoint.sh new file mode 100755 index 00000000..3de1349f --- /dev/null +++ b/3.4-nginx/docker-entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/bash -e + +ENV_VARIABLES=$(awk 'BEGIN{for(v in ENVIRON) print "$"v}') + +for FILE in etc/nginx/nginx.conf etc/nginx/conf.d/default.conf etc/modsecurity.d/modsecurity-override.conf +do + envsubst "$ENV_VARIABLES" <$FILE | sponge $FILE +done + +source /opt/modsecurity/activate-rules.sh + +exec "$@" diff --git a/3.4-nginx/nginx.conf b/3.4-nginx/nginx.conf new file mode 100644 index 00000000..3a245850 --- /dev/null +++ b/3.4-nginx/nginx.conf @@ -0,0 +1,32 @@ +load_module modules/ngx_http_modsecurity_module.so; + +user ${USER}; +worker_processes 1; + +error_log ${ERRORLOG} ${LOGLEVEL}; +pid /var/run/nginx.pid; + +events { + worker_connections ${WORKER_CONNECTIONS}; +} + +http { + + modsecurity on; + modsecurity_rules_file /etc/modsecurity.d/setup.conf; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + + keepalive_timeout ${NGINX_KEEPALIVE_TIMEOUT}; + + include /etc/nginx/conf.d/*.conf; +}