"Use when the user asks to expose Splunk Enterprise on the public internet, harden a Splunk search head
Scanned 9/9/2026
Install to Claude Code
npx -y skills add chambear2809/splunk-cisco-skills --skill splunk-enterprise-public-exposure-hardening --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Splunk Enterprise Public Exposure Hardening?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/chambear2809-splunk-enterprise-public-exposure-hardening)More formats (shields.io, HTML) on the badges page.
---
name: splunk-enterprise-public-exposure-hardening
description: "Use when the user asks to expose Splunk Enterprise on the public internet, harden a Splunk search head
against internet exposure, configure TLS / HSTS / CSP / mTLS / per-IP rate limit / DMZ heavy forwarder,
lock down splunkd or the KV store, fix splunk.secret / pass4SymmKey defaults, evaluate against the
latest SVD floor (10.4.0 / 10.2.2 / 10.0.5 / 9.4.10 / 9.3.11), or render nginx / HAProxy / WAF reference
configs in front of Splunk. Render, preflight, apply, and validate hardening of an on-prem Splunk
Enterprise deployment for public-internet exposure across all four edge surfaces (Splunk Web on 8000,
HEC on 8088, Splunk-to-Splunk on 9997, splunkd REST on 8089) plus reference reverse-proxy / WAF /
firewall templates and a structured operator handoff."
compatibility: "Splunk Cloud Platform 10.5.2605: not applicable. This self-managed runtime workflow remains on the public Splunk Enterprise or Universal Forwarder 10.4 baseline."
metadata:
splunk_cloud_10_5: "self-managed-10.4"
compatibility_verified: "2026-08-20"
---
# Splunk Enterprise Public Internet Exposure Hardening
## Prerequisites
| Tool or access | Purpose | Verify |
|---|---|---|
| Bash and Python 3 | Run bundled setup and validation helpers | `bash --version && python3 --version` |
| Required product/platform access | Inspect or configure the selected target | Complete the documented preflight |
| Credential files for live modes | Keep secrets out of chat | Verify paths only |
## Workflow Overview
```text
┌───────────┐ ┌───────────────┐ ┌───────────────┐ ┌─────────────────┐
│ Preflight │ → │ Render/review │ → │ Apply/handoff │ → │ Validate evidence │
└───────────┘ └───────────────┘ └───────────────┘ └─────────────────┘
```
## When to Activate
- Expose Splunk Enterprise on the public internet, harden a Splunk search head against internet exposure, configure
TLS / HSTS / CSP / mTLS / per-IP rate limit / DMZ heavy forwarder, lock down splunkd or the KV store, fix
splunk.secret /.
- Preview and review the splunk enterprise public exposure hardening workflow before any live apply phase.
- Diagnose failed prerequisites, generated assets, configuration, or validation evidence.
## Scope
Follow the documented read-only or render-first path whenever it is available.
This skill does not imply permission to mutate live systems. Require explicit
apply flags, protected credentials, and operator review for state changes.
## Examples
Inspect the supported setup modes before selecting one:
```bash
bash skills/splunk-enterprise-public-exposure-hardening/scripts/setup.sh --help
```
Expected output: usage, supported modes, and required arguments are displayed
without changing the target environment.
Inspect validation modes before running completion checks:
```bash
bash skills/splunk-enterprise-public-exposure-hardening/scripts/validate.sh --help
```
Expected output: offline, live, and completion options are displayed when the
skill supports them; help exits without mutation.
## Troubleshooting
| Issue | Cause | Resolution |
|---|---|---|
| Preflight fails | A required tool or access path is missing | Resolve it before rendering or applying |
| Rendered assets are incomplete | Required non-secret inputs are absent | Complete intake and render again |
| Apply is blocked | Review, credentials, or explicit acceptance is missing | Use the documented handoff |
| Validation is incomplete | Live evidence is unavailable | Record the gap and keep completion open |
This skill prepares an **on-prem Splunk Enterprise** deployment for
public-internet exposure with **defense in depth across the Splunk node, the
reverse-proxy / WAF tier, and the network**, plus an explicit operator
handoff for parts that cannot be safely automated. It is render-first: the
default phase produces a reviewable directory of `*.conf` overlays,
nginx / HAProxy / firewall templates, and operator handoff Markdown — and
refuses to apply changes until the operator passes `--accept-public-exposure`.
## Read this first — what Splunk does NOT have
Splunk Enterprise is "designed to run on a trusted network." Several
common assumptions about Splunk Web are wrong, and the skill explicitly
guards against them:
- **No `customHttpHeaders` setting in `web.conf`.** Browser security
headers (`Strict-Transport-Security`, `Content-Security-Policy`,
`X-Content-Type-Options`, `Referrer-Policy`, `Permissions-Policy`,
`Cache-Control`) come from the **reverse proxy only**.
- **No CAPTCHA / bot challenge** on the login form.
- **No native WebAuthn / FIDO2** in Splunk Web — federate to an IdP
(Okta, Entra ID, Duo Universal Prompt) for phishing-resistant MFA.
- **`lockoutAttempts` is per-user**, not per-IP. The `admin` role ships
with `never_lockout = enabled`. The skill flips this to `disabled` and
the WAF / proxy provides the per-IP rate limit.
- **No XFF / `trustedProxiesList`.** When `tools.proxy.on = true` Splunk
trusts `X-Forwarded-*` from any immediate client. Combine with
`acceptFrom` on `web.conf [settings]` AND `server.conf [httpServer]`
to lock down the trust boundary.
- **Splunkd 8089, the KV store on 8191, `appServerPorts` on 8065, and
the indexer-cluster replication port on 9887 must NEVER be reachable
from the public internet.** Preflight and validate fail closed if
they are.
## Architecture the skill assumes
```
Public Internet
│
▼
CDN / DDoS (Cloudflare / AWS / Akamai) ── operator handoff
│
▼
WAF rules (OWASP CRS, rate limit, geo) ── operator handoff
│
▼
Reverse proxy (nginx / HAProxy in DMZ) ── rendered templates
│ TLS termination + browser headers + return_to / header sanitisation
▼
Splunk Search Head + HEC + DMZ Heavy Forwarder
│ Splunkd / KV / replication NEVER public.
▼
Indexer cluster (private)
```
## Agent behavior — credentials
Never paste secrets into chat or pass them on argv. The skill consumes
**file paths** for every secret it needs and never embeds secret values
in rendered output:
```bash
bash skills/shared/scripts/write_secret_file.sh /tmp/splunk_admin_password
bash skills/shared/scripts/write_secret_file.sh /tmp/splunk_pass4symmkey
bash skills/shared/scripts/write_secret_file.sh /tmp/splunk_ssl_key_password
bash skills/shared/scripts/write_secret_file.sh /tmp/splunk_idp_signing_cert
```
Pass them in via `--admin-password-file`, `--pass4symmkey-file`,
`--ssl-key-password-file`, etc.
For non-secret values (FQDN, IPs, indexes, role names) use
`template.example`.
## Quick start
Render the full hardening bundle for a single search head with proxy in
front, public Splunk Web only:
```bash
bash skills/splunk-enterprise-public-exposure-hardening/scripts/setup.sh \
--phase render \
--topology single-search-head \
--public-fqdn splunk.example.com \
--proxy-cidr 10.0.10.0/24 \
--enable-web true \
--enable-hec false \
--enable-s2s false
```
Render with HEC and DMZ heavy forwarder for ingest:
```bash
bash skills/splunk-enterprise-public-exposure-hardening/scripts/setup.sh \
--phase render \
--topology shc-with-hec-and-hf \
--public-fqdn splunk.example.com \
--hec-fqdn hec.example.com \
--proxy-cidr 10.0.10.0/24 \
--enable-web true \
--enable-hec true \
--enable-s2s true \
--hec-mtls true \
--indexer-cluster-cidr 10.0.20.0/24
```
Run preflight against a live host (read-only checks; refuses to apply):
```bash
bash skills/splunk-enterprise-public-exposure-hardening/scripts/setup.sh \
--phase preflight \
--public-fqdn splunk.example.com \
--public-ca-file /etc/pki/ca-trust/source/anchors/public-proxy-ca.pem \
--external-probe-cmd "ssh probe@bastion.example.com nc -zv"
```
Omit `--public-ca-file` for a publicly trusted certificate. Public probes use
system trust by default and always verify the certificate chain and FQDN;
there is no insecure `curl -k` production-pass path. The external probe value
is parsed once as POSIX-style argv, never evaluated as shell source, and the
target FQDN and port are appended as separate arguments. Shell metacharacters
and control characters are rejected.
Apply the hardening app on a search head (mutates Splunk; requires the
explicit accept flag):
```bash
bash skills/splunk-enterprise-public-exposure-hardening/scripts/setup.sh \
--phase apply \
--apply-target search-head \
--public-fqdn splunk.example.com \
--accept-public-exposure \
--pass4symmkey-file /tmp/splunk_pass4symmkey
```
Validate live state post-apply:
```bash
bash skills/splunk-enterprise-public-exposure-hardening/scripts/validate.sh \
--public-fqdn splunk.example.com
```
## What it renders
Under the project root in `splunk-public-exposure-rendered/`:
- `splunk/apps/000_public_exposure_hardening/` — Splunk app with
`app.conf`, `web.conf`, `server.conf`, `inputs.conf`, `outputs.conf`,
`authentication.conf`, `authorize.conf`, `limits.conf`, `commands.conf`,
and `metadata/{default,local}.meta`. Drop into
`$SPLUNK_HOME/etc/apps/` (or the SHC deployer's `shcluster/apps/`).
- `splunk/apply-search-head.sh`, `apply-hec-tier.sh`,
`apply-s2s-receiver.sh`, `apply-heavy-forwarder.sh`,
`apply-deployer.sh`, `apply-cluster-manager.sh`,
`apply-license-manager.sh` — role-aware local-host scripts selected with
`--apply-target`. Search-head, HEC-tier, and heavy-forwarder targets mutate
directly. S2S-receiver and cluster-manager targets exit nonzero and delegate
to the indexer-cluster workflow so a single peer is never restarted and an
undocumented secret-file CLI flag is never invented. Deployer stages the
bundle then exits nonzero pending a secret-safe SHC bundle handoff;
license-manager also delegates and exits nonzero.
SHC topologies reject direct `search-head`/`hec-tier` mutation and require
the deployer path.
- `splunk/transaction-helpers.sh` — shared direct-apply transaction engine.
It securely reads secret files through no-follow descriptors, stages in a
private directory on the target filesystem, snapshots the prior app and
`splunk-launch.conf`, validates btool before restart, and restores plus
restart-verifies the exact prior state on any error or signal.
- `splunk/rotate-pass4symmkey.sh`, `rotate-splunk-secret.sh` — secret
rotation helpers that read keys from local files only.
- `splunk/certificates/verify-certs.sh`,
`generate-csr-template.sh` — operator-side cert helpers.
- `proxy/nginx/{splunk-web.conf,splunk-hec.conf}` — production nginx
vhosts with TLS, HSTS, CSP, header sanitisation, return_to allowlist,
per-IP rate limit, streaming-safe timeouts, WebSocket plumbing.
- `proxy/haproxy/{splunk-web.cfg,splunk-hec.cfg}` — HAProxy equivalents
using `option http-server-close` (NOT `option httpclose`).
- `proxy/firewall/{iptables.rules,nftables.conf,firewalld.xml,aws-sg.json}`
— internet-edge firewall snippets that explicitly drop `8089`,
`8191`, `8065`, `9887`, plus direct `9997` and `8088` from the
public CIDR.
- `handoff/` — Markdown checklists for WAF (Cloudflare / AWS / F5+Imperva),
SAML IdP, Duo MFA, certificate procurement, SOC alerting,
backup-and-restore, splunk.secret incident response, compliance.
- `preflight.sh` and `validate.sh` — fail-closed scripts the operator
runs from this directory.
- `README.md` and `metadata.json` — full documentation and rendered
configuration manifest.
## Phases
- `render` (default) — produce the reviewable rendered directory.
- `preflight` — render then run the 20-step preflight against the live
host (default-cert detection, SVD floor, `splunk.secret` posture,
`pass4SymmKey` rotation, capability hygiene, firewall reachability,
TLS scan, header-injection probe, `return_to` redirect probe, cookie
scrubbing, etc.). Refuses to mark the deployment ready when any check
fails.
- `apply` — render, run the fail-closed live preflight, then run the apply
script for the role you specified. Requires `--accept-public-exposure` (a
single-flag acknowledgement that you are about to bind Splunk to a
public-facing FQDN). Search-head, HEC-tier, and heavy-forwarder applies are
transactional and roll back both disk state and the Splunk restart if any
btool, restart, encryption, or post-restart readback check fails.
Preflight and validation treat failed, empty, missing, or unexpected btool
output as a failure; `role_admin.never_lockout` must be `disabled`, and
`authType` must be a recognized non-Scripted value matching the render.
- `validate` — render then run the live validation probes.
- `all` — render + preflight + apply + validate for direct local targets,
gated by `--accept-public-exposure`. Delegated cluster/license targets stop
nonzero at their handoff, so validation must run after the child workflow.
## SVD floor (refuses to apply below this)
| Series | Required version | Source |
|---|---|---|
| 10.4.x | 10.4.0 | Not affected by SVD-2026-0304/0303 at GA; use latest 10.4.x maintenance |
| 10.2.x | 10.2.2 | SVD-2026-0304, SVD-2026-0303 |
| 10.0.x | 10.0.5 | SVD-2026-0303, SVD-2025-1006 |
| 9.4.x | 9.4.10 | SVD-2025-1006, SVD-2025-1203 |
| 9.3.x | 9.3.11 | SVD-2025-1006, SVD-2025-1203 |
Floor lives in
[references/cve-svd-floor.json](references/cve-svd-floor.json) and
ships embedded in the renderer; `--svd-floor-file` can override.
## Cross-skill handoff matrix
The skill consumes — does not duplicate — these. When you also use
one of the adjacent skills below, run THIS skill's preflight +
validate against the fronting search head, then layer the adjacent
skill's hardening on top.
| Adjacent skill | What it owns | What this skill provides |
|---|---|---|
| [splunk-platform-pki-setup](../splunk-platform-pki-setup/SKILL.md) | Full TLS / PKI lifecycle (Private CA or Public CSR + handoff to Vault PKI / ACME / AD CS / EJBCA), per-component cert distribution across every Splunk surface, FIPS 140-2/140-3 wiring, three TLS algorithm presets, KV-Store dual-EKU enforcement, replication-port TLS migration, SAML SP signing cert, LDAPS trust, `cacert.pem` alignment, delegated rotation runbook | Consumes the cert paths the PKI skill provisions; this skill's preflight refuses to declare a public-exposed SH ready until PKI verify-leaf has returned `OK`; the PKI skill consumes this skill's `--enable-fips` / `--fips-version` semantics rather than redefining |
| [splunk-hec-service-setup](../splunk-hec-service-setup/SKILL.md) | HEC token lifecycle, allowed indexes, ACS HEC tokens | HEC TLS / mTLS rendering, body-size alignment, proxy vhost, sensitive-path denies |
| [splunk-enterprise-host-setup](../splunk-enterprise-host-setup/SKILL.md) | Splunk host install / cluster bootstrap | Preflight refuses unbootstrapped hosts; SVD floor enforcement |
| [splunk-indexer-cluster-setup](../splunk-indexer-cluster-setup/SKILL.md) | Indexer cluster bundle | `pass4SymmKey` rotation helper + acceptFrom enforcement for cluster CIDR |
| [splunk-agent-management-setup](../splunk-agent-management-setup/SKILL.md) | SHC deployer, server classes | Hardening app drops into `shcluster/apps/`; SHC deployer pass4SymmKey rotation |
| [splunk-license-manager-setup](../splunk-license-manager-setup/SKILL.md) | License manager / peer wiring | License master 8089 acceptFrom + pass4SymmKey rotation |
| [splunk-cloud-acs-admin-setup](../splunk-cloud-acs-admin-setup/SKILL.md) | Splunk **Cloud** ACS allowlists | Out of scope — this skill is on-prem only |
| [splunk-federated-search-setup](../splunk-federated-search-setup/SKILL.md) | Federation provider/consumer wiring | Provider-side acceptFrom + service-account rotation helper (federation auth is NOT pass4SymmKey) |
| [splunk-monitoring-console-setup](../splunk-monitoring-console-setup/SKILL.md) | Monitoring Console distributed config | MC integration: forward `_audit` and platform alerts on hardening drift |
| [splunk-connect-for-syslog-setup](../splunk-connect-for-syslog-setup/SKILL.md) | SC4S Docker/Helm runtime, syslog TLS listener | If SC4S delivers via HEC, run THIS skill against the HEC-receiving SH first |
| [splunk-connect-for-snmp-setup](../splunk-connect-for-snmp-setup/SKILL.md) | SC4SNMP Docker/Helm runtime | Same as SC4S |
| [splunk-mcp-server-setup](../splunk-mcp-server-setup/SKILL.md) | MCP server install + token issuance | If MCP is exposed publicly, run THIS skill against the SH fronting it; MCP token policy is owned by the MCP skill |
| [splunk-stream-setup](../splunk-stream-setup/SKILL.md) | Wire data capture stack | Stream is internal-only; this skill does not apply |
| [splunk-index-lifecycle-smartstore-setup](../splunk-index-lifecycle-smartstore-setup/SKILL.md) | SmartStore S3/GCS/Azure backend | Outbound-to-storage; this skill does not apply |
| [splunk-enterprise-security-config](../splunk-enterprise-security-config/SKILL.md) (and ES/SOAR/ITSI/UBA/ARI/AA) | Premium apps + additional capabilities | Run THIS skill first; then re-audit `role_public_reader` against the [premium-apps-capability-overlay](references/premium-apps-capability-overlay.md) |
## References
Read [reference.md](reference.md) before any apply. Topical deep dives:
- [references/tls-hardening.md](references/tls-hardening.md)
- [references/reverse-proxy-templates.md](references/reverse-proxy-templates.md)
- [references/waf-cdn-handoff.md](references/waf-cdn-handoff.md)
- [references/auth-mfa-saml.md](references/auth-mfa-saml.md)
- [references/network-segmentation.md](references/network-segmentation.md)
- [references/role-capability-hardening.md](references/role-capability-hardening.md)
- [references/risky-command-safeguards.md](references/risky-command-safeguards.md)
- [references/splunk-secret-rotation.md](references/splunk-secret-rotation.md)
- [references/cve-svd-tracking.md](references/cve-svd-tracking.md)
- [references/threat-intel.md](references/threat-intel.md)
- [references/disa-stig-cross-reference.md](references/disa-stig-cross-reference.md)
- [references/compliance-gap-statement.md](references/compliance-gap-statement.md)
- [references/dmz-heavy-forwarder-pattern.md](references/dmz-heavy-forwarder-pattern.md)
- [references/operator-handoff-checklist.md](references/operator-handoff-checklist.md)
- [references/setting-name-corrections.md](references/setting-name-corrections.md)
- [references/fips-mode.md](references/fips-mode.md)
- [references/auth-ldap-hardening.md](references/auth-ldap-hardening.md)
- [references/premium-apps-capability-overlay.md](references/premium-apps-capability-overlay.md)
+ [premium-apps-capability-overlay.json](references/premium-apps-capability-overlay.json) (machine-readable companion consumed by preflight)
- [references/secure-gateway-handoff.md](references/secure-gateway-handoff.md)
- [references/federated-search-provider-hardening.md](references/federated-search-provider-hardening.md)
- [references/cve-svd-floor.json](references/cve-svd-floor.json) (Splunk core + SG-app per-branch floors)
- [references/default-cert-fingerprints.json](references/default-cert-fingerprints.json) (machine-readable companion to default-cert-fingerprints / verify-certs.sh)
## What this skill does NOT do
- Procure certificates or talk to a CA. (Provides a CSR template +
`verify-certs.sh`.)
- Push WAF / CDN config to vendor APIs. (Operator-driven via `handoff/`.)
- Bootstrap the Splunk host itself —
[splunk-enterprise-host-setup](../splunk-enterprise-host-setup/SKILL.md).
- Issue HEC tokens —
[splunk-hec-service-setup](../splunk-hec-service-setup/SKILL.md).
- Patch / upgrade Splunk — preflight refuses below the SVD floor and the
operator must upgrade first.
- Implement IdP-side configuration (Okta, Entra, Duo) — handoff docs only.
- Provide compliance attestation. The skill maps controls (DISA STIG
cross-reference) but does not certify PCI / HIPAA / FedRAMP / SOC 2.
- Configure Splunk Secure Gateway, Splunk Mobile, SC4S, or the Splunk
MCP Server for public exposure — each needs its own threat model.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!