Commit Graph

2015 Commits

Author SHA1 Message Date
fuomag9
edd4e6879f fix: make WAF events table fit in viewport
- DataTable: add overflowX auto to TableContainer + minWidth 600
- WAF events: tighten column widths (Time 150, Host 150, IP 140,
  Method 60), add ellipsis+tooltip on Host column, let Rule Message
  expand to fill remaining space

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 08:26:36 +01:00
fuomag9
54a2a9ea0d feat: parse WAF rule logs for rule ID/message/severity
Coraza does not write matched rules to the audit log (known upstream
bug). Rule details are logged by Caddy's http.handlers.waf logger.

Two changes:

1. caddy.ts: Always configure a dedicated Caddy log sink that writes
   http.handlers.waf logger output to /logs/waf-rules.log as JSON.

2. waf-log-parser.ts: Before parsing the audit log, read the new
   waf-rules.log to build a Map<unique_id, RuleInfo>. Each audit log
   entry joins against this map via transaction.id to populate
   ruleId, ruleMessage, and severity fields. Skips anomaly evaluation
   rules (949110/980130) to show the actual detection rule instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 08:21:49 +01:00
fuomag9
5e7ceedfe3 fix: filter WAF events by is_interrupted instead of messages array
Coraza does not populate the messages array in the audit log JSON
(known bug — matched rules appear in Caddy's error log but not in
the audit log's messages field). The transaction.is_interrupted flag
IS correctly set to true for blocked/detected requests.

Changes:
- Filter on tx.is_interrupted instead of entry.messages.length
- Check both top-level and tx.messages for rule info (future compat)
- Fall back to tx.highest_severity when messages missing
- Document the Coraza messages bug in interface comments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 08:16:02 +01:00
fuomag9
ab7fb70ee4 fix: revert SecAuditEngine to On — RelevantOnly suppresses WAF-blocked logs
Coraza's RelevantOnly mode does not write audit log entries for requests
blocked by the WAF itself (403 responses), so the waf-log-parser had
nothing to parse. Reverting to On so all transactions are logged, and
relying on the parser-side messages[] filter to skip clean requests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 02:29:06 +01:00
fuomag9
a2c6991abd fix: only log WAF events where rules matched
- Change SecAuditEngine from On to RelevantOnly so Coraza only writes
  audit log entries for transactions that triggered at least one rule.
  Previously all requests were logged regardless of matches.
- Add parser-side guard to skip entries with empty messages array as
  belt-and-suspenders against any pre-existing clean entries in log.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 02:25:21 +01:00
fuomag9
e9f61481eb fix: include OWASP CRS files via @-prefixed embedded FS paths
load_owasp_crs: true only merges the embedded coraza-coreruleset
filesystem - it does NOT auto-include rule files. The correct way to
load CRS rules is to explicitly Include them using the @ prefix which
references the embedded FS:

  Include @coraza.conf-recommended
  Include @crs-setup.conf.example
  Include @owasp_crs/*.conf

Without these includes, SecRuleEngine On had no rules to apply and
all requests passed through unblocked (rulesets: null in audit log).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 02:19:21 +01:00
fuomag9
1c81e1a385 fix WAF: load_owasp_crs=true loads CRS automatically, no Include needed
The Caddyfile adapter test confirms: load_owasp_crs loads all CRS rules
internally without any Include directives. Include @owasp_crs/... was
wrong — that path is not accessible from SecLang directives.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 02:02:14 +01:00
fuomag9
d996f9461f fix WAF: load_owasp_crs=true AND Include directives are both required
load_owasp_crs:true mounts the embedded CRS filesystem (@owasp_crs prefix),
but Include @owasp_crs/... directives are still needed to actually load the
rules. Previously we had one or the other — now both are set together.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 01:57:44 +01:00
fuomag9
9bdf10a2c0 fix WAF: directives is a string not []string, keep Include for OWASP CRS
The coraza-caddy Go struct defines directives as type string, not []string.
Revert to joined string but keep the Include @owasp_crs/... fix for CRS loading.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 01:54:43 +01:00
fuomag9
634f8f1593 fix WafFields: add missing waf_enabled hidden input
The enabled switch state was never submitted to the form, so the host
WAF config was always saved as enabled: false regardless of the toggle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 01:52:34 +01:00
fuomag9
d7e20b10b5 fix WAF: use directives array and Include for OWASP CRS, fix log parser field paths
- buildWafHandler: directives must be string[] not a joined string (coraza-caddy
  JSON API requirement); load_owasp_crs is Caddyfile-only and silently ignored in
  JSON config — replaced with Include @owasp_crs/... directives
- waf-log-parser: use unix_timestamp (nanoseconds) for precise ts; host header is
  headers.host[] (lowercase array); messages[].data.{id,msg,severity} not rule.*

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 01:49:22 +01:00
fuomag9
1a56e5e842 better ui 2026-03-04 00:31:02 +01:00
fuomag9
0dad675c6d feat: integrate Coraza WAF with full UI and event logging
- Add coraza-caddy/v2 to Caddy Docker build
- Add waf_events + waf_log_parse_state DB tables (migration 0010)
- Add WafSettings type and get/save functions to settings
- Add WafHostConfig/WafMode types to proxy-hosts model
- Add resolveEffectiveWaf + buildWafHandler to caddy config generation
- Create waf-log-parser.ts: parse Coraza JSON audit log → waf_events
- Add WafFields.tsx per-host WAF UI (accordion, mode, CRS, directives)
- Add global WAF settings card to SettingsClient
- Add WAF Events dashboard page with search, pagination, severity chips
- Add WAF Events nav link to sidebar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 22:16:34 +01:00
fuomag9
1b157afc72 Add .worktrees to .gitignore 2026-03-03 19:35:33 +01:00
fuomag9
1e3632f048 remove unused stuff 2026-02-28 21:31:34 +01:00
fuomag9
f7cd854cda fix for log file permissions 2026-02-28 21:11:26 +01:00
fuomag9
f4acb0f637 remove — 2026-02-27 22:40:00 +01:00
fuomag9
494535d767 fixed website rendering chars 2026-02-27 22:34:35 +01:00
fuomag9
461df12ae8 fix search crash 2026-02-27 22:28:19 +01:00
fuomag9
6ac8fa5664 remove unneeded screenshots from readme 2026-02-27 22:27:03 +01:00
fuomag9
26e4a7c6f3 updated website 2026-02-27 21:58:04 +01:00
fuomag9
d7f0738bf0 update website 2026-02-27 21:32:36 +01:00
fuomag9
336c899b1e updated screenshots 2026-02-27 21:07:08 +01:00
fuomag9
000607cee7 updated documentation 2026-02-27 20:10:54 +01:00
fuomag9
fb561f7433 update dependencies 2026-02-27 19:53:01 +01:00
fuomag9
a45a156068 fix pages viewing 2026-02-27 19:49:11 +01:00
fuomag9
3d88f565ca fix: await searchParams Promise in all paginated pages (Next.js 15+) 2026-02-27 18:40:56 +01:00
fuomag9
f64eb2c8d0 fix: sync search state on navigation; move pagination before create form in access-lists
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 18:05:15 +01:00
fuomag9
f7a092f1e4 feat: add pagination to certificates ACME table
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 18:01:27 +01:00
fuomag9
5126273101 feat: add server-side pagination to access-lists page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 18:00:36 +01:00
fuomag9
6bd7fe92d8 feat: add server-side pagination to proxy-hosts page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 18:00:26 +01:00
fuomag9
ce042d968d feat: add server-side pagination and search to audit-log page 2026-02-27 18:00:23 +01:00
fuomag9
8bf07011f9 feat: add paginated list functions to DB models
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:58:23 +01:00
fuomag9
8555de7b9d fix: use numeric timestamp comparison for cert expiry; extract PaginationBar to avoid unconditional useSearchParams subscription
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:56:23 +01:00
fuomag9
89c5d4b838 feat: add pagination support to DataTable component
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:53:23 +01:00
fuomag9
28f9fc1d8a feat: show ACME cert expiry and issuer in certificates page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:51:14 +01:00
fuomag9
97ba5547f1 feat: add ACME cert scanner utility
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:48:55 +01:00
fuomag9
27a7e6dab9 chore: mount caddy-data read-only to web container for cert scanning
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:48:54 +01:00
fuomag9
f9fba6963b docs: add implementation plan for ACME cert info and sitewide pagination 2026-02-27 17:44:26 +01:00
fuomag9
296d17205f fix: count ACME-issued certs in overview (not just imported ones)
Previously only counted rows in the certificates table (0 for most setups).
Now counts: proxy hosts with certificate_id=NULL (each gets one Caddy ACME cert
via HTTP-01/DNS-01) + imported certs with actual PEM data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 16:19:24 +01:00
fuomag9
7e5626f328 fix: align nav icons with overview card icons
SwapHorizIcon→Proxy Hosts, VpnKeyIcon→Access Lists, SecurityIcon→Certificates,
HistoryIcon→Audit Log. Nav now uses the exact same icons as the overview stat
cards so identical sections share identical icons.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 16:03:26 +01:00
fuomag9
3a6a5297d6 fix: replace thin/outlined nav icons with solid filled equivalents
DnsIcon→RouterIcon, SecurityIcon→LockIcon, ShieldIcon→WorkspacePremiumIcon,
HistoryIcon→AssignmentIcon — all now match the visual weight of Dashboard,
BarChart, and Settings icons.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 15:31:19 +01:00
fuomag9
2096ebf1ed fix: replace Outlined icon variants with filled equivalents for visual consistency
Replace DeleteOutline→Delete, CheckCircleOutline→CheckCircle, ErrorOutline→Error,
RemoveCircleOutline→RemoveCircle, InfoOutlined→Info across all dashboard components.
Replace custom SVG bar chart in OverviewClient with BarChartIcon.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 15:25:19 +01:00
fuomag9
bfb6b2060f fix: restore full-width nav list with rounded corners (borderRadius: 3)
Revert 2-column squircle grid back to original list layout —
same space usage as before, just with squircle-style border radius
on each ListItemButton instead of sharp rectangle edges.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 14:43:31 +01:00
fuomag9
155845f7ed fix: distribute nav squircles evenly across full sidebar height
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 14:39:41 +01:00
fuomag9
86172b38ed feat: redesign nav as 2-column squircle icon tiles
Replace full-width ListItemButton rows with a 2-column grid of
square tiles (borderRadius: 22%, aspectRatio: 1) containing a
centred icon and small label. Active tile uses primary.main fill.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 14:33:32 +01:00
fuomag9
0955084772 fix: swap Proxy Hosts and Analytics nav order
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 14:27:05 +01:00
fuomag9
c8bc1f7500 fix: fixed-width host picker to prevent layout shift on long names
Replace minWidth/maxWidth with a fixed width:260 + flexShrink:0 so the
Autocomplete never resizes the header row. Chip labels also truncate
with ellipsis instead of wrapping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 13:32:59 +01:00
fuomag9
1028322645 fix: collapse selected host chips to count badge when >2 selected
renderTags now shows individual chips for 1-2 selections, and a single
'N hosts' chip (with clear-all × button) for 3+. Prevents the input
from growing vertically when many hosts are selected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 12:13:08 +01:00
fuomag9
50028581b0 feat: add Select All/Clear buttons to host picker, fix popup overscroll
- PaperComponent header with "Select all" / "Clear" buttons; onMouseDown
  preventDefault keeps the popup open when clicking them
- ListboxProps overscrollBehavior: contain prevents the dropdown list's
  scroll from propagating to the page when reaching top/bottom

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 11:52:38 +01:00