Private
Public Access
2
0
This commit is contained in:
2026-01-14 11:03:59 +03:00
parent de92065d22
commit 562f9511db
43 changed files with 619 additions and 422 deletions

1
ansible/roles/waf_install/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/docs/

View File

@@ -0,0 +1,146 @@
# Web Application Firewall
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:
- Multisite (cavec configuration des CRS par site)
- Redirection vers nom canonique
- Rediction HTTP vers HTTPS
- Certificats SSL (autmotiques via Let's Encrypt et customs)
- OWASP CRS
- Redirect (SSL et www et autres)
- Filtrage par:
- adresses IP
- réseaux IP
- Antibot par:
- défi JavaScript
- Passive backend checks
- Compression Gzip et zstd
Fomctionnalités à ajouter:
- Active backend checks
- Antibot par:
- Cookie
- Captcha
- reCAPTCHA
- hCaptcha
- Turnstile
- mCaptcha
- Changement de format de configuration: Caddyfile -> JSON
- Mise en œuvre d'un cluster Redis (ou Consul) pour le partage de informations entre les WAF d'un cluster
- Mieux tester le configuration des CRS
- Mode détection sans blocage
- Filtrage par:
- rDNS
- DNSBL
- ASN
- User-Agent (robots, crawlers, IA bots)
- méthode HTTP
- taille
- URI patterns
- pays
- (ip:danmeuk-tor-exit, ua:mitchellkrogza-bad-user-agents, /etc/hapee-1.9/blacklist.acl)
- Gestion CORS
- Client cache
- Proxy cache
- Filtrage par pays
- Compression Brotli
- 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
- Reverse scan
- Robots.txt (DarkVisitors API/Community Lists/Custom URLs/Manual Rules)
- Sessions
- Whitelist
- Bad behavior
- Auth
- Anti DoDS
- Greylist
- HTML injection
- Metrics (Elasticsearch + Metabase)
- Static files et FastCGI pour PHP
## 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/)
Modules
- []()
- []()

View File

@@ -0,0 +1,27 @@
waf_install_go_version: "1.25.5"
waf_install_xcaddy_version: "0.4.5"
waf_install_caddy_version: "2.10.2"
waf_install_coraza_caddy_version: "2.1.0" # Coraza v3.3.3
waf_install_owasp_crs_version: "4.21.0"
# Cluster mode (e.g. with consul)
waf_install_cluster: false
# Cf.: https://github.com/coreruleset/plugin-registry
waf_install_crs_plugins:
- name: "drupal-rule-exclusions"
version: "1.0.0"
- name: "wordpress-rule-exclusions"
version: "1.2.0"
- name: "nextcloud-rule-exclusions"
version: "1.5.0"
- name: "dokuwiki-rule-exclusions"
version: "1.0.0"
- name: "phpmyadmin-rule-exclusions"
version: "1.0.0"
- name: "roundcube-rule-exclusions"
version: "1.0.4"
provider: "EsadCetiner"
- name: "sogo-rule-exclusions"
version: "1.0.4"
provider: "EsadCetiner"

View File

@@ -0,0 +1,5 @@
- name: Restart Caddy
ansible.builtin.service:
name: "caddy"
state: "restarted"
daemon_reload: true

View File

@@ -0,0 +1,47 @@
- name: Download plugin {{ plugin.name }}
ansible.builtin.get_url:
url: "https://github.com/{{ plugin.provider | default('coreruleset') }}/{{ plugin.name }}-plugin/archive/refs/tags/v{{ plugin.version }}.tar.gz"
dest: "/usr/local/src/"
mode: "0644"
register: "waf_install_plugin_downloaded"
- name: Deploy plugin {{ plugin.name }}
# noqa: no-handler
when: "waf_install_plugin_downloaded.changed"
block:
- name: Get temp dir {{ plugin.name }}
ansible.builtin.tempfile:
state: "directory"
register: "waf_install_temp_plugin_dir"
- name: Unarchive plugin {{ plugin.name }}
ansible.builtin.unarchive:
src: "/usr/local/src/{{ plugin.name }}-plugin-{{ plugin.version }}.tar.gz"
dest: "{{ waf_install_temp_plugin_dir.path }}"
remote_src: true
- name: Copy plugin files {{ plugin.name }}
ansible.builtin.copy:
src: "{{ waf_install_temp_plugin_dir.path }}/{{ plugin.name }}-plugin-{{ plugin.version }}/plugins/"
dest: "/etc/caddy/plugins/"
mode: "0644"
# directory_mode: "0750"
group: "caddy"
remote_src: true
notify:
- "Reload Caddy"
# FIXME: bad hack, why is it required?
- name: Adjust /etc/caddy/plugins permissions
ansible.builtin.file:
path: "/etc/caddy/plugins"
state: "directory"
group: "caddy"
mode: "0750"
- name: Delete temp dir {{ plugin.name }}
when: "waf_install_temp_plugin_dir.path is defined"
ansible.builtin.file:
path: "{{ waf_install_temp_plugin_dir.path }}"
state: "absent"

View File

@@ -0,0 +1,125 @@
- name: Remove packaged Go
ansible.builtin.apt:
name:
- "golang"
state: "absent"
autoremove: true
purge: true
- name: Install requirements
ansible.builtin.apt:
name:
- "git"
- "libnss3-tools"
- name: Create Go directory
ansible.builtin.file:
path: "/usr/local/go-{{ waf_install_go_version }}"
state: "directory"
mode: "0755"
- name: Install Go
ansible.builtin.unarchive:
src: "https://go.dev/dl/go{{ waf_install_go_version }}.linux-amd64.tar.gz"
dest: "/usr/local/go-{{ waf_install_go_version }}"
remote_src: true
- name: Link Go
ansible.builtin.file:
src: "/usr/local/go-{{ waf_install_go_version }}/go/bin/go"
dest: "/usr/local/bin/go"
state: "link"
# FIXME: no .deb
- name: Install xcaddy
when: |
'xcaddy' not in ansible_facts.packages
or ansible_facts.packages['xcaddy'][0]['version'] != waf_install_xcaddy_version
ansible.builtin.apt:
deb: "{{ waf_install_xcaddy_download }}/v{{ waf_install_xcaddy_version }}/xcaddy_{{ waf_install_xcaddy_version }}_linux_amd64.deb"
force: true
- name: Create Caddy build command
ansible.builtin.set_fact:
waf_install_build_command: >
xcaddy build v{{ waf_install_caddy_version }}
{% if waf_install_cluster %} --with github.com/pteich/caddy-tlsconsul{% endif %}
--with github.com/corazawaf/coraza-caddy/v2@v{{ waf_install_coraza_caddy_version }}
--with github.com/mholt/caddy-ratelimit
--with github.com/steffenbusch/caddy-bot-barrier
--output /usr/local/bin/caddy
- name: Test Caddy version
ansible.builtin.copy:
dest: "/usr/local/bin/.caddy.build"
content: "{{ waf_install_build_command }}"
mode: "0644"
register: waf_install_test_caddy_version
- name: Build Caddy
# noqa: no-handler
when: "waf_install_test_caddy_version.changed"
ansible.builtin.command:
cmd: "{{ waf_install_build_command }}"
creates: "/usr/local/bin/caddy"
notify:
- "Restart Caddy"
- name: Create caddy system group
ansible.builtin.group:
name: "caddy"
system: true
- name: Create caddy system user
ansible.builtin.user:
name: "caddy"
group: "caddy"
groups: ["ssl-cert"]
password: "!"
system: true
home: "/opt/caddy"
- name: Create caddy config directories
ansible.builtin.file:
path: "{{ item }}"
state: "directory"
group: "caddy"
mode: "0750"
loop:
- "/etc/caddy"
- "/etc/caddy/plugins"
- "/etc/caddy/sites"
- name: Create caddy log dir
ansible.builtin.file:
path: "/var/log/caddy"
state: "directory"
group: "caddy"
mode: "0770"
- name: Install OWASP CRS
ansible.builtin.unarchive:
src: "https://github.com/coreruleset/coreruleset/archive/refs/tags/v{{ waf_install_owasp_crs_version }}.tar.gz"
dest: "/etc/caddy"
group: "caddy"
remote_src: true
- name: Install plugins
loop: "{{ waf_install_crs_plugins }}"
loop_control:
loop_var: "plugin"
ansible.builtin.include_tasks: "install_plugin.yml"
- name: Deploy caddy service file
ansible.builtin.template:
src: "templates/caddy.service"
dest: "/etc/systemd/system/caddy.service"
mode: "0644"
notify:
- "Restart Caddy"
- name: Enable Caddy
ansible.builtin.service:
name: "caddy"
enabled: true
daemon_reload: true

View File

@@ -0,0 +1,20 @@
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=15s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1 @@
waf_install_xcaddy_download: "https://github.com/caddyserver/xcaddy/releases/download"