WIP
This commit is contained in:
146
README.md
Normal file
146
README.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# BYOW - Build Your Own WAF
|
||||
|
||||
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
|
||||
- []()
|
||||
- []()
|
||||
40
ansible/README.md
Normal file
40
ansible/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
### 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 11, 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 pynetbox # pour collection netbox.netbox
|
||||
pipx inject ansible netaddr # pour les rôles CheckMK
|
||||
pipx inject ansible mitogen # optionnel, pour utiliser Mitogen
|
||||
```
|
||||
|
||||
1. Vérifier l'environnement:
|
||||
```
|
||||
pipx list --include-injected
|
||||
ansible --version -> ansible [core 2.16.9]
|
||||
ansible-lint --version -> ansible-lint 24.7.0
|
||||
```
|
||||
@@ -1,3 +1,17 @@
|
||||
# Example of a ansible_local.env file that is used to customize the local
|
||||
# operation of Ansible with environment variables.
|
||||
|
||||
# Usage:
|
||||
# 1. Copy ansible/ansible_local.env.example to ansible/ansible_local.env or create a new version.
|
||||
# 2. Customize the contents of the ansible_local.env file, there can only be definitions of environment variables.
|
||||
# cf.: https://docs.ansible.com/ansible/latest/reference_appendices/config.html
|
||||
# 3. The run_ansible.sh script will automatically source the ansible/ansible_local.env file if it exists before running ansible.
|
||||
|
||||
# The ansible_local.env file is ignored by Git (present in.gitignore).
|
||||
|
||||
# Example of using the ANSIBLE_STRATEGY_PLUGINS and ANSIBLE_STRATEGY environment variables to enable Mitogen (speeds up the execution of Ansible playbooks by a factor of 2 to 10).
|
||||
# cf.: https://mitogen.networkgenomics.com/ansible_detailed.html
|
||||
|
||||
ANSIBLE_STRATEGY_PLUGINS=/home/seb/.local/share/pipx/venvs/ansible/lib/python3.13/site-packages/ansible_mitogen/plugins/strategy
|
||||
export ANSIBLE_STRATEGY_PLUGINS
|
||||
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
linux:
|
||||
vars:
|
||||
ansible_user: "root"
|
||||
|
||||
ubuntu24:
|
||||
vars:
|
||||
ansible_python_interpreter: "/usr/bin/python3.12"
|
||||
|
||||
proxy:
|
||||
hosts:
|
||||
proxy1:
|
||||
|
||||
www:
|
||||
hosts:
|
||||
www1:
|
||||
www2:
|
||||
www3:
|
||||
|
||||
waf:
|
||||
hosts:
|
||||
waf1:
|
||||
waf2:
|
||||
waf3:
|
||||
|
||||
mysql:
|
||||
hosts:
|
||||
mysql1:
|
||||
|
||||
www:
|
||||
hosts:
|
||||
www1:
|
||||
www2:
|
||||
www3:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
multipass list --format=json |jq '{
|
||||
_meta: {hostvars: [.list[] | {(.name): {ansible_host: .ipv4[-1]}}] | add},
|
||||
linux: {hosts: [.list[].name]}
|
||||
_meta: {hostvars: [.list[] | {(.name): {ansible_host: .ipv4[0]}}] | add},
|
||||
linux: {hosts: [.list[].name]},
|
||||
ubuntu24: {hosts: [.list[].name]},
|
||||
}'
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
- "vars/common.yml"
|
||||
- "vars/secrets.yml"
|
||||
vars:
|
||||
certs_ca_passphrase: "{{ secrets.ca.passphrase }}"
|
||||
certs_default_country_name: "{{ common.certificates.country_name }}"
|
||||
certs_default_locality_name: "{{ common.certificates.locality_name }}"
|
||||
certs_default_organization_name: "{{ common.certificates.organization_name }}"
|
||||
certs_default_email_address: "{{ common.certificates.email_address }}"
|
||||
certs_list:
|
||||
local_ca_certs_ca_passphrase: "{{ secrets.ca.passphrase }}"
|
||||
local_ca_certs_default_country_name: "{{ common.certificates.country_name }}"
|
||||
local_ca_certs_default_locality_name: "{{ common.certificates.locality_name }}"
|
||||
local_ca_certs_default_organization_name: "{{ common.certificates.organization_name }}"
|
||||
local_ca_certs_default_email_address: "{{ common.certificates.email_address }}"
|
||||
local_ca_certs_list:
|
||||
- cn: "test.lab"
|
||||
domains:
|
||||
- "DNS:test.lab"
|
||||
|
||||
@@ -24,20 +24,6 @@
|
||||
tags:
|
||||
- "local_ca"
|
||||
|
||||
- name: Proxy server
|
||||
hosts: proxy
|
||||
gather_facts: false
|
||||
vars_files:
|
||||
- "vars/common.yml"
|
||||
- "vars/secrets.yml"
|
||||
vars:
|
||||
squid_authorized_networks:
|
||||
- "{{ ansible_default_ipv4.network }}/24"
|
||||
roles:
|
||||
- "squid"
|
||||
tags:
|
||||
- "proxy"
|
||||
|
||||
- name: Common
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
@@ -45,23 +31,17 @@
|
||||
- "vars/common.yml"
|
||||
- "vars/secrets.yml"
|
||||
vars:
|
||||
common_proxy_server: "{{ hostvars['proxy1'].ansible_default_ipv4.address }}:3128"
|
||||
common_default_packages:
|
||||
- "net-tools"
|
||||
- "htop"
|
||||
- "aptitude"
|
||||
- "screen"
|
||||
- "tcpdump"
|
||||
roles:
|
||||
- "common"
|
||||
tags:
|
||||
- "common"
|
||||
|
||||
- name: HTTP Servers
|
||||
hosts: www
|
||||
gather_facts: false
|
||||
vars_files:
|
||||
- "vars/common.yml"
|
||||
- "vars/secrets.yml"
|
||||
roles:
|
||||
- "www"
|
||||
tags:
|
||||
- "www"
|
||||
|
||||
- name: Web Application Firewalls (install)
|
||||
hosts: waf
|
||||
gather_facts: false
|
||||
@@ -69,12 +49,12 @@
|
||||
- "vars/common.yml"
|
||||
- "vars/secrets.yml"
|
||||
vars:
|
||||
certs_ca_passphrase: "{{ secrets.ca.passphrase }}"
|
||||
certs_default_country_name: "{{ common.certificates.country_name }}"
|
||||
certs_default_locality_name: "{{ common.certificates.locality_name }}"
|
||||
certs_default_organization_name: "{{ common.certificates.organization_name }}"
|
||||
certs_default_email_address: "{{ common.certificates.email_address }}"
|
||||
certs_list:
|
||||
local_ca_certs_ca_passphrase: "{{ secrets.ca.passphrase }}"
|
||||
local_ca_certs_default_country_name: "{{ common.certificates.country_name }}"
|
||||
local_ca_certs_default_locality_name: "{{ common.certificates.locality_name }}"
|
||||
local_ca_certs_default_organization_name: "{{ common.certificates.organization_name }}"
|
||||
local_ca_certs_default_email_address: "{{ common.certificates.email_address }}"
|
||||
local_ca_certs_list:
|
||||
# Consul
|
||||
- cn: "server.{{ common.consul.datacenter }}.{{ common.consul.domain }}"
|
||||
domains:
|
||||
@@ -89,31 +69,132 @@
|
||||
consul_domain: "{{ common.consul.domain }}"
|
||||
consul_datacenter: "{{ common.consul.datacenter }}"
|
||||
consul_secret_key: "{{ secrets.consul.secret_key }}"
|
||||
consul_nodes:
|
||||
- "waf1"
|
||||
- "waf2"
|
||||
- "waf3"
|
||||
# FIXME: -> Cady modules
|
||||
waf_install_cluster: true
|
||||
vip_script_user: "caddy"
|
||||
vip_monitored_process: "caddy"
|
||||
vip_vrrp_password: "{{ secrets.keepalived.secret }}"
|
||||
vip_vrrp_ips:
|
||||
- master: "waf1"
|
||||
virtual_router_id: 11
|
||||
addr: "{{ {{ ansible_default_ipv4.address }} | split('.')[0-3] | join('.') }}.250"
|
||||
- master: "waf2"
|
||||
virtual_router_id: 12
|
||||
addr: "{{ {{ ansible_default_ipv4.address }} | split('.')[0-3] | join('.') }}.251"
|
||||
- master: "waf3"
|
||||
virtual_router_id: 13
|
||||
addr: "{{ {{ ansible_default_ipv4.address }} | split('.')[0-3] | join('.') }}.252"
|
||||
consul_servers: ["waf1", "waf2", "waf3"]
|
||||
consul_server: true
|
||||
consul_services:
|
||||
- name: "in"
|
||||
port: 443
|
||||
check_http: "http://{{ ansible_default_ipv4.address }}:80/"
|
||||
# keepalived_script_user: "caddy"
|
||||
# keepalived_monitored_process: "caddy"
|
||||
# keepalived_vrrp_password: "{{ secrets.keepalived.secret }}"
|
||||
# keepalived_vrrp_ips:
|
||||
# - master: "waf1"
|
||||
# virtual_router_id: 251
|
||||
# addr: "{{ ansible_default_ipv4.address | regex_replace('\\.[0-9]+$', '') }}.251/24"
|
||||
# - master: "waf2"
|
||||
# virtual_router_id: 252
|
||||
# addr: "{{ ansible_default_ipv4.address | regex_replace('\\.[0-9]+$', '') }}.252/24"
|
||||
# - master: "waf3"
|
||||
# virtual_router_id: 253
|
||||
# addr: "{{ ansible_default_ipv4.address | regex_replace('\\.[0-9]+$', '') }}.253/24"
|
||||
# # Multipass network doesn't seem to support well multicast.
|
||||
# keepalived_unicast_peers:
|
||||
# - "{{ hostvars['waf1'].ansible_default_ipv4.address }}"
|
||||
# - "{{ hostvars['waf2'].ansible_default_ipv4.address }}"
|
||||
# - "{{ hostvars['waf3'].ansible_default_ipv4.address }}"
|
||||
unbound_listen_interfaces:
|
||||
- "{{ ansible_default_ipv4.address }}"
|
||||
unbound_stub_zones:
|
||||
- name: "{{ common.consul.datacenter }}.{{ common.consul.domain }}"
|
||||
stub_to: "127.0.0.1@8600"
|
||||
waf_config_sites: "{{ common.sites }}"
|
||||
ovh_ldp_cluster: "gra2.logs.ovh.com"
|
||||
ovh_ldp_token: ¨{{ secrets.ovh_ldp.token }}
|
||||
roles:
|
||||
- "certs"
|
||||
- "local_ca_certs"
|
||||
- "consul"
|
||||
- "waf_install"
|
||||
- "vip"
|
||||
# - "keepalived"
|
||||
- "waf_config"
|
||||
- "unbound"
|
||||
- "ovh_ldp"
|
||||
tags:
|
||||
- "waf"
|
||||
|
||||
- name: MySQL servers
|
||||
hosts: mysql
|
||||
gather_facts: false
|
||||
vars_files:
|
||||
- "vars/common.yml"
|
||||
- "vars/secrets.yml"
|
||||
vars:
|
||||
local_ca_certs_ca_passphrase: "{{ secrets.ca.passphrase }}"
|
||||
local_ca_certs_default_country_name: "{{ common.certificates.country_name }}"
|
||||
local_ca_certs_default_locality_name: "{{ common.certificates.locality_name }}"
|
||||
local_ca_certs_default_organization_name: "{{ common.certificates.organization_name }}"
|
||||
local_ca_certs_default_email_address: "{{ common.certificates.email_address }}"
|
||||
local_ca_certs_list:
|
||||
- cn: "{{ ansible_fqdn }}"
|
||||
domains:
|
||||
- "DNS:{{ ansible_fqdn }}"
|
||||
- "DNS:{{ ansible_hostname }}"
|
||||
- "IP:{{ ansible_default_ipv4.address }}"
|
||||
mysql_databases:
|
||||
- "wordpress"
|
||||
mysql_users:
|
||||
- name: "wordpress"
|
||||
password: "{{ secrets.wordpress.mysql_password }}"
|
||||
priv: "wordpress.*:ALL"
|
||||
host: "{{ ansible_default_ipv4.network }}/255.255.255.0"
|
||||
consul_domain: "{{ common.consul.domain }}"
|
||||
consul_datacenter: "{{ common.consul.datacenter }}"
|
||||
consul_secret_key: "{{ secrets.consul.secret_key }}"
|
||||
consul_key_file: "/etc/ssl/private/{{ ansible_fqdn }}.key"
|
||||
consul_cert_file: "/etc/ssl/certs/{{ ansible_fqdn }}.crt"
|
||||
consul_servers: ["waf1", "waf2", "waf3"]
|
||||
consul_services:
|
||||
- name: "test-lab-mysql"
|
||||
port: 3306
|
||||
check_tcp: "{{ ansible_default_ipv4.address }}:3306"
|
||||
roles:
|
||||
- "local_ca_certs"
|
||||
- "mysql"
|
||||
- "consul"
|
||||
tags:
|
||||
- "mysql"
|
||||
|
||||
- name: HTTP Servers
|
||||
hosts: www
|
||||
gather_facts: false
|
||||
vars_files:
|
||||
- "vars/common.yml"
|
||||
- "vars/secrets.yml"
|
||||
vars:
|
||||
local_ca_certs_ca_passphrase: "{{ secrets.ca.passphrase }}"
|
||||
local_ca_certs_default_country_name: "{{ common.certificates.country_name }}"
|
||||
local_ca_certs_default_locality_name: "{{ common.certificates.locality_name }}"
|
||||
local_ca_certs_default_organization_name: "{{ common.certificates.organization_name }}"
|
||||
local_ca_certs_default_email_address: "{{ common.certificates.email_address }}"
|
||||
local_ca_certs_list:
|
||||
- cn: "{{ ansible_fqdn }}"
|
||||
domains:
|
||||
- "DNS:{{ ansible_fqdn }}"
|
||||
- "DNS:{{ ansible_hostname }}"
|
||||
- "IP:{{ ansible_default_ipv4.address }}"
|
||||
wordpress_site: "test.lab"
|
||||
wordpress_url: "test.lab"
|
||||
wordpress_site_title: "Lab Test"
|
||||
wordpress_admin_user: "spock"
|
||||
wordpress_admin_password: "{{ secrets.wordpress.admin_password }}"
|
||||
wordpress_admin_email: "seb@itik.fr"
|
||||
wordpress_themes: ["twentytwentyfive"]
|
||||
wordpress_active_theme: "twentytwentyfive"
|
||||
wordpress_db_host: "mysql1"
|
||||
wordpress_db_pass: "{{ secrets.wordpress.mysql_password }}"
|
||||
consul_domain: "{{ common.consul.domain }}"
|
||||
consul_datacenter: "{{ common.consul.datacenter }}"
|
||||
consul_secret_key: "{{ secrets.consul.secret_key }}"
|
||||
consul_key_file: "/etc/ssl/private/{{ ansible_fqdn }}.key"
|
||||
consul_cert_file: "/etc/ssl/certs/{{ ansible_fqdn }}.crt"
|
||||
consul_servers: ["waf1", "waf2", "waf3"]
|
||||
consul_services:
|
||||
- name: "test-lab-www"
|
||||
port: 80
|
||||
check_http: "http://localhost:80/"
|
||||
roles:
|
||||
- "local_ca_certs"
|
||||
- "wordpress"
|
||||
- "consul"
|
||||
tags:
|
||||
- "www"
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# Defaults
|
||||
certs_default_country_name: null
|
||||
certs_default_locality_name: null
|
||||
certs_default_organization_name: null
|
||||
certs_default_email_address: null
|
||||
certs_default_not_after: "+365d" # valid for one year
|
||||
certs_default_not_before: "-1d" # valid since yesterday
|
||||
|
||||
# Required
|
||||
certs_ca_passphrase: null
|
||||
certs_list: {}
|
||||
# - cn: <string>
|
||||
# domains: <array of strings>
|
||||
# country_name: <string>
|
||||
# locality_name: <string>
|
||||
# organization_name: <string>
|
||||
# email_address: <string>
|
||||
# not_after: <string>
|
||||
# not_before: <string>
|
||||
@@ -1,42 +0,0 @@
|
||||
- name: Create private key for new certificate
|
||||
community.crypto.openssl_privatekey:
|
||||
path: "/etc/ssl/private/{{ cert.cn }}.key"
|
||||
mode: "0640"
|
||||
group: "ssl-cert"
|
||||
|
||||
- name: Create CSR for new certificate
|
||||
community.crypto.openssl_csr:
|
||||
path: "/etc/ssl/certs/{{ cert.cn }}.csr"
|
||||
privatekey_path: "/etc/ssl/private/{{ cert.cn }}.key"
|
||||
common_name: "{{ cert.cn }}"
|
||||
subject_alt_name: "{{ cert.domains }}"
|
||||
country_name: "{{ cert.country_name | default(certs_default_country_name) | mandatory }}"
|
||||
locality_name: "{{ cert.locality_name | default(certs_default_locality_name) | mandatory }}"
|
||||
organization_name: "{{ cert.organization_name | default(certs_default_organization_name) | mandatory }}"
|
||||
email_address: "{{ cert.email_address | default(certs_default_email_address) | mandatory }}"
|
||||
return_content: true
|
||||
register: certs_csr
|
||||
|
||||
- name: Sign certificate with our CA
|
||||
delegate_to: "localhost"
|
||||
# noqa: no-handler
|
||||
when: "certs_csr.changed"
|
||||
community.crypto.x509_certificate_pipe:
|
||||
csr_content: "{{ certs_csr.csr }}"
|
||||
provider: "ownca"
|
||||
ownca_path: "ca/ca-certificate.crt"
|
||||
ownca_privatekey_path: "ca/ca-certificate.key"
|
||||
ownca_privatekey_passphrase: "{{ certs_ca_passphrase }}"
|
||||
ownca_not_after: "{{ cert.not_after | default(certs_default_not_after) }}"
|
||||
ownca_not_before: "{{ cert.not_before | default(certs_default_not_before) }}"
|
||||
register: certs_certificate
|
||||
|
||||
- name: Write certificate file on server
|
||||
# noqa: no-handler
|
||||
when: "certs_csr.changed"
|
||||
ansible.builtin.copy:
|
||||
dest: "/etc/ssl/certs/{{ cert.cn }}.crt"
|
||||
content: "{{ certs_certificate.certificate }}"
|
||||
mode: "0644"
|
||||
notify:
|
||||
- "Reboot host"
|
||||
2
ansible/roles/common/defaults/main.yml
Normal file
2
ansible/roles/common/defaults/main.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
common_default_packages: []
|
||||
common_proxy_server: null
|
||||
@@ -1,2 +1,7 @@
|
||||
- name: Setup proxy client
|
||||
when: "common_proxy_server != None"
|
||||
ansible.builtin.include_tasks: "setup_proxy_client.yml"
|
||||
|
||||
- name: Setup packages
|
||||
when: "common_default_packages | length > 0"
|
||||
ansible.builtin.include_tasks: "setup_packages.yml"
|
||||
|
||||
9
ansible/roles/common/tasks/setup_packages.yml
Normal file
9
ansible/roles/common/tasks/setup_packages.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
- name: Keep packages up to date
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
upgrade: "safe"
|
||||
|
||||
- name: Install default packages
|
||||
ansible.builtin.apt:
|
||||
name: "{{ common_default_packages }}"
|
||||
autoclean: true
|
||||
@@ -2,7 +2,11 @@
|
||||
consul_datacenter: null
|
||||
consul_domain: null
|
||||
consul_secret_key: null
|
||||
consul_nodes: []
|
||||
consul_server: false
|
||||
consul_servers: []
|
||||
|
||||
# Required for registering services
|
||||
consul_services: []
|
||||
|
||||
# Defaults
|
||||
consul_version: "1.22.2"
|
||||
@@ -12,3 +16,5 @@ consul_ca_file: "/etc/ssl/certs/local-ca.crt"
|
||||
consul_client_addr: "0.0.0.0"
|
||||
consul_bind_addr: "{{ ansible_default_ipv4.address }}"
|
||||
consul_advertise_addr: "{{ ansible_default_ipv4.address }}"
|
||||
consul_default_check_interval: "15s"
|
||||
consul_default_check_timeout: "2s"
|
||||
|
||||
@@ -3,8 +3,3 @@
|
||||
name: "consul"
|
||||
state: "restarted"
|
||||
daemon_reload: true
|
||||
|
||||
- name: Reload Consul
|
||||
ansible.builtin.service:
|
||||
name: "consul"
|
||||
state: "reloaded"
|
||||
|
||||
6
ansible/roles/consul/notes.txt
Normal file
6
ansible/roles/consul/notes.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Security:
|
||||
- Gossip protocol encryption
|
||||
- Built-in ACL
|
||||
- Consul agent communication
|
||||
- mTLS for authentitication and encryption
|
||||
- Certificate authority
|
||||
@@ -60,7 +60,7 @@
|
||||
group: "consul"
|
||||
mode: "0640"
|
||||
notify:
|
||||
- "Reload Consul"
|
||||
- "Restart Consul"
|
||||
|
||||
- name: Deploy Consul service file
|
||||
ansible.builtin.template:
|
||||
@@ -76,3 +76,31 @@
|
||||
state: "started"
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
|
||||
- name: Register services to consul
|
||||
loop: "{{ consul_services }}"
|
||||
community.general.consul_agent_service:
|
||||
name: "{{ item.name }}"
|
||||
service_port: "{{ item.port }}"
|
||||
tags: ="{{ item.tags | default([]) }}"
|
||||
|
||||
- name: Register HTTP checks to consul
|
||||
loop: "{{ consul_services }}"
|
||||
when: "item.check_http | default(None) != None"
|
||||
community.general.consul_agent_check:
|
||||
name: "{{ item.name }}_check"
|
||||
service_id: "{{ item.name }}"
|
||||
interval: "{{ item.check_interval | default(consul_default_check_interval) }}"
|
||||
timeout: "{{ item.check_timeout | default(consul_default_check_timeout) }}"
|
||||
http: "{{ item.check_http }}"
|
||||
scheme: "{{ item.check_scheme | default('http') }}"
|
||||
|
||||
- name: Register TCP checks to consul
|
||||
loop: "{{ consul_services }}"
|
||||
when: "item.check_tcp | default(None) != None"
|
||||
community.general.consul_agent_check:
|
||||
name: "{{ item.name }}_check"
|
||||
service_id: "{{ item.name }}"
|
||||
interval: "{{ item.check_interval | default(consul_default_check_interval) }}"
|
||||
timeout: "{{ item.check_timeout | default(consul_default_check_timeout) }}"
|
||||
tcp: "{{ item.check_tcp }}"
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"log_level": "INFO",
|
||||
"node_name": "{{ ansible_hostname }}",
|
||||
"domain": "{{ consul_domain }}",
|
||||
"server": true,
|
||||
"datacenter": "{{ consul_datacenter | mandatory }}",
|
||||
"key_file": "{{ consul_key_file }}",
|
||||
"cert_file": "{{ consul_cert_file }}",
|
||||
"ca_file": "{{ consul_ca_file }}",
|
||||
@@ -10,17 +9,20 @@
|
||||
"verify_outgoing": true,
|
||||
"verify_server_hostname": true,
|
||||
"encrypt": "{{ consul_secret_key }}",
|
||||
"data_dir": "/opt/consul",
|
||||
{% if consul_server %}
|
||||
"node_name": "{{ ansible_hostname }}",
|
||||
"server": true,
|
||||
"ui": true,
|
||||
"leave_on_terminate": true,
|
||||
"data_dir": "/opt/consul",
|
||||
"datacenter": "{{ consul_datacenter | mandatory }}",
|
||||
"client_addr": "{{ consul_client_addr }}",
|
||||
"bind_addr": "{{ consul_bind_addr }}",
|
||||
"advertise_addr": "{{ consul_advertise_addr }}",
|
||||
"bootstrap_expect": {{ consul_nodes | length }},
|
||||
"retry_join": ["{{ consul_nodes | join('", "') }}"],
|
||||
"bootstrap_expect": {{ consul_servers | length }},
|
||||
"enable_syslog": true,
|
||||
"performance": {
|
||||
"raft_multiplier": 1
|
||||
}
|
||||
},
|
||||
{% endif %}
|
||||
"retry_join": ["{{ consul_servers | join('", "') }}"]
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ Type=notify
|
||||
User=consul
|
||||
Group=consul
|
||||
ExecStart=/usr/local/bin/consul agent -config-file=/etc/consul/config.json
|
||||
ExecReload=/usr/local/bin/consul reload
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
LimitNOFILE=65536
|
||||
|
||||
16
ansible/roles/keepalived/defaults/main.yml
Normal file
16
ansible/roles/keepalived/defaults/main.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
# Required
|
||||
keepalived_script_user: null
|
||||
keepalived_monitored_process: null
|
||||
keepalived_vrrp_password: null # Max 8 characters
|
||||
keepalived_vrrp_ips: null
|
||||
# - master: <string>
|
||||
# virtual_router_id: <int>
|
||||
# addr: <string>
|
||||
|
||||
# Optionnal
|
||||
keepalived_alerts_to: []
|
||||
keepalived_unicast_peers: []
|
||||
|
||||
# Required if length keepalived_alerts_to > 0
|
||||
keepalived_smtp_from: null
|
||||
keepalived_smtp_relay: null
|
||||
58
ansible/roles/keepalived/templates/keepalived.conf
Normal file
58
ansible/roles/keepalived/templates/keepalived.conf
Normal file
@@ -0,0 +1,58 @@
|
||||
# FIXME: NOTICE: setting config option max_auto_priority should result in better keepalived performance
|
||||
|
||||
global_defs {
|
||||
enable_script_security
|
||||
script_user "{{ keepalived_script_user }}"
|
||||
{% if keepalived_alerts_to | length > 0 %}
|
||||
|
||||
notification_email {
|
||||
{% for dest in keepalived_alerts_to %}
|
||||
{{ dest }}
|
||||
{% endfor %}
|
||||
}
|
||||
notification_email_from {{ keepalived_smtp_from }}
|
||||
smtp_server {{ keepalived_smtp_relay }}
|
||||
smtp_connect_timeout 30
|
||||
router_id {{ ansible_hostname }}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
vrrp_script chk_{{ keepalived_monitored_process }} {
|
||||
script "/usr/bin/killall -0 {{ keepalived_monitored_process }}" # Check if process is running
|
||||
interval 2 # Check every 2 seconds
|
||||
weight 2 # Weight to influence master election
|
||||
}
|
||||
{% for ip in keepalived_vrrp_ips %}
|
||||
|
||||
# master: {{ ip.master }}
|
||||
vrrp_instance VI_{{ ip.virtual_router_id }} {
|
||||
state {{ (ansible_hostname==ip.master) | ternary('MASTER', 'BACKUP') }}
|
||||
interface {{ ansible_default_ipv4.interface }}
|
||||
virtual_router_id {{ ip.virtual_router_id }}
|
||||
priority {{ (ansible_hostname==ip.master) | ternary('101', '100') }}
|
||||
advert_int 1
|
||||
promote_secondaries
|
||||
{% if keepalived_alerts_to | length > 0 %}
|
||||
smtp_alert true
|
||||
{% endif %}
|
||||
authentication {
|
||||
auth_type PASS
|
||||
auth_pass {{ keepalived_vrrp_password }}
|
||||
}
|
||||
virtual_ipaddress {
|
||||
{{ ip.addr }}
|
||||
}
|
||||
{% if keepalived_unicast_peers | length > 0 %}
|
||||
unicast_peer {
|
||||
{% for peer in keepalived_unicast_peers %}
|
||||
{% if peer != ansible_default_ipv4.address %}
|
||||
{{ peer }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
track_script {
|
||||
chk_{{ keepalived_monitored_process }}
|
||||
}
|
||||
}
|
||||
{% endfor %}
|
||||
19
ansible/roles/local_ca_certs/defaults/main.yml
Normal file
19
ansible/roles/local_ca_certs/defaults/main.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
# Defaults
|
||||
local_ca_certs_default_country_name: null
|
||||
local_ca_certs_default_locality_name: null
|
||||
local_ca_certs_default_organization_name: null
|
||||
local_ca_certs_default_email_address: null
|
||||
local_ca_certs_default_not_after: "+365d" # valid for one year
|
||||
local_ca_certs_default_not_before: "-1d" # valid since yesterday
|
||||
|
||||
# Required
|
||||
local_ca_certs_ca_passphrase: null
|
||||
local_ca_certs_list: {}
|
||||
# - cn: <string>
|
||||
# domains: <array of strings>
|
||||
# country_name: <string>
|
||||
# locality_name: <string>
|
||||
# organization_name: <string>
|
||||
# email_address: <string>
|
||||
# not_after: <string>
|
||||
# not_before: <string>
|
||||
42
ansible/roles/local_ca_certs/tasks/create_cert.yml
Normal file
42
ansible/roles/local_ca_certs/tasks/create_cert.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
- name: Create private key for new certificate
|
||||
community.crypto.openssl_privatekey:
|
||||
path: "/etc/ssl/private/{{ cert.cn }}.key"
|
||||
mode: "0640"
|
||||
group: "ssl-cert"
|
||||
|
||||
- name: Create CSR for new certificate
|
||||
community.crypto.openssl_csr:
|
||||
path: "/etc/ssl/certs/{{ cert.cn }}.csr"
|
||||
privatekey_path: "/etc/ssl/private/{{ cert.cn }}.key"
|
||||
common_name: "{{ cert.cn }}"
|
||||
subject_alt_name: "{{ cert.domains }}"
|
||||
country_name: "{{ cert.country_name | default(local_ca_certs_default_country_name) | mandatory }}"
|
||||
locality_name: "{{ cert.locality_name | default(local_ca_certs_default_locality_name) | mandatory }}"
|
||||
organization_name: "{{ cert.organization_name | default(local_ca_certs_default_organization_name) | mandatory }}"
|
||||
email_address: "{{ cert.email_address | default(local_ca_certs_default_email_address) | mandatory }}"
|
||||
return_content: true
|
||||
register: local_ca_certs_csr
|
||||
|
||||
- name: Sign certificate with our CA
|
||||
delegate_to: "localhost"
|
||||
# noqa: no-handler
|
||||
when: "local_ca_certs_csr.changed"
|
||||
community.crypto.x509_certificate_pipe:
|
||||
csr_content: "{{ local_ca_certs_csr.csr }}"
|
||||
provider: "ownca"
|
||||
ownca_path: "ca/ca-certificate.crt"
|
||||
ownca_privatekey_path: "ca/ca-certificate.key"
|
||||
ownca_privatekey_passphrase: "{{ local_ca_certs_ca_passphrase }}"
|
||||
ownca_not_after: "{{ cert.not_after | default(local_ca_certs_default_not_after) }}"
|
||||
ownca_not_before: "{{ cert.not_before | default(local_ca_certs_default_not_before) }}"
|
||||
register: local_ca_certs_certificate
|
||||
|
||||
- name: Write certificate file on server
|
||||
# noqa: no-handler
|
||||
when: "local_ca_certs_csr.changed"
|
||||
ansible.builtin.copy:
|
||||
dest: "/etc/ssl/certs/{{ cert.cn }}.crt"
|
||||
content: "{{ local_ca_certs_certificate.certificate }}"
|
||||
mode: "0644"
|
||||
notify:
|
||||
- "Reboot host"
|
||||
@@ -10,7 +10,7 @@
|
||||
mode: "0644"
|
||||
|
||||
- name: Create certs
|
||||
loop: "{{ certs_list }}"
|
||||
loop: "{{ local_ca_certs_list }}"
|
||||
loop_control:
|
||||
loop_var: "cert"
|
||||
ansible.builtin.include_tasks: "create_cert.yml"
|
||||
6
ansible/roles/mysql/defaults/main.yml
Normal file
6
ansible/roles/mysql/defaults/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
# Required
|
||||
mysql_databases: []
|
||||
mysql_users: []
|
||||
# - name: <string
|
||||
# password: <string>
|
||||
# priv: <string>
|
||||
5
ansible/roles/mysql/handlers/main.yml
Normal file
5
ansible/roles/mysql/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
- name: Restart MySQL
|
||||
ansible.builtin.service:
|
||||
name: "mysql"
|
||||
state: "restarted"
|
||||
daemon_reload: true
|
||||
31
ansible/roles/mysql/tasks/main.yml
Normal file
31
ansible/roles/mysql/tasks/main.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
- name: Installation de MySQL
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- "mysql-server"
|
||||
- "python3-pymysql"
|
||||
notify:
|
||||
- "Restart MySQL"
|
||||
|
||||
- name: Set MySQL bind_address parameter
|
||||
ansible.builtin.lineinfile:
|
||||
path: "/etc/mysql/mysql.conf.d/mysqld.cnf"
|
||||
regexp: "^bind-address\\s+="
|
||||
line: "bind-address = *"
|
||||
notify:
|
||||
- "Restart MySQL"
|
||||
|
||||
- name: Création des bases de données MySQL
|
||||
loop: "{{ mysql_databases }}"
|
||||
community.mysql.mysql_db:
|
||||
login_unix_socket: "/var/run/mysqld/mysqld.sock"
|
||||
name: "{{ item }}"
|
||||
encoding: "utf8"
|
||||
|
||||
- name: Création des utilisateur MySQL
|
||||
loop: "{{ mysql_users }}"
|
||||
community.mysql.mysql_user:
|
||||
login_unix_socket: "/var/run/mysqld/mysqld.sock"
|
||||
name: "{{ item.name }}"
|
||||
password: "{{ item.password }}"
|
||||
priv: "{{ item.priv }}"
|
||||
host: "{{ item.host }}"
|
||||
6
ansible/roles/ovh_ldp/defaults/main.yml
Normal file
6
ansible/roles/ovh_ldp/defaults/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
# Required
|
||||
ovh_ldp_token: null
|
||||
ovh_ldp_cluster: null
|
||||
|
||||
# Defaults
|
||||
ovh_ldp_tls_syslog_port: 6514
|
||||
5
ansible/roles/ovh_ldp/handlers/main.yml
Normal file
5
ansible/roles/ovh_ldp/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
- name: Restart syslog-ng
|
||||
ansible.builtin.service:
|
||||
name: "syslog-ng"
|
||||
state: "restarted"
|
||||
daemon_reload: true
|
||||
13
ansible/roles/ovh_ldp/tasks/main.yml
Normal file
13
ansible/roles/ovh_ldp/tasks/main.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
- name: Install syslog-ng
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- "syslog-ng"
|
||||
- "ca-certificates"
|
||||
|
||||
- name: Generate syslog-ng config file for OVH LDP
|
||||
ansible.builtin.template:
|
||||
src: "templates/ldp-ovh.conf"
|
||||
dest: "/etc/syslog-ng/conf.d/ldp-ovh.conf"
|
||||
mode: "0640"
|
||||
notify:
|
||||
- "Restart syslog-ng"
|
||||
22
ansible/roles/ovh_ldp/templates/ldp-ovh.conf
Normal file
22
ansible/roles/ovh_ldp/templates/ldp-ovh.conf
Normal file
@@ -0,0 +1,22 @@
|
||||
rewrite ovh-token {
|
||||
set("{{ ovh_ldp_token }}", value(".SDATA.token@29084.X-OVH-TOKEN"));
|
||||
};
|
||||
|
||||
destination ovhPaaSLogs {
|
||||
network("{{ ovh_ldp_cluster }}"
|
||||
port({{ ovh_ldp_tls_syslog_port }})
|
||||
transport("tls")
|
||||
flags(syslog-protocol)
|
||||
ts_format("iso")
|
||||
frac-digits(6)
|
||||
tls(peer-verify("required-trusted") ca_dir("/etc/ssl/certs/"))
|
||||
keep-alive(yes)
|
||||
so_keepalive(yes)
|
||||
);
|
||||
};
|
||||
|
||||
log {
|
||||
source(s_src);
|
||||
rewrite(ovh-token);
|
||||
destination(ovhPaaSLogs);
|
||||
};
|
||||
@@ -1,2 +0,0 @@
|
||||
squid_authorized_networks: ["127.0.0.1"]
|
||||
squid_cache_size: 10240
|
||||
@@ -1,4 +0,0 @@
|
||||
- name: Restart squid
|
||||
ansible.builtin.systemd:
|
||||
name: "squid"
|
||||
state: "restarted"
|
||||
@@ -1,23 +0,0 @@
|
||||
- name: Install squid package
|
||||
ansible.builtin.apt:
|
||||
name: "squid"
|
||||
notify:
|
||||
- "Restart squid"
|
||||
|
||||
- name: Deploy squid configuration file
|
||||
ansible.builtin.template:
|
||||
src: "templates/squid.conf"
|
||||
dest: "/etc/squid/squid.conf"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "0644"
|
||||
notify:
|
||||
- "Restart squid"
|
||||
|
||||
- name: Enable squid
|
||||
ansible.builtin.systemd:
|
||||
name: "squid"
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
notify:
|
||||
- "Restart squid"
|
||||
File diff suppressed because it is too large
Load Diff
14
ansible/roles/unbound/defaults/main.yml
Normal file
14
ansible/roles/unbound/defaults/main.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
unbound_listen_interfaces:
|
||||
- "0.0.0.0"
|
||||
|
||||
unbound_access_control:
|
||||
- "0.0.0.0/0 allow"
|
||||
|
||||
unbound_forward_zones:
|
||||
- name: "."
|
||||
forward_to: "8.8.8.8"
|
||||
|
||||
unbound_stub_zones: []
|
||||
# - name: <string>
|
||||
# stub_to: <string>
|
||||
# no_cache: no (default yes)
|
||||
4
ansible/roles/unbound/handlers/main.yml
Normal file
4
ansible/roles/unbound/handlers/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
- name: Restart unbound
|
||||
ansible.builtin.service:
|
||||
name: "unbound"
|
||||
state: "restarted"
|
||||
14
ansible/roles/unbound/tasks/main.yml
Normal file
14
ansible/roles/unbound/tasks/main.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- name: Install Unbound
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- "unbound"
|
||||
notify:
|
||||
- "Restart unbound"
|
||||
|
||||
- name: Deploy unbounf config file
|
||||
ansible.builtin.template:
|
||||
src: "templates/unbound.conf"
|
||||
dest: "/etc/unbound/unbound.conf.d/unbound.conf"
|
||||
mode: "0644"
|
||||
notify:
|
||||
- "Restart unbound"
|
||||
21
ansible/roles/unbound/templates/unbound.conf
Normal file
21
ansible/roles/unbound/templates/unbound.conf
Normal file
@@ -0,0 +1,21 @@
|
||||
server:
|
||||
do-not-query-localhost: no
|
||||
{% for interface in unbound_listen_interfaces %}
|
||||
interface: {{ interface }}
|
||||
{% endfor %}
|
||||
{% for access in unbound_access_control %}
|
||||
access-control: {{ access }}
|
||||
{% endfor %}
|
||||
{% for zone in unbound_stub_zones %}
|
||||
|
||||
stub-zone:
|
||||
name: "{{ zone.name }}"
|
||||
stub-addr: {{ zone.stub_to }}
|
||||
stub-no-cache: {{ zone.no_cache | default('yes') }}
|
||||
{% endfor %}
|
||||
{% for zone in unbound_forward_zones %}
|
||||
|
||||
forward-zone:
|
||||
name: "{{ zone.name }}"
|
||||
forward-addr: {{ zone.forward_to }}
|
||||
{% endfor %}
|
||||
@@ -1,16 +0,0 @@
|
||||
# Required
|
||||
vip_script_user: null
|
||||
vip_monitored_process: null
|
||||
vip_vrrp_password: null # Max 8 characters
|
||||
vip_vrrp_ips: null
|
||||
# - master: <string>
|
||||
# virtual_router_id: <int>
|
||||
# addr: <string>
|
||||
|
||||
# Optionnal
|
||||
vip_alerts_to: null
|
||||
# - <string>
|
||||
|
||||
# Required if length vip_alerts_to > 0
|
||||
vip_smtp_from: null
|
||||
vip_smtp_relay: null
|
||||
@@ -1,45 +0,0 @@
|
||||
global_defs {
|
||||
enable_script_security
|
||||
script_user "{{ vip_script_user }}"
|
||||
{% if vip_alerts_to | default([]) | length > 0 %}
|
||||
|
||||
notification_email {
|
||||
{% for dest in vip_alerts_to %}
|
||||
{{ dest }}
|
||||
{% endfor %}
|
||||
}
|
||||
notification_email_from {{ vip_smtp_from }}
|
||||
smtp_server {{ vip_smtp_relay }}
|
||||
smtp_connect_timeout 30
|
||||
router_id {{ ansible_hostname }}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
vrrp_script chk_{{ vip_monitored_process }} {
|
||||
script "/usr/bin/killall -0 {{ vip_monitored_process }}" # Check if process is running
|
||||
interval 2 # Check every 2 seconds
|
||||
weight 2 # Weight to influence master election
|
||||
}
|
||||
{% for ip in vip_vrrp_ips %}
|
||||
|
||||
# master: {{ ip.master }}
|
||||
vrrp_instance VI_{{ ip.virtual_router_id }} {
|
||||
state {{ (ansible_hostname==ip.master) | ternary('MASTER', 'BACKUP') }}
|
||||
interface eth0
|
||||
virtual_router_id {{ ip.virtual_router_id }}
|
||||
priority {{ (ansible_hostname==ip.master) | ternary('101', '100') }}
|
||||
advert_int 1
|
||||
promote_secondaries
|
||||
smtp_alert true
|
||||
authentication {
|
||||
auth_type PASS
|
||||
auth_pass {{ vip_vrrp_password }}
|
||||
}
|
||||
virtual_ipaddress {
|
||||
{{ ip.addr }}
|
||||
}
|
||||
track_script {
|
||||
chk_{{ vip_monitored_process }}
|
||||
}
|
||||
}
|
||||
{% endfor %}
|
||||
@@ -1,5 +1,5 @@
|
||||
# Defaults
|
||||
waf_config_owasp_crs_version: "4.21.0"
|
||||
waf_config_owasp_crs_version: "4.22.0"
|
||||
|
||||
# Required unless not site.custom_cert
|
||||
waf_config_email: null
|
||||
@@ -22,8 +22,6 @@ waf_config_sites: []
|
||||
# - ""
|
||||
# aliases:
|
||||
# - ""
|
||||
# plugins: FIXME:TODO
|
||||
# - ""
|
||||
# exceptions:
|
||||
# before_request:
|
||||
# - ""
|
||||
@@ -35,6 +33,7 @@ waf_config_defaults:
|
||||
custom_cert: true
|
||||
custom_cert_file: ""
|
||||
custom_key_file: ""
|
||||
plugins: []
|
||||
|
||||
rate_events: 1000
|
||||
rate_window: "1m"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- name: Reload Caddy
|
||||
- name: Restart Caddy
|
||||
ansible.builtin.service:
|
||||
name: "caddy"
|
||||
state: "reloaded"
|
||||
state: "restarted"
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
- name: Create sites config directories
|
||||
loop: "{{ waf_config_sites }}"
|
||||
loop_control:
|
||||
loop_var: "site"
|
||||
ansible.builtin.file:
|
||||
path: "/etc/caddy/sites/{{ site.name }}"
|
||||
path: "/etc/caddy/sites/{{ item.name }}"
|
||||
state: "directory"
|
||||
group: "caddy"
|
||||
mode: "0750"
|
||||
@@ -18,7 +16,7 @@
|
||||
group: "caddy"
|
||||
mode: "0640"
|
||||
notify:
|
||||
- "Reload Caddy"
|
||||
- "Restart Caddy"
|
||||
|
||||
- name: Generate sites crs-setup config file
|
||||
loop: "{{ waf_config_sites }}"
|
||||
@@ -30,7 +28,7 @@
|
||||
group: "caddy"
|
||||
mode: "0640"
|
||||
notify:
|
||||
- "Reload Caddy"
|
||||
- "Restart Caddy"
|
||||
|
||||
- name: Generate sites exclusions before request file
|
||||
loop: "{{ waf_config_sites }}"
|
||||
@@ -42,7 +40,7 @@
|
||||
group: "caddy"
|
||||
mode: "0640"
|
||||
notify:
|
||||
- "Reload Caddy"
|
||||
- "Restart Caddy"
|
||||
|
||||
- name: Generate sites exclusions after response file
|
||||
loop: "{{ waf_config_sites }}"
|
||||
@@ -54,7 +52,7 @@
|
||||
group: "caddy"
|
||||
mode: "0640"
|
||||
notify:
|
||||
- "Reload Caddy"
|
||||
- "Restart Caddy"
|
||||
|
||||
- name: Generate Caddyfile
|
||||
ansible.builtin.template:
|
||||
@@ -63,7 +61,7 @@
|
||||
group: "caddy"
|
||||
mode: "0640"
|
||||
notify:
|
||||
- "Reload Caddy"
|
||||
- "Restart Caddy"
|
||||
|
||||
- name: Copy bot barrier template
|
||||
ansible.builtin.copy:
|
||||
@@ -72,4 +70,4 @@
|
||||
group: "caddy"
|
||||
mode: "0640"
|
||||
notify:
|
||||
- "Reload Caddy"
|
||||
- "Restart Caddy"
|
||||
|
||||
@@ -103,12 +103,16 @@
|
||||
directives `
|
||||
Include "/etc/caddy/sites/{{ site.name }}/coraza.conf"
|
||||
Include "/etc/caddy/sites/{{ site.name }}/crs-setup.conf"
|
||||
Include "/etc/caddy/plugins/*-config.conf"
|
||||
Include "/etc/caddy/plugins/*-before.conf"
|
||||
{% for plugin in site.plugins | default(waf_config_defaults.plugins) %}
|
||||
Include "/etc/caddy/plugins/{{ plugin }}-config.conf"
|
||||
Include "/etc/caddy/plugins/{{ plugin }}-before.conf"
|
||||
{% endfor %}
|
||||
Include "/etc/caddy/sites/{{ site.name }}/exclusions-request-before.conf"
|
||||
Include "/etc/caddy/coreruleset-{{ waf_config_owasp_crs_version }}/rules/*.conf"
|
||||
Include "/etc/caddy/sites/{{ site.name }}/exclusions-response-after.conf"
|
||||
Include "/etc/caddy/plugins/*-after.conf"
|
||||
{% for plugin in site.plugins | default(waf_config_defaults.plugins) %}
|
||||
Include "/etc/caddy/plugins/{{ plugin }}-after.conf"
|
||||
{% endfor %}
|
||||
SecRuleEngine On
|
||||
`
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@ 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
|
||||
waf_install_owasp_crs_version: "4.22.0"
|
||||
|
||||
# Cf.: https://github.com/coreruleset/plugin-registry
|
||||
waf_install_crs_plugins:
|
||||
@@ -19,6 +16,7 @@ waf_install_crs_plugins:
|
||||
version: "1.0.0"
|
||||
- name: "phpmyadmin-rule-exclusions"
|
||||
version: "1.0.0"
|
||||
has_after_config: true
|
||||
- name: "roundcube-rule-exclusions"
|
||||
version: "1.0.4"
|
||||
provider: "EsadCetiner"
|
||||
|
||||
@@ -30,7 +30,15 @@
|
||||
group: "caddy"
|
||||
remote_src: true
|
||||
notify:
|
||||
- "Reload Caddy"
|
||||
- "Restart Caddy"
|
||||
|
||||
- name: Create after config {{ plugin.name }}
|
||||
when: "not(plugin.has_after_config | default(false))"
|
||||
ansible.builtin.copy:
|
||||
content: ""
|
||||
dest: "/etc/caddy/plugins/{{ plugin.name }}-after.conf"
|
||||
mode: "0644"
|
||||
group: "caddy"
|
||||
|
||||
# FIXME: bad hack, why is it required?
|
||||
- name: Adjust /etc/caddy/plugins permissions
|
||||
|
||||
@@ -30,20 +30,29 @@
|
||||
dest: "/usr/local/bin/go"
|
||||
state: "link"
|
||||
|
||||
# FIXME: no .deb
|
||||
- name: Create xcaddy directory
|
||||
ansible.builtin.file:
|
||||
path: "/usr/local/xcaddy-{{ waf_install_xcaddy_version }}"
|
||||
state: "directory"
|
||||
mode: "0755"
|
||||
|
||||
- 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
|
||||
ansible.builtin.unarchive:
|
||||
src: "{{ waf_install_xcaddy_download }}/v{{ waf_install_xcaddy_version }}/xcaddy_{{ waf_install_xcaddy_version }}_linux_amd64.tar.gz"
|
||||
dest: "/usr/local/xcaddy-{{ waf_install_xcaddy_version }}"
|
||||
remote_src: true
|
||||
|
||||
- name: Link xcaddy
|
||||
ansible.builtin.file:
|
||||
src: "/usr/local/xcaddy-{{ waf_install_xcaddy_version }}/xcaddy"
|
||||
dest: "/usr/local/bin/xcaddy"
|
||||
state: "link"
|
||||
|
||||
- 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/pteich/caddy-tlsconsul
|
||||
--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
|
||||
|
||||
23
ansible/roles/wordpress/defaults/main.yml
Normal file
23
ansible/roles/wordpress/defaults/main.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
# Required
|
||||
wordpress_url: null
|
||||
wordpress_site: null
|
||||
wordpress_site_title: null
|
||||
wordpress_admin_user: null
|
||||
wordpress_admin_password: null
|
||||
wordpress_admin_email: null
|
||||
wordpress_db_pass: null
|
||||
wordpress_themes: []
|
||||
wordpress_active_theme: null
|
||||
|
||||
# Defaults
|
||||
wordpress_user: "wordpress"
|
||||
wordpress_plugins: []
|
||||
wordpress_locale: "fr_FR"
|
||||
wordpress_db_host: "localhost"
|
||||
wordpress_db_name: "{{ wordpress_user }}"
|
||||
wordpress_db_user: "{{ wordpress_user }}"
|
||||
wordpress_db_prefix: "wp_"
|
||||
wordpress_db_charset: "utf8mb4"
|
||||
|
||||
# Optionnal
|
||||
wordpress_import_ocdi_indexes: []
|
||||
17
ansible/roles/wordpress/handlers/main.yml
Normal file
17
ansible/roles/wordpress/handlers/main.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
- name: Restart Nginx
|
||||
ansible.builtin.systemd:
|
||||
name: "nginx"
|
||||
state: "restarted"
|
||||
|
||||
- name: Flush Wordpress
|
||||
become: true
|
||||
become_user: "{{ wordpress_user }}"
|
||||
ansible.builtin.shell:
|
||||
executable: "/usr/bin/bash"
|
||||
chdir: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
cmd: |
|
||||
set -o pipefail
|
||||
wp cache flush
|
||||
wp transient delete --all
|
||||
wp rewrite flush --hard
|
||||
changed_when: true
|
||||
12
ansible/roles/wordpress/tasks/install_plugins.yml
Normal file
12
ansible/roles/wordpress/tasks/install_plugins.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
- name: Installation des plugins Wordpress
|
||||
become: true
|
||||
become_user: "{{ wordpress_user }}"
|
||||
loop: "{{ wordpress_plugins_to_install }}"
|
||||
ansible.builtin.command:
|
||||
chdir: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
cmd: "wp plugin install {{ item }} --activate"
|
||||
creates: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-content/plugins/{{ item | basename | splitext | first }}"
|
||||
register: "wordpress_out_plugin_install"
|
||||
changed_when: "'Success: Installed 1 of 1 plugins' in wordpress_out_plugin_install.stdout"
|
||||
notify:
|
||||
- "Flush Wordpress"
|
||||
199
ansible/roles/wordpress/tasks/main.yml
Normal file
199
ansible/roles/wordpress/tasks/main.yml
Normal file
@@ -0,0 +1,199 @@
|
||||
- name: Installation des pré-requis
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- "nginx"
|
||||
- "php-fpm"
|
||||
- "php-mysql"
|
||||
- "php-curl"
|
||||
- "php-json"
|
||||
- "php-xml"
|
||||
- "php-mbstring"
|
||||
- "php-zip"
|
||||
- "zip"
|
||||
|
||||
- name: Installation de wp-cli
|
||||
ansible.builtin.get_url:
|
||||
url: "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar"
|
||||
dest: "/usr/local/bin/wp"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "755"
|
||||
|
||||
- name: Création de l'utilisateur système pour Wordpress
|
||||
ansible.builtin.user:
|
||||
name: "{{ wordpress_user | mandatory }}"
|
||||
home: "/var/www/{{ wordpress_user }}"
|
||||
group: "www-data"
|
||||
shell: "/usr/bin/bash"
|
||||
password_lock: true
|
||||
create_home: true
|
||||
|
||||
- name: Création du répertoire de Wordpress
|
||||
ansible.builtin.file:
|
||||
path: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
state: "directory"
|
||||
owner: "{{ wordpress_user }}"
|
||||
group: "www-data"
|
||||
mode: "0750"
|
||||
|
||||
- name: Installation de Wordpress
|
||||
become: true
|
||||
become_user: "{{ wordpress_user }}"
|
||||
ansible.builtin.command:
|
||||
chdir: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
cmd: "wp core download --locale='{{ wordpress_locale }}' --skip-content"
|
||||
creates: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-config-sample.php"
|
||||
|
||||
# TODO: https://make.wordpress.org/cli/handbook/references/config/#config-files
|
||||
- name: Configuration de Wordpress
|
||||
become: true
|
||||
become_user: "{{ wordpress_user }}"
|
||||
ansible.builtin.shell:
|
||||
chdir: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
executable: "/usr/bin/bash"
|
||||
cmd: |
|
||||
set -o pipefail
|
||||
wp config create \
|
||||
--dbhost='{{ wordpress_db_host }}' \
|
||||
--dbname='{{ wordpress_db_name }}' \
|
||||
--dbuser='{{ wordpress_db_user }}' \
|
||||
--dbpass='{{ wordpress_db_pass }}' \
|
||||
--dbprefix='{{ wordpress_db_prefix }}' \
|
||||
--dbcharset='{{ wordpress_db_charset }}' \
|
||||
--extra-php <<PHP
|
||||
define('FS_METHOD', 'direct');
|
||||
define('FORCE_SSL_ADMIN', false);
|
||||
define('WP_HOME', 'https://{{ wordpress_site }}');
|
||||
define('WP_SITEURL', 'https://{{ wordpress_site }}');
|
||||
|
||||
error_reporting(0);
|
||||
@ini_set('display_errors', 0);
|
||||
define('DISALLOW_FILE_EDIT', true);
|
||||
|
||||
if (isset(\$_SERVER['HTTP_X_FORWARDED_PROTO']) && \$_SERVER['HTTP_X_FORWARDED_PROTO']=='https')
|
||||
\$_SERVER['HTTPS'] = 'on';
|
||||
PHP
|
||||
creates: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-config.php"
|
||||
notify:
|
||||
- "Flush Wordpress"
|
||||
|
||||
- name: Create Wordpress database tables
|
||||
become: true
|
||||
become_user: "{{ wordpress_user }}"
|
||||
run_once: true
|
||||
ansible.builtin.command:
|
||||
chdir: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
cmd: >
|
||||
wp core install
|
||||
--url='{{ wordpress_url }}'
|
||||
--title='{{ wordpress_site_title }}'
|
||||
--admin_user='{{ wordpress_admin_user }}'
|
||||
--admin_password='{{ wordpress_admin_password }}'
|
||||
--admin_email='{{ wordpress_admin_email }}'
|
||||
--locale='{{ wordpress_locale }}'
|
||||
--skip-email
|
||||
creates: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-content/uploads/ }}"
|
||||
register: "wordpress_out_core_install"
|
||||
changed_when: "'Success: WordPress installed successfully.' in wordpress_out_core_install.stdout"
|
||||
notify:
|
||||
- "Flush Wordpress"
|
||||
|
||||
- name: Installation des thèmes Wordpress
|
||||
become: true
|
||||
become_user: "{{ wordpress_user }}"
|
||||
loop: "{{ wordpress_themes }}"
|
||||
ansible.builtin.command:
|
||||
chdir: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
cmd: "wp theme install '{{ item }}'"
|
||||
creates: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-content/themes/{{ item | basename | splitext | first }}"
|
||||
register: "wordpress_out_theme_install"
|
||||
changed_when: "'Success: Installed 1 of 1 themes' in wordpress_out_theme_install.stdout"
|
||||
notify:
|
||||
- "Flush Wordpress"
|
||||
|
||||
- name: Activation du thème Wordpress
|
||||
become: true
|
||||
become_user: "{{ wordpress_user }}"
|
||||
ansible.builtin.command:
|
||||
chdir: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
cmd: "wp theme activate '{{ wordpress_active_theme }}'"
|
||||
register: "wordpress_out_theme_activate"
|
||||
changed_when: "'Success: Switched to ' in wordpress_out_theme_activate.stdout"
|
||||
notify:
|
||||
- "Flush Wordpress"
|
||||
|
||||
- name: Installation des plugins wordpress-importer et one-click-demo-import
|
||||
vars:
|
||||
wordpress_plugins_to_install:
|
||||
- "wordpress-importer"
|
||||
- "one-click-demo-import"
|
||||
ansible.builtin.include_tasks: "install_plugins.yml"
|
||||
|
||||
- name: Importation des plugins OCDI
|
||||
become: true
|
||||
become_user: "{{ wordpress_user }}"
|
||||
loop: "{{ wordpress_import_ocdi_indexes }}"
|
||||
ansible.builtin.shell:
|
||||
chdir: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}"
|
||||
executable: "/usr/bin/bash"
|
||||
cmd: |
|
||||
set -o pipefail
|
||||
wp ocdi import --predefined='{{ item }}' \
|
||||
&& touch /var/www/{{ wordpress_user }}/{{ wordpress_site }}/.ocdi_index{{ item }}_imported
|
||||
creates: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/.ocdi_index{{ item }}_imported"
|
||||
register: "wordpress_out_ocdi_import"
|
||||
changed_when: "'Success: Content import finished!' in wordpress_out_ocdi_import.stdout"
|
||||
notify:
|
||||
- "Flush Wordpress"
|
||||
|
||||
- name: Installation des plugins Wordpress
|
||||
vars:
|
||||
wordpress_plugins_to_install: "{{ wordpress_plugins }}"
|
||||
ansible.builtin.include_tasks: "install_plugins.yml"
|
||||
|
||||
- name: Création du répertoire cache de Wordpress
|
||||
ansible.builtin.file:
|
||||
path: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-content/cache"
|
||||
state: "directory"
|
||||
owner: "{{ wordpress_user }}"
|
||||
group: "www-data"
|
||||
mode: "0750"
|
||||
|
||||
- name: Apply permissions
|
||||
loop:
|
||||
- "uploads"
|
||||
- "cache"
|
||||
ansible.builtin.file:
|
||||
path: "/var/www/{{ wordpress_user }}/{{ wordpress_site }}/wp-content/{{ item }}/"
|
||||
owner: "{{ wordpress_user }}"
|
||||
group: "www-data"
|
||||
mode: "u=rwX,g=rwX,o=rX"
|
||||
recurse: true
|
||||
|
||||
- name: Configuration de Nginx
|
||||
ansible.builtin.template:
|
||||
src: "templates/nginx_vhost.conf"
|
||||
dest: "/etc/nginx/sites-available/{{ wordpress_site }}.conf"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "0644"
|
||||
notify:
|
||||
- "Restart Nginx"
|
||||
|
||||
- name: Link Nginx vhost config
|
||||
ansible.builtin.file:
|
||||
src: "/etc/nginx/sites-available/{{ wordpress_site }}.conf"
|
||||
dest: "/etc/nginx/sites-enabled/{{ wordpress_site }}.conf"
|
||||
state: "link"
|
||||
notify:
|
||||
- "Restart Nginx"
|
||||
|
||||
- name: Unlink Nginx default vhost config
|
||||
ansible.builtin.file:
|
||||
path: "/etc/nginx/sites-enabled/default"
|
||||
state: "absent"
|
||||
notify:
|
||||
- "Restart Nginx"
|
||||
|
||||
# FIXME: php. ini config
|
||||
# Mainly: upload_max_filesize, post_max_size, max_execution_time
|
||||
50
ansible/roles/wordpress/templates/nginx_vhost.conf
Normal file
50
ansible/roles/wordpress/templates/nginx_vhost.conf
Normal file
@@ -0,0 +1,50 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name {{ wordpress_site }} www.{{ wordpress_site }};
|
||||
root /var/www/{{ wordpress_user }}/{{ wordpress_site }};
|
||||
index index.html index.htm index.php;
|
||||
client_max_body_size 50M;
|
||||
|
||||
location /nginx_status {
|
||||
stub_status on;
|
||||
access_log off;
|
||||
allow 127.0.0.1;
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ~ /wp-config\.php\$ {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ~ /wp-content/uploads/.*\.php\$ {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/var/run/php/php-fpm.sock;
|
||||
}
|
||||
|
||||
# Réécritures pour WordPress
|
||||
location ~ ^/index\.php$ { }
|
||||
location / {
|
||||
if (!-e $request_filename){
|
||||
rewrite ^/(.*)$ /index.php last;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
# location / {
|
||||
# try_files \$uri \$uri/ /index.php?\$args;
|
||||
# }
|
||||
|
||||
# location ~ \.php\$ {
|
||||
# include snippets/fastcgi-php.conf;
|
||||
# fastcgi_pass unix:/var/run/php/php-fpm.sock;
|
||||
# fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
|
||||
# }
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
- name: Install Apache 2
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- "apache2"
|
||||
@@ -21,7 +21,11 @@ common:
|
||||
custom_cert: true
|
||||
custom_cert_file: "/etc/ssl/certs/test.lab.crt"
|
||||
custom_key_file: "/etc/ssl/private/test.lab.key"
|
||||
# exceptions:
|
||||
plugins:
|
||||
- "wordpress-rule-exclusions"
|
||||
exceptions:
|
||||
# Cf. https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-(v3.x)
|
||||
# before_request:
|
||||
# - 'SecRule REQUEST_URI "@beginsWith /?bin/sh" "id:1,nolog,ctl:ruleRemoveById=932160"'
|
||||
# - 'SecRule REQUEST_URI "@beginsWith /?bin/sh" "id:2,nolog,ctl:ruleRemoveById=932250"'
|
||||
# - 'SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" "id:1,nolog,ctl:ruleRemoveById=932260"'
|
||||
after_response:
|
||||
- 'SecRuleUpdateTargetById 932260 "!ARGS:tag-name"'
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
61643639653530613066383464333939383034643565386434616361653331656237303835653837
|
||||
3431646133336265393237383366653364373039376365340a396438643530383965343865383837
|
||||
62636338366437356661356561356138383032353133396461643362323536303965353564666232
|
||||
3735363038323139620a386364633933303139623436626337346535663737386264303036323866
|
||||
31303762336638313961383034386137376566383662323961336536303230303063396661333135
|
||||
66646133333565656233303461356166303862303037663133383534613263383130316261643738
|
||||
65656165346432636363393436646532643531393066346332326561656230316232383866643665
|
||||
36626333656335626534333737633231396561633831653464383036323431616431306433623139
|
||||
61346630663636313463376237353036343264613936366539393165623265656233303864386563
|
||||
63386661343061373930383139376666353035373531386230306432663132653130633039616665
|
||||
38383735326339353738383166623932316564636634343830326432613563306436666532313562
|
||||
65326431346639636338
|
||||
30356233646632316565363533613033376333306433626366623230633838356230363461383135
|
||||
3834363137353762316262363134643763353632306362640a613538306235633565356563613532
|
||||
64643862613431313666363130376338356538323035346532636331316637646235346236333331
|
||||
6336313466313434640a316437343866343061383838383362633638363633363535363330333463
|
||||
64616330333361643166663061306338616265316262646339663438306465623231336139653764
|
||||
63353862303538636636306430333464383339316233326133623564613337306266353730616564
|
||||
63366562626135626136663665353663323265346438346131363838383263663665653937393066
|
||||
32353061396661346138386561633734353634363164663438656331383663323035613264653265
|
||||
38646164633465363238623232393731633761393466326466653430316532633139636533613033
|
||||
39303764363861353666356239306366633662643865663033383235336663623632373566383330
|
||||
32363334653936393962633266666439623130616161373231313037343735616361303131383230
|
||||
62333863313432353536363962623161383434363136316264663061343038633065316232313334
|
||||
38653233356135623431343166356464666663636330373663303663326561363333633837303337
|
||||
66616464393661653835636665353439353539393530623730656331316235643032336337616436
|
||||
64373163373932653038613765633061306331363962333932383564333735353534646637303237
|
||||
62376561303364386662343331373631343166326261636362623432323437643735663437333564
|
||||
39323961626131616334323131393963323231626638393231326631306337306230666138323830
|
||||
63373331636234646431666332633633353637313338353536663539303531663938336132356134
|
||||
30323631646666396239323261366435656434623537343935393531633966643135633561633636
|
||||
31626266366432613936643937646537636164646334316562396639363132313862616433653535
|
||||
34666537653433663466323730373363363064393334386133366365383435616436623963626634
|
||||
31376162306565623262663732356463616464376231356432316137373138356466393663653035
|
||||
613336396164633836626637393036303336
|
||||
|
||||
@@ -2,11 +2,8 @@ vms = {
|
||||
waf1 = {},
|
||||
waf2 = {},
|
||||
waf3 = {},
|
||||
mysql1 = {},
|
||||
www1 = {},
|
||||
www2 = {},
|
||||
www3 = {},
|
||||
proxy1 = {
|
||||
memory = "8g"
|
||||
disk = "20g"
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user