{ http_port {{ caddy_http_port }} https_port {{ caddy_https_port }} default_bind {{ caddy_default_bind }} order geoip2_vars first order coraza_waf first admin off persist_config off {% if caddy_geoip_account_id != None and caddy_geoip_license_key != None %} geoip2 { accountId "{{ caddy_geoip_account_id }}" licenseKey "{{ caddy_geoip_license_key }}" databaseDirectory "{{ caddy_home_dir }}" lockFile "{{ caddy_home_dir }}/.geoip2.lock" editionID "{{ caddy_geoip_edition_ids }}" updateUrl "https://updates.maxmind.com" updateFrequency {{ caddy_geoip_update_frequency }} } {% endif %} {% if caddy_email | default(None) != None %} email "{{ caddy_email }}" {% endif %} {% if caddy_ca_root | default(None) != None %} tls { ca_root "{{ caddy_ca_root }}" } {% endif %} {% if caddy_debug %} log { format json level DEBUG output file {{ caddy_log_dir }}/debug.log } {% endif %} log waf { format json include "http.handlers.waf" output file {{ caddy_log_dir }}/waf.log } } {% 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 %} {{ site.site_aliases | join(', ') }} { redir https://{{ site.name }}{uri} } {% else %} {% for alias in site.site_aliases | default(caddy_sites_defaults.site_aliases) %} {{ alias }}, {% endfor %} {% endif %} {{ site.name }} { 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 {{ site.proxy_lb_policy | default(caddy_sites_defaults.proxy_lb_policy) }} # 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_cert_key_file }} {% endif %} {% if site.filter_blacklist | default(caddy_sites_defaults.filter_blacklist) | length > 0 %} @blocked { {% for ip in site.filter_blacklist | default(caddy_sites_defaults.filter_blacklist) %} remote_ip {{ ip }} {% endfor %} } respond @blocked "Access Denied" 403 {% endif %} {% if site.geoip | default(caddy_sites_defaults.geoip) %} geoip2_vars strict @geofilter expression {{ site.geoip_filter_expression | default(caddy_sites_defaults.geoip_filter_expression) }} respond @geofilter "Access Denied" 403 {% if site.geoip_debug | default(caddy_sites_defaults.geoip_debug) %} header geoip-is_anonymous "{geoip2.is_anonymous}" header geoip-is_anonymous_vpn "{geoip2.is_anonymous_vpn}" header geoip-is_hosting_provider "{geoip2.is_hosting_provider}" header geoip-is_public_proxy "{geoip2.is_public_proxy}" header geoip-is_residential_proxy "{geoip2.is_residential_proxy}" header geoip-is_tor_exit_node "{geoip2.is_tor_exit_node}" header geoip-connection_type "{geoip2.connection_type}" header geoip-domain "{geoip2.domain}" header geoip-country_code "{geoip2.country_code}" header geoip-country_confidence "{geoip2.country_confidence}" header geoip-country_eu "{geoip2.country_eu}" header geoip-country_geoname_id "{geoip2.country_geoname_id}" header geoip-country_name "{geoip2.country_name}" header geoip-continent_code "{geoip2.continent_code}" header geoip-continent_geoname_id "{geoip2.continent_geoname_id}" header geoip-continent_name "{geoip2.continent_name}" header geoip-city_confidence "{geoip2.city_confidence}" header geoip-city_geoname_id "{geoip2.city_geoname_id}" header geoip-city_name "{geoip2.city_name}" header geoip-location_time_zone "{geoip2.location_time_zone}" header geoip-autonomous_system_number "{geoip2.autonomous_system_number}" header geoip-autonomous_system_organization "{geoip2.autonomous_system_organization}" header geoip-isp "{geoip2.isp}" header geoip-mobile_country_code "{geoip2.mobile_country_code}" header geoip-mobile_network_code "{geoip2.mobile_network_code}" header geoip-organization "{geoip2.organization}" header geoip-ip_address "{geoip2.ip_address}" {% endif %} # {% if site.geoip_deny_countries | default(caddy_sites_defaults.geoip_deny_countries) | length > 0 %} # @deny_countries { # maxmind_geolocation { # db_path "/var/lib/GeoIP/GeoLite2-Country.mmdb" # deny_countries {{ site.geoip_deny_countries | default(caddy_sites_defaults.geoip_deny_countries) | joint(" ") }} # } # } # respond @deny_countries "Access Denied" 403 # {% endif %} # # {% if site.geoip_allow_countries | default(caddy_sites_defaults.geoip_allow_countries) | length > 0 %} # @not_allow_countries not { # maxmind_geolocation { # db_path "/var/lib/GeoIP/GeoLite2-Country.mmdb" # allow_countries {{ site.geoip_allow_countries | default(caddy_sites_defaults.geoip_allow_countries) | joint(" ") }} # } # } # respond @not_allow_countries "Access Denied" 403 # {% endif %} # # {% if site.geopip_deny_asn | default(caddy_sites_defaults.geopip_deny_asn) | length > 0 %} # @deny_asn { # maxmind_geolocation { # db_path "/var/lib/GeoIP/GeoLite2-ASN.mmdb" # deny_asn {{ site.geopip_deny_asn | default(caddy_sites_defaults.geopip_deny_asn) | joint(" ") }} # } # } # respond @deny_asn "Access Denied" 403 # {% endif %} # # {% if site.geopip_allow_asn | default(caddy_sites_defaults.geopip_allow_asn) | length > 0 %} # @not_allow_asn not { # maxmind_geolocation { # db_path "/var/lib/GeoIP/GeoLite2-ASN.mmdb" # allow_asn {{ site.geopip_allow_asn | default(caddy_sites_defaults.geopip_allow_asn) | joint(" ") }} # } # } # respond @not_allow_asn "Access Denied" 403 # {% endif %} {% endif %} @not_whitelisted not { {% for ip in site.filter_whitelist | default(caddy_sites_defaults.filter_whitelist) %} remote_ip {{ ip }} {% endfor %} } {% if site.bot_barrier | default(caddy_sites_defaults.bot_barrier) %} bot_barrier @not_whitelisted { secret {{ site.bot_barrier_secret | default(caddy_sites_defaults.bot_barrier_secret) | mandatory }} complexity {{ site.bot_barrier_complexity | default(caddy_sites_defaults.bot_barrier_complexity) }} valid_for {{ site.bot_barrier_valid_for | default(caddy_sites_defaults.bot_barrier_valid_for) }} seed_cookie_name __chall_{{ site.id }}_seed solution_cookie_name __chall_{{ site.id }}_solution mac_cookie_name __chall_{{ site.id }}_mac template {{ caddy_config_dir }}/bot_barrier_template.html } {% endif %} {% if site.rate_limit | default(caddy_sites_defaults.rate_limit) %} rate_limit @not_whitelisted { # distributed zone remote_ip { key {remote.ip} events {{ site.rate_limit_events | default(caddy_sites_defaults.rate_limit_events) }} window {{ site.rate_limit_window | default(caddy_sites_defaults.rate_limit_window) }} } } {% endif %} {% if site.crs | default(caddy_sites_defaults.crs) %} coraza_waf @not_whitelisted { load_owasp_crs directives ` Include "{{ caddy_config_dir }}/sites/{{ site.id }}/coraza.conf" Include "{{ caddy_config_dir }}/sites/{{ site.id }}/crs-setup.conf" {% for plugin in site.crs_plugins | default(caddy_sites_defaults.crs_plugins) %} Include "{{ caddy_config_dir }}/crs-plugins/{{ plugin }}-config.conf" Include "{{ caddy_config_dir }}/crs-plugins/{{ plugin }}-before.conf" {% endfor %} Include "{{ caddy_config_dir }}/sites/{{ site.id }}/exclusions-request-before.conf" Include "{{ caddy_config_dir }}/coreruleset-{{ site.crs_version | default(caddy_sites_defaults.crs_version) }}/rules/*.conf" Include "{{ caddy_config_dir }}/sites/{{ site.id }}/exclusions-response-after.conf" {% for plugin in site.crs_plugins | default(caddy_sites_defaults.crs_plugins) %} Include "{{ caddy_config_dir }}/crs-plugins/{{ plugin }}-after.conf" {% endfor %} SecRuleEngine On ` } {% endif %} header { Content-Security-Policy "{{ caddy_sites_defaults.header_content_security_policy | combine(site.header_content_security_policy | default({})) | dict2str(sep1=' ', sep2='; ', sep3=';') }}" 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-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=';') }}" 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) }}" Strict-Transport-Security "{{ site.header_strict_transport_security | default(caddy_sites_defaults.header_strict_transport_security) }}" X-Content-Type-Options "{{ site.header_x_content_type_options | default(caddy_sites_defaults.header_x_content_type_options) }}" X-Frame-Options "{{ site.header_x_frame_options | default(caddy_sites_defaults.header_x_frame_options) }}" X-Robots-Tag "{{ site.header_x_robots_tag | default(caddy_sites_defaults.header_x_robots_tag) }}" ?Content-Type "{{ site.header_default_content_type | default(caddy_sites_defaults.header_default_content_type) }}" >Set-Cookie "(.*)" "$1; {{ site.header_cookies_attributes | default(caddy_sites_defaults.header_cookies_attributes) }}" {% for header in site.header_delete | default(caddy_sites_defaults.header_delete) %} -{{ header }} {% endfor %} {% for header in site.header_add | default(caddy_sites_defaults.header_add) %} {{ header.name }} "{{ header.value }}" {% endfor %} } handle_errors 403 { header X-Blocked "true" respond "Your request was blocked. 🔴" } log { format json output file {{ caddy_log_dir }}/site_{{ site.id }}.log } } {% endfor %}