Private
Public Access
2
0

caddy: CORS

This commit is contained in:
2026-02-02 22:09:18 +03:00
parent 7e4857f762
commit d7b6e468d7
2 changed files with 115 additions and 50 deletions

View File

@@ -1,7 +1,9 @@
{
http_port {{ caddy_http_port }}
https_port {{ caddy_https_port }}
{% if caddy_default_bind != "" %}
default_bind {{ caddy_default_bind }}
{% endif %}
order geoip2_vars first
order coraza_waf first
admin off
@@ -44,6 +46,43 @@
}
}
# 0=origin, 1=methods, 2=headers, 3=allow credentials, 4=max age, 5=vary, 6=expose headers
(cors) {
@match-cors-preflight-{args.0} {
header Origin {args.0}
method OPTIONS
}
header @match-cors-preflight-{args.0} {
Access-Control-Allow-Origin "{args.0}"
Access-Control-Allow-Methods "{args.1}"
Access-Control-Allow-Headers "{args.2}"
Access-Control-Allow-Credentials "{args.3}"
Access-Control-Max-Age "{args.4}"
Vary "{args.5}"
}
handle @match-cors-preflight-{args.0} {
respond "" 204
}
@match-cors-request-{args.0} {
header Origin {args.0}
not method OPTIONS
}
header @match-cors-request-{args.0} {
>Access-Control-Allow-Origin "{args.0}"
>Access-Control-Allow-Credentials "{args.3}"
>Vary "{args.5}"
>Access-Control-Expose-Headers "{args.6}"
}
}
(cors-deny) {
@cors-preflight-deny method OPTIONS
handle @cors-preflight-deny {
respond "" 403
}
}
{% 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 %}
@@ -103,33 +142,33 @@
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}"
header x-geoip-is-anonymous "{geoip2.is_anonymous}"
header x-geoip-is-anonymous-vpn "{geoip2.is_anonymous_vpn}"
header x-geoip-is-hosting-provider "{geoip2.is_hosting_provider}"
header x-geoip-is-public-proxy "{geoip2.is_public_proxy}"
header x-geoip-is-residential-proxy "{geoip2.is_residential_proxy}"
header x-geoip-is-tor-exit-node "{geoip2.is_tor_exit_node}"
header x-geoip-connection-type "{geoip2.connection_type}"
header x-geoip-domain "{geoip2.domain}"
header x-geoip-country-code "{geoip2.country_code}"
# header x-geoip-country-confidence "{geoip2.country_confidence}"
header x-geoip-country-eu "{geoip2.country_eu}"
header x-geoip-country-geoname-id "{geoip2.country_geoname_id}"
header x-geoip-country-name "{geoip2.country_name}"
header x-geoip-continent-code "{geoip2.continent_code}"
header x-geoip-continent-geoname-id "{geoip2.continent_geoname_id}"
header x-geoip-continent-name "{geoip2.continent_name}"
# header x-geoip-city-confidence "{geoip2.city_confidence}"
header x-geoip-city-geoname-id "{geoip2.city_geoname_id}"
header x-geoip-city-name "{geoip2.city_name}"
header x-geoip-location-time-zone "{geoip2.location_time_zone}"
header x-geoip-autonomous-system-number "{geoip2.autonomous_system_number}"
header x-geoip-autonomous-system-organization "{geoip2.autonomous_system_organization}"
header x-geoip-isp "{geoip2.isp}"
header x-geoip-mobile-country-code "{geoip2.mobile_country_code}"
header x-geoip-mobile-network-code "{geoip2.mobile_network_code}"
header x-geoip-organization "{geoip2.organization}"
header x-geoip-ip-address "{geoip2.ip_address}"
{% endif %}
{% endif %}
@@ -139,18 +178,6 @@
{% 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
@@ -183,11 +210,31 @@
}
{% endif %}
{% if site.cors | default(caddy_sites_defaults.cors) %}
{% 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(', ') }}"
{% endfor %}
import cors-deny
{% endif %}
{% 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 %}
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) }}"
# FIXME
# 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) }}"