2026-01-21 15:29:56 +03:00
|
|
|
# BYOW - Build Your Own WAF
|
|
|
|
|
|
|
|
|
|
A WAF _à la carte_.
|
2026-01-07 14:27:55 +03:00
|
|
|
|
|
|
|
|
Ce rôle Ansible déploie un WAF basé sur Caddy, Coraza et les OWASP Core Security Rules.
|
|
|
|
|
|
|
|
|
|
## Principes
|
|
|
|
|
|
|
|
|
|
### Go
|
|
|
|
|
|
|
|
|
|
Caddy, Coraza, le module Coraza pour Caddy et l'outil `xcaddy` sont
|
|
|
|
|
développés avec le langage Go.
|
|
|
|
|
|
|
|
|
|
L'outil `xcaddy` a besoin d'une version récente des outils de
|
|
|
|
|
développement Go. C'est pourquoi le rôle installe Go depuis
|
|
|
|
|
le site de téléchargement officiel et non via le gestionnaire
|
|
|
|
|
de paquets de la distribution Linux.
|
|
|
|
|
|
|
|
|
|
Go est installé dans le répertoire `/usr/local/go-1.25.5/go` et
|
|
|
|
|
un lien symbolique est créé de `/usr/local/bin/go` vers
|
|
|
|
|
`/usr/local/go-1.25.5/go/bin/go`.
|
|
|
|
|
|
|
|
|
|
### Caddy
|
|
|
|
|
|
|
|
|
|
Caddy est un serveur Web et reverse proxy HTTP puissant et versatile.
|
|
|
|
|
|
|
|
|
|
Étant développé en Go, son déploiement prend la forme d'un simble
|
|
|
|
|
binaire exécutable qui contient toutes les librairies requises. Ce
|
|
|
|
|
programme est construit avec l'outil `xcaddy` puis copié dans le
|
|
|
|
|
fichier `/usr/local/bin/caddy`. La ligne de commande utilisée pour
|
|
|
|
|
construire ce binaire est enregsitrée dans le fichier
|
|
|
|
|
`/usr/local/bin/.caddy.buil`.
|
|
|
|
|
|
|
|
|
|
Le fichier de configuration de caddy utilise le format `Caddyfile`.
|
|
|
|
|
Il est généré automatiquement à partir des paramètres du rôle puis
|
|
|
|
|
enregistré sous `/etc/caddy/Caddyfile`.
|
|
|
|
|
|
|
|
|
|
### Coraza
|
|
|
|
|
|
|
|
|
|
Coraza est directement inclus dans le binaire `caddy`
|
|
|
|
|
|
|
|
|
|
### Module Coraza pour Caddy
|
|
|
|
|
|
|
|
|
|
### xcaddy
|
|
|
|
|
|
|
|
|
|
qui permet de lier tous les modules Go requis
|
|
|
|
|
pour le WAF
|
|
|
|
|
|
|
|
|
|
### Plugins OWASP CRS
|
|
|
|
|
|
|
|
|
|
(À ne pas confondre avec les plugins Coraza.)
|
|
|
|
|
|
|
|
|
|
Voir: https://github.com/coreruleset/plugin-registry
|
|
|
|
|
|
|
|
|
|
- name: "drupal-rule-exclusions"
|
|
|
|
|
- name: "wordpress-rule-exclusions"
|
|
|
|
|
- name: "nextcloud-rule-exclusions"
|
|
|
|
|
- name: "dokuwiki-rule-exclusions"
|
|
|
|
|
- name: "phpmyadmin-rule-exclusions"
|
|
|
|
|
- name: "roundcube-rule-exclusions"
|
|
|
|
|
- name: "sogo-rule-exclusions"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Paramètres du rôle Ansible
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## TODO
|
|
|
|
|
|
|
|
|
|
Fonctionnalités déjà implémentées:
|
|
|
|
|
|
2026-02-02 22:07:56 +03:00
|
|
|
- Déploiement et configuration avec une collection Ansible
|
2026-01-21 15:29:56 +03:00
|
|
|
- Serveurs transient
|
|
|
|
|
- VIP (avec Keepalived)
|
|
|
|
|
- DNS dynamique (via Nomad)
|
|
|
|
|
- Cluster via Nomad
|
2026-01-07 14:27:55 +03:00
|
|
|
- OWASP CRS
|
2026-01-21 15:29:56 +03:00
|
|
|
- Multisite (avec configuration complète des CRS par site)
|
|
|
|
|
- Alias avec redirection optionnelle vers nom canonique
|
|
|
|
|
- Redirection HTTP vers HTTPS
|
|
|
|
|
- Certificats SSL (personnalisés automatiques via Let's Encrypt)
|
|
|
|
|
- Filtrage (blacklists) par:
|
2026-01-07 14:27:55 +03:00
|
|
|
- adresses IP
|
|
|
|
|
- réseaux IP
|
|
|
|
|
- Antibot par:
|
|
|
|
|
- défi JavaScript
|
|
|
|
|
- Passive backend checks
|
2026-01-21 15:29:56 +03:00
|
|
|
- Compression Gzip et zstd
|
|
|
|
|
- Mode détection sans blocage par les CRS
|
|
|
|
|
- Filtrage par:
|
|
|
|
|
- méthode HTTP
|
2026-01-23 17:47:28 +03:00
|
|
|
- pays
|
|
|
|
|
- ASN
|
2026-01-21 15:29:56 +03:00
|
|
|
- En-têtes de sécurité:
|
|
|
|
|
- HSTS
|
|
|
|
|
- CSP
|
|
|
|
|
- X-Frame-Options
|
|
|
|
|
- X-Content-Type-Options
|
|
|
|
|
- Referrer Policy
|
|
|
|
|
- Permissions Policy
|
|
|
|
|
- Keep Headers
|
|
|
|
|
- Cookie Flags
|
|
|
|
|
- Custom headers
|
|
|
|
|
- suppression d'en-têtes
|
|
|
|
|
- Collecte des logs via OVH LDP
|
2026-01-23 11:21:21 +03:00
|
|
|
- Whitelist
|
|
|
|
|
- Static files et FastCGI pour PHP (NON, par design !)
|
2026-02-05 09:54:03 +03:00
|
|
|
- Authorizations (NON, par design !)
|
2026-02-02 22:07:56 +03:00
|
|
|
- Rate limit (non distribué)
|
2026-02-02 22:12:46 +03:00
|
|
|
- CORS
|
2026-01-21 15:29:56 +03:00
|
|
|
|
|
|
|
|
Urgemment:
|
2026-01-07 14:27:55 +03:00
|
|
|
|
2026-01-21 15:29:56 +03:00
|
|
|
- Connexion à consul, ACL consul
|
2026-01-07 14:27:55 +03:00
|
|
|
|
2026-02-02 22:07:56 +03:00
|
|
|
Fonctionnalités à ajouter:
|
2026-01-07 14:27:55 +03:00
|
|
|
|
2026-02-05 09:54:03 +03:00
|
|
|
- option "api: true" for activating API default settings
|
2026-01-21 15:29:56 +03:00
|
|
|
- Rate limiting distribué
|
2026-02-05 09:54:03 +03:00
|
|
|
- Antivirus
|
2026-01-07 14:27:55 +03:00
|
|
|
- Antibot par:
|
|
|
|
|
- Cookie
|
|
|
|
|
- Captcha
|
|
|
|
|
- reCAPTCHA
|
|
|
|
|
- hCaptcha
|
|
|
|
|
- Turnstile
|
|
|
|
|
- mCaptcha
|
|
|
|
|
- Filtrage par:
|
|
|
|
|
- rDNS
|
|
|
|
|
- DNSBL
|
|
|
|
|
- User-Agent (robots, crawlers, IA bots)
|
|
|
|
|
- taille
|
|
|
|
|
- URI patterns
|
2026-01-23 17:47:28 +03:00
|
|
|
- (ip:danmeuk-tor-exit, ua:mitchellkrogza-bad-user-agents)
|
2026-01-07 14:27:55 +03:00
|
|
|
- Client cache
|
|
|
|
|
- Proxy cache
|
2026-02-05 09:54:03 +03:00
|
|
|
- Random WAF signatures
|
2026-01-07 14:27:55 +03:00
|
|
|
- Compression Brotli
|
|
|
|
|
- Reverse scan
|
|
|
|
|
- Robots.txt (DarkVisitors API/Community Lists/Custom URLs/Manual Rules)
|
2026-01-21 15:29:56 +03:00
|
|
|
- Gestion des sessions
|
|
|
|
|
- Bad behavior (via Caddy events ?)
|
|
|
|
|
- Authentification
|
2026-02-05 09:54:03 +03:00
|
|
|
- cf. https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
|
|
|
|
|
- avec vérification force du mot de passe (cf. CdC Essor)
|
|
|
|
|
- avec test mot de passe moins un caractère
|
|
|
|
|
- avec test mot de passe comprommis
|
2026-01-21 15:29:56 +03:00
|
|
|
- Anti DDoS
|
2026-01-07 14:27:55 +03:00
|
|
|
- Greylist
|
2026-02-05 09:54:03 +03:00
|
|
|
- HTML Sanitization
|
2026-01-07 14:27:55 +03:00
|
|
|
- HTML injection
|
|
|
|
|
- Metrics (Elasticsearch + Metabase)
|
2026-01-21 15:29:56 +03:00
|
|
|
- Crowdsec
|
2026-02-05 09:54:03 +03:00
|
|
|
- Stream support
|
2026-01-23 17:47:28 +03:00
|
|
|
- Caddy as internal CA
|
2026-01-21 15:29:56 +03:00
|
|
|
- https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list
|
2026-01-07 14:27:55 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
## Ressources
|
|
|
|
|
|
|
|
|
|
- [Documentation officielle Caddy](https://caddyserver.com/docs/)
|
|
|
|
|
- [Site Officiel de Coraza](https://coraza.io)
|
|
|
|
|
- [Coraza WAF Caddy module](https://github.com/corazawaf/coraza-caddy)
|
|
|
|
|
- [Documentation AWOSP CRS](https://coreruleset.org/docs/)
|
2026-01-21 15:29:56 +03:00
|
|
|
- https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-(v3.x)
|
2026-01-07 14:27:55 +03:00
|
|
|
|
2026-02-05 09:54:03 +03:00
|
|
|
- (1) https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html
|
|
|
|
|
- (2) https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Cookie_Theft_Mitigation_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Credential_Stuffing_Prevention_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html
|
|
|
|
|
- https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html
|
|
|
|
|
|
2026-01-21 15:29:56 +03:00
|
|
|
|
|
|
|
|
### Installation d'Ansible avec pipx
|
|
|
|
|
|
|
|
|
|
1. Désinstaller *Ansible* et *ansible-lint* s'ils sont déjà installés. Par
|
|
|
|
|
exemple avec *Homebrew*:
|
|
|
|
|
```
|
|
|
|
|
brew uninstall ansible ansible-lint
|
|
|
|
|
```
|
|
|
|
|
1. Installer *pipx*. Par exemple avec *Homebrew*:
|
|
|
|
|
```
|
|
|
|
|
brew install pipx
|
|
|
|
|
```
|
|
|
|
|
1. Inscrire le chemin de recherche des exécutables de *pipx* dans les
|
|
|
|
|
scripts d'ouverture de session (fermer le shell et en ouvrir un nouveau
|
|
|
|
|
pour activer ce chemin de recherche):
|
|
|
|
|
```
|
|
|
|
|
pipx ensurepath
|
|
|
|
|
```
|
|
|
|
|
1. Installer *Ansible* (version 12, et au moins version core 2.16.9, pour
|
|
|
|
|
être compatible avec *Mitogen*) dans un environnement isolé (qui sera
|
|
|
|
|
nommé `ansible`) puis injecter *ansible-lint* et les librairies requises
|
|
|
|
|
dans cet environnement:
|
|
|
|
|
```
|
|
|
|
|
pipx install ansible==12.3.0 --include-deps
|
|
|
|
|
pipx inject ansible ansible-lint --include-apps
|
|
|
|
|
pipx inject ansible requests
|
|
|
|
|
pipx inject ansible pip-system-certs
|
|
|
|
|
pipx inject ansible passlib # pour |password_hash sur macOS (et autres)
|
|
|
|
|
pipx inject ansible jmespath # pour |query_result
|
|
|
|
|
pipx inject ansible pytz # pour plugin inventory auto
|
|
|
|
|
pipx inject ansible mitogen # optionnel, pour utiliser Mitogen
|
|
|
|
|
```
|
|
|
|
|
1. Vérifier l'environnement:
|
|
|
|
|
```
|
|
|
|
|
pipx list --include-injected
|
|
|
|
|
ansible --version -> ansible [core 2.19.5]
|
|
|
|
|
ansible-lint --version -> ansible-lint 26.1.1
|
|
|
|
|
```
|