Put an internal web application behind Korthveil. Browsers connect to Korthveil over HTTPS, Korthveil checks every request with the web application firewall (WAF), and only clean requests reach the server. This guide publishes the SentinelOps web console (https://192.168.2.11) under the name sentinelops.home.arpa, for PCs inside the house only. Nothing is opened to the internet, and nothing changes on the upstream router.
What you need:
192.168.2.13 on the home LAN (zone MGMT) or 192.168.20.1 on the Wi-Fi (zone WIFI).The screenshots come from a test firewall with a test site shop.test behind listener e2e. Your names and values are the ones in the tables.
PC in the house Korthveil firewall SentinelOps server
┌────────────────────┐ HTTPS ┌──────────────────────────────────┐ HTTPS ┌──────────────────┐
│ browser │ ───────▶ │ reverse proxy, port 8443 │ ──────▶ │ 192.168.2.11 │
│ sentinelops. │ │ certificate: sentinelops │ │ web console │
│ home.arpa:8443 │ │ asks the WAF about each request │ └──────────────────┘
│ trusts your CA │ ◀─────── │ WAF: OWASP Core Rule Set 4.25.2 │
└────────────────────┘ 403 page │ detect, or block │
└──────────────────────────────────┘
Korthveil makes and renews the certificate itself (System › Certificates). The reverse proxy takes it from there, and gets each renewal automatically.
Go to System › Certificates, panel Add a certificate:
home-ca, Common name Home web CA. Click Create. (A CA made for NAC, such as nac-ca, also works.)| Field | Set to |
|---|---|
| Name in the store | sentinelops |
| Issuing CA | home-ca |
| Use | Server (web sites, VPN servers) |
| Common name | sentinelops.home.arpa |
| DNS names | sentinelops.home.arpa |
| Renew automatically | on |
Click Create.

The key never leaves the firewall. While the site uses it, the store lists the reverse proxy under Used by, and the certificate can't be deleted by mistake. When it renews, the site serves the new one within seconds, without a commit.
The name home.arpa is reserved for home networks, so it never clashes with a real internet name.
Your CA's certificate for the PCs: in the Store, click Download on home-ca. You get home-ca.pem: the CA's public certificate, which each PC that opens the site must trust (Step 7). It holds no key.
A certificate from elsewhere (a public CA, or one you made yourself): import it on System › Certificates (Import from your registrar or CA) and choose it the same way, or upload it in the reverse proxy's Certificates tab (Uploaded certificates).
Tab Server pools, click Add server pool:
| Field | Set to | Meaning |
|---|---|---|
| Name | sentinelops |
|
| Servers | https://192.168.2.11 |
One row per server. Use Add server for a second one |
| Load balancing | Round robin | Only matters with two or more servers |
| Check servers over HTTP | on, Path / |
Checked every 10 seconds; 3 failures mark a server down, 2 answers bring it back |
| Trusted CA (PEM, optional) | The SentinelOps console's own certificate (see below) | Korthveil checks the server's certificate against this instead of the public CAs |
| Expected server name | The name in that certificate, if 192.168.2.11 is not in it |

Getting the console's certificate: on the PC, run echo | openssl s_client -connect 192.168.2.11:443 -showcerts and copy the last -----BEGIN CERTIFICATE----- … -----END CERTIFICATE----- block (the root of its chain, or the only one if it is self-signed). Or open https://192.168.2.11 in a browser and export the certificate from the padlock.
Leave Do not verify server certificates (insecure) off. It is there only for servers whose certificate can't be checked at all.
Tab Listeners. A new installation has a listener public with HTTP 80 and HTTPS 443 and no zone. Change it, or click Add listener:
| Field | Set to | Why |
|---|---|---|
| Listener name | inside |
|
| Zones | Only the zones of the PCs that may open the console: MGMT (home LAN), and WIFI if you like |
Never tick WAN: then nothing is reachable from outside |
| HTTP port | empty | HTTPS only |
| HTTPS port | 8443 (the default for a new listener) |
Port 443 in a zone takes the Korthveil web console away from that zone |

Keep Access log on: one record per request, without cookies, credentials, or query strings.
No firewall rule is needed: the add-in opens the port in the chosen zones by itself.
Tab Sites, click Publish a site:
| Field | Set to |
|---|---|
| Name | sentinelops |
| Host names | sentinelops.home.arpa |
| Server pool | sentinelops |
| Listeners | tick inside only |
| Certificate | sentinelops, under From System › Certificates (renewed automatically) |
| Redirect HTTP to HTTPS | off (the listener has no HTTP port; left on, the commit shows a warning) |
| HSTS (browsers use HTTPS only) | on, HSTS max-age (days) 365 |
| Largest request body (MiB) | 10 (the default) |
| Allow WebSocket connections | Turn it on if live parts of the console stay empty (see Troubleshooting) |

Click Save to pending changes. Errors and warnings appear above the button, each with the setting it is about.
Go to Security › Web application firewall and click Protect sentinelops. A new policy starts in detect mode.
| Field | Set to | Meaning |
|---|---|---|
| Virtual host | sentinelops (sentinelops.home.arpa) |
|
| Mode | Detect only (log, never block) for now | Every request is checked and logged; nothing is stopped yet |
| Application | Generic web application | |
| OWASP Core Rule Set | on | Shows the version, 4.25.2 |
| Paranoia level | 1 — few false positives (recommended) | Higher levels add rules and false positives |
| Anomaly score that blocks | 5 (the default) |
5 blocks on one critical match; Step 8 starts blocking at 20 |
| Inspect up to (MiB) | 13 (the default) |
Request bodies larger than this are rejected (413), or partly inspected if you choose so under Larger bodies |
Allowlist (trusted clients): click Add trusted client for your admin PC, so a false positive never locks you out:
| Name | Addresses | Only under path | Action |
|---|---|---|---|
Admin PC |
its address, for example 192.168.2.50/32 |
empty (all paths) | Inspect, never block |
Inspect, never block still logs what the PC triggers (labelled with the entry's name). Skip inspection doesn't look at its requests at all; use it rarely.

Click Save to pending changes.
Click Review and commit in the bar at the top of the page. Check the Configuration changes, type a Comment such as Publish SentinelOps behind the WAF, keep Safety rollback (5 minutes) on, and click Commit. Confirm the change within five minutes, or the firewall goes back by itself.
Both add-ins start with the commit. The commit is all-or-nothing: if the certificate, the pool, or the WAF policy is wrong, nothing changes and the reason is shown.
The name. The PC must find sentinelops.home.arpa at the firewall's address in its zone. Use one of:
C:\Windows\System32\drivers\etc\hosts/etc/hosts192.168.2.13 sentinelops.home.arpa
On the Wi-Fi, use 192.168.20.1 instead.
sentinelops.home.arpa, type A, value the firewall's address. Save and commit.Don't change the upstream router for this; the hosts file or Korthveil's resolver is all it takes.
Trust your CA. Install home-ca.pem (from Step 1) as a trusted root. On Windows, rename it to home-ca.crt first:
home-ca.crt › Install Certificate › Local Machine › Place all certificates in the following store › Trusted Root Certification Authorities.home-ca.pem in Keychain Access (System keychain), open the certificate, Trust › When using this certificate: Always Trust.sudo cp home-ca.pem /usr/local/share/ca-certificates/home-ca.crt && sudo update-ca-certificates.Open https://sentinelops.home.arpa:8443/. The SentinelOps console appears with a padlock and no warning.
Let the site run in detect mode while you use the console normally, for a few days if you can (the guide WAF learning mode explains every step). Then, on the WAF page, panel Learning and readiness:

The verdict needs some traffic and days of observation. For a quick test you can set Mode to Block attacks in the policy directly, or type ENABLE at Block anyway, but you then skip the checks that protect you from false positives.
False positives by hand: under Rule exclusions, Add exclusion with the Rule IDs from Recent blocks, limited to a Path prefix and, better, to the one variable (for example ARGS:q), so the rule keeps protecting everything else. Write Why for the next person.
https://sentinelops.home.arpa:8443/./?id=1' OR '1'='1 is a classic SQL injection. Click Test: the answer says whether it would be blocked and by which rule.
https://sentinelops.home.arpa:8443/?id=1' OR '1'='1. In block mode the page says Request blocked with a reference: that is the event ID in Recent blocks. At threshold 20 a single simple attack may still pass; at 5 it is blocked. In detect mode the page loads and the request is logged as detected.

https://192.168.2.11.

The dashboard's threat activity also shows WAF blocks per second, once a policy is running.
| What | Where |
|---|---|
| Mode, paranoia level, anomaly threshold | Security › Web application firewall, the site's policy |
| Trusted clients and rule exclusions | The same policy: Allowlist (trusted clients), Rule exclusions |
| Every other Core Rule Set option (methods, content types, limits) | The same policy: Advanced engine and Core Rule Set settings |
| Your own blocking rules (virtual patches) | The same policy: Custom rules (SecLang, each rule with an id) |
| Who can reach the site | Security › Reverse proxy › Listeners: the zones |
| A renewed certificate | Nothing to do: Korthveil renews sentinelops before it expires, and the site serves the new one at once. Renew now on System › Certificates forces it |
| More servers, health checks | Security › Reverse proxy › Server pools |
| Switch an add-in off or remove it | The switch and Remove at the top of its page (applies on commit) |
| Symptom | Check |
|---|---|
| The browser warns that the connection is not private | home-ca.pem isn't trusted on this PC, or only in the system while you use Firefox (Step 7). Or the name in the address bar differs from the certificate's: it must be exactly sentinelops.home.arpa. |
| The site can't be reached | The hosts entry points at the firewall's address in the PC's zone. The listener has that zone ticked and the commit is done. Status › Listeners and add-ins shows the listener's bound ports, or why it is not listening. |
| Site not found | The name the browser used isn't in the site's Host names, or the site isn't ticked on that listener. |
| Temporarily unavailable: No application server is available, or 502 Bad Gateway | Status › Servers: the server is down and shows why. certificate signed by unknown authority: paste the console's certificate into Trusted CA. certificate is valid for …, not 192.168.2.11: put that name in Expected server name. A health check failing on /: choose a path that answers 200 or a redirect. |
| The console loads, but live parts stay empty, or the browser console shows WebSocket errors | Tick Allow WebSocket connections on the site. Without it, upgrade requests get Not allowed. |
| Normal pages are blocked after switching to block mode | Recent blocks › Details shows the rule and the value. Add a narrow exclusion, raise Anomaly score that blocks for now, or go Back to detect mode. Allowlist your admin PC so you can always get in. |
| Every request gets Temporarily unavailable: Request inspection is temporarily unavailable | Block mode fails closed when the WAF isn't answering. Status › Listeners and add-ins shows Web application firewall … not answering. Check System › Add-ins; detect mode lets requests through in that case. |
| Request too large on uploads | Raise Largest request body (MiB) on the site, and Inspect up to (MiB) in the WAF policy (or Larger bodies: Inspect the first part, pass the rest). |
| Test a request says the virtual host has no committed WAF policy | Save the policy and commit first; the test uses the committed policy. |
| The Korthveil web console is gone from a zone | A listener uses HTTPS port 443 in that zone. Use 8443, or move the web console's port (System › Certificates › Web console › HTTPS port). |
| Live activity is empty | The graphs fill from the add-in's counters every few seconds after the page opens; they stay flat while nobody uses the site. |
More: modules/reverse-proxy.md and modules/waf.md describe both add-ins in depth.