add caddy waf docs

This commit is contained in:
2026-02-25 12:15:49 -05:00
parent f3c313e610
commit 416321206d
4 changed files with 137 additions and 37 deletions

View File

@@ -1,7 +1,9 @@
FROM docker.io/caddy:2-builder AS builder FROM docker.io/caddy:2-builder AS builder
RUN xcaddy build \ RUN xcaddy build \
--with github.com/caddy-dns/route53@v1.6.0 --with github.com/caddy-dns/route53@v1.6.0 \
--with github.com/fabriziosalmi/caddy-waf
FROM docker.io/caddy:2 FROM docker.io/caddy:2

View File

@@ -6,6 +6,8 @@
- [Ansible](#ansible) - [Ansible](#ansible)
- [Manual](#manual) - [Manual](#manual)
- [Adding a new Caddy Record](#adding-a-new-caddy-record) - [Adding a new Caddy Record](#adding-a-new-caddy-record)
- [Logs](#logs)
- [Caddy WAF](#caddy-waf)
## Custom Caddy Image ## Custom Caddy Image
@@ -138,3 +140,66 @@ ddns service:
1. Update the [ddns caddy records](/active/container_ddns/secrets/caddy_records.yaml) 1. Update the [ddns caddy records](/active/container_ddns/secrets/caddy_records.yaml)
2. (Optional) Update the Caddyfile at `active/container_caddy/secrets/Caddyfile` 2. (Optional) Update the Caddyfile at `active/container_caddy/secrets/Caddyfile`
3. Run the [caddy ansible playbook](/active/container_caddy/caddy.md#install-caddy) 3. Run the [caddy ansible playbook](/active/container_caddy/caddy.md#install-caddy)
## Logs
```bash
# Follow remote connections
podman logs -f caddy | grep -e '^{' | jq -c '.request | {remote_ip,host}'
# Filter out noisy hosts
podman logs -f caddy | grep -e '^{' | jq -c '.request | {remote_ip,host} | select(.host != "gitea.reeseapps.com")'
# Focus on user agents
podman logs -f caddy | grep -e '^{' | jq -c '
{
"User-Agent": .request.headers["User-Agent"],
remote_ip: .request.remote_ip,
host: .request.host,
status: .status
}
'
```
## Caddy WAF
<https://github.com/fabriziosalmi/caddy-waf>
1. Copy the rules.json to `/etc/caddy/rules.json`
2. Update the Caddyfile to something like this:
```Caddyfile
gitea.reeseapps.com:443 {
log {
output stdout
format json {
message_key msg # Key for the log message
level_key severity # Key for the log level
time_key timestamp # Key for the timestamp
name_key logger # Key for the logger name
caller_key function # Key for the caller information
stacktrace_key stack # Key for error stacktraces
time_format "2006-01-02 15:04:05 MST" # RFC3339-like format
time_local # Use local timezone
duration_format "ms" # Show durations in milliseconds
level_format "upper" # Uppercase log levels
}
}
route {
waf {
metrics_endpoint /waf_metrics
rule_file rules.json
}
@wafmetrics {
path /waf_metrics
}
handle @wafmetrics { } # empty → let the WAF serve the metrics
handle {
reverse_proxy gitea.reeselink.com:3000
}
}
}
```

View File

@@ -7,7 +7,7 @@
dest: /etc/caddy/Containerfile dest: /etc/caddy/Containerfile
owner: root owner: root
group: root group: root
mode: '0644' mode: "0644"
- name: Build Caddy Image - name: Build Caddy Image
shell: shell:
cmd: podman build -t gitea.reeseapps.com/services/caddy:latest -f /etc/caddy/Containerfile cmd: podman build -t gitea.reeseapps.com/services/caddy:latest -f /etc/caddy/Containerfile
@@ -15,21 +15,28 @@
ansible.builtin.file: ansible.builtin.file:
path: /etc/caddy path: /etc/caddy
state: directory state: directory
mode: '0755' mode: "0755"
- name: Copy Caddyfile - name: Copy Caddyfile
template: template:
src: secrets/proxy.Caddyfile src: secrets/proxy.Caddyfile
dest: /etc/caddy/Caddyfile dest: /etc/caddy/Caddyfile
owner: root owner: root
group: root group: root
mode: '0644' mode: "0644"
- name: Copy rules.json
template:
src: rules.json
dest: /etc/caddy/rules.json
owner: root
group: root
mode: "0644"
- name: Template Caddy Container Services - name: Template Caddy Container Services
template: template:
src: caddy.container src: caddy.container
dest: /etc/containers/systemd/caddy.container dest: /etc/containers/systemd/caddy.container
owner: root owner: root
group: root group: root
mode: '0644' mode: "0644"
- name: Reload and start the Caddy service - name: Reload and start the Caddy service
ansible.builtin.systemd_service: ansible.builtin.systemd_service:
state: restarted state: restarted

View File

@@ -0,0 +1,26 @@
[
{
"id": "block-scanners",
"phase": 1,
"pattern": "(?i)(nikto|sqlmap|nmap|acunetix|nessus|openvas|wpscan|dirbuster|burpsuite|owasp zap|netsparker|appscan|arachni|skipfish|gobuster|wfuzz|hydra|metasploit|nessus|openvas|qualys|zap|w3af|openwebspider|netsparker|appspider|rapid7|nessus|qualys|nuclei|zgrab|vega|gospider|gxspider|whatweb|xspider|joomscan|uniscan|blindelephant)",
"targets": [
"HEADERS:User-Agent"
],
"severity": "CRITICAL",
"action": "block",
"score": 10,
"description": "Block traffic from known vulnerability scanners and penetration testing tools. Includes more scanners."
},
{
"id": "block-crawlers",
"phase": 1,
"pattern": "(meta-externalagent)",
"targets": [
"HEADERS:User-Agent"
],
"severity": "CRITICAL",
"action": "block",
"score": 10,
"description": "Block traffic from web scrapers and crawlers."
}
]