Pi-hole Template#24
Conversation
|
@YouKyi Could you check my template generator, i started using him for this template but i am not sure if the format is correct and how to setup the template to require to upload configs: https://github.com/palmcoasty/bunkerweb-conf-formatter Some feedback would be great and ease future template pull requests. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
Pi-hole Template AdditionTemplate Structure & FilesTemplate correctly placed at
All referenced configuration files exist and are properly integrated. template.json SchemaDefines
ModSecurity Configuration — CRS Rule Relaxation
For
For
This represents a significant WAF relaxation on the administrative and API interfaces. No false-positive mitigation rationale is documented in the PR description or readme. Nginx Configuration
Documentation
Repository Documentation UpdatesNOT UPDATED:
Naming inconsistency: Template uses CI/Pre-commit HooksNo SummaryPi-hole template is structurally complete and configuration files are syntactically valid, but submission is incomplete: CHANGELOG and TEMPLATE_CATALOG require updates, and significant CRS rule disabling (LFI, RCE, injection, XSS categories) lacks justification or false-positive documentation. The ModSecurity relaxation for WalkthroughA new Pi-hole integration template for BunkerWeb is introduced, encompassing ModSecurity exclusion rules, Nginx reverse proxy configuration, template definition, and usage documentation. Four new files establish the complete deployment template. Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@templates/pi-hole/configs/modsec/pihole-exclusions.conf`:
- Around line 1-6: Add this new template to the templates list in template.json
(configs array) and update pihole-exclusions.conf: replace low-numbered rule IDs
(1001–1006) with unique 9,000,000+ IDs, change each ctl:ruleRemoveByTag=... to
ctl:ruleRemoveById=<specific-rule-id> referencing the exact ModSecurity rule IDs
you intend to disable for those paths (use the SecRule lines as anchors), add a
one-line inline comment after each SecRule describing the specific legitimate
traffic being unblocked, and add a top-of-file header comment naming the
template and the Pi‑Hole version it was validated against. Ensure SecRule
entries (the lines beginning with SecRule REQUEST_FILENAME "@beginsWith /api/"
and "/admin/") use the new 9M+ IDs and ctl:ruleRemoveById usage to avoid
removing entire attack families.
- Around line 1-6: The SecRule entries in pihole-exclusions.conf use IDs
1001-1006 which are below the required user/custom range and the file lacks
top-of-file metadata and is not referenced from the template.json configs array;
update each SecRule id to a value >= 9000000 (e.g., 9000000–9000005 or another
block reserved for this template), add a top-of-file comment with the template
name and the Pi-hole version this template was validated against (and any
minimal required metadata such as author or description if your project expects
it), and add "pihole-exclusions.conf" to the owning template.json's configs
array so the file is not orphaned.
In `@templates/pi-hole/configs/server-http/pihole.conf`:
- Line 1: Add a top-of-file comment to the Pi-hole Nginx template indicating
this snippet is for Pi-hole and the specific Pi-hole version it was validated
against (e.g., "Pi-hole template snippet — validated against Pi-hole vX.Y.Z"),
placing it above the existing "location /admin/" line so reviewers can quickly
identify the template and version.
- Around line 5-6: Replace the ineffective response header configuration by
keeping proxy_hide_header X-Frame-Options and replacing proxy_set_header
X-Frame-Options "SAMEORIGIN" with add_header X-Frame-Options "SAMEORIGIN"
always; update both occurrences (lines using proxy_hide_header and
proxy_set_header) so clients actually receive the header. Add a top-of-file
comment in pihole.conf that states the template purpose and the Pi-hole version
this was validated against. Finally, register this file path in the configs
array inside template.json so the template is included in the build/deployment.
In `@templates/pi-hole/readme.md`:
- Line 5: Update the README sentence to clearly explain when to use the provided
template.json versus the raw config: state that the supported/default path is to
use template.json for guided import via the repository's import workflow, and
only use the raw config when the user's DNS setup requires a root-domain entry
that the guided importer cannot represent (the specific "root-domain
exception"); mention the exact condition that triggers the exception and point
readers to the guided import workflow and the raw-config fallback so they know
which path to follow.
- Line 3: Fix the typo "its self" to "itself" and tighten the redirect sentence
for clarity: update the sentence that mentions "/admin/" so it reads succinctly
in British English (e.g. "Pi-hole will always redirect to /admin/ — this
behaviour is inherent to Pi-hole and cannot be changed without modifying Pi-hole
itself."). Ensure the preceding note about serving Pi-hole at the root remains
(warn about extra attack surface) and apply British spelling/concise phrasing.
In `@templates/pi-hole/template.json`:
- Around line 1-30: The template.json for the "pihole" template is missing a
configs array that declares the shipped files; add a top-level "configs" array
in templates/pi-hole/template.json listing "configs/server-http/pihole.conf" and
"configs/modsec/pihole-exclusions.conf" so every file referenced by the template
is declared (ensure the array key is "configs" and use the exact relative paths
used in the repo to match the existing files).
- Around line 1-30: The JSON is missing the root closing brace and must include
an immutable id matching the template directory name and a configs array listing
required config paths; fix template.json by (1) changing the "id" value from
"pihole" to "pi-hole" (lowercase-kebab-case), (2) adding a top-level "configs":
[ "configs/modsec/pihole-exclusions.conf", "configs/server-http/pihole.conf" ]
entry, and (3) appending the missing closing curly brace for the root object
after the existing "settings" block so the file is valid JSON.
- Line 2: The template's immutable id value in template.json is incorrect:
change the "id" field value from "pihole" to the lowercase-kebab-case directory
name "pi-hole" so the id matches the template directory and follows the
project's immutable id convention (update the "id" property in template.json
accordingly).
- Line 20: The default template currently sets MODSECURITY_SEC_RULE_ENGINE to
"DetectionOnly", which weakens enforcement; update the template.json entry for
MODSECURITY_SEC_RULE_ENGINE to an enforcing value (e.g., "On" or "Enabled") so
ModSecurity is active by default, and ensure no other template keys disable
ModSecurity or the CRS (refer to MODSECURITY_SEC_RULE_ENGINE in the file to
locate and replace the value).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4873a3b0-8f80-4c3d-8079-a516658214a5
📒 Files selected for processing (4)
templates/pi-hole/configs/modsec/pihole-exclusions.conftemplates/pi-hole/configs/server-http/pihole.conftemplates/pi-hole/readme.mdtemplates/pi-hole/template.json
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.md
⚙️ CodeRabbit configuration file
**/*.md: Documentation should be concise, accurate, and written in British English:
- Keep a sensible heading hierarchy and prefer concrete instructions over narrative.
- Commands go in backticks or fenced code blocks; keep lines under roughly 100 characters.
- Check that referenced paths, settings, workflows, and external links still match the current repository.
- When a PR changes behaviour, defaults, or packaging, require the matching doc update in the same PR.
Files:
templates/pi-hole/readme.md
templates/**/configs/**/*.conf
⚙️ CodeRabbit configuration file
templates/**/configs/**/*.conf: These are NGINX and ModSecurity snippets loaded by BunkerWeb at runtime. They must be safe and minimal:
- ModSecurity / CRS tuning files (
*_false_positives.conf): prefer targetedctl:ruleRemoveTargetById=/ctl:ruleRemoveById=overSecRuleRemoveByIdwith broad ranges. Every exclusion must have a short comment explaining the specific legitimate traffic it unblocks (endpoint, parameter, rule ID, reason). Do not disable whole paranoia levels or broad rule families.- Rule IDs authored here must live in the user range (>= 9,000,000 for
SecActionmarkers used by CRS plugins, or the custom range documented by the upstream CRS plugin being enabled).- Do not set
SecRuleEngine OfforSecRequestBodyAccess Offin a template config.- NGINX fragments: avoid
ifinsidelocationwhere a prefix match would do; neverproxy_passto an upstream constructed from a request variable (SSRF); do not strip security headers added by BunkerWeb core; do not lower TLS/SSL protocol or cipher strength.- Every file referenced here must also be listed in the owning
template.jsonconfigsarray, and vice versa. Flag orphans in either direction.- Add a short top-of-file comment describing the template the snippet belongs to and the upstream service version it was validated against.
Files:
templates/pi-hole/configs/server-http/pihole.conftemplates/pi-hole/configs/modsec/pihole-exclusions.conf
templates/**/template.json
⚙️ CodeRabbit configuration file
templates/**/template.json:template.jsonis the BunkerWeb template definition consumed by the configurator and the guided-import UI. Apply these rules:
- Required top-level fields:
id(lowercase-kebab-case, matching the template directory name, treated as immutable once published),name(concise user-facing label). Optional:settings(object of BunkerWeb multisite settings),configs(array of relative paths),steps(ordered guided-import workflow).- Two-space indentation, double-quoted keys and strings, no trailing commas. The file must parse with
jq . templates/<name>/template.json.- Setting keys must match BunkerWeb multisite setting names exactly (e.g.
SERVER_NAME,USE_REVERSE_PROXY,REVERSE_PROXY_HOST,MODSECURITY_CRS_PLUGINS,USE_LIMIT_REQ,LIMIT_REQ_RATE,WHITELIST_RDNS). Flag typos, unknown keys, and values that violate documented types or ranges.- Every path referenced from
configs(top-level or inside a step) must resolve to a file that exists under the template directory. Flag missing files, paths that escape the template directory, or duplicate entries. Templates must be self-contained: never reference files outside their owntemplates/<name>/directory.- Each
steps[].settingsentry must refer to a key that also exists in the top-levelsettingsobject — the UI surfaces the step by reading those keys. Flag orphan references.- Templates must stay integration-agnostic. They work identically across Docker, Kubernetes, and Linux, so never introduce environment-specific assets (Dockerfiles,
docker-compose.yml, Kubernetes manifests, Helm charts, systemd units) insidetemplates/<name>/, and never condition settings on the host integration.- Templates must be app-specific, not generic hardening. BunkerWeb already ships built-in
low/medium/highpresets for generic defaults; a template in this repo should target a named upstream service and ship app-aware configs and guidedsteps. Push back on PR...
Files:
templates/pi-hole/template.json
🪛 LanguageTool
templates/pi-hole/readme.md
[grammar] ~3-~3: Did you mean “it’s” (contraction of “it is/has”)?
Context: ...kerweb you would need to modify pi-hole its self to achieve that. If you still wan...
(ITS_TO_IT_S)
| SecRule REQUEST_FILENAME "@beginsWith /api/" "id:1001,phase:2,pass,nolog,ctl:ruleRemoveByTag=attack-lfi" | ||
| SecRule REQUEST_FILENAME "@beginsWith /api/" "id:1002,phase:2,pass,nolog,ctl:ruleRemoveByTag=attack-rce" | ||
| SecRule REQUEST_FILENAME "@beginsWith /api/" "id:1003,phase:2,pass,nolog,ctl:ruleRemoveByTag=attack-injection" | ||
| SecRule REQUEST_FILENAME "@beginsWith /api/" "id:1004,phase:2,pass,nolog,ctl:ruleRemoveById=920420" | ||
| SecRule REQUEST_FILENAME "@beginsWith /admin/" "id:1005,phase:2,pass,nolog,ctl:ruleRemoveByTag=attack-lfi" | ||
| SecRule REQUEST_FILENAME "@beginsWith /admin/" "id:1006,phase:2,pass,nolog,ctl:ruleRemoveByTag=attack-xss" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "pihole-exclusions.conf" -o -name "template.json" | head -20Repository: bunkerity/bunkerweb-templates
Length of output: 411
🏁 Script executed:
ls -la templates/pi-hole/ 2>/dev/null | head -20Repository: bunkerity/bunkerweb-templates
Length of output: 367
🏁 Script executed:
git ls-files templates/pi-hole/ | head -30Repository: bunkerity/bunkerweb-templates
Length of output: 238
🏁 Script executed:
cat -n templates/pi-hole/configs/modsec/pihole-exclusions.confRepository: bunkerity/bunkerweb-templates
Length of output: 749
🏁 Script executed:
cat templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 1226
🏁 Script executed:
find templates -name "*.conf" -path "*/modsec/*" -type f | xargs head -5Repository: bunkerity/bunkerweb-templates
Length of output: 1929
🏁 Script executed:
cat -n templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 1436
🏁 Script executed:
grep -r "1001\|1002\|1003\|1004\|1005\|1006" templates/ --include="*.json" 2>/dev/nullRepository: bunkerity/bunkerweb-templates
Length of output: 55
🏁 Script executed:
grep -A 20 '"configs"' templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 55
🏁 Script executed:
wc -l templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 107
🏁 Script executed:
tail -20 templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 929
🏁 Script executed:
cat templates/netbird/template.json | grep -A 5 '"configs"'Repository: bunkerity/bunkerweb-templates
Length of output: 373
🏁 Script executed:
cat templates/wordpress/template.json | grep -A 2 '"configs"'Repository: bunkerity/bunkerweb-templates
Length of output: 219
🏁 Script executed:
cat templates/xen-orchestra/template.json | grep -A 2 '"configs"'Repository: bunkerity/bunkerweb-templates
Length of output: 261
🏁 Script executed:
grep -r "id:[0-9]" templates/*/configs/modsec/*.conf | grep -o "id:[0-9]*" | sort -uRepository: bunkerity/bunkerweb-templates
Length of output: 227
Add pihole-exclusions.conf to template.json configs array and use rule IDs in the 9M+ range.
This file is not declared in template.json's configs array, so it will not be loaded. Additionally, rule IDs 1001–1006 violate the documented convention that authored rule IDs must use the user range (≥ 9,000,000); see NetBird (3000000+), WordPress (9005000+), and Xen-Orchestra (9010000) for correct patterns. Adopt IDs from the 9M+ range to avoid collision and align with project standards.
Furthermore, lines 1–3 and 5–6 remove entire attack families by tag (attack-lfi, attack-rce, attack-injection, attack-xss) across /api/ and /admin/ endpoints. Replace with specific ctl:ruleRemoveById= and include a one-line inline comment explaining the legitimate traffic each exclusion unblocks. Add a top-of-file header comment stating the template name and the Pi-Hole version this was validated against.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/configs/modsec/pihole-exclusions.conf` around lines 1 - 6,
Add this new template to the templates list in template.json (configs array) and
update pihole-exclusions.conf: replace low-numbered rule IDs (1001–1006) with
unique 9,000,000+ IDs, change each ctl:ruleRemoveByTag=... to
ctl:ruleRemoveById=<specific-rule-id> referencing the exact ModSecurity rule IDs
you intend to disable for those paths (use the SecRule lines as anchors), add a
one-line inline comment after each SecRule describing the specific legitimate
traffic being unblocked, and add a top-of-file header comment naming the
template and the Pi‑Hole version it was validated against. Ensure SecRule
entries (the lines beginning with SecRule REQUEST_FILENAME "@beginsWith /api/"
and "/admin/") use the new 9M+ IDs and ctl:ruleRemoveById usage to avoid
removing entire attack families.
🧩 Analysis chain
🏁 Script executed:
# First, check if the file exists and read its content
cat -n templates/pi-hole/configs/modsec/pihole-exclusions.confRepository: bunkerity/bunkerweb-templates
Length of output: 749
🏁 Script executed:
# Check if template.json exists for pi-hole and list its configs
if [ -f templates/pi-hole/template.json ]; then
cat templates/pi-hole/template.json | jq '.configs // empty' 2>/dev/null | head -50
fiRepository: bunkerity/bunkerweb-templates
Length of output: 55
🏁 Script executed:
# Search for the file in case the path is different
fd -type f -name "*pihole*exclusions*"Repository: bunkerity/bunkerweb-templates
Length of output: 243
🏁 Script executed:
# Find template.json files in templates directory
find templates -name "template.json" -type f | head -20Repository: bunkerity/bunkerweb-templates
Length of output: 337
🏁 Script executed:
# Check the pi-hole template directory structure
ls -la templates/pi-hole/Repository: bunkerity/bunkerweb-templates
Length of output: 367
🏁 Script executed:
# Look for the pi-hole template.json specifically
cat templates/pi-hole/template.json 2>/dev/null | jq '.configs' 2>/dev/nullRepository: bunkerity/bunkerweb-templates
Length of output: 55
🏁 Script executed:
# Read the template.json file directly
cat templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 1226
🏁 Script executed:
# Also check the configs directory structure
find templates/pi-hole/configs -type fRepository: bunkerity/bunkerweb-templates
Length of output: 178
🏁 Script executed:
# Get the full template.json content and look for configs section
cat templates/pi-hole/template.json | jq -r '.configs' 2>/dev/null || cat templates/pi-hole/template.json | grep -A 20 '"configs"'Repository: bunkerity/bunkerweb-templates
Length of output: 55
🏁 Script executed:
# Also read the entire template.json to see full structure
wc -l templates/pi-hole/template.json && tail -100 templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 1261
🏁 Script executed:
# Read the complete template.json file from start to finish
cat templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 1226
🏁 Script executed:
# Get the last 10 lines of template.json to see the configs array
tail -10 templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 458
🏁 Script executed:
# Alternative: use python to parse and check if configs exists
python3 << 'EOF'
import json
with open('templates/pi-hole/template.json', 'r') as f:
data = json.load(f)
if 'configs' in data:
print("configs array exists:")
print(json.dumps(data['configs'], indent=2))
else:
print("No 'configs' key found in template.json")
print("Keys present:", list(data.keys()))
EOFRepository: bunkerity/bunkerweb-templates
Length of output: 812
🏁 Script executed:
# Read specific lines to see what's at the end
sed -n '20,30p' templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 510
🏁 Script executed:
# Check actual file size and content
hexdump -C templates/pi-hole/template.json | tail -20Repository: bunkerity/bunkerweb-templates
Length of output: 118
🏁 Script executed:
# Check if there's anything beyond line 30
sed -n '28,$p' templates/pi-hole/template.json | cat -ARepository: bunkerity/bunkerweb-templates
Length of output: 164
🏁 Script executed:
# Count actual lines and check file end
tail -c 100 templates/pi-hole/template.json | od -cRepository: bunkerity/bunkerweb-templates
Length of output: 115
🏁 Script executed:
# Check if other templates have configs arrays to understand the expected structure
for template in templates/*/template.json; do
echo "=== $template ==="
grep -c '"configs"' "$template" 2>/dev/null || echo "No configs found"
doneRepository: bunkerity/bunkerweb-templates
Length of output: 468
🏁 Script executed:
# Look at a complete template to see the pattern
cat templates/wordpress/template.json 2>/dev/null | tail -20Repository: bunkerity/bunkerweb-templates
Length of output: 674
Fix rule IDs to comply with user range, add required metadata, and reference file in template.json.
Lines 1-6 use IDs 1001-1006, which fall below the required user range (>= 9,000,000 for custom SecAction markers); the file lacks a top-of-file comment documenting the template name and Pi-hole version validated against; and pihole-exclusions.conf is not listed in the owning template.json configs array, creating an orphaned file.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/configs/modsec/pihole-exclusions.conf` around lines 1 - 6,
The SecRule entries in pihole-exclusions.conf use IDs 1001-1006 which are below
the required user/custom range and the file lacks top-of-file metadata and is
not referenced from the template.json configs array; update each SecRule id to a
value >= 9000000 (e.g., 9000000–9000005 or another block reserved for this
template), add a top-of-file comment with the template name and the Pi-hole
version this template was validated against (and any minimal required metadata
such as author or description if your project expects it), and add
"pihole-exclusions.conf" to the owning template.json's configs array so the file
is not orphaned.
| @@ -0,0 +1,17 @@ | |||
| location /admin/ { | |||
There was a problem hiding this comment.
Add the required file header comment.
Please add a short top-of-file comment indicating this is the Pi-hole template snippet and the Pi-hole version it was validated against.
As per coding guidelines "Add a short top-of-file comment describing the template the snippet belongs to and the upstream service version it was validated against."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/configs/server-http/pihole.conf` at line 1, Add a
top-of-file comment to the Pi-hole Nginx template indicating this snippet is for
Pi-hole and the specific Pi-hole version it was validated against (e.g.,
"Pi-hole template snippet — validated against Pi-hole vX.Y.Z"), placing it above
the existing "location /admin/" line so reviewers can quickly identify the
template and version.
| proxy_hide_header X-Frame-Options; | ||
| proxy_set_header X-Frame-Options "SAMEORIGIN"; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find and examine the pihole.conf file
find . -path "*templates/pi-hole/configs/server-http/pihole.conf" -type fRepository: bunkerity/bunkerweb-templates
Length of output: 124
🏁 Script executed:
# Also check if template.json exists for pi-hole
find . -path "*templates/pi-hole/template.json" -type fRepository: bunkerity/bunkerweb-templates
Length of output: 106
🏁 Script executed:
cat -n ./templates/pi-hole/configs/server-http/pihole.confRepository: bunkerity/bunkerweb-templates
Length of output: 760
🏁 Script executed:
cat ./templates/pi-hole/template.json | head -100Repository: bunkerity/bunkerweb-templates
Length of output: 1226
🏁 Script executed:
cat ./templates/pi-hole/template.json | jq '.configs // "NO_CONFIGS_KEY"'Repository: bunkerity/bunkerweb-templates
Length of output: 134
🌐 Web query:
NGINX proxy_set_header vs add_header X-Frame-Options response header
💡 Result:
proxy_set_header sets request headers sent to the upstream server, while add_header adds response headers to the client. For the X-Frame-Options response header, use add_header in the nginx server or location block, even with proxy_pass. To set X-Frame-Options SAMEORIGIN: add_header X-Frame-Options "SAMEORIGIN" always; The 'always' parameter (since nginx 1.7.5) ensures the header is added for all response codes, including errors. If the upstream server sets X-Frame-Options and you want nginx to override it, first hide the upstream header: proxy_hide_header X-Frame-Options; add_header X-Frame-Options "SAMEORIGIN" always; proxy_set_header cannot be used for response headers like X-Frame-Options.
Citations:
- 1: https://nginx.org/en/docs/http/ngx_http_headers_module.html
- 2: https://stackoverflow.com/questions/14501047/how-to-add-a-response-header-on-nginx-when-using-proxy-pass
- 3: https://nginx.org/r/proxy_set_header
- 4: https://nginx.org/en/docs/http/ngx_http_proxy_module.html
- 5: https://oneuptime.com/blog/post/2026-01-25-nginx-security-headers/view
- 6: https://www.simplified.guide/nginx/header-custom
🏁 Script executed:
wc -l ./templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 109
🏁 Script executed:
sed -n '1,50p' ./templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 1226
🏁 Script executed:
tail -20 ./templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 929
Replace proxy_set_header with add_header to actually set the response header.
Lines 5–6 and 14–15 use proxy_hide_header X-Frame-Options followed by proxy_set_header X-Frame-Options "SAMEORIGIN". This is ineffective: proxy_set_header sets only request headers sent to the upstream, not response headers to clients. Clients receive no X-Frame-Options header, weakening clickjacking protection. Replace with:
proxy_hide_header X-Frame-Options;
add_header X-Frame-Options "SAMEORIGIN" always;
Also add a top-of-file comment describing the template and Pi-hole version this was validated against, and register this file in the configs array of template.json.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/configs/server-http/pihole.conf` around lines 5 - 6,
Replace the ineffective response header configuration by keeping
proxy_hide_header X-Frame-Options and replacing proxy_set_header X-Frame-Options
"SAMEORIGIN" with add_header X-Frame-Options "SAMEORIGIN" always; update both
occurrences (lines using proxy_hide_header and proxy_set_header) so clients
actually receive the header. Add a top-of-file comment in pihole.conf that
states the template purpose and the Pi-hole version this was validated against.
Finally, register this file path in the configs array inside template.json so
the template is included in the build/deployment.
| @@ -0,0 +1,37 @@ | |||
| # Pi-hole on Root Domain with BunkerWeb | |||
|
|
|||
| It is possible to serve Pi-hole at the root of your domain, but this adds an extra attack surface and is **not advised**. Additionally, you will always be redirected to `/admin/` — this is how Pi-hole is built and cannot be changed, by using bunkerweb you would need to modify pi-hole its self to achieve that. | |||
There was a problem hiding this comment.
Fix wording and grammar on the redirect explanation.
Line 3 has a typo (“its self” → “itself”) and awkward phrasing. Please tighten this sentence for clarity in British English.
As per coding guidelines "Documentation should be concise, accurate, and written in British English."
🧰 Tools
🪛 LanguageTool
[grammar] ~3-~3: Did you mean “it’s” (contraction of “it is/has”)?
Context: ...kerweb you would need to modify pi-hole its self to achieve that. If you still wan...
(ITS_TO_IT_S)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/readme.md` at line 3, Fix the typo "its self" to "itself"
and tighten the redirect sentence for clarity: update the sentence that mentions
"/admin/" so it reads succinctly in British English (e.g. "Pi-hole will always
redirect to /admin/ — this behaviour is inherent to Pi-hole and cannot be
changed without modifying Pi-hole itself."). Ensure the preceding note about
serving Pi-hole at the root remains (warn about extra attack surface) and apply
British spelling/concise phrasing.
|
|
||
| It is possible to serve Pi-hole at the root of your domain, but this adds an extra attack surface and is **not advised**. Additionally, you will always be redirected to `/admin/` — this is how Pi-hole is built and cannot be changed, by using bunkerweb you would need to modify pi-hole its self to achieve that. | ||
|
|
||
| If you still want to proceed, use the raw config below instead of the template.json. |
There was a problem hiding this comment.
Clarify when to use template.json vs raw config.
Line 5 instructs users to bypass template.json, which is confusing in a template PR. Please explicitly state the supported path for guided import and the specific root-domain exception requiring raw config.
As per coding guidelines "Check that referenced paths, settings, workflows ... still match the current repository."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/readme.md` at line 5, Update the README sentence to clearly
explain when to use the provided template.json versus the raw config: state that
the supported/default path is to use template.json for guided import via the
repository's import workflow, and only use the raw config when the user's DNS
setup requires a root-domain entry that the guided importer cannot represent
(the specific "root-domain exception"); mention the exact condition that
triggers the exception and point readers to the guided import workflow and the
raw-config fallback so they know which path to follow.
| { | ||
| "id": "pihole", | ||
| "name": "Pihole BunkerWeb Configuration", | ||
| "settings": { | ||
| "IS_DRAFT": "no", | ||
| "SERVER_NAME": "example.com", | ||
| "BAD_BEHAVIOR_STATUS_CODES": "400 403 404 405 429 444", | ||
| "BAD_BEHAVIOR_THRESHOLD": "20", | ||
| "BAD_BEHAVIOR_BAN_TIME": "3600", | ||
| "USE_BUNKERNET": "yes", | ||
| "USE_DNSBL": "no", | ||
| "GZIP_PROXIED": "expired no-cache no-store private auth", | ||
| "REMOVE_HEADERS": "Server Expect-CT X-Powered-By X-AspNet-Version X-AspNetMvc-Version Public-Key-Pins X-Frame-Options", | ||
| "AUTO_LETS_ENCRYPT": "yes", | ||
| "EMAIL_LETS_ENCRYPT": "registration@example.com", | ||
| "LIMIT_CONN_MAX_HTTP2": "50", | ||
| "LIMIT_CONN_MAX_HTTP3": "50", | ||
| "LIMIT_REQ_RATE": "20r/s", | ||
| "USE_METRICS": "no", | ||
| "MODSECURITY_SEC_RULE_ENGINE": "DetectionOnly", | ||
| "USE_REAL_IP": "yes", | ||
| "REAL_IP_FROM": "172.65.0.0/16 172.64.0.0/13 104.16.0.0/13", | ||
| "REAL_IP_HEADER": "CF-Connecting-IP", | ||
| "USE_REVERSE_PROXY": "yes", | ||
| "REVERSE_PROXY_HOST_1": "http://pihole-server-ip:80/", | ||
| "REVERSE_PROXY_WS_1": "yes", | ||
| "REVERSE_PROXY_KEEPALIVE_1": "yes", | ||
| "REVERSE_PROXY_HIDE_HEADERS_1": "", | ||
| "REVERSE_PROXY_CONNECT_TIMEOUT_1": "30s" | ||
| } |
There was a problem hiding this comment.
Add a configs array to declare both shipped config files.
templates/pi-hole/configs/server-http/pihole.conf and templates/pi-hole/configs/modsec/pihole-exclusions.conf exist, but no configs mapping is declared in this template definition.
As per coding guidelines "Every file referenced here must also be listed in the owning template.json configs array, and vice versa. Flag orphans in either direction."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/template.json` around lines 1 - 30, The template.json for
the "pihole" template is missing a configs array that declares the shipped
files; add a top-level "configs" array in templates/pi-hole/template.json
listing "configs/server-http/pihole.conf" and
"configs/modsec/pihole-exclusions.conf" so every file referenced by the template
is declared (ensure the array key is "configs" and use the exact relative paths
used in the repo to match the existing files).
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
jq . templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 134
🏁 Script executed:
# Read the complete template.json file
cat -n templates/pi-hole/template.jsonRepository: bunkerity/bunkerweb-templates
Length of output: 1436
🏁 Script executed:
# List all files in the pi-hole template directory
find templates/pi-hole -type f -lsRepository: bunkerity/bunkerweb-templates
Length of output: 526
🏁 Script executed:
# Check if there are config files that should be referenced
ls -la templates/pi-hole/Repository: bunkerity/bunkerweb-templates
Length of output: 367
Fix template.json syntax and add missing id and configs fields.
The file is missing the closing brace for the root object (line 30 ends with settings close only; jq parsing fails with "Unfinished JSON term at EOF"). Additionally, the id on line 2 is "pihole" but the template directory is pi-hole — guidelines require the id to match the directory name in lowercase-kebab-case and treat it as immutable. Finally, two config files exist in the template directory (configs/modsec/pihole-exclusions.conf and configs/server-http/pihole.conf) but are not referenced in a configs array; the template must declare its configuration dependencies for the configurator to load them.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/template.json` around lines 1 - 30, The JSON is missing the
root closing brace and must include an immutable id matching the template
directory name and a configs array listing required config paths; fix
template.json by (1) changing the "id" value from "pihole" to "pi-hole"
(lowercase-kebab-case), (2) adding a top-level "configs": [
"configs/modsec/pihole-exclusions.conf", "configs/server-http/pihole.conf" ]
entry, and (3) appending the missing closing curly brace for the root object
after the existing "settings" block so the file is valid JSON.
| @@ -0,0 +1,30 @@ | |||
| { | |||
| "id": "pihole", | |||
There was a problem hiding this comment.
Template ID must match the directory and kebab-case form.
Line 2 uses "pihole", but the directory is pi-hole; the ID should be "pi-hole" to stay consistent and immutable.
As per coding guidelines "id (lowercase-kebab-case, matching the template directory name, treated as immutable once published)."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/template.json` at line 2, The template's immutable id value
in template.json is incorrect: change the "id" field value from "pihole" to the
lowercase-kebab-case directory name "pi-hole" so the id matches the template
directory and follows the project's immutable id convention (update the "id"
property in template.json accordingly).
| "LIMIT_CONN_MAX_HTTP3": "50", | ||
| "LIMIT_REQ_RATE": "20r/s", | ||
| "USE_METRICS": "no", | ||
| "MODSECURITY_SEC_RULE_ENGINE": "DetectionOnly", |
There was a problem hiding this comment.
Avoid weakening ModSecurity posture in the default template.
Line 20 sets MODSECURITY_SEC_RULE_ENGINE to DetectionOnly, which relaxes enforcement for a production template baseline.
As per coding guidelines "ModSecurity / CRS ... Do not disable ModSecurity or the CRS in a template."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@templates/pi-hole/template.json` at line 20, The default template currently
sets MODSECURITY_SEC_RULE_ENGINE to "DetectionOnly", which weakens enforcement;
update the template.json entry for MODSECURITY_SEC_RULE_ENGINE to an enforcing
value (e.g., "On" or "Enabled") so ModSecurity is active by default, and ensure
no other template keys disable ModSecurity or the CRS (refer to
MODSECURITY_SEC_RULE_ENGINE in the file to locate and replace the value).
Summary
Testing
jq . templates/<template-name>/template.jsonValidation details
Checklist
pre-commit run --all-files.template.jsonreferences only files shipped in the same template directory.