From 348645eab373735464fef4f87d8537385c172bfa Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Tue, 18 Feb 2020 11:03:10 +0100 Subject: [PATCH] Update project structure --- .github/workflows/dockerimage.yml | 2 +- 3.3-apache/Dockerfile | 28 ++++----- .../extra}/httpd-logging-after-modsec.conf | 0 .../extra}/httpd-logging-before-modsec.conf | 0 3.3-apache/conf/extra/httpd-modsecurity.conf | 17 ++++++ 3.3-apache/docker-entrypoint.sh | 5 ++ 3.3-nginx/Dockerfile | 4 +- 3.3-nginx/docker-entrypoint.sh | 5 ++ README.md | 8 ++- .../modsecurity.d/modsecurity-override.conf | 32 +++++++++++ src/etc/modsecurity.d/setup.conf | 8 +++ src/httpd-default.conf | 23 -------- src/modsecurity.conf | 57 ------------------- .../modsecurity/activate-rules.sh} | 19 +------ 14 files changed, 88 insertions(+), 120 deletions(-) rename {src => 3.3-apache/conf/extra}/httpd-logging-after-modsec.conf (100%) rename {src => 3.3-apache/conf/extra}/httpd-logging-before-modsec.conf (100%) create mode 100644 3.3-apache/conf/extra/httpd-modsecurity.conf create mode 100755 3.3-apache/docker-entrypoint.sh create mode 100755 3.3-nginx/docker-entrypoint.sh create mode 100644 src/etc/modsecurity.d/modsecurity-override.conf create mode 100644 src/etc/modsecurity.d/setup.conf delete mode 100644 src/httpd-default.conf delete mode 100644 src/modsecurity.conf rename src/{docker-entrypoint.sh => opt/modsecurity/activate-rules.sh} (94%) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 8ef1e611..23fe49ac 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -22,7 +22,7 @@ jobs: -p "${{ secrets.dockerhub_token }}" - name: Build ${{ matrix.image }} - run: docker build src -f ${{ matrix.image }}/Dockerfile + run: docker build . -f ${{ matrix.image }}/Dockerfile --tag owasp/modsecurity-crs:${{ matrix.image }} --tag owasp/modsecurity-crs:$(echo ${{ matrix.image }} | sed 's/.*-//') diff --git a/3.3-apache/Dockerfile b/3.3-apache/Dockerfile index 3ff80a94..89ed03d6 100644 --- a/3.3-apache/Dockerfile +++ b/3.3-apache/Dockerfile @@ -6,11 +6,10 @@ ARG COMMIT=v3.3/dev ARG BRANCH=v3.3/dev ARG REPO=SpiderLabs/owasp-modsecurity-crs -ENV WEBSERVER=Apache \ - PARANOIA=1 \ +ENV PARANOIA=1 \ ANOMALY_INBOUND=5 \ ANOMALY_OUTBOUND=4 \ - TIMEOUT=60 \ + APACHE_TIMEOUT=60 \ LOGLEVEL=warn \ ERRORLOG='/proc/self/fd/2' \ USER=daemon \ @@ -23,9 +22,14 @@ ENV WEBSERVER=Apache \ MODSEC_REQ_BODY_LIMIT=13107200 \ MODSEC_REQ_BODY_NOFILES_LIMIT=131072 \ MODSEC_RESP_BODY_ACCESS=on \ - MODSEC_RESP_BODY_LIMIT=524288 \ - MODSEC_PCRE_MATCH_LIMIT=1000 \ - MODSEC_PCRE_MATCH_LIMIT_RECURSION=1000 + 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.3-apache/conf/extra/*.conf /usr/local/apache2/conf/extra/ +COPY 3.3-apache/docker-entrypoint.sh / RUN apt-get update \ && apt-get -y install \ @@ -40,17 +44,7 @@ RUN apt-get update \ && git checkout ${COMMIT} \ && mv -v crs-setup.conf.example crs-setup.conf \ && ln -sv /opt/owasp-crs /etc/modsecurity.d/ \ - && echo 'Include /etc/modsecurity.d/owasp-crs/crs-setup.conf' > /etc/modsecurity.d/include.conf \ - && echo 'Include /etc/modsecurity.d/owasp-crs/rules/*.conf' >> /etc/modsecurity.d/include.conf \ - && sed -i /etc/modsecurity.d/modsecurity.conf \ - -e 's/SecRuleEngine DetectionOnly/SecRuleEngine On/g' - -COPY httpd-*.conf /usr/local/apache2/conf/extra/ -COPY modsecurity.conf /etc/modsecurity.d/ -COPY docker-entrypoint.sh / - -EXPOSE ${PORT} -EXPOSE 443 + && 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/src/httpd-logging-after-modsec.conf b/3.3-apache/conf/extra/httpd-logging-after-modsec.conf similarity index 100% rename from src/httpd-logging-after-modsec.conf rename to 3.3-apache/conf/extra/httpd-logging-after-modsec.conf diff --git a/src/httpd-logging-before-modsec.conf b/3.3-apache/conf/extra/httpd-logging-before-modsec.conf similarity index 100% rename from src/httpd-logging-before-modsec.conf rename to 3.3-apache/conf/extra/httpd-logging-before-modsec.conf diff --git a/3.3-apache/conf/extra/httpd-modsecurity.conf b/3.3-apache/conf/extra/httpd-modsecurity.conf new file mode 100644 index 00000000..936a96eb --- /dev/null +++ b/3.3-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.3-apache/docker-entrypoint.sh b/3.3-apache/docker-entrypoint.sh new file mode 100755 index 00000000..0d07e2d2 --- /dev/null +++ b/3.3-apache/docker-entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +source /opt/modsecurity/activate-rules.sh + +exec "$@" diff --git a/3.3-nginx/Dockerfile b/3.3-nginx/Dockerfile index f3ccd685..1676c951 100644 --- a/3.3-nginx/Dockerfile +++ b/3.3-nginx/Dockerfile @@ -5,7 +5,6 @@ LABEL maintainer="Chaim Sanders " ARG COMMIT=v3.3/dev ARG BRANCH=v3.3/dev ARG REPO=SpiderLabs/owasp-modsecurity-crs -ENV WEBSERVER=Nginx ENV PARANOIA=1 ENV ANOMALY_INBOUND=5 ENV ANOMALY_OUTBOUND=4 @@ -28,7 +27,8 @@ RUN apt-get update \ && sed -i /etc/modsecurity.d/modsecurity.conf \ -e 's/SecRuleEngine DetectionOnly/SecRuleEngine On/g' -COPY docker-entrypoint.sh / +COPY 3.3-nginx/docker-entrypoint.sh / +COPY src/opt/modsecurity/activate-rules.sh /opt/modsecurity/ EXPOSE 80 diff --git a/3.3-nginx/docker-entrypoint.sh b/3.3-nginx/docker-entrypoint.sh new file mode 100755 index 00000000..0d07e2d2 --- /dev/null +++ b/3.3-nginx/docker-entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +source /opt/modsecurity/activate-rules.sh + +exec "$@" diff --git a/README.md b/README.md index 05954eb7..5fe0032b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ or docker build -t owasp/modsecurity-crs . docker run -p 80:80 -ti -e PARANOIA=4 -e PROXY=1 --rm owasp/modsecurity-crs ``` + +## Apache +The Apache webserver is configured via the `httpd-modsecurity.conf` file overriding directives from the base file. + ## Environment Variables The following environment variables are available to configure the CRS container: @@ -51,7 +55,7 @@ The following environment variables are available to configure the CRS container | TOTAL_ARG_LENGTH | An integer indicating the total_arg_length (Default: unlimited) | | MAX_FILE_SIZE | An integer indicating the max_file_size (Default: unlimited) | | COMBINED_FILE_SIZES | An integer indicating the combined_file_sizes (Default: unlimited) | -| TIMEOUT | Apache integer value indicating the number of seconds before receiving and sending time out (Default: 60) | +| APACHE_TIMEOUT | Apache integer value indicating the number of seconds before receiving and sending time out (Default: 60) | | LOGLEVEL | Apache string value controlling the number of messages logged to the error_log, Apache (Default: warn) | | ERRORLOG | Apache string value indicating the location of the error log file (Default: '/proc/self/fd/2') | | PORT | Apache integer value indicating the port where Apache is listening to (Default: 80) | @@ -131,7 +135,7 @@ docker run -dti 80:80 --rm \ -e MAX_FILE_SIZE=100000 \ -e COMBINED_FILE_SIZES=1000000 \ -e PROXY=1 \ - -e TIMEOUT=60 \ + -e APACHE_TIMEOUT=60 \ -e LOGLEVEL=warn \ -e ERRORLOG='/proc/self/fd/2' \ -e USER=daemon \ diff --git a/src/etc/modsecurity.d/modsecurity-override.conf b/src/etc/modsecurity.d/modsecurity-override.conf new file mode 100644 index 00000000..9242a7c5 --- /dev/null +++ b/src/etc/modsecurity.d/modsecurity-override.conf @@ -0,0 +1,32 @@ +# Original of the latest recommended version: +# https://github.com/SpiderLabs/ModSecurity/blob/v3/master/modsecurity.conf-recommended + +SecRuleEngine ${MODSEC_RULE_ENGINE} +SecRequestBodyAccess ${MODSEC_REQ_BODY_ACCESS} + +SecRequestBodyLimit ${MODSEC_REQ_BODY_LIMIT} +SecRequestBodyNoFilesLimit ${MODSEC_REQ_BODY_NOFILES_LIMIT} +SecRequestBodyInMemoryLimit 131072 +SecRequestBodyLimitAction Reject + +SecPcreMatchLimit ${MODSEC_PCRE_MATCH_LIMIT} +SecPcreMatchLimitRecursion ${MODSEC_PCRE_MATCH_LIMIT_RECURSION} + +SecResponseBodyAccess ${MODSEC_RESP_BODY_ACCESS} +SecResponseBodyMimeType text/plain text/html text/xml +SecResponseBodyLimit ${MODSEC_RESP_BODY_LIMIT} +SecResponseBodyLimitAction ProcessPartial + +SecTmpDir /tmp/ +SecDataDir /tmp/ + +SecAuditEngine RelevantOnly +SecAuditLogRelevantStatus "^(?:5|4(?!04))" +SecAuditLogParts ABIJDEFHZ +SecAuditLogType Serial +SecAuditLog /var/log/modsec_audit.log + +SecArgumentSeparator & +SecCookieFormat 0 +SecUnicodeMapFile unicode.mapping 20127 +SecStatusEngine On diff --git a/src/etc/modsecurity.d/setup.conf b/src/etc/modsecurity.d/setup.conf new file mode 100644 index 00000000..1c530cba --- /dev/null +++ b/src/etc/modsecurity.d/setup.conf @@ -0,0 +1,8 @@ +# Allow custom rules to be specified in: +# /opt/modsecurity/rules/{before,after}-crs/*.conf + +Include /etc/modsecurity.d/modsecurity.conf +Include /etc/modsecurity.d/modsecurity-override.conf + +Include /etc/modsecurity.d/owasp-crs/crs-setup.conf +Include /etc/modsecurity.d/owasp-crs/rules/*.conf diff --git a/src/httpd-default.conf b/src/httpd-default.conf deleted file mode 100644 index 67421e7d..00000000 --- a/src/httpd-default.conf +++ /dev/null @@ -1,23 +0,0 @@ -Timeout ${TIMEOUT} -LogLevel ${LOGLEVEL} -ErrorLog ${ERRORLOG} -Listen ${PORT} -ServerAdmin ${SERVERADMIN} - - -User ${USER} -Group ${GROUP} - - -KeepAlive On -MaxKeepAliveRequests 100 -KeepAliveTimeout 5 -UseCanonicalName Off -AccessFileName .htaccess -ServerTokens Prod -ServerSignature Off -HostnameLookups Off - - - RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500 - diff --git a/src/modsecurity.conf b/src/modsecurity.conf deleted file mode 100644 index 20f14add..00000000 --- a/src/modsecurity.conf +++ /dev/null @@ -1,57 +0,0 @@ -# Recommended configuration https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended - -SecRuleEngine ${MODSEC_RULE_ENGINE} -SecRequestBodyAccess ${MODSEC_REQ_BODY_ACCESS} - -SecRequestBodyLimit ${MODSEC_REQ_BODY_LIMIT} -SecRequestBodyNoFilesLimit ${MODSEC_REQ_BODY_NOFILES_LIMIT} -SecRequestBodyInMemoryLimit 131072 -SecRequestBodyLimitAction Reject - -SecRule REQUEST_HEADERS:Content-Type "(?:application(?:/soap\+|/)|text/)xml" \ - "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" -SecRule REQUEST_HEADERS:Content-Type "application/json" \ - "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" -SecRule REQBODY_ERROR "!@eq 0" \ - "id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2" -SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \ - "id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'" -SecRule TX:/^MSC_/ "!@streq 0" \ - "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'" -SecRule MULTIPART_STRICT_ERROR "!@eq 0" \ - "id:'200003',phase:2,t:none,log,deny,status:400, \ - msg:'Multipart request body failed strict validation: \ - PE %{REQBODY_PROCESSOR_ERROR}, \ - BQ %{MULTIPART_BOUNDARY_QUOTED}, \ - BW %{MULTIPART_BOUNDARY_WHITESPACE}, \ - DB %{MULTIPART_DATA_BEFORE}, \ - DA %{MULTIPART_DATA_AFTER}, \ - HF %{MULTIPART_HEADER_FOLDING}, \ - LF %{MULTIPART_LF_LINE}, \ - SM %{MULTIPART_MISSING_SEMICOLON}, \ - IQ %{MULTIPART_INVALID_QUOTING}, \ - IP %{MULTIPART_INVALID_PART}, \ - IH %{MULTIPART_INVALID_HEADER_FOLDING}, \ - FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'" - -SecPcreMatchLimit ${MODSEC_PCRE_MATCH_LIMIT} -SecPcreMatchLimitRecursion ${MODSEC_PCRE_MATCH_LIMIT_RECURSION} - -SecResponseBodyAccess ${MODSEC_RESP_BODY_ACCESS} -SecResponseBodyMimeType text/plain text/html text/xml -SecResponseBodyLimit ${MODSEC_RESP_BODY_LIMIT} -SecResponseBodyLimitAction ProcessPartial - -SecTmpDir /tmp/ -SecDataDir /tmp/ - -SecAuditEngine RelevantOnly -SecAuditLogRelevantStatus "^(?:5|4(?!04))" -SecAuditLogParts ABIJDEFHZ -SecAuditLogType Serial -SecAuditLog /var/log/modsec_audit.log - -SecArgumentSeparator & -SecCookieFormat 0 -SecUnicodeMapFile unicode.mapping 20127 -SecStatusEngine On diff --git a/src/docker-entrypoint.sh b/src/opt/modsecurity/activate-rules.sh similarity index 94% rename from src/docker-entrypoint.sh rename to src/opt/modsecurity/activate-rules.sh index b4fd5c1a..ece53ab4 100755 --- a/src/docker-entrypoint.sh +++ b/src/opt/modsecurity/activate-rules.sh @@ -1,6 +1,4 @@ -#!/bin/bash - -set -e +#!/bin/bash -e # Paranoia Level sed -z -E -i 's/#SecAction.{7}id:900000.*tx\.paranoia_level=1\"/SecAction \\\n \"id:900000, \\\n phase:1, \\\n nolog, \\\n pass, \\\n t:none, \\\n setvar:tx.paranoia_level='"$PARANOIA"'\"/' /etc/modsecurity.d/owasp-crs/crs-setup.conf @@ -81,19 +79,4 @@ fi # Block request if the total size of all combined uploaded files is too high if [ -n "$COMBINED_FILE_SIZES" ]; then sed -z -E -i 's/#SecAction.{6}id:900350.*tx\.combined_file_sizes=1048576\"/SecAction \\\n \"id:900350, \\\n phase:1, \\\n nolog, \\\n pass, \\\n t:none, \\\n setvar:tx.combined_file_sizes='"$COMBINED_FILE_SIZES"'\"/' /etc/modsecurity.d/owasp-crs/crs-setup.conf -fi - -if [ "$WEBSERVER" = "Apache" ]; then - if [ "$PROXY" = "1" ]; then - WEBSERVER_ARGUMENTS='-D crs_proxy' - if [ -z "$UPSTREAM" ]; then - UPSTREAM="$(/sbin/ip route | grep ^default | perl -pe 's/^.*?via ([\d.]+).*/$1/g'):81" - export UPSTREAM - fi - fi -elif [ "$WEBSERVER" = "Nginx" ]; then - WEBSERVER_ARGUMENTS='' fi - - -exec "$@" $WEBSERVER_ARGUMENTS