Private
Public Access
2
0
This commit is contained in:
2026-01-20 17:40:16 +03:00
parent cda556eec6
commit b78da80550
83 changed files with 108 additions and 82 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.ansible/ .ansible/
__pycache__/ __pycache__/
infra-*/
.DS_Store .DS_Store

View File

@@ -134,7 +134,7 @@ Fomctionnalités à ajouter:
- Robots.txt (DarkVisitors API/Community Lists/Custom URLs/Manual Rules) - Robots.txt (DarkVisitors API/Community Lists/Custom URLs/Manual Rules)
- Gestion des sessions - Gestion des sessions
- Whitelist - Whitelist
- Bad behavior - Bad behavior (via Caddy events ?)
- Authentification - Authentification
- Anti DDoS - Anti DDoS
- Greylist - Greylist
@@ -156,3 +156,42 @@ Fomctionnalités à ajouter:
Modules Modules
- []() - []()
- []() - []()
### 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
```

View File

@@ -1,37 +0,0 @@
### 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
```

View File

@@ -0,0 +1 @@
../../filter_plugins

View File

@@ -18,7 +18,7 @@ waf:
mysql: mysql:
hosts: hosts:
mysql1: sql1:
nfs: nfs:
hosts: hosts:

View File

@@ -75,7 +75,7 @@
- name: "www" - 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: "byow"
# keepalived_monitored_process: "caddy" # keepalived_monitored_process: "caddy"
# keepalived_vrrp_password: "{{ secrets.keepalived.secret }}" # keepalived_vrrp_password: "{{ secrets.keepalived.secret }}"
# keepalived_vrrp_ips: # keepalived_vrrp_ips:
@@ -208,7 +208,7 @@
wordpress_admin_email: "seb@itik.fr" wordpress_admin_email: "seb@itik.fr"
wordpress_themes: ["twentytwentyfive"] wordpress_themes: ["twentytwentyfive"]
wordpress_active_theme: "twentytwentyfive" wordpress_active_theme: "twentytwentyfive"
wordpress_db_host: "mysql1" wordpress_db_host: "sql1"
wordpress_db_pass: "{{ secrets.wordpress.mysql_password }}" wordpress_db_pass: "{{ secrets.wordpress.mysql_password }}"
consul_domain: "{{ common.consul.domain }}" consul_domain: "{{ common.consul.domain }}"
consul_datacenter: "{{ common.consul.datacenter }}" consul_datacenter: "{{ common.consul.datacenter }}"

1
example/ansible/roles Symbolic link
View File

@@ -0,0 +1 @@
../../roles

5
example/tofu/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.terraform/
.terraform.lock.hcl
.terraform.tfstate.lock.info
terraform.tfstate
terraform.tfstate.backup

View File

@@ -0,0 +1,10 @@
vms = {
waf1 = {},
waf2 = {},
waf3 = {},
sql1 = {},
nfs1 = {},
www1 = {},
www2 = {},
www3 = {},
}

View File

@@ -2,8 +2,8 @@ variable "vms" {
description = "Liste des machines virtuelles" description = "Liste des machines virtuelles"
type = map(object({ type = map(object({
cpus = optional(number, 2), cpus = optional(number, 2),
memory = optional(string, "2g"), memory = optional(string, "3g"),
disk = optional(string, "12g"), disk = optional(string, "12g"),
image = optional(string, "https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2"), image = optional(string, "24.04"),
})) }))
} }

View File

@@ -231,15 +231,15 @@ caddy_waf_defaults:
# FIXME # FIXME
# https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#server # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#server
# https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-powered-by
# https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-aspnet-version # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-aspnet-version
# https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-aspnetmvc-version # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-aspnetmvc-version
# https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-powered-by
delete_headers: delete_headers:
- "Server" - "Server"
- "X-Powered-By" - "Via"
- "X-AspNet-Version" - "X-AspNet-Version"
- "X-AspNetMvc-Version" - "X-AspNetMvc-Version"
- "Via" - "X-Powered-By"
custom_headers: {} custom_headers: {}
# - name: <string> # - name: <string>
@@ -253,6 +253,7 @@ caddy_waf_defaults:
bot_barrier: false bot_barrier: false
# corazawaf/coraza-caddy # corazawaf/coraza-caddy
enable_crs: true
crs_plugins: [] crs_plugins: []
log_only: false log_only: false
paranoia_level: 1 paranoia_level: 1
@@ -278,14 +279,14 @@ caddy_waf_defaults:
- "POST" - "POST"
- "OPTIONS" - "OPTIONS"
allowed_request_content_type: allowed_request_content_type:
- "|application/x-www-form-urlencoded|" - "|application/csp-report|"
- "|multipart/form-data|"
- "|text/xml|"
- "|application/xml|"
- "|application/soap+xml|"
- "|application/json|" - "|application/json|"
- "|application/reports+json|" - "|application/reports+json|"
- "|application/csp-report|" - "|application/soap+xml|"
- "|application/x-www-form-urlencoded|"
- "|application/xml|"
- "|multipart/form-data|"
- "|text/xml|"
restricted_extensions: restricted_extensions:
- ".ani/" - ".ani/"
- ".asa/" - ".asa/"
@@ -294,10 +295,10 @@ caddy_waf_defaults:
- ".back/" - ".back/"
- ".backup/" - ".backup/"
- ".bak/" - ".bak/"
- ".bat/"
- ".bck/" - ".bck/"
- ".bk/" - ".bk/"
- ".bkp/" - ".bkp/"
- ".bat/"
- ".cdx/" - ".cdx/"
- ".cer/" - ".cer/"
- ".cfg/" - ".cfg/"
@@ -305,8 +306,8 @@ caddy_waf_defaults:
- ".cnf/" - ".cnf/"
- ".com/" - ".com/"
- ".compositefont/" - ".compositefont/"
- ".config/"
- ".conf/" - ".conf/"
- ".config/"
- ".copy/" - ".copy/"
- ".crt/" - ".crt/"
- ".cs/" - ".cs/"
@@ -341,9 +342,9 @@ caddy_waf_defaults:
- ".old/" - ".old/"
- ".pass/" - ".pass/"
- ".pdb/" - ".pdb/"
- ".pem/"
- ".pfx/" - ".pfx/"
- ".pif/" - ".pif/"
- ".pem/"
- ".pol/" - ".pol/"
- ".prf/" - ".prf/"
- ".printer/" - ".printer/"
@@ -369,8 +370,8 @@ caddy_waf_defaults:
- ".tmp/" - ".tmp/"
- ".vb/" - ".vb/"
- ".vbe/" - ".vbe/"
- ".vbs/"
- ".vbproj/" - ".vbproj/"
- ".vbs/"
- ".vsdisco/" - ".vsdisco/"
- ".vxd/" - ".vxd/"
- ".webinfo/" - ".webinfo/"
@@ -382,15 +383,15 @@ caddy_waf_defaults:
- ".xsx/" - ".xsx/"
restricted_headers_basic: restricted_headers_basic:
- "/content-encoding/" - "/content-encoding/"
- "/proxy/"
- "/lock-token/"
- "/content-range/" - "/content-range/"
- "/expect/"
- "/if/" - "/if/"
- "/lock-token/"
- "/proxy/"
- "/x-http-method-override/" - "/x-http-method-override/"
- "/x-http-method/" - "/x-http-method/"
- "/x-method-override/" - "/x-method-override/"
- "/x-middleware-subrequest/" - "/x-middleware-subrequest/"
- "/expect/"
restricted_headers_extended: restricted_headers_extended:
- "/accept-charset/" - "/accept-charset/"
allowed_http_versions: allowed_http_versions:

View File

@@ -14,7 +14,7 @@
log waf { log waf {
format json format json
include "http.handlers.waf" include "http.handlers.waf"
output stdout output file {{ caddy_log_dir }}/waf.log
} }
{% if caddy_local_ca_name | default(None) != None %} {% if caddy_local_ca_name | default(None) != None %}
@@ -96,6 +96,7 @@
window {{ site.rate_window | default('1m') }} window {{ site.rate_window | default('1m') }}
} }
} }
{% if site.enable_crs | default(caddy_waf_defaults.enable_crs) %}
coraza_waf { coraza_waf {
load_owasp_crs load_owasp_crs
@@ -115,6 +116,7 @@
SecRuleEngine On SecRuleEngine On
` `
} }
{% endif %}
header { header {
Content-Security-Policy "{{ caddy_waf_defaults.header_content_security_policy | combine(site.header_content_security_policy | default({})) | dict2str(sep1=' ', sep2='; ', sep3=';') }}" Content-Security-Policy "{{ caddy_waf_defaults.header_content_security_policy | combine(site.header_content_security_policy | default({})) | dict2str(sep1=' ', sep2='; ', sep3=';') }}"

View File

@@ -123,7 +123,7 @@ SecAction \
ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\ ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\
setvar:'tx.allowed_methods={{ site.allowed_methods | default(caddy_waf_defaults.allowed_methods) | join(" ") }}'" setvar:'tx.allowed_methods={{ site.allowed_methods | default(caddy_waf_defaults.allowed_methods) | join(" ") }}'"
# Content-Types that a client is allowed to send in a request ## Content-Types that a client is allowed to send in a request
SecAction \ SecAction \
"id:900220,\ "id:900220,\
phase:1,\ phase:1,\
@@ -178,7 +178,7 @@ SecAction \
ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\ ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\
setvar:'tx.restricted_headers_extended={{ site.restricted_headers_extended | default(caddy_waf_defaults.restricted_headers_extended) | join(" ") }}'" setvar:'tx.restricted_headers_extended={{ site.restricted_headers_extended | default(caddy_waf_defaults.restricted_headers_extended) | join(" ") }}'"
# Content-Types charsets that a client is allowed to send in a request ## Content-Types charsets that a client is allowed to send in a request
SecAction \ SecAction \
"id:900280,\ "id:900280,\
phase:1,\ phase:1,\
@@ -189,7 +189,7 @@ SecAction \
ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\ ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\
setvar:'tx.allowed_request_content_type_charset={{ caddy_waf_defaults.allowed_request_content_type_charset | default(caddy_waf_defaults.allowed_request_content_type_charset) | join(" ") }}'" setvar:'tx.allowed_request_content_type_charset={{ caddy_waf_defaults.allowed_request_content_type_charset | default(caddy_waf_defaults.allowed_request_content_type_charset) | join(" ") }}'"
# Block request if number of arguments is too high ## Block request if number of arguments is too high
SecAction \ SecAction \
"id:900300,\ "id:900300,\
phase:1,\ phase:1,\
@@ -200,7 +200,7 @@ SecAction \
ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\ ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\
setvar:tx.max_num_args={{ site.max_num_args | default(caddy_waf_defaults.max_num_args) }}" setvar:tx.max_num_args={{ site.max_num_args | default(caddy_waf_defaults.max_num_args) }}"
# Block request if the length of any argument name is too high ## Block request if the length of any argument name is too high
SecAction \ SecAction \
"id:900310,\ "id:900310,\
phase:1,\ phase:1,\
@@ -211,7 +211,7 @@ SecAction \
ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\ ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\
setvar:tx.arg_name_length={{ site.arg_name_length | default(caddy_waf_defaults.arg_name_length) }}" setvar:tx.arg_name_length={{ site.arg_name_length | default(caddy_waf_defaults.arg_name_length) }}"
# Block request if the length of any argument value is too high ## Block request if the length of any argument value is too high
SecAction \ SecAction \
"id:900320,\ "id:900320,\
phase:1,\ phase:1,\
@@ -222,7 +222,7 @@ SecAction \
ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\ ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\
setvar:tx.arg_length={{ site.arg_length | default(caddy_waf_defaults.arg_length) }}" setvar:tx.arg_length={{ site.arg_length | default(caddy_waf_defaults.arg_length) }}"
# Block request if the total length of all combined arguments is too high ## Block request if the total length of all combined arguments is too high
SecAction \ SecAction \
"id:900330,\ "id:900330,\
phase:1,\ phase:1,\
@@ -233,7 +233,7 @@ SecAction \
ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\ ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\
setvar:tx.total_arg_length={{ site.total_arg_length | default(caddy_waf_defaults.total_arg_length) }}" setvar:tx.total_arg_length={{ site.total_arg_length | default(caddy_waf_defaults.total_arg_length) }}"
# Block request if the file size of any individual uploaded file is too high ## Block request if the file size of any individual uploaded file is too high
SecAction \ SecAction \
"id:900340,\ "id:900340,\
phase:1,\ phase:1,\
@@ -244,7 +244,7 @@ SecAction \
ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\ ver:'OWASP_CRS/{{ caddy_owasp_crs_version }}',\
setvar:tx.max_file_size={{ site.max_file_size | default(caddy_waf_defaults.max_file_size) }}" setvar:tx.max_file_size={{ site.max_file_size | default(caddy_waf_defaults.max_file_size) }}"
# Block request if the total size of all combined uploaded files is too high ## Block request if the total size of all combined uploaded files is too high
SecAction \ SecAction \
"id:900350,\ "id:900350,\
phase:1,\ phase:1,\

View File

@@ -6,6 +6,10 @@ Security:
- Certificate authority - Certificate authority
FIXME:
- Ne fonctionne pas sous Debian 13
"acl": { "acl": {
"enabled": true, "enabled": true,
{% if not consul_acl_bootstraped %} {% if not consul_acl_bootstraped %}
@@ -44,3 +48,15 @@ Jan 20 14:00:20 waf1 consul[3863]: agent.auto_config: The 'verify_incoming' fiel
Jan 20 14:00:20 waf1 consul[3863]: agent.auto_config: The 'verify_outgoing' field is deprecated. Use the 'tls.defaults.verify_outgoing' field instead. Jan 20 14:00:20 waf1 consul[3863]: agent.auto_config: The 'verify_outgoing' field is deprecated. Use the 'tls.defaults.verify_outgoing' field instead.
Jan 20 14:00:20 waf1 consul[3863]: agent.auto_config: The 'verify_server_hostname' field is deprecated. Use the 'tls.internal_rpc.verify_server_hostname' field instead. Jan 20 14:00:20 waf1 consul[3863]: agent.auto_config: The 'verify_server_hostname' field is deprecated. Use the 'tls.internal_rpc.verify_server_hostname' field instead.
Jan 20 14:00:20 waf1 consul[3863]: agent.auto_config: The 'ui' field is deprecated. Use the 'ui_config.enabled' field instead. Jan 20 14:00:20 waf1 consul[3863]: agent.auto_config: The 'ui' field is deprecated. Use the 'ui_config.enabled' field instead.
FIXME:
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/demo/v1/recordlabel
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/demo/v1/artist
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/demo/v1/album
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/demo/v1/concept
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/demo/v2/festival
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/multicluster/v2/exportedservices
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/multicluster/v2/namespaceexportedservices
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/multicluster/v2/partitionexportedservices
Jan 20 15:32:40 waf1 consul[2072]: agent.http: Registered resource endpoint: endpoint=/api/internal/v1/tombstone

View File

@@ -3,6 +3,7 @@
name: name:
- "unzip" - "unzip"
# Not required for Ubuntu 24, was a test for Debian 13
- name: Disable IPv6 on all interfaces - name: Disable IPv6 on all interfaces
ansible.posix.sysctl: ansible.posix.sysctl:
name: "net.ipv6.conf.all.disable_ipv6" name: "net.ipv6.conf.all.disable_ipv6"

4
tofu/.gitignore vendored
View File

@@ -1,4 +0,0 @@
/.terraform/
/.terraform.lock.hcl
terraform.tfstate
terraform.tfstate.backup

View File

@@ -1,10 +0,0 @@
vms = {
waf1 = {},
waf2 = {},
waf3 = {},
mysql1 = {},
nfs1 = {},
www1 = {},
www2 = {},
www3 = {},
}