Option domaine public : Let's Encrypt (poc_tls) et accès réservé par IP (poc_allowed_sources)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
de23e19910
commit
0e5426b7c3
4 files changed
+43
-2
No files matched your search
@@ -229,6 +229,25 @@ La SQLi de Juice Shop renvoie alors la liste complète des produits (200) au lie
|
|||||||
- **Mode détection seule** : `MODSECURITY_SEC_RULE_ENGINE: "DetectionOnly"` sur un site, pour observer avant de bloquer, comme on le ferait en production.
|
- **Mode détection seule** : `MODSECURITY_SEC_RULE_ENGINE: "DetectionOnly"` sur un site, pour observer avant de bloquer, comme on le ferait en production.
|
||||||
- **Journaux** : `docker logs -f bunkerweb` sur `bw-waf`, et l'audit ModSecurity dans `/var/log/bunkerweb/modsec_audit.log` du conteneur.
|
- **Journaux** : `docker logs -f bunkerweb` sur `bw-waf`, et l'audit ModSecurity dans `/var/log/bunkerweb/modsec_audit.log` du conteneur.
|
||||||
|
|
||||||
|
## Exposer le PoC sur un domaine public (Let's Encrypt)
|
||||||
|
|
||||||
|
Par défaut tout est en `bwpoc.internal` avec des certificats auto-signés. Pour un vrai domaine (exemple : `lab.naoned.net`) :
|
||||||
|
|
||||||
|
1. DNS : `www`, `shop`, `api` et `bwui` du domaine pointent sur l'IP publique NATée vers le WAF.
|
||||||
|
2. Pare-feu : 80 et 443 (TCP, plus 443/UDP pour HTTP/3) vers l'IP du WAF ; réservation DHCP sur la MAC du WAF pour que l'IP ne bouge pas.
|
||||||
|
3. Variables (inventaire ou `-e`) :
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
poc_domain: lab.naoned.net
|
||||||
|
poc_tls: letsencrypt
|
||||||
|
poc_letsencrypt_email: vous@example.org
|
||||||
|
poc_allowed_sources: ["203.0.113.10"] # IP autorisées sur les sites de poc_restricted_sites (bwui par défaut)
|
||||||
|
```
|
||||||
|
|
||||||
|
4. `make waf client tests`.
|
||||||
|
|
||||||
|
La restriction par IP est une règle ModSecurity par site (id 10002) qui laisse passer le challenge ACME. Le client de test est toujours autorisé. Ajoutez `shop` à `poc_restricted_sites` pour ne pas exposer Juice Shop à tout Internet.
|
||||||
|
|
||||||
## Exploitation
|
## Exploitation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -9,6 +9,19 @@
|
|||||||
# ".internal" est réservé par l'ICANN pour l'usage privé : pas de collision possible.
|
# ".internal" est réservé par l'ICANN pour l'usage privé : pas de collision possible.
|
||||||
poc_domain: bwpoc.internal # A ADAPTER si vous avez une zone DNS de labo
|
poc_domain: bwpoc.internal # A ADAPTER si vous avez une zone DNS de labo
|
||||||
|
|
||||||
|
# --- TLS ----------------------------------------------------------------
|
||||||
|
# selfsigned : certificats auto-signés (labo fermé, domaine non public)
|
||||||
|
# letsencrypt : ACME HTTP-01, les 4 noms doivent pointer sur le WAF et le port 80 être joignable d'Internet
|
||||||
|
poc_tls: selfsigned
|
||||||
|
poc_letsencrypt_email: ""
|
||||||
|
poc_letsencrypt_staging: false # true pour tester sans consommer les quotas Let's Encrypt
|
||||||
|
|
||||||
|
# --- Exposition publique ------------------------------------------------
|
||||||
|
# Sites réservés à certaines IP sources (403 pour les autres, sauf challenge ACME).
|
||||||
|
# Le client de test du PoC est toujours autorisé. Liste vide = pas de restriction.
|
||||||
|
poc_restricted_sites: [bwui]
|
||||||
|
poc_allowed_sources: [] # ex. ["203.0.113.10", "198.51.100.0/24"]
|
||||||
|
|
||||||
# --- Proxmox ----------------------------------------------------------
|
# --- Proxmox ----------------------------------------------------------
|
||||||
pve_node: lancelot
|
pve_node: lancelot
|
||||||
pve_storage: zfs # stockage ZFS de lancelot
|
pve_storage: zfs # stockage ZFS de lancelot
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ bw_global_settings:
|
|||||||
MULTISITE: "yes"
|
MULTISITE: "yes"
|
||||||
DISABLE_DEFAULT_SERVER: "yes" # Host inconnu = connexion fermée (444)
|
DISABLE_DEFAULT_SERVER: "yes" # Host inconnu = connexion fermée (444)
|
||||||
SERVE_FILES: "no"
|
SERVE_FILES: "no"
|
||||||
# TLS : certificats auto-signés par site (pas d'ACME en labo fermé)
|
# TLS : auto-signé (labo fermé) ou Let's Encrypt (domaine public), voir poc_tls
|
||||||
GENERATE_SELF_SIGNED_SSL: "yes"
|
GENERATE_SELF_SIGNED_SSL: "{{ 'yes' if poc_tls == 'selfsigned' else 'no' }}"
|
||||||
|
AUTO_LETS_ENCRYPT: "{{ 'yes' if poc_tls == 'letsencrypt' else 'no' }}"
|
||||||
|
EMAIL_LETS_ENCRYPT: "{{ poc_letsencrypt_email }}"
|
||||||
|
LETS_ENCRYPT_CHALLENGE: "http"
|
||||||
|
USE_LETS_ENCRYPT_STAGING: "{{ 'yes' if poc_letsencrypt_staging | bool else 'no' }}"
|
||||||
AUTO_REDIRECT_HTTP_TO_HTTPS: "yes"
|
AUTO_REDIRECT_HTTP_TO_HTTPS: "yes"
|
||||||
# WAF : ModSecurity + OWASP CRS v4 actifs partout (défaut BunkerWeb)
|
# WAF : ModSecurity + OWASP CRS v4 actifs partout (défaut BunkerWeb)
|
||||||
USE_MODSECURITY: "yes"
|
USE_MODSECURITY: "yes"
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ services:
|
|||||||
{% for k, v in (site.custom_confs | default({})).items() %}
|
{% for k, v in (site.custom_confs | default({})).items() %}
|
||||||
{{ fqdn }}_CUSTOM_CONF_{{ k }}: {{ val(v) }}
|
{{ fqdn }}_CUSTOM_CONF_{{ k }}: {{ val(v) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% if name in poc_restricted_sites and poc_allowed_sources | length > 0 %}
|
||||||
|
# Accès réservé (poc_allowed_sources + client de test), challenge ACME toujours permis
|
||||||
|
{{ fqdn }}_CUSTOM_CONF_MODSEC_poc-allowlist: {{ val('SecRule REMOTE_ADDR "!@ipMatch ' ~ ((poc_allowed_sources + [client_ip]) | join(',')) ~ '" "id:10002,phase:1,deny,status:403,log,msg:\'PoC BunkerWeb : source non autorisee\',chain"
|
||||||
|
SecRule REQUEST_URI "!@beginsWith /.well-known/acme-challenge/"') }}
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
networks:
|
networks:
|
||||||
- bw-universe
|
- bw-universe
|
||||||
|
|||||||
Reference in new issue
Block a user