This commit is contained in:
Mateusz Gruszczyński committed 2026-10-25 17:45:57 +01:00
1 parent bd077754a9
commit ed7e3377c1
40 files changed
+1764 -365

No files matched your search

+84 -29
View File
@@ -2088,40 +2088,93 @@
</div>
<nav aria-label="Rules and headers" class="settings-tabs sub-tabs"
id="policy-settings-tabs" role="tablist">
<button aria-selected="true" data-policy-settings-tab="user-agent"
data-i18n="globalUaBlockingTitle" type="button">Global User-Agent
blocklist</button>
<button aria-selected="true" data-policy-settings-tab="block-allow"
data-i18n="globalBlockAllow" type="button">Global block / allow</button>
<button aria-selected="false" data-policy-settings-tab="security-headers"
data-i18n="globalSecurityHeaders" type="button">Security headers</button>
<button aria-selected="false" data-policy-settings-tab="headers"
data-i18n="customHeaders" type="button">Global custom headers</button>
<button aria-selected="false" data-policy-settings-tab="response"
data-i18n="responseSettings" type="button">Client response</button>
</nav>
</div>
<div data-policy-settings-page="user-agent">
<article class="card security-policy-card">
<div data-policy-settings-page="block-allow">
<form class="card edit-form global-policy-form" id="global-security-form">
<div class="card-heading">
<div><span class="small-label" data-i18n="userAgentBlocking">USER-AGENT
BLOCKING</span>
<h2 data-i18n="globalUaBlockingTitle">Global User-Agent blocklist</h2>
<p class="fine" data-i18n="globalUaBlockingHelp">Blocks matching User-Agent
values on public proxy vhosts before an upstream is opened. Per-vhost
lists are configured in Vhosts → Security.</p>
</div>
<div><span class="small-label" data-i18n="globalPolicyScope">PUBLIC HTTP LISTENERS</span>
<h2 data-i18n="globalBlockAllow">Global block / allow</h2>
</div><span class="pill live" data-i18n="hotApply">LIVE APPLY</span>
</div>
<form class="edit-form security-inline-form" id="global-ua-block-form">
<label class="check"><input id="global-ua-block-enabled" type="checkbox" /><span
data-i18n="enabled">Enabled</span></label>
<label><span data-i18n="uaBlockPatterns">Blocked patterns, one per
line</span><textarea id="global-ua-block-patterns" rows="6"
maxlength="32768" spellcheck="false"
placeholder="BadBot&#10;curl/*&#10;*scanner*"></textarea></label>
<p class="fine" data-i18n="uaBlockPatternHelp">Matching is case-insensitive.
Plain text matches a substring; * is a wildcard. Requests without User-Agent
are not blocked by this rule.</p>
<div class="form-actions"><button class="primary" data-i18n="apply"
type="submit">Validate, save and apply</button></div>
</form>
</article>
<p class="fine" data-i18n="globalPolicyHelp">These rules apply before routing to the backend on all public HTTP vhosts, redirects and 404 hosts. Per-vhost restrictions remain active; a local allow cannot bypass a global block. Administration and TCP/UDP Streams are excluded.</p>
<section class="global-policy-section">
<div class="global-policy-heading"><h3 data-i18n="globalCountryTitle">Country access</h3><p class="fine" data-i18n="globalCountryHelp">Uses the verified client IP and GeoIP database. Unknown countries are denied in allow mode, but allowed in block mode.</p></div>
<div class="global-policy-fields">
<label><span data-i18n="globalCountryMode">Country policy</span><select id="global-country-mode">
<option value="off" data-i18n="vhOff">Off</option>
<option value="block" data-i18n="vhCountryBlock">Block listed</option>
<option value="allow" data-i18n="vhCountryAllow">Allow listed only</option>
</select></label>
<label><span data-i18n="globalCountryList">ISO country codes (one per line)</span><textarea id="global-country-list" rows="3" maxlength="1024" spellcheck="false" placeholder="RU&#10;CN"></textarea></label>
</div>
</section>
<section class="global-policy-section">
<div class="global-policy-heading"><h3 data-i18n="globalUaTitle">User-Agent blocklist</h3><p class="fine" data-i18n="uaBlockPatternHelp">Case-insensitive substring matching; * is a wildcard. A missing User-Agent is not blocked.</p></div>
<label class="check"><input id="global-ua-block-enabled" type="checkbox"/><span data-i18n="globalUaEnabled">Block matching User-Agents</span></label>
<label><span data-i18n="uaBlockPatterns">Blocked patterns, one per line</span><textarea id="global-ua-block-patterns" rows="4" maxlength="32768" spellcheck="false" placeholder="BadBot&#10;curl/*&#10;*scanner*"></textarea></label>
</section>
<section class="global-policy-section">
<div class="global-policy-heading"><h3 data-i18n="globalIpTitle">IP / CIDR access</h3><p class="fine" data-i18n="globalIpHelp">Each line: allow or deny followed by IPv4/IPv6 address, CIDR or allow-only DNS name. Default allow with no rules leaves access unrestricted.</p></div>
<label class="check"><input id="global-ip-enabled" type="checkbox"/><span data-i18n="globalIpEnabled">Enable global IP rules</span></label>
<div class="global-policy-fields">
<label><span data-i18n="aclDefault">Default action</span><select id="global-ip-default"><option value="allow" data-i18n="allow">Allow</option><option value="deny" data-i18n="deny">Deny</option></select></label>
<label><span data-i18n="globalIpRules">Rules (one per line)</span><textarea id="global-ip-rules" rows="3" maxlength="32768" placeholder="deny 192.0.2.0/24&#10;allow 10.0.0.0/8" spellcheck="false"></textarea></label>
</div>
</section>
<section class="global-policy-section">
<div class="global-policy-heading"><h3 data-i18n="globalMethodTitle">HTTP methods</h3><p class="fine" data-i18n="globalMethodHelp">Block selected methods or allow only those listed. Applies before redirects and cache invalidation; denied requests receive 405.</p></div>
<div class="global-policy-fields">
<label><span data-i18n="globalMethodMode">Method policy</span><select id="global-method-mode"><option value="off" data-i18n="vhOff">Off</option><option value="block" data-i18n="locationMethodBlock">Block listed</option><option value="allow" data-i18n="locationMethodAllow">Allow listed only</option></select></label>
<label><span data-i18n="globalMethodList">Methods (comma, space or newline separated)</span><textarea id="global-method-list" rows="2" maxlength="1024" spellcheck="false" placeholder="TRACE, TRACK"></textarea></label>
</div>
</section>
<section class="global-policy-section">
<div class="global-policy-heading"><h3 data-i18n="globalContentTypeTitle">Request Content-Type</h3><p class="fine" data-i18n="globalContentTypeHelp">Reject declared MIME types (exact or type/*) with 403. This is a header rule, not body inspection.</p></div>
<label class="check"><input id="global-content-type-enabled" type="checkbox"/><span data-i18n="globalContentTypeEnabled">Enable Content-Type denylist</span></label>
<label><span data-i18n="globalContentTypeList">Blocked MIME types, one per line</span><textarea id="global-content-type-list" rows="3" maxlength="16384" spellcheck="false" placeholder="application/x-msdownload&#10;application/x-sh"></textarea></label>
</section>
<section class="global-policy-section">
<div class="global-policy-heading"><h3 data-i18n="globalRateTitle">Shared rate limit</h3><p class="fine" data-i18n="globalRateHelp">Optional per-client-IP limit shared by all public vhosts. Runs in addition to per-vhost limits; use conservative values to avoid blocking legitimate shared clients.</p></div>
<label class="check"><input id="global-rate-enabled" type="checkbox"/><span data-i18n="globalRateEnabled">Enable global request rate limit</span></label>
<div class="global-rate-fields">
<label><span data-i18n="globalRateRequests">Requests per window</span><input id="global-rate-requests" type="number" min="1" max="1000000" required value="120"/></label>
<label><span data-i18n="globalRateWindow">Window (seconds)</span><input id="global-rate-window" type="number" min="1" max="3600" required value="60"/></label>
<label><span data-i18n="globalRateBurst">Burst allowance</span><input id="global-rate-burst" type="number" min="0" max="1000000" required value="30"/></label>
</div>
</section>
<div class="form-actions"><button class="primary" data-i18n="globalPolicySave" type="submit">Apply global block / allow rules</button></div>
</form>
</div>
<div data-policy-settings-page="security-headers" hidden="">
<form class="card edit-form global-policy-form" id="global-security-headers-form">
<div class="card-heading"><div><span class="small-label" data-i18n="globalPolicyScope">PUBLIC HTTP LISTENERS</span><h2 data-i18n="globalSecurityHeaders">Security headers</h2></div><span class="pill live" data-i18n="hotApply">LIVE APPLY</span></div>
<p class="fine" data-i18n="globalHeadersSecurityHelp">Global response-header baseline for public HTTP vhosts, redirects and 404 hosts. Explicit per-vhost values override matching global headers. HSTS is sent only over HTTPS; test CSP carefully before rollout.</p>
<section class="global-policy-section"><h3 data-i18n="vhSecurityHstsSection">HTTP Strict Transport Security (HSTS)</h3>
<label class="check"><input id="global-hsts-enabled" type="checkbox"/><span data-i18n="vhHsts">Enable HSTS</span></label>
<div class="global-rate-fields">
<label><span data-i18n="vhHstsAge">Max age (seconds)</span><input id="global-hsts-age" type="number" min="0" max="63072000" required value="31536000"/></label>
<label class="check"><input id="global-hsts-sub" type="checkbox"/><span data-i18n="vhHstsSub">Include subdomains</span></label>
<label class="check"><input id="global-hsts-preload" type="checkbox"/><span data-i18n="vhHstsPreload">Preload</span></label>
</div>
</section>
<section class="global-policy-section"><h3 data-i18n="vhSecurityHeadersSection">Response security headers</h3>
<label class="check"><input id="global-nosniff" type="checkbox"/><span data-i18n="vhNosniff">X-Content-Type-Options: nosniff</span></label>
<label><span data-i18n="vhFrame">X-Frame-Options</span><select id="global-frame"><option value="preserve" data-i18n="vhPreserve">Preserve origin value</option><option value="deny" data-i18n="vhDeny">DENY</option><option value="sameorigin" data-i18n="vhSameorigin">SAMEORIGIN</option></select></label>
<label><span data-i18n="vhReferrer">Referrer-Policy</span><input id="global-referrer" maxlength="8192" spellcheck="false" placeholder="strict-origin-when-cross-origin"/></label>
<label><span data-i18n="vhCsp">Content-Security-Policy</span><textarea id="global-csp" rows="3" maxlength="8192" spellcheck="false" placeholder="default-src 'self'"></textarea></label>
<label><span data-i18n="vhPermissions">Permissions-Policy</span><input id="global-permissions" maxlength="8192" spellcheck="false" placeholder="camera=(), microphone=()"/></label>
</section>
<div class="form-actions"><button class="primary" data-i18n="globalSecurityHeadersSave" type="submit">Apply security headers</button></div>
</form>
</div>
<div data-policy-settings-page="headers" hidden="">
<form class="card edit-form" id="headers-form">
@@ -2447,8 +2500,9 @@
<label data-i18n="cacheStaticExtensions" for="cache-static-extensions">Global static
extensions</label><textarea id="cache-static-extensions" rows="5"
spellcheck="false"></textarea>
<p class="fine" data-i18n="cacheStaticHelp">Cookie bypass is limited to these file
<p class="fine cache-static-guidance" data-i18n="cacheStaticHelp">Cookie bypass is limited to these file
extensions. Response privacy rules still apply.</p>
<h3 class="subheading cache-header-settings-heading" data-i18n="cacheHeadersSection">Cache response headers</h3>
<div class="switch-grid"><label class="check"><input id="cache-status-header"
type="checkbox" /><span>X-Cache: HIT / MISS /
BYPASS</span></label><label class="check"><input id="cache-hits-header"
@@ -2541,7 +2595,7 @@
<p class="fine" id="transform-preset-summary">-</p>
</div>
<p class="fine" id="transform-memory-warning" hidden></p>
<div class="field-grid">
<div class="field-grid transform-limits-grid">
<div><label data-i18n="transformMemoryBudget"
for="transform-memory-budget">Temporary
transform memory budget (MiB)</label><input id="transform-memory-budget"
@@ -2554,7 +2608,8 @@
concurrent transformations</label><input id="transform-max-inflight" min="1"
max="1024" required="" type="number" /></div>
</div>
<div class="switch-grid">
<h3 class="subheading transform-operations-title" data-i18n="transformOperationsTitle">Content transformations</h3>
<div class="switch-grid transform-operations-grid">
<label class="check"><input id="transform-javascript" type="checkbox" /><span
data-i18n="transformJavascript">JavaScript minification</span></label>
<label class="check"><input id="transform-css" type="checkbox" /><span