dev #16
@@ -1,36 +1,48 @@
|
|||||||
# Defaults
|
# Several instances of the WAF can be deployed onto the same host if their
|
||||||
caddy_config_only: false
|
# names are different and they bind to different ports/interfaces. These
|
||||||
caddy_debug: false
|
# instances may use different versions of Go, xcaddy, Caddy, and Coraza.
|
||||||
|
caddy_my_name: "mywaf"
|
||||||
caddy_http_port: 80
|
caddy_http_port: 80
|
||||||
caddy_https_port: 443
|
caddy_https_port: 443
|
||||||
caddy_default_bind: ""
|
caddy_default_bind: ""
|
||||||
|
|
||||||
|
# If true, will not install software, just deploy Caddy and OWASP CRS
|
||||||
|
# configuration files.
|
||||||
|
caddy_config_only: false
|
||||||
|
|
||||||
|
# Debug will go to /var/log/<caddy_my_name>/debug.log.
|
||||||
|
caddy_debug: false
|
||||||
|
|
||||||
|
# Required for Let's Encrypt auto certificates.
|
||||||
|
caddy_email: null
|
||||||
|
|
||||||
|
# If a custom CA root have to be used.
|
||||||
|
caddy_ca_root: null
|
||||||
|
|
||||||
|
# Accound id and license key are required if a site use Geoip filtering.
|
||||||
|
# See: https://dev.maxmind.com/geoip/updating-databases/
|
||||||
|
caddy_geoip_account_id: null
|
||||||
|
caddy_geoip_license_key: null
|
||||||
|
caddy_geoip_edition_ids: "GeoLite2-ASN,GeoLite2-Country,GeoLite2-City"
|
||||||
|
caddy_geoip_update_frequency: 86400 # In seconds
|
||||||
|
|
||||||
|
# Sotware versions
|
||||||
caddy_version: "2.10.2"
|
caddy_version: "2.10.2"
|
||||||
caddy_go_version: "1.25.6"
|
caddy_go_version: "1.25.6"
|
||||||
caddy_xcaddy_version: "0.4.5"
|
caddy_xcaddy_version: "0.4.5"
|
||||||
caddy_coraza_caddy_version: "2.1.0" # Coraza v3.3.3
|
caddy_coraza_caddy_version: "v2@v2.1.0" # Coraza v3.3.3
|
||||||
|
# Different sites can use different versions of OWASP CRS
|
||||||
caddy_owasp_crs_versions: ["4.22.0"]
|
caddy_owasp_crs_versions: ["4.22.0"]
|
||||||
|
|
||||||
caddy_my_name: "mywaf"
|
# Paths
|
||||||
|
caddy_binary: "/usr/local/bin/{{ caddy_my_name }}"
|
||||||
caddy_system_user: "{{ caddy_my_name }}"
|
caddy_system_user: "{{ caddy_my_name }}"
|
||||||
caddy_system_group: "{{ caddy_my_name }}"
|
caddy_system_group: "{{ caddy_my_name }}"
|
||||||
caddy_home_dir: "/opt/{{ caddy_my_name }}"
|
caddy_home_dir: "/opt/{{ caddy_my_name }}"
|
||||||
caddy_config_dir: "/etc/{{ caddy_my_name }}"
|
caddy_config_dir: "/etc/{{ caddy_my_name }}"
|
||||||
caddy_log_dir: "/var/log/{{ caddy_my_name }}"
|
caddy_log_dir: "/var/log/{{ caddy_my_name }}"
|
||||||
|
|
||||||
# Required for Let's Encrypt auto certificates
|
# OWASP CRS plugins that will can be actived per site.
|
||||||
caddy_email: null
|
|
||||||
|
|
||||||
# If a custom CA root have to be used
|
|
||||||
caddy_ca_root: null
|
|
||||||
|
|
||||||
# See: https://dev.maxmind.com/geoip/updating-databases/
|
|
||||||
caddy_geoip_account_id: null
|
|
||||||
caddy_geoip_license_key: null
|
|
||||||
caddy_geoip_edition_ids: "GeoLite2-ASN,GeoLite2-Country,GeoLite2-City"
|
|
||||||
caddy_geoip_update_frequency: 86400 # In seconds
|
|
||||||
|
|
||||||
|
|
||||||
# Cf.: https://github.com/coreruleset/plugin-registry
|
# Cf.: https://github.com/coreruleset/plugin-registry
|
||||||
caddy_crs_plugins:
|
caddy_crs_plugins:
|
||||||
- name: "drupal-rule-exclusions"
|
- name: "drupal-rule-exclusions"
|
||||||
@@ -52,15 +64,16 @@ caddy_crs_plugins:
|
|||||||
provider: "EsadCetiner"
|
provider: "EsadCetiner"
|
||||||
|
|
||||||
|
|
||||||
# For each site, mandatories parameters
|
# Sites
|
||||||
caddy_sites: []
|
caddy_sites: []
|
||||||
# - id: ""
|
# - id: "" # Mandatory: short id for the site (for site specific directories and files)
|
||||||
# name: ""
|
# name: "" # Mandatory: canonical domain name
|
||||||
# paths:
|
# paths: # Mandatory: targets for the reverse proxy
|
||||||
# - path: "" (default "*")
|
# - path: "" # Optionnal: path of the request, default "*"
|
||||||
# addrs: (minimum 1 required)
|
# addrs: # Mandatory: upstreams
|
||||||
# - ""
|
# - "" # Mandatory: URL of the upstream, minimum 1 required
|
||||||
|
|
||||||
|
|
||||||
# Will be merged with caddy_global_sites_defaults
|
# For overriding default global parameters. Will be merged with
|
||||||
|
# caddy_global_sites_defaults (in vars/main.yml).
|
||||||
caddy_my_sites_defaults: {}
|
caddy_my_sites_defaults: {}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
- "git"
|
- "git"
|
||||||
- "libnss3-tools"
|
- "libnss3-tools"
|
||||||
- "ssl-cert"
|
- "ssl-cert"
|
||||||
# - "geoipupdate"
|
|
||||||
|
|
||||||
- name: Create Go directory
|
- name: Create Go directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
@@ -35,15 +34,15 @@
|
|||||||
caddy_build_command: >
|
caddy_build_command: >
|
||||||
/usr/local/xcaddy-{{ caddy_xcaddy_version }}/xcaddy build v{{ caddy_version }}
|
/usr/local/xcaddy-{{ caddy_xcaddy_version }}/xcaddy build v{{ caddy_version }}
|
||||||
--with github.com/pteich/caddy-tlsconsul
|
--with github.com/pteich/caddy-tlsconsul
|
||||||
--with github.com/corazawaf/coraza-caddy/v2@v{{ caddy_coraza_caddy_version }}
|
--with github.com/corazawaf/coraza-caddy/{{ caddy_coraza_caddy_version }}
|
||||||
--with github.com/mholt/caddy-ratelimit
|
--with github.com/mholt/caddy-ratelimit
|
||||||
--with github.com/steffenbusch/caddy-bot-barrier
|
--with github.com/steffenbusch/caddy-bot-barrier
|
||||||
--with github.com/zhangjiayin/caddy-geoip2
|
--with github.com/zhangjiayin/caddy-geoip2
|
||||||
--output /usr/local/bin/{{ caddy_my_name }}
|
--output {{ caddy_binary }}
|
||||||
|
|
||||||
- name: Remember and test Caddy version
|
- name: Remember and test Caddy version
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
dest: "/usr/local/bin/.caddy.build"
|
dest: "/usr/local/bin/.caddy.{{ caddy_my_name }}.build"
|
||||||
content: >
|
content: >
|
||||||
XCADDY_WHICH_GO=/usr/local/go-{{ caddy_go_version }}/go/bin/go
|
XCADDY_WHICH_GO=/usr/local/go-{{ caddy_go_version }}/go/bin/go
|
||||||
{{ caddy_build_command }}"
|
{{ caddy_build_command }}"
|
||||||
@@ -57,7 +56,7 @@
|
|||||||
XCADDY_WHICH_GO: "/usr/local/go-{{ caddy_go_version }}/go/bin/go"
|
XCADDY_WHICH_GO: "/usr/local/go-{{ caddy_go_version }}/go/bin/go"
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
cmd: "{{ caddy_build_command }}"
|
cmd: "{{ caddy_build_command }}"
|
||||||
creates: "/usr/local/bin/{{ caddy_my_name }}"
|
creates: "{{ caddy_binary }}"
|
||||||
notify:
|
notify:
|
||||||
- "Restart Caddy"
|
- "Restart Caddy"
|
||||||
|
|
||||||
@@ -75,23 +74,21 @@
|
|||||||
system: true
|
system: true
|
||||||
home: "{{ caddy_home_dir }}"
|
home: "{{ caddy_home_dir }}"
|
||||||
|
|
||||||
- name: Create Caddy config directories
|
- name: Create Caddy directories
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ item }}"
|
path: "{{ item.path }}"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
|
owner: "{{ item.owner | default('root') }}"
|
||||||
group: "{{ caddy_system_group }}"
|
group: "{{ caddy_system_group }}"
|
||||||
mode: "0750"
|
mode: "{{ item.mode | default('0750') }}"
|
||||||
loop:
|
loop:
|
||||||
- "{{ caddy_config_dir }}"
|
- path: "{{ caddy_config_dir }}"
|
||||||
- "{{ caddy_config_dir }}/crs-plugins"
|
- path: "{{ caddy_config_dir }}/crs-plugins"
|
||||||
- "{{ caddy_config_dir }}/sites"
|
- path: "{{ caddy_config_dir }}/sites"
|
||||||
|
- path: "{{ caddy_log_dir }}"
|
||||||
- name: Create Caddy log dir
|
mode: "0770"
|
||||||
ansible.builtin.file:
|
- path: "{{ caddy_home_dir }}/geoip2"
|
||||||
path: "{{ caddy_log_dir }}"
|
owner: "{{ caddy_system_user }}"
|
||||||
state: "directory"
|
|
||||||
group: "{{ caddy_system_group }}"
|
|
||||||
mode: "0770"
|
|
||||||
|
|
||||||
- name: Install OWASP CRS
|
- name: Install OWASP CRS
|
||||||
loop: "{{ caddy_owasp_crs_versions }}"
|
loop: "{{ caddy_owasp_crs_versions }}"
|
||||||
@@ -105,7 +102,7 @@
|
|||||||
loop: "{{ caddy_crs_plugins }}"
|
loop: "{{ caddy_crs_plugins }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: "plugin"
|
loop_var: "plugin"
|
||||||
ansible.builtin.include_tasks: "plugin_install.yml"
|
ansible.builtin.include_tasks: "caddy_install_plugin.yml"
|
||||||
|
|
||||||
- name: Deploy caddy service file
|
- name: Deploy caddy service file
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
geoip2 {
|
geoip2 {
|
||||||
accountId "{{ caddy_geoip_account_id }}"
|
accountId "{{ caddy_geoip_account_id }}"
|
||||||
licenseKey "{{ caddy_geoip_license_key }}"
|
licenseKey "{{ caddy_geoip_license_key }}"
|
||||||
databaseDirectory "{{ caddy_home_dir }}"
|
databaseDirectory "{{ caddy_home_dir }}/geoip2"
|
||||||
lockFile "{{ caddy_home_dir }}/.geoip2.lock"
|
lockFile "{{ caddy_home_dir }}/geoip2/.geoip2.lock"
|
||||||
editionID "{{ caddy_geoip_edition_ids }}"
|
editionID "{{ caddy_geoip_edition_ids }}"
|
||||||
updateUrl "https://updates.maxmind.com"
|
updateUrl "https://updates.maxmind.com"
|
||||||
updateFrequency {{ caddy_geoip_update_frequency }}
|
updateFrequency {{ caddy_geoip_update_frequency }}
|
||||||
@@ -90,13 +90,10 @@
|
|||||||
{% for site in caddy_sites %}
|
{% for site in caddy_sites %}
|
||||||
|
|
||||||
{% if (site.site_redirect_from_aliases | default(caddy_sites_defaults.site_redirect_from_aliases)) and (site.site_aliases | default([]) | length) > 0 %}
|
{% if (site.site_redirect_from_aliases | default(caddy_sites_defaults.site_redirect_from_aliases)) and (site.site_aliases | default([]) | length) > 0 %}
|
||||||
|
|
||||||
{{ site.site_aliases | join(', ') }} {
|
{{ site.site_aliases | join(', ') }} {
|
||||||
redir https://{{ site.name }}{uri}
|
redir https://{{ site.name }}{uri}
|
||||||
}
|
}
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
{% for alias in site.site_aliases | default(caddy_sites_defaults.site_aliases) %}
|
{% for alias in site.site_aliases | default(caddy_sites_defaults.site_aliases) %}
|
||||||
{{ alias }},
|
{{ alias }},
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -110,19 +107,27 @@
|
|||||||
to {{ path.addrs | join(' ') }}
|
to {{ path.addrs | join(' ') }}
|
||||||
header_up X-Real-IP {remote}
|
header_up X-Real-IP {remote}
|
||||||
lb_policy {{ site.proxy_lb_policy | default(caddy_sites_defaults.proxy_lb_policy) }}
|
lb_policy {{ site.proxy_lb_policy | default(caddy_sites_defaults.proxy_lb_policy) }}
|
||||||
# Active checks
|
|
||||||
# health_uri /
|
{% if site.proxy_active_checks | default(caddy_sites_defaults.proxy_active_checks) %}
|
||||||
# health_interval 10s
|
health_uri {{ site.proxy_active_checks_uri | default(caddy_sites_defaults.proxy_active_checks_uri) }}
|
||||||
# health_timeout 5s
|
health_port {{ site.proxy_active_checks_port | default(caddy_sites_defaults.proxy_active_checks_port) }}
|
||||||
# health_status 200
|
health_interval {{ site.proxy_active_checks_interval | default(caddy_sites_defaults.proxy_active_checks_interval) }}
|
||||||
# Passive checks
|
health_timeout {{ site.proxy_active_checks_timeout | default(caddy_sites_defaults.proxy_active_checks_timeout) }}
|
||||||
fail_duration 30s
|
health_method {{ site.proxy_active_checks_method | default(caddy_sites_defaults.proxy_active_checks_method) }}
|
||||||
max_fails 3
|
health_status {{ site.proxy_active_checks_status | default(caddy_sites_defaults.proxy_active_checks_status) }}
|
||||||
unhealthy_latency 2000ms
|
{% if site.proxy_active_checks_body | default(caddy_sites_defaults.proxy_active_checks_body) != None %}
|
||||||
transport http {
|
health_body {{ site.proxy_active_checks_body | default(caddy_sites_defaults.proxy_active_checks_body) }}
|
||||||
# tls_server_name {host}
|
{% endif %}
|
||||||
# tls_insecure_skip_verify
|
{% endif %}
|
||||||
}
|
{% if site.proxy_passive_checks | default(caddy_sites_defaults.proxy_passive_checks) %}
|
||||||
|
fail_duration {{ site.proxy_passive_checks_fail_duration | default(caddy_sites_defaults.proxy_passive_checks_fail_duration) }}
|
||||||
|
max_fails {{ site.proxy_passive_checks_max_fails | default(caddy_sites_defaults.proxy_passive_checks_max_fails) }}
|
||||||
|
unhealthy_status {{ site.proxy_passive_checks_unhealthy_status | default(caddy_sites_defaults.proxy_passive_checks_unhealthy_status) }}
|
||||||
|
unhealthy_latency {{ site.proxy_passive_checks_unhealthy_latency | default(caddy_sites_defaults.proxy_passive_checks_unhealthy_latency) }}
|
||||||
|
{% if site.proxy_passive_checks_unhealthy_request_count | default(caddy_sites_defaults.proxy_passive_checks_unhealthy_request_count) != None %}
|
||||||
|
unhealthy_request_count {{ site.proxy_passive_checks_unhealthy_request_count | default(caddy_sites_defaults.proxy_passive_checks_unhealthy_request_count) }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -216,7 +221,13 @@
|
|||||||
|
|
||||||
{% if site.cors | default(caddy_sites_defaults.cors) %}
|
{% if site.cors | default(caddy_sites_defaults.cors) %}
|
||||||
{% for origin in site.cors_allow_origins | mandatory %}
|
{% for origin in site.cors_allow_origins | mandatory %}
|
||||||
import cors {{ origin }} "{{ site.cors_allow_methods | default(caddy_sites_defaults.cors_allow_methods) | join(', ') }}" "{{ site.cors_allow_headers | default(caddy_sites_defaults.cors_allow_headers) | join(', ') }}" "{{ site.cors_allow_credentials | default(caddy_sites_defaults.cors_allow_credentials) | ternary('true', 'false') }}" "{{ site.cors_max_age | default(caddy_sites_defaults.cors_max_age) }}" "{{ site.cors_vary | default(caddy_sites_defaults.cors_vary) | join(', ') }}" "{{ site.cors_expose_headers | default(caddy_sites_defaults.cors_expose_headers) | join(', ') }}"
|
import cors {{ origin }} "{{
|
||||||
|
site.cors_allow_methods | default(caddy_sites_defaults.cors_allow_methods) | listadddel(site.cors_allow_methods_add | default([]), site.cors_allow_methods_del | default([])) | join(', ') }}" "{{
|
||||||
|
site.cors_allow_headers | default(caddy_sites_defaults.cors_allow_headers) | listadddel(site.cors_allow_headers_add | default([]), site.cors_allow_headers_del | default([])) | join(', ') }}" "{{
|
||||||
|
site.cors_allow_credentials | default(caddy_sites_defaults.cors_allow_credentials) | ternary('true', 'false') }}" "{{
|
||||||
|
site.cors_max_age | default(caddy_sites_defaults.cors_max_age) }}" "{{
|
||||||
|
site.cors_vary | default(caddy_sites_defaults.cors_vary) | listadddel(site.cors_vary_add | default([]), site.cors_vary_del | default([])) | join(', ') }}" "{{
|
||||||
|
site.cors_expose_headers | default(caddy_sites_defaults.cors_expose_headers) | listadddel(site.cors_expose_headers_add | default([]), site.cors_expose_headers_del | default([])) | join(', ') }}"
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
import cors-deny
|
import cors-deny
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -235,10 +246,9 @@
|
|||||||
|
|
||||||
header {
|
header {
|
||||||
Content-Security-Policy "{{ caddy_sites_defaults.header_content_security_policy | combine(site.header_content_security_policy | default({})) | dict2str(sep1=' ', sep2='; ', sep3=';') }}"
|
Content-Security-Policy "{{ caddy_sites_defaults.header_content_security_policy | combine(site.header_content_security_policy | default({})) | dict2str(sep1=' ', sep2='; ', sep3=';') }}"
|
||||||
# FIXME
|
Cross-Origin-Embedder-Policy "{{ site.header_cross_origin_embedder_policy | default(caddy_sites_defaults.header_cross_origin_embedder_policy) }}"
|
||||||
# Cross-Origin-Embedder-Policy "{{ site.header_cross_origin_embedder_policy | default(caddy_sites_defaults.header_cross_origin_embedder_policy) }}"
|
Cross-Origin-Opener-Policy "{{ site.header_cross_origin_opener_policy | default(caddy_sites_defaults.header_cross_origin_opener_policy) }}"
|
||||||
# Cross-Origin-Opener-Policy "{{ site.header_cross_origin_opener_policy | default(caddy_sites_defaults.header_cross_origin_opener_policy) }}"
|
Cross-Origin-Resource-Policy "{{ site.header_cross_origin_resource_policy | default(caddy_sites_defaults.header_cross_origin_resource_policy) }}"
|
||||||
# Cross-Origin-Resource-Policy "{{ site.header_cross_origin_resource_policy | default(caddy_sites_defaults.header_cross_origin_resource_policy) }}"
|
|
||||||
Feature-Policy "{{ caddy_sites_defaults.header_feature_policy | combine(site.header_feature_policy | default({})) | dict2str(sep1=' ', sep2='; ', sep3=';') }}"
|
Feature-Policy "{{ caddy_sites_defaults.header_feature_policy | combine(site.header_feature_policy | default({})) | dict2str(sep1=' ', sep2='; ', sep3=';') }}"
|
||||||
Permissions-Policy "{{ caddy_sites_defaults.header_permissions_policy | combine(site.header_permissions_policy | default({})) | dict2str(sep2=', ') }}"
|
Permissions-Policy "{{ caddy_sites_defaults.header_permissions_policy | combine(site.header_permissions_policy | default({})) | dict2str(sep2=', ') }}"
|
||||||
Referrer-Policy "{{ site.header_referrer_policy | default(caddy_sites_defaults.header_referrer_policy) }}"
|
Referrer-Policy "{{ site.header_referrer_policy | default(caddy_sites_defaults.header_referrer_policy) }}"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=WAF {{ caddy_my_name }} (built with BYOW: Build Your Own WAF)
|
Description=WAF ({{ caddy_my_name }}) (built with BYOW: Build Your Own WAF)
|
||||||
After=network.target network-online.target
|
After=network.target network-online.target
|
||||||
Requires=network-online.target
|
Requires=network-online.target
|
||||||
|
|
||||||
@@ -7,8 +7,8 @@ Requires=network-online.target
|
|||||||
Type=notify
|
Type=notify
|
||||||
User={{ caddy_system_user }}
|
User={{ caddy_system_user }}
|
||||||
Group={{ caddy_system_group }}
|
Group={{ caddy_system_group }}
|
||||||
ExecStart=/usr/local/bin/{{ caddy_my_name }} run --environ --config {{ caddy_config_dir }}/Caddyfile
|
ExecStart={{ caddy_binary }} run --environ --config {{ caddy_config_dir }}/Caddyfile
|
||||||
ExecReload=/usr/local/bin/{{ caddy_my_name }} reload --config {{ caddy_config_dir }}/Caddyfile --force
|
ExecReload={{ caddy_binary }} reload --config {{ caddy_config_dir }}/Caddyfile --force
|
||||||
TimeoutStopSec=15s
|
TimeoutStopSec=15s
|
||||||
LimitNOFILE=1048576
|
LimitNOFILE=1048576
|
||||||
PrivateTmp=true
|
PrivateTmp=true
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ SecAction \
|
|||||||
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
||||||
setvar:tx.enable_default_collections=1"
|
setvar:tx.enable_default_collections=1"
|
||||||
|
|
||||||
## HTTP Policy Settings
|
## Allowed HTTP methods
|
||||||
SecAction \
|
SecAction \
|
||||||
"id:900200,\
|
"id:900200,\
|
||||||
phase:1,\
|
phase:1,\
|
||||||
@@ -121,7 +121,7 @@ SecAction \
|
|||||||
nolog,\
|
nolog,\
|
||||||
tag:'OWASP_CRS',\
|
tag:'OWASP_CRS',\
|
||||||
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
||||||
setvar:'tx.allowed_methods={{ site.crs_allowed_methods | default(caddy_sites_defaults.crs_allowed_methods) | join(" ") }}'"
|
setvar:'tx.allowed_methods={{ site.crs_allowed_methods | default(caddy_sites_defaults.crs_allowed_methods) | listadddel(site.crs_allowed_methods_add | default([]), site.crs_allowed_methods_del | default([])) | 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 \
|
||||||
@@ -132,7 +132,7 @@ SecAction \
|
|||||||
nolog,\
|
nolog,\
|
||||||
tag:'OWASP_CRS',\
|
tag:'OWASP_CRS',\
|
||||||
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
||||||
setvar:'tx.allowed_request_content_type={{ site.crs_allowed_request_content_type | default(caddy_sites_defaults.crs_allowed_request_content_type) | join(" ") }}'"
|
setvar:'tx.allowed_request_content_type={{ site.crs_allowed_request_content_type | default(caddy_sites_defaults.crs_allowed_request_content_type) | listadddel(site.crs_allowed_request_content_type_add | default([]), site.crs_allowed_request_content_type_del | default([])) | join(" ") }}'"
|
||||||
|
|
||||||
## Allowed HTTP versions
|
## Allowed HTTP versions
|
||||||
SecAction \
|
SecAction \
|
||||||
@@ -143,7 +143,7 @@ SecAction \
|
|||||||
nolog,\
|
nolog,\
|
||||||
tag:'OWASP_CRS',\
|
tag:'OWASP_CRS',\
|
||||||
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
||||||
setvar:'tx.allowed_http_versions={{ site.crs_allowed_http_versions | default(caddy_sites_defaults.crs_allowed_http_versions) | join(" ") }}'"
|
setvar:'tx.allowed_http_versions={{ site.crs_allowed_http_versions | default(caddy_sites_defaults.crs_allowed_http_versions) | listadddel(site.crs_allowed_http_versions_add | default([]), site.crs_allowed_http_versions_del | default([])) | join(" ") }}'"
|
||||||
|
|
||||||
## Forbidden file extensions
|
## Forbidden file extensions
|
||||||
SecAction \
|
SecAction \
|
||||||
@@ -154,7 +154,7 @@ SecAction \
|
|||||||
nolog,\
|
nolog,\
|
||||||
tag:'OWASP_CRS',\
|
tag:'OWASP_CRS',\
|
||||||
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
||||||
setvar:'tx.restricted_extensions={{ site.crs_restricted_extensions | default(caddy_sites_defaults.crs_restricted_extensions) | join(" ") }}'"
|
setvar:'tx.restricted_extensions={{ site.crs_restricted_extensions | default(caddy_sites_defaults.crs_restricted_extensions) | listadddel(site.crs_restricted_extensions_add | default([]), site.crs_restricted_extensions_del | default([])) | join(" ") }}'"
|
||||||
|
|
||||||
## Restricted request headers
|
## Restricted request headers
|
||||||
SecAction \
|
SecAction \
|
||||||
@@ -165,7 +165,7 @@ SecAction \
|
|||||||
nolog,\
|
nolog,\
|
||||||
tag:'OWASP_CRS',\
|
tag:'OWASP_CRS',\
|
||||||
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
||||||
setvar:'tx.restricted_headers_basic={{ site.crs_restricted_headers_basic | default(caddy_sites_defaults.crs_restricted_headers_basic) | join(" ") }}'"
|
setvar:'tx.restricted_headers_basic={{ site.crs_restricted_headers_basic | default(caddy_sites_defaults.crs_restricted_headers_basic) | listadddel(site.restricted_headers_basic_add | default([]), site.restricted_headers_basic_del | default([])) | join(" ") }}'"
|
||||||
|
|
||||||
## Extended restricted request headers (forbidden at a higher paranoia level)
|
## Extended restricted request headers (forbidden at a higher paranoia level)
|
||||||
SecAction \
|
SecAction \
|
||||||
@@ -176,7 +176,7 @@ SecAction \
|
|||||||
nolog,\
|
nolog,\
|
||||||
tag:'OWASP_CRS',\
|
tag:'OWASP_CRS',\
|
||||||
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
||||||
setvar:'tx.restricted_headers_extended={{ site.crs_restricted_headers_extended | default(caddy_sites_defaults.crs_restricted_headers_extended) | join(" ") }}'"
|
setvar:'tx.restricted_headers_extended={{ site.crs_restricted_headers_extended | default(caddy_sites_defaults.crs_restricted_headers_extended) | listadddel(site.restricted_headers_extended_add | default([]), site.restricted_headers_extended_del | default([])) | 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 \
|
||||||
@@ -187,7 +187,7 @@ SecAction \
|
|||||||
nolog,\
|
nolog,\
|
||||||
tag:'OWASP_CRS',\
|
tag:'OWASP_CRS',\
|
||||||
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
ver:'OWASP_CRS/{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}',\
|
||||||
setvar:'tx.allowed_request_content_type_charset={{ caddy_sites_defaults.crs_allowed_request_content_type_charset | default(caddy_sites_defaults.crs_allowed_request_content_type_charset) | join(" ") }}'"
|
setvar:'tx.allowed_request_content_type_charset={{ caddy_sites_defaults.crs_allowed_request_content_type_charset | default(caddy_sites_defaults.crs_allowed_request_content_type_charset) | listadddel(site.allowed_request_content_type_charset_add | default([]), site.allowed_request_content_type_charset_del | default([])) | join(" ") }}'"
|
||||||
|
|
||||||
## Block request if number of arguments is too high
|
## Block request if number of arguments is too high
|
||||||
SecAction \
|
SecAction \
|
||||||
|
|||||||
@@ -5,13 +5,15 @@ caddy_global_sites_defaults:
|
|||||||
site_aliases: []
|
site_aliases: []
|
||||||
site_redirect_from_aliases: true
|
site_redirect_from_aliases: true
|
||||||
|
|
||||||
|
|
||||||
# Log settings
|
# Log settings
|
||||||
|
# If log_to_file is true, logs will go:
|
||||||
|
# - for each site, in: /var/log/<caddy_my_name>/site_<site id>.log
|
||||||
|
# - for WAF logs (Coraza), in /var/log/<caddy_my_name>/waf.log
|
||||||
log_to_file: false
|
log_to_file: false
|
||||||
log_format: "json"
|
log_format: "json"
|
||||||
|
|
||||||
|
|
||||||
# Proxy settings
|
# Proxy settings
|
||||||
|
# See: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#lb_policy
|
||||||
proxy_lb_policy: "ip_hash" # random
|
proxy_lb_policy: "ip_hash" # random
|
||||||
# random_choose <n>
|
# random_choose <n>
|
||||||
# first
|
# first
|
||||||
@@ -24,28 +26,51 @@ caddy_global_sites_defaults:
|
|||||||
# query [key]
|
# query [key]
|
||||||
# header [field]
|
# header [field]
|
||||||
# cookie [<name> [<secret>]]
|
# cookie [<name> [<secret>]]
|
||||||
|
|
||||||
|
# Upstreams active checks
|
||||||
|
# See: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#active-health-checks
|
||||||
|
proxy_active_checks: false
|
||||||
|
proxy_active_checks_uri: "/"
|
||||||
|
proxy_active_checks_port: 80
|
||||||
|
proxy_active_checks_interval: "30s"
|
||||||
|
proxy_active_checks_timeout: "5s"
|
||||||
|
proxy_active_checks_method: "GET"
|
||||||
|
proxy_active_checks_status: "2xx"
|
||||||
|
proxy_active_checks_body: null
|
||||||
|
|
||||||
|
# Upstreams passive checks
|
||||||
|
# See: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#passive-health-checks
|
||||||
|
proxy_passive_checks: false
|
||||||
|
proxy_passive_checks_fail_duration: "30s"
|
||||||
|
proxy_passive_checks_max_fails: 1
|
||||||
|
proxy_passive_checks_unhealthy_status: "5xx"
|
||||||
|
proxy_passive_checks_unhealthy_latency: "2000ms"
|
||||||
|
proxy_passive_checks_unhealthy_request_count: null
|
||||||
|
|
||||||
# Filters
|
# Filters
|
||||||
filter_blacklist: [] # Superseeds filter_whitelist
|
filter_blacklist: [] # Superseeds filter_whitelist
|
||||||
filter_whitelist: ["127.0.0.1"]
|
filter_whitelist: ["127.0.0.1"]
|
||||||
|
|
||||||
|
|
||||||
# Custom TLS certificate
|
# Custom TLS certificate
|
||||||
custom_cert: false
|
custom_cert: false
|
||||||
custom_cert_file: ""
|
custom_cert_file: null # Mandatory if custum_cert is true
|
||||||
custom_cert_key_file: ""
|
custom_cert_key_file: null # Mandatory if custum_cert is true
|
||||||
|
|
||||||
|
|
||||||
# CORS - Cross Origin Resource Sharing
|
# CORS - Cross Origin Resource Sharing
|
||||||
cors: false
|
cors: false
|
||||||
cors_allow_origins: null # Mandatory
|
cors_allow_origins: [] # Minimum 1 required
|
||||||
cors_allow_methods:
|
cors_allow_methods:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# cors_allow_methods_add: ["XXX"]
|
||||||
|
# cors_allow_methods_del: ["YYY"]
|
||||||
- "GET"
|
- "GET"
|
||||||
- "HEAD"
|
- "HEAD"
|
||||||
- "POST"
|
- "POST"
|
||||||
- "OPTIONS"
|
- "OPTIONS"
|
||||||
cors_allow_headers:
|
cors_allow_headers:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# cors_allow_headers_add: ["Xxx"]
|
||||||
|
# cors_allow_headers_del: ["Yyy"]
|
||||||
- "Cache-Control"
|
- "Cache-Control"
|
||||||
- "Content-Type"
|
- "Content-Type"
|
||||||
- "If-Modified-Since"
|
- "If-Modified-Since"
|
||||||
@@ -54,8 +79,14 @@ caddy_global_sites_defaults:
|
|||||||
cors_max_age: 3600
|
cors_max_age: 3600
|
||||||
cors_allow_credentials: false
|
cors_allow_credentials: false
|
||||||
cors_vary:
|
cors_vary:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# cors_vary_add: ["Xxx"]
|
||||||
|
# cors_vary_del: ["Yyy"]
|
||||||
- "Origin"
|
- "Origin"
|
||||||
cors_expose_headers:
|
cors_expose_headers:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# cors_expose_headers_add: ["Xxx"]
|
||||||
|
# cors_expose_headers_del: ["Yyy"]
|
||||||
- "Content-Length"
|
- "Content-Length"
|
||||||
- "Content-Range"
|
- "Content-Range"
|
||||||
|
|
||||||
@@ -240,20 +271,17 @@ caddy_global_sites_defaults:
|
|||||||
- name: "X-BYOW"
|
- name: "X-BYOW"
|
||||||
value: "🍷"
|
value: "🍷"
|
||||||
|
|
||||||
|
|
||||||
# caddy-ratelimit
|
# caddy-ratelimit
|
||||||
rate_limit: true
|
rate_limit: true
|
||||||
rate_limit_events: 1000
|
rate_limit_events: 1000
|
||||||
rate_limit_window: "1m"
|
rate_limit_window: "1m"
|
||||||
|
|
||||||
|
|
||||||
# steffenbusch/caddy-bot-barrier
|
# steffenbusch/caddy-bot-barrier
|
||||||
bot_barrier: false
|
bot_barrier: false
|
||||||
bot_barrier_secret: null # Required
|
bot_barrier_secret: null # Required
|
||||||
bot_barrier_complexity: 18
|
bot_barrier_complexity: 18
|
||||||
bot_barrier_valid_for: "60m"
|
bot_barrier_valid_for: "60m"
|
||||||
|
|
||||||
|
|
||||||
# corazawaf/coraza-caddy
|
# corazawaf/coraza-caddy
|
||||||
crs: true
|
crs: true
|
||||||
crs_version: "4.22.0"
|
crs_version: "4.22.0"
|
||||||
@@ -262,7 +290,7 @@ caddy_global_sites_defaults:
|
|||||||
crs_exceptions:
|
crs_exceptions:
|
||||||
before_request: []
|
before_request: []
|
||||||
after_response: []
|
after_response: []
|
||||||
crs_paranoia_level: 1
|
crs_paranoia_level: 4
|
||||||
crs_detection_paranoia_level: null
|
crs_detection_paranoia_level: null
|
||||||
crs_enforce_bodyproc_urlencoded: 1
|
crs_enforce_bodyproc_urlencoded: 1
|
||||||
crs_critical_anomaly_score: 5
|
crs_critical_anomaly_score: 5
|
||||||
@@ -280,11 +308,17 @@ caddy_global_sites_defaults:
|
|||||||
crs_combined_file_sizes: 20970520 # 20 Mo
|
crs_combined_file_sizes: 20970520 # 20 Mo
|
||||||
crs_sampling_percentage: 100
|
crs_sampling_percentage: 100
|
||||||
crs_allowed_methods:
|
crs_allowed_methods:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# crs_allowed_methods_add: ["XXX"]
|
||||||
|
# crs_allowed_methods_del: ["YYY"]
|
||||||
- "GET"
|
- "GET"
|
||||||
- "HEAD"
|
- "HEAD"
|
||||||
- "POST"
|
- "POST"
|
||||||
- "OPTIONS"
|
- "OPTIONS"
|
||||||
crs_allowed_request_content_type:
|
crs_allowed_request_content_type:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# crs_allowed_request_content_type_add: ["|xxx/yyy|"]
|
||||||
|
# crs_allowed_request_content_type_del: ["|zzz/aaa|"]
|
||||||
- "|application/csp-report|"
|
- "|application/csp-report|"
|
||||||
- "|application/json|"
|
- "|application/json|"
|
||||||
- "|application/reports+json|"
|
- "|application/reports+json|"
|
||||||
@@ -294,6 +328,9 @@ caddy_global_sites_defaults:
|
|||||||
- "|multipart/form-data|"
|
- "|multipart/form-data|"
|
||||||
- "|text/xml|"
|
- "|text/xml|"
|
||||||
crs_restricted_extensions:
|
crs_restricted_extensions:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# crs_restricted_extensions_add: [".xxx/"]
|
||||||
|
# crs_restricted_extensions_del: [".yyy/"]
|
||||||
- ".ani/"
|
- ".ani/"
|
||||||
- ".asa/"
|
- ".asa/"
|
||||||
- ".asax/"
|
- ".asax/"
|
||||||
@@ -388,6 +425,9 @@ caddy_global_sites_defaults:
|
|||||||
- ".xsd/"
|
- ".xsd/"
|
||||||
- ".xsx/"
|
- ".xsx/"
|
||||||
crs_restricted_headers_basic:
|
crs_restricted_headers_basic:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# crs_restricted_headers_basic_add: ["/xxx/"]
|
||||||
|
# crs_restricted_headers_basic_del: ["/yyy/"]
|
||||||
- "/content-encoding/"
|
- "/content-encoding/"
|
||||||
- "/content-range/"
|
- "/content-range/"
|
||||||
- "/expect/"
|
- "/expect/"
|
||||||
@@ -399,8 +439,14 @@ caddy_global_sites_defaults:
|
|||||||
- "/x-method-override/"
|
- "/x-method-override/"
|
||||||
- "/x-middleware-subrequest/"
|
- "/x-middleware-subrequest/"
|
||||||
crs_restricted_headers_extended:
|
crs_restricted_headers_extended:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# crs_restricted_headers_extended_add: ["/xxx/"]
|
||||||
|
# crs_restricted_headers_extended_del: ["/yyy/"]
|
||||||
- "/accept-charset/"
|
- "/accept-charset/"
|
||||||
crs_allowed_http_versions:
|
crs_allowed_http_versions:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# crs_allowed_http_versions_add: ["HTTP/x.x"]
|
||||||
|
# crs_allowed_http_versions_del: ["HTTP/y.y"]
|
||||||
- "HTTP/1.0"
|
- "HTTP/1.0"
|
||||||
- "HTTP/1.1"
|
- "HTTP/1.1"
|
||||||
- "HTTP/2"
|
- "HTTP/2"
|
||||||
@@ -408,12 +454,14 @@ caddy_global_sites_defaults:
|
|||||||
- "HTTP/3"
|
- "HTTP/3"
|
||||||
- "HTTP/3.0"
|
- "HTTP/3.0"
|
||||||
crs_allowed_request_content_type_charset:
|
crs_allowed_request_content_type_charset:
|
||||||
|
# These variables can be used for adding and removing extensions from the list:
|
||||||
|
# crs_allowed_request_content_type_charset_add: ["|xxx|"]
|
||||||
|
# crs_allowed_request_content_type_charset_del: ["|yyy|"]
|
||||||
- "|utf-8|"
|
- "|utf-8|"
|
||||||
- "|iso-8859-1|"
|
- "|iso-8859-1|"
|
||||||
- "|iso-8859-15|"
|
- "|iso-8859-15|"
|
||||||
- "|windows-1252|"
|
- "|windows-1252|"
|
||||||
|
|
||||||
|
|
||||||
# github.com/zhangjiayin/caddy-geoip2
|
# github.com/zhangjiayin/caddy-geoip2
|
||||||
geoip: false
|
geoip: false
|
||||||
geoip_debug: false
|
geoip_debug: false
|
||||||
|
|||||||
Reference in New Issue
Block a user