WIP
This commit is contained in:
23
README.md
23
README.md
@@ -67,11 +67,11 @@ Voir: https://github.com/coreruleset/plugin-registry
|
|||||||
|
|
||||||
Fonctionnalités déjà implémentées:
|
Fonctionnalités déjà implémentées:
|
||||||
|
|
||||||
|
- OWASP CRS
|
||||||
- Multisite (cavec configuration des CRS par site)
|
- Multisite (cavec configuration des CRS par site)
|
||||||
- Redirection vers nom canonique
|
- Redirection vers nom canonique
|
||||||
- Rediction HTTP vers HTTPS
|
- Rediction HTTP vers HTTPS
|
||||||
- Certificats SSL (autmotiques via Let's Encrypt et customs)
|
- Certificats SSL (automatiques via Let's Encrypt et customs)
|
||||||
- OWASP CRS
|
|
||||||
- Redirect (SSL et www et autres)
|
- Redirect (SSL et www et autres)
|
||||||
- Filtrage par:
|
- Filtrage par:
|
||||||
- adresses IP
|
- adresses IP
|
||||||
@@ -80,7 +80,19 @@ Fonctionnalités déjà implémentées:
|
|||||||
- défi JavaScript
|
- défi JavaScript
|
||||||
- Passive backend checks
|
- Passive backend checks
|
||||||
- Compression Gzip et zstd
|
- Compression Gzip et zstd
|
||||||
|
- Mieux tester le configuration des CRS
|
||||||
|
- Mode détection sans blocage
|
||||||
|
- Filtrage par:
|
||||||
|
- méthode HTTP
|
||||||
|
|
||||||
|
Urgemment:
|
||||||
|
|
||||||
|
- Connexion à consul
|
||||||
|
- ACL consul
|
||||||
|
- Changement de format de configuration: Caddyfile -> JSON
|
||||||
|
- Lire doc. config JSON de Caddy
|
||||||
|
- Renommer tous les répertoires/utilisateurs caddy -> byow
|
||||||
|
- Collection Ansible
|
||||||
|
|
||||||
Fomctionnalités à ajouter:
|
Fomctionnalités à ajouter:
|
||||||
|
|
||||||
@@ -92,16 +104,12 @@ Fomctionnalités à ajouter:
|
|||||||
- hCaptcha
|
- hCaptcha
|
||||||
- Turnstile
|
- Turnstile
|
||||||
- mCaptcha
|
- 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
|
- 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:
|
- Filtrage par:
|
||||||
- rDNS
|
- rDNS
|
||||||
- DNSBL
|
- DNSBL
|
||||||
- ASN
|
- ASN
|
||||||
- User-Agent (robots, crawlers, IA bots)
|
- User-Agent (robots, crawlers, IA bots)
|
||||||
- méthode HTTP
|
|
||||||
- taille
|
- taille
|
||||||
- URI patterns
|
- URI patterns
|
||||||
- pays
|
- pays
|
||||||
@@ -127,7 +135,7 @@ Fomctionnalités à ajouter:
|
|||||||
- Whitelist
|
- Whitelist
|
||||||
- Bad behavior
|
- Bad behavior
|
||||||
- Auth
|
- Auth
|
||||||
- Anti DoDS
|
- Anti DDoS
|
||||||
- Greylist
|
- Greylist
|
||||||
- HTML injection
|
- HTML injection
|
||||||
- Metrics (Elasticsearch + Metabase)
|
- Metrics (Elasticsearch + Metabase)
|
||||||
@@ -140,6 +148,7 @@ Fomctionnalités à ajouter:
|
|||||||
- [Site Officiel de Coraza](https://coraza.io)
|
- [Site Officiel de Coraza](https://coraza.io)
|
||||||
- [Coraza WAF Caddy module](https://github.com/corazawaf/coraza-caddy)
|
- [Coraza WAF Caddy module](https://github.com/corazawaf/coraza-caddy)
|
||||||
- [Documentation AWOSP CRS](https://coreruleset.org/docs/)
|
- [Documentation AWOSP CRS](https://coreruleset.org/docs/)
|
||||||
|
- https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-(v3.x)
|
||||||
|
|
||||||
Modules
|
Modules
|
||||||
- []()
|
- []()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
- "IP:{{ ansible_default_ipv4.address }}"
|
- "IP:{{ ansible_default_ipv4.address }}"
|
||||||
waf_config_sites: "{{ common.sites }}"
|
waf_config_sites: "{{ common.sites }}"
|
||||||
roles:
|
roles:
|
||||||
- "certs"
|
- "local_ca_certs"
|
||||||
- "waf_config"
|
- "waf_config"
|
||||||
tags:
|
tags:
|
||||||
- "waf"
|
- "waf"
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
consul_servers: ["waf1", "waf2", "waf3"]
|
consul_servers: ["waf1", "waf2", "waf3"]
|
||||||
consul_server: true
|
consul_server: true
|
||||||
consul_services:
|
consul_services:
|
||||||
- name: "in"
|
- name: "www"
|
||||||
port: 443
|
port: 443
|
||||||
check_http: "http://{{ ansible_default_ipv4.address }}:80/"
|
check_http: "http://{{ ansible_default_ipv4.address }}:80/"
|
||||||
# keepalived_script_user: "caddy"
|
# keepalived_script_user: "caddy"
|
||||||
|
|||||||
@@ -18,3 +18,5 @@ consul_bind_addr: "{{ ansible_default_ipv4.address }}"
|
|||||||
consul_advertise_addr: "{{ ansible_default_ipv4.address }}"
|
consul_advertise_addr: "{{ ansible_default_ipv4.address }}"
|
||||||
consul_default_check_interval: "15s"
|
consul_default_check_interval: "15s"
|
||||||
consul_default_check_timeout: "2s"
|
consul_default_check_timeout: "2s"
|
||||||
|
|
||||||
|
consul_acl_bootstraped: false
|
||||||
|
|||||||
@@ -77,12 +77,30 @@
|
|||||||
enabled: true
|
enabled: true
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
|
|
||||||
|
# consul acl bootstrap -format=json
|
||||||
|
# {
|
||||||
|
# "CreateIndex": 1042,
|
||||||
|
# "ModifyIndex": 1042,
|
||||||
|
# "AccessorID": "50f8bfb6-b259-4c08-f9aa-2dc0eeb08e99",
|
||||||
|
# "SecretID": "b7f16a8a-0b4f-4661-fea2-f79d95dd011b",
|
||||||
|
# "Description": "Bootstrap Token (Global Management)",
|
||||||
|
# "Policies": [
|
||||||
|
# {
|
||||||
|
# "ID": "00000000-0000-0000-0000-000000000001",
|
||||||
|
# "Name": "global-management"
|
||||||
|
# }
|
||||||
|
# ],
|
||||||
|
# "Local": false,
|
||||||
|
# "CreateTime": "2026-01-19T18:41:13.294800712+03:00",
|
||||||
|
# "Hash": "X2AgaFhnQGRhSSF/h0m6qpX1wj/HJWbyXcxkEM/5GrY="
|
||||||
|
# }
|
||||||
|
|
||||||
- name: Register services to consul
|
- name: Register services to consul
|
||||||
loop: "{{ consul_services }}"
|
loop: "{{ consul_services }}"
|
||||||
community.general.consul_agent_service:
|
community.general.consul_agent_service:
|
||||||
name: "{{ item.name }}"
|
name: "{{ item.name }}"
|
||||||
service_port: "{{ item.port }}"
|
service_port: "{{ item.port }}"
|
||||||
tags: ="{{ item.tags | default([]) }}"
|
tags: "{{ item.tags | default([]) }}"
|
||||||
|
|
||||||
- name: Register HTTP checks to consul
|
- name: Register HTTP checks to consul
|
||||||
loop: "{{ consul_services }}"
|
loop: "{{ consul_services }}"
|
||||||
|
|||||||
@@ -23,6 +23,18 @@
|
|||||||
"performance": {
|
"performance": {
|
||||||
"raft_multiplier": 1
|
"raft_multiplier": 1
|
||||||
},
|
},
|
||||||
|
"acl": {
|
||||||
|
"enabled": true,
|
||||||
|
{% if not consul_acl_bootstraped %}
|
||||||
|
"default_policy": "allow",
|
||||||
|
{% else %}
|
||||||
|
"default_policy": "deny",
|
||||||
|
"tokens": {
|
||||||
|
"agent": "FIXME"
|
||||||
|
},
|
||||||
|
{% endif %}
|
||||||
|
"down_policy": "extend-cache"
|
||||||
|
},
|
||||||
{% endif %}
|
{% endif %}
|
||||||
"retry_join": ["{{ consul_servers | join('", "') }}"]
|
"retry_join": ["{{ consul_servers | join('", "') }}"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,12 +35,14 @@ waf_config_defaults:
|
|||||||
custom_key_file: ""
|
custom_key_file: ""
|
||||||
plugins: []
|
plugins: []
|
||||||
|
|
||||||
|
# caddy-ratelimit
|
||||||
rate_events: 1000
|
rate_events: 1000
|
||||||
rate_window: "1m"
|
rate_window: "1m"
|
||||||
|
|
||||||
|
# steffenbusch/caddy-bot-barrier
|
||||||
bot_barrier: false
|
bot_barrier: false
|
||||||
|
|
||||||
# CRS defaults
|
# corazawaf/coraza-caddy
|
||||||
log_only: false
|
log_only: false
|
||||||
paranoia_level: 1
|
paranoia_level: 1
|
||||||
detection_paranoia_level: null
|
detection_paranoia_level: null
|
||||||
@@ -178,6 +180,8 @@ waf_config_defaults:
|
|||||||
- "/x-method-override/"
|
- "/x-method-override/"
|
||||||
- "/x-middleware-subrequest/"
|
- "/x-middleware-subrequest/"
|
||||||
- "/expect/"
|
- "/expect/"
|
||||||
|
restricted_headers_extended:
|
||||||
|
- "/accept-charset/"
|
||||||
allowed_http_versions:
|
allowed_http_versions:
|
||||||
- "HTTP/1.0"
|
- "HTTP/1.0"
|
||||||
- "HTTP/1.1"
|
- "HTTP/1.1"
|
||||||
@@ -185,8 +189,6 @@ waf_config_defaults:
|
|||||||
- "HTTP/2.0"
|
- "HTTP/2.0"
|
||||||
- "HTTP/3"
|
- "HTTP/3"
|
||||||
- "HTTP/3.0"
|
- "HTTP/3.0"
|
||||||
restricted_headers_extended:
|
|
||||||
- "/accept-charset/"
|
|
||||||
allowed_request_content_type_charset:
|
allowed_request_content_type_charset:
|
||||||
- "|utf-8|"
|
- "|utf-8|"
|
||||||
- "|iso-8859-1|"
|
- "|iso-8859-1|"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
# storage redis
|
|
||||||
grace_period 10s
|
grace_period 10s
|
||||||
order coraza_waf first
|
order coraza_waf first
|
||||||
{% if waf_config_email | default(None) != None %}
|
{% if waf_config_email | default(None) != None %}
|
||||||
@@ -15,7 +14,7 @@
|
|||||||
log waf {
|
log waf {
|
||||||
format json
|
format json
|
||||||
include "http.handlers.waf"
|
include "http.handlers.waf"
|
||||||
output file /var/log/caddy/waf.log
|
output stdout
|
||||||
}
|
}
|
||||||
{% if waf_config_local_ca_name | default(None) != None %}
|
{% if waf_config_local_ca_name | default(None) != None %}
|
||||||
|
|
||||||
@@ -117,6 +116,28 @@
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Cf. https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html
|
||||||
|
header {
|
||||||
|
# Access-Control-Allow-Origin "https://secure.gravatar.com"
|
||||||
|
Content-Security-Policy "upgrade-insecure-requests; worker-src 'self' blob:; connect-src 'self'; media-src 'self'; img-src 'self' data: https://secure.gravatar.com/avatar/; font-src 'self' data:; style-src 'self' 'unsafe-inline'; object-src 'none'; frame-src 'self' blob:; child-src 'self'; form-action 'self'; frame-ancestors 'self'"
|
||||||
|
# Cross-Origin-Embedder-Policy "require-corp"
|
||||||
|
Cross-Origin-Opener-Policy "same-origin"
|
||||||
|
Cross-Origin-Resource-Policy "same-site"
|
||||||
|
Permissions-Policy "geolocation=(), camera=(), microphone=(), interest-cohort=()"
|
||||||
|
Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
|
Strict-Transport-Security "max-age=2635200; includeSubDomains"
|
||||||
|
X-Content-Type-Options "nosniff"
|
||||||
|
X-Frame-Options "DENY"
|
||||||
|
X-Robots-Tag "noindex, nofollow"
|
||||||
|
?Content-Type "text/html; charset=UTF-8"
|
||||||
|
>Set-Cookie "(.*)" "$1; SameSite=None; Secure;"
|
||||||
|
-Server
|
||||||
|
-Via
|
||||||
|
-X-Powered-By
|
||||||
|
-X-AspNet-Version
|
||||||
|
-X-AspNetMvc-Version
|
||||||
|
}
|
||||||
|
|
||||||
handle_errors 403 {
|
handle_errors 403 {
|
||||||
header X-Blocked "true"
|
header X-Blocked "true"
|
||||||
respond "Your request was blocked."
|
respond "Your request was blocked."
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
- "php-xml"
|
- "php-xml"
|
||||||
- "php-mbstring"
|
- "php-mbstring"
|
||||||
- "php-zip"
|
- "php-zip"
|
||||||
|
- "php-igbinary"
|
||||||
|
- "php-imagick"
|
||||||
|
- "php-intl"
|
||||||
|
- "php-apcu"
|
||||||
- "zip"
|
- "zip"
|
||||||
|
|
||||||
- name: Installation de wp-cli
|
- name: Installation de wp-cli
|
||||||
@@ -171,8 +175,9 @@
|
|||||||
- name: Apply permissions
|
- name: Apply permissions
|
||||||
when: "wordpress_create_master != None and wordpress_create_master == ansible_hostname"
|
when: "wordpress_create_master != None and wordpress_create_master == ansible_hostname"
|
||||||
loop:
|
loop:
|
||||||
- "uploads"
|
|
||||||
- "cache"
|
- "cache"
|
||||||
|
- "upgrade"
|
||||||
|
- "uploads"
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-content/{{ item }}/"
|
path: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-content/{{ item }}/"
|
||||||
owner: "{{ wordpress_user }}"
|
owner: "{{ wordpress_user }}"
|
||||||
|
|||||||
Reference in New Issue
Block a user