Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 68 additions & 5 deletions .github/workflows/verifyimage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,90 @@ jobs:
README.md \
"${{ matrix.target }}.env"
echo "Starting container ${{ matrix.target }}-verification"
# The backend is a dummy
docker run \
--pull "never" \
-d \
--name ${{ matrix.target }}-test \
--env-file "${{ matrix.target }}.env" \
-p 8080:8080 \
-e BACKEND=http://localhost:9999 \
"${{ matrix.target }}-verification"
sleep 30
docker logs ${{ matrix.target }}-test

- name: Verify ${{ matrix.target }}
run: |
[ $(docker inspect ${{ matrix.target }}-test --format='{{.State.Running}}') = 'true' ]
if grep -q "nginx "<<< "${{ matrix.target }}"; then
curl -q -D headers.txt http://localhost:8080/?test=../../etc/passwd
HOST_AND_PORT="localhost:8080"
counter=10
while true; do
printf "Checking whether container is running..."
if [ $(docker inspect ${{ matrix.target }}-test --format='{{.State.Running}}') = 'true' ]; then
echo "ok"
printf "Trying to connect..."
if curl -s --connect-timeout 5 --max-time 1 "${HOST_AND_PORT}" > /dev/null 2>&1; then
echo "ok"
break
fi
fi

echo "failed"
((counter--))
if [ ${counter} -gt 0 ]; then
echo "Will retry in 5 seconds"
sleep 5
else
printf "No more retries. Here'se the log output from the container\n\n\n"
Comment thread
theseion marked this conversation as resolved.
Outdated
docker logs ${{ matrix.target }}-test
exit 1
fi
done

if grep -q "nginx"<<< "${{ matrix.target }}"; then
printf "\n\n### nginx tests ###\n\n"

printf "Storing headers for sample attack..."
curl -s -D headers.txt -o /dev/null "${HOST_AND_PORT}/?test=../../etc/passwd"
printf "...done\n\n\n"

printf "Check status 403..."
grep -q "HTTP/1.1 403 Forbidden" headers.txt
printf "yes\n\n\n"

printf "Check 'Access-Control-Allow-Origin' header..."
grep -q "Access-Control-Allow-Origin: *" headers.txt
printf "yes\n\n\n"

printf "Check 'Access-Control-Max-Age' header..."
grep -q "Access-Control-Max-Age: 3600" headers.txt
printf "yes\n\n\n"

printf "Check 'Access-Control-Allow-Methods' header..."
grep -q "Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS" headers.txt
printf "yes\n\n\n"

printf "Check 'Access-Control-Allow-Headers'..."
grep -q "Access-Control-Allow-Headers: *" headers.txt
printf "yes\n\n\n"

echo "### nginx tests - done ###"
fi

printf "\n\n### generic tests ###\n\n"

echo "Test HTTP/2 upgrade..."
curl -v --http2 --no-progress-meter -o /dev/null "${HOST_AND_PORT}" 2>&1 | tee out.txt
grep -iP "< 101 Switching Protocols|< HTTP/2" < out.txt | tee out2.txt
wc -l out2.txt | grep -qoP "\d+" | xargs -I % test % -eq 2
rm out*.txt
printf "...yes\n\n\n"

echo "Test HTTP/2 prior knowledge..."
curl -v --http2-prior-knowledge --no-progress-meter -o /dev/null "${HOST_AND_PORT}" 2>&1 | tee out.txt
grep -iq "< HTTP/2" out.txt
grep -iqv "< 101 Switching Protocols" out.txt
printf "...yes\n\n\n"

echo "### generic tests - done ###"

- name: Checkout CRS
uses: actions/checkout@v4
with:
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ These variables are common to image variants and will set defaults based on the
| APACHE_LOGFORMAT | A string value indicating the LogFormat that apache should use. (Default: `'"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""'` (combined). Tip: use single quotes outside your double quoted format string.) ⚠️ Do not add a `|` as part of the log format. It is used internally. |
| APACHE_METRICS_LOGFORMAT | A string value indicating the LogFormat that the additional log apache metrics should use. (Default:'"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""' (combined). Tip: use single quotes outside your double quoted format string.) ⚠️ Do not add a `|` as part of the log format. It is used internally. |
| BACKEND_WS | A string indicating the IP/URL of the WebSocket service (Default: `ws://localhost:8081`) |
| H2_PROTOCOLS | A string value indicating the protocols supported by the HTTP2 module (Default: `h2 http/1.1`) |
| H2_DIRECT | A string indicating whether unencrypted HTTP/2 connections are allowed without upgrading from HTTP/1.1. This mode is also called "prior knowledge. (Allowed values: `on`, `off`. Default: `on`) |
| H2_PROTOCOLS | A string value indicating the protocols supported by the HTTP/2 module (Default: `h2 h2c http/1.1`) |
| MUTEX | Configure mutex and lock file directory for all specified mutexes (see [Mutex](https://httpd.apache.org/docs/2.4/mod/core.html#mutex)) (Default: `default`) |
| PORT | An int value indicating the port where the webserver is listening to | `8080` | - |
| PROXY_ERROR_OVERRIDE | A string indicating that errors from the backend services should be overridden by this proxy server (see [ProxyErrorOverride](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxyerroroverride) directive). (Allowed values: `on`, `off`. Default: `on`) |
Expand Down Expand Up @@ -215,6 +216,7 @@ These variables are common to image variants and will set defaults based on the
| CORS_HEADER_403_CONTENT_TYPE | The value of the `Content-Type` header for `403` responses. Default: (`"text/plain"`) |
| CORS_HEADER_403_MAX_AGE | The value of the [Access-Control-Max-Age](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age) header for `403` responses. The number of seconds that preflight requests for this resource may be cached by the browser. (Default: `3600`) |
| DNS_SERVER | Deprecated. Use `RESOLVERS`.
| HTTP2 | A string value indicating whether HTTP/2 should be enabled (for all locations) (Allowed values: `on`, `off`. Default: `on`) |
| KEEPALIVE_TIMEOUT | Number of seconds for a keep-alive client connection to stay open on the server side (Default: `60s`) |
| NGINX_ALWAYS_TLS_REDIRECT | A string value indicating if http should redirect to https (Allowed values: `on`, `off`. Default: `off`) |
| PORT | An int value indicating the port where the webserver is listening to | `8080` | We run as unprivileged user. |
Expand Down
5 changes: 3 additions & 2 deletions apache/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ ENV \
APACHE_ERRORLOG_FORMAT='"[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"' \
APACHE_LOGFORMAT='"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""' \
APACHE_METRICS_LOGFORMAT='"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""' \
BACKEND=http://localhost:8080 \
BACKEND=http://localhost:80 \
BACKEND_WS=ws://localhost:8081 \
ERRORLOG='/proc/self/fd/2' \
H2_PROTOCOLS='h2 http/1.1' \
H2_DIRECT=on \
H2_PROTOCOLS='h2 h2c http/1.1' \
LOGLEVEL=warn \
METRICS_ALLOW_FROM='127.0.0.0/255.0.0.0 ::1/128' \
METRICS_DENY_FROM='All' \
Expand Down
3 changes: 2 additions & 1 deletion apache/Dockerfile-alpine
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ ENV \
BACKEND=http://localhost:8080 \
BACKEND_WS=ws://localhost:8081 \
ERRORLOG='/proc/self/fd/2' \
H2_PROTOCOLS='h2 http/1.1' \
H2_DIRECT=on \
H2_PROTOCOLS='h2 h2c http/1.1' \
LOGLEVEL=warn \
METRICS_ALLOW_FROM='127.0.0.0/255.0.0.0 ::1/128' \
METRICS_DENY_FROM='All' \
Expand Down
11 changes: 7 additions & 4 deletions apache/conf/extra/httpd-vhosts.conf
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ SSLProxyCACertificateFile ${PROXY_SSL_CA_CERT}
UseCanonicalName on

<VirtualHost *:${PORT}>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteCond %{ENV:APACHE_ALWAYS_TLS_REDIRECT} on
RewriteRule ^(.*)$ https://%{SERVER_NAME}:${SSL_PORT}$1 [L,R=301]
Protocols ${H2_PROTOCOLS}
H2Direct ${H2_DIRECT}
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteCond %{ENV:APACHE_ALWAYS_TLS_REDIRECT} on
RewriteRule ^(.*)$ https://%{SERVER_NAME}:${SSL_PORT}$1 [L,R=301]
</VirtualHost>

<VirtualHost *:${SSL_PORT}>
Protocols ${H2_PROTOCOLS}
H2Direct ${H2_DIRECT}
SSLEngine ${SSL_ENGINE}
SSLCertificateFile ${SSL_CERT}
SSLCertificateKeyFile ${SSL_CERT_KEY}
Expand Down
28 changes: 2 additions & 26 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
# This docker-compose file starts owasp/modsecurity-crs
#
# ATTENTION!
# Some of the environment variables at the bottom of this
# docker-compose.yaml file and TLS are only available
# for self-built images based on Dockerfile-2.9-apache,
# and only if build args SETTLS and SETPROXY were set during
# the build of the parent owasp/modsecurity:2.9-apache image.

x-defaults: &default-settings
environment:
SERVERNAME: localhost
Expand All @@ -29,18 +21,6 @@ x-defaults: &default-settings
# New in CRS 4
REPORTING_LEVEL: 2

#######################################################
# Reverse Proxy mode
# (only available if SETPROXY was enabled during the
# parent ModSecurity image)
#######################################################
# PROXYLOCATION: Application Backend of Reverse Proxy
# PROXYLOCATION: http://app:8000/
#
# If needed: add own httpd-proxy.conf (only available if SETPROXY
# was enabled during build of parent ModSecurity image)
# - ./httpd-proxy.conf:/usr/local/apache2/conf/extra/httpd-proxy.conf

#######################################################
# Various CRS Variables with Default Values
#######################################################
Expand Down Expand Up @@ -73,8 +53,6 @@ x-defaults: &default-settings

#######################################################
# Add TLS server certificate and key
# (only available if SETPROXY was enabled during the
# parent ModSecurity image)
#######################################################
# - ./server.crt:/usr/local/apache2/conf/server.crt
# - ./server.key:/usr/local/apache2/conf/server.key
Expand All @@ -83,15 +61,13 @@ services:
crs-apache:
image: owasp/modsecurity-crs:apache
ports:
- "80:8080"
# only available if SETTLS was enabled:
- "8080:8080"
- "443:8443"
<<: *default-settings

crs-nginx:
image: owasp/modsecurity-crs:nginx
ports:
- "80:8080"
# only available if SETTLS was enabled:
- "8080:8080"
- "443:8443"
<<: *default-settings
1 change: 1 addition & 0 deletions nginx/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ ENV \
CORS_HEADER_403_MAX_AGE=3600 \
CORS_HEADER_ACCESS_CONTROL_ALLOW_HEADERS="*" \
ERRORLOG=/var/log/nginx/error.log \
HTTP2=on \
KEEPALIVE_TIMEOUT=60s \
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib \
LOGLEVEL=warn \
Expand Down
1 change: 1 addition & 0 deletions nginx/Dockerfile-alpine
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ ENV \
CORS_HEADER_403_MAX_AGE=3600 \
CORS_HEADER_ACCESS_CONTROL_ALLOW_HEADERS="*" \
ERRORLOG=/var/log/nginx/error.log \
HTTP2=on \
KEEPALIVE_TIMEOUT=60s \
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib \
LOGLEVEL=warn \
Expand Down
1 change: 1 addition & 0 deletions nginx/templates/nginx.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ http {
default_type application/octet-stream;
keepalive_timeout ${KEEPALIVE_TIMEOUT};
sendfile on;
http2 ${HTTP2};

resolver RESOLVERS RESOLVER_CONFIG;
include /etc/nginx/conf.d/*.conf;
Expand Down
Loading