add caddy waf docs
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
FROM docker.io/caddy:2-builder AS builder
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
- [Ansible](#ansible)
|
||||
- [Manual](#manual)
|
||||
- [Adding a new Caddy Record](#adding-a-new-caddy-record)
|
||||
- [Logs](#logs)
|
||||
- [Caddy WAF](#caddy-waf)
|
||||
|
||||
## Custom Caddy Image
|
||||
|
||||
@@ -137,4 +139,67 @@ ddns service:
|
||||
|
||||
1. Update the [ddns caddy records](/active/container_ddns/secrets/caddy_records.yaml)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,38 +1,45 @@
|
||||
- name: Create Caddy Proxy
|
||||
hosts: caddy
|
||||
tasks:
|
||||
- name: Copy Containerfile for build
|
||||
template:
|
||||
src: Containerfile
|
||||
dest: /etc/caddy/Containerfile
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
- name: Build Caddy Image
|
||||
shell:
|
||||
cmd: podman build -t gitea.reeseapps.com/services/caddy:latest -f /etc/caddy/Containerfile
|
||||
- name: Create /etc/caddy dir
|
||||
ansible.builtin.file:
|
||||
path: /etc/caddy
|
||||
state: directory
|
||||
mode: '0755'
|
||||
- name: Copy Caddyfile
|
||||
template:
|
||||
src: secrets/proxy.Caddyfile
|
||||
dest: /etc/caddy/Caddyfile
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
- name: Template Caddy Container Services
|
||||
template:
|
||||
src: caddy.container
|
||||
dest: /etc/containers/systemd/caddy.container
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
- name: Reload and start the Caddy service
|
||||
ansible.builtin.systemd_service:
|
||||
state: restarted
|
||||
name: caddy.service
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
- name: Copy Containerfile for build
|
||||
template:
|
||||
src: Containerfile
|
||||
dest: /etc/caddy/Containerfile
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
- name: Build Caddy Image
|
||||
shell:
|
||||
cmd: podman build -t gitea.reeseapps.com/services/caddy:latest -f /etc/caddy/Containerfile
|
||||
- name: Create /etc/caddy dir
|
||||
ansible.builtin.file:
|
||||
path: /etc/caddy
|
||||
state: directory
|
||||
mode: "0755"
|
||||
- name: Copy Caddyfile
|
||||
template:
|
||||
src: secrets/proxy.Caddyfile
|
||||
dest: /etc/caddy/Caddyfile
|
||||
owner: root
|
||||
group: root
|
||||
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
|
||||
template:
|
||||
src: caddy.container
|
||||
dest: /etc/containers/systemd/caddy.container
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
- name: Reload and start the Caddy service
|
||||
ansible.builtin.systemd_service:
|
||||
state: restarted
|
||||
name: caddy.service
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
|
||||
26
active/container_caddy/rules.json
Normal file
26
active/container_caddy/rules.json
Normal 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."
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user