{
  grace_period 10s
  order coraza_waf first
{% if waf_config_email | default(None) != None %}
  email "{{ waf_config_email }}"
{% endif %}

{% if waf_config_ca_root | default(None) != None %}
  tls {
    ca_root "{{ waf_config_ca_root }}"
  }

{% endif %}
  log waf {
    format json
    include "http.handlers.waf"
    output stdout
  }
{% if waf_config_local_ca_name | default(None) != None %}

  pki {
    ca local {
      name "{{ waf_config_local_ca_name }}"
    }
  }
{% endif %}
}

{% for site in waf_config_sites %}
{% if (site.redirect_from_aliases | default(true)) and (site.aliases | default([]) | length) > 0 %}
{{ site.aliases | join(', ') }} {
  redir https://{{ site.site }}{uri}
}

{% else %}
{% for alias in site.aliases | default([]) %}
{{ alias }},
{% endfor %}
{% endif %}
{{ site.site }} {
  encode gzip zstd

{% for path in site.paths %}
  handle {{ path.path | default('*') }} {
    reverse_proxy {
      to {{ path.addrs | join(' ') }}
      header_up X-Real-IP {remote}
      lb_policy ip_hash
      # Active checks
#     health_uri /
#     health_interval 10s
#     health_timeout 5s
#     health_status 200
      # Passive checks
      fail_duration 30s
      max_fails 3
      unhealthy_latency 2000ms
      transport http {
#       tls_server_name {host}
#       tls_insecure_skip_verify
      }
    }
  }
{% endfor %}

{% if site.custom_cert | default (false) %}
  tls {{ site.custom_cert_file }} {{ site.custom_key_file }}

{% endif %}
{% if site.blacklist | default([]) | length > 0 %}
  @blocked {
{% for ip in site.blacklist | default([]) %}
    remote_ip {{ ip }}
{% endfor %}
  }
  respond @blocked "Access Denied" 403

{% endif %}
{% if site.bot_barrier | default (false) %}
  bot_barrier {
     secret {{ waf_config_bot_barrier_secret }}
     complexity 18
     valid_for 30m
     seed_cookie_name __chall_{{ site.name }}_seed
     solution_cookie_name __chall_{{ site.name }}_solution
     mac_cookie_name __chall_{{ site.name }}_mac
     template /etc/caddy/bot_barrier_template.html
  }

{% endif %}
  rate_limit {
#   distributed
    zone remote_ip {
      key {remote.ip}
      events {{ site.rate_events | default('1000') }}
      window {{ site.rate_window | default('1m') }}
    }
  }

  coraza_waf {
    load_owasp_crs
    directives `
      Include "/etc/caddy/sites/{{ site.name }}/coraza.conf"
      Include "/etc/caddy/sites/{{ site.name }}/crs-setup.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"
{% for plugin in site.plugins | default(waf_config_defaults.plugins) %}
      Include "/etc/caddy/plugins/{{ plugin }}-after.conf"
{% endfor %}
      SecRuleEngine On
    `
  }

  # 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 {
    header X-Blocked "true"
    respond "Your request was blocked."
  }

  log {
    format json
    output file /var/log/caddy/site_{{ site.name }}.log
  }
}

{% endfor %}
