Protecting Piler With A Waf
31 Mar 2024 - sj, tags: archiving, insights, news, product
If you use traefik for piler to provide a https certificate, then you are just minutes away to protect piler with a Web Application Firewall (WAF).
Assuming that you already have the above setup running, let extend it to have WAF protection against SQL injection, XSS and other attacks.
Run the WAF in a docker container
Create docker-compose.yaml with the following content:
services:
waf:
image: owasp/modsecurity-crs:nginx-alpine
container_name: waf
environment:
- PARANOIA=2
- ANOMALY_INBOUND=10
- ANOMALY_OUTBOUND=5
- BACKEND=http://dummy
ports:
- "127.0.0.1:8000:8080"
dummy:
image: traefik/whoami
container_name: dummy
Start the containers
docker compose up -d
Extend traefik.yaml
Add the following blocks to traefik.yaml
The modsecurity plugin
experimental:
plugins:
traefik-modsecurity-plugin:
moduleName: github.com/acouvreur/traefik-modsecurity-plugin
version: v1.3.0
Middleware to send request to the WAF for inspection
http:
middlewares:
waf:
plugin:
traefik-modsecurity-plugin:
modSecurityUrl: http://127.0.0.1:8000
maxBodySize: 10485760
Update the piler router to use the “waf” middleware as well
routers:
piler:
rule: "Host(`archive.example.com`)"
service: piler
middlewares:
- "piler_headers"
- "waf"
tls:
certResolver: le
Update /etc/systemd/system/traefik.service
You need to specify the WorkingDirectory
[Service]
WorkingDirectory=/usr/local/etc/traefik
Create the plugins-storage directory for traefik
mkdir /usr/local/etc/traefik/plugins-storage
chown www-data /usr/local/etc/traefik/plugins-storage
Reload systemd
systemctl daemon-reload
Restart the traefik service
systemctl restart traefik
Test the WAF
curl https://archive.example.com
The result looks fine:
<!DOCTYPE html>
<html lang="en" data-bs-theme="auto">
<head>
<title>Login</title>
<meta charset="utf-8" />
<meta name="robots" content="none" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="dark light">
...
Now let’s try an XSS attempt:
curl "https://archive.example.com/search?waf<script>alert(0)</script>"
The result is a HTTP/403 response, the WAF rejected our attempt:
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
You may check the WAF container’s log to see why it rejected the request.
Note that in the above example we run only the WAF containers in docker, however it’s possible to run all components (traefik, piler, etc) in containers.
For more details and examples visit https://github.com/jsuto/piler-examples/tree/master/examples/waf