Commit Graph

34 Commits

Author SHA1 Message Date
fuomag9
a520717aab Fix excluded_paths dropped by sanitize functions during creation
The sanitizeAuthentikMeta and sanitizeCpmForwardAuthMeta functions
did not process excluded_paths, causing the field to be silently
stripped when creating a proxy host.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 10:21:18 +02:00
fuomag9
8f4c24119e Add excluded paths support for forward auth (fixes #108)
Allow users to exclude specific paths from Authentik/CPM forward auth
protection. When excluded_paths is set, all paths require authentication
EXCEPT the excluded ones — useful for apps like Navidrome that need
/share/* and /rest/* to bypass auth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 10:11:35 +02:00
fuomag9
3a16d6e9b1 Replace next-auth with Better Auth, migrate DB columns to camelCase
- Replace next-auth v5 beta with better-auth v1.6.2 (stable releases)
- Add multi-provider OAuth support with admin UI configuration
- New oauthProviders table with encrypted secrets (AES-256-GCM)
- Env var bootstrap (OAUTH_*) syncs to DB, UI-created providers fully editable
- OAuth provider REST API: GET/POST/PUT/DELETE /api/v1/oauth-providers
- Settings page "Authentication Providers" section for admin management
- Account linking uses new accounts table (multi-provider per user)
- Username plugin for credentials sign-in (replaces email@localhost pattern)
- bcrypt password compatibility (existing hashes work)
- Database-backed sessions via Kysely adapter (bun:sqlite direct)
- Configurable rate limiting via AUTH_RATE_LIMIT_* env vars
- All DB columns migrated from snake_case to camelCase
- All TypeScript types/models migrated to camelCase properties
- Removed casing: "snake_case" from Drizzle config
- Callback URL format: {baseUrl}/api/auth/oauth2/callback/{providerId}
- package-lock.json removed and gitignored (using bun.lock)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 21:11:48 +02:00
fuomag9
dc121700fd Suppress false-positive CodeQL ReDoS alerts on placeholder-stripping regex
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 14:52:28 +02:00
fuomag9
5d0b4837d8 Security hardening: fix SQL injection, WAF bypass, placeholder injection, and more
- C1: Replace all ClickHouse string interpolation with parameterized queries
  (query_params) to eliminate SQL injection in analytics endpoints
- C3: Strip Caddy placeholder patterns from redirect rules, protected paths,
  and Authentik auth endpoint to prevent config injection
- C4: Replace WAF custom directive blocklist with allowlist approach — only
  SecRule/SecAction/SecMarker/SecDefaultAction permitted; block ctl:ruleEngine
  and Include directives
- H2: Validate GCM authentication tag is exactly 16 bytes before decryption
- H3: Validate forward auth redirect URIs (scheme, no credentials) to prevent
  open redirects
- H4: Switch 11 analytics/WAF/geoip endpoints from session-only requireAdmin
  to requireApiAdmin supporting both Bearer token and session auth
- H5: Add input validation for instance-mode (whitelist) and sync-token
  (32-char minimum) in settings API
- M1: Add non-root user to l4-port-manager Dockerfile
- M5: Document Caddy admin API binding security rationale
- Document C2 (custom config injection) and H1 (SSRF via upstreams) as
  intentional admin features

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:13:50 +02:00
fuomag9
23bc2a0476 Fix security issues found during pentest
- Add per-user API token limit (max 10) and name length validation (max 100 chars)
- Return 404 instead of 500 for "not found" errors in API responses
- Disable X-Powered-By header to prevent framework fingerprinting
- Enforce http/https protocol on proxy host upstream URLs
- Remove stale comment about OAuth users defaulting to admin role

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 15:09:21 +02:00
fuomag9
03c8f40417 Add forward auth portal — CPM as built-in IdP replacing Authentik
CPM can now act as its own forward auth provider for proxied sites.
Users authenticate at a login portal (credentials or OAuth) and Caddy
gates access via a verify subrequest, eliminating the need for external
IdPs like Authentik.

Key components:
- Forward auth flow: verify endpoint, exchange code callback, login portal
- User groups with membership management
- Per-proxy-host access control (users and/or groups)
- Caddy config generation for forward_auth handler + callback route
- OAuth and credential login on the portal page
- Admin UI: groups page, inline user/group assignment in proxy host form
- REST API: /api/v1/groups, /api/v1/forward-auth-sessions, per-host access
- Integration tests for groups and forward auth schema

Also fixes mTLS E2E test selectors broken by the RBAC refactor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 22:32:17 +02:00
fuomag9
277ae6e79c Add mTLS RBAC with path-based access control, role/cert trust model, and comprehensive tests
Implements full role-based access control for mTLS client certificates:
- Database: mtls_roles, mtls_certificate_roles, mtls_access_rules tables with migration
- Models: CRUD for roles, cert-role assignments, path-based access rules
- Caddy config: HTTP-layer RBAC enforcement via CEL fingerprint matching in subroutes
- New trust model: select individual certs or entire roles instead of CAs (derives CAs automatically)
- REST API: /api/v1/mtls-roles, cert assignments, proxy-host access rules endpoints
- UI: Roles management tab (card-based), cert/role trust picker, inline RBAC rule editor
- Fix: dialog autoclose bug after creating proxy host (key-based remount)
- Tests: 85 new tests (785 total) covering models, schema, RBAC route generation, leaf override, edge cases

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 18:40:21 +02:00
fuomag9
0f9bd04ec7 feat: add LocationRule type and model layer support
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:51:08 +01:00
fuomag9
9c60d11c2c feat: improve UI contrast, dark mode, dialog sizing, color coherence, and add table sorting
- Fix dialog scrollability (flex layout + max-h-[90dvh]) and increase L4 dialog to lg width
- Add styled enable card to L4 dialog matching proxy host pattern
- Unify section colors across proxy host and L4 dialogs (cyan=LB, emerald=DNS, violet=upstream DNS, rose=geo, amber=mTLS)
- Improve light mode contrast: muted-foreground oklch 0.552→0.502, remove opacity modifiers on secondary text
- Improve dark mode: boost muted-foreground to 0.85, increase border opacity 10%→16%, input 15%→20%
- Add bg-card to DataTable wrapper and bg-muted/40 to table headers for surface hierarchy
- Add semantic badge variants (success, warning, info, muted) and StatusChip dark mode fix
- Add server-side sortable columns to Proxy Hosts and L4 Proxy Hosts (name, upstream, status, protocol, listen)
- Add sortKey to DataTable Column type with clickable sort headers (ArrowUp/Down indicators, URL param driven)
- Fix E2E test selectors for shadcn UI (label associations, combobox roles, dropdown menus, mobile drawer)
- Add htmlFor/id to proxy host form fields and aria-labels to select triggers for accessibility
- Add sorting E2E tests for both proxy host pages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:17:56 +01:00
fuomag9
4b5323a7bf feat: add structured redirects and path prefix rewrite for proxy hosts
Adds two new UI-configurable Caddy patterns that previously required raw JSON:
- Per-path redirect rules (from/to/status) emitted as a subroute handler before
  auth so .well-known paths work without login; supports full URLs, cross-domain
  targets, and wildcard path patterns (e.g. /.well-known/*)
- Path prefix rewrite that prepends a segment to every request before proxying
  (e.g. /recipes → upstream sees /recipes/original/path)

Config is stored in the existing meta JSON column (no schema migration). Includes
integration tests for meta serialization and E2E functional tests against a real
Caddy instance covering relative/absolute destinations, all 3xx status codes, and
various wildcard combinations. Adds traefik/whoami to the test stack to verify
rewritten paths actually reach the upstream.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 17:53:33 +01:00
fuomag9
73c90894b1 Handle wildcard proxy hosts and stabilize test coverage
- accept wildcard proxy host domains like *.example.com with validation and normalization
- make exact hosts win over overlapping wildcards in generated routes and TLS policies
- add unit coverage for host-pattern priority and wildcard domain handling
- add a single test:all entry point and clean up lint/typecheck issues so the suite runs cleanly
- run mobile layout Playwright checks under both chromium and mobile-iphone
2026-03-14 01:03:34 +01:00
fuomag9
b348dae4be remove DetectionOnly WAF mode
DetectionOnly was fundamentally broken in coraza-caddy (actually blocks
requests via anomaly scoring), caused massive audit log flooding, and the
threshold workaround had several issues:
- t:none is meaningless in a SecAction (no target to transform)
- SecRuleEngine directive ordering relative to SecAction is implementation-
  defined, making the override fragile
- host.mode ?? 'DetectionOnly' fallbacks silently gave any host without an
  explicit mode the broken DetectionOnly behaviour

Changes:
- Remove DetectionOnly from UI (global settings radio, per-host engine mode)
- Coerce legacy DB values of 'DetectionOnly' to 'On' in buildWafHandler
- Fix fallback defaults: host.mode ?? 'DetectionOnly' → host.mode ?? 'On'
- Fix action parsers: unknown mode defaults to 'On' (was 'DetectionOnly')
- Fix global settings defaultValue: ?? 'DetectionOnly' → ?? 'On' (or 'Off')
- Remove the fragile threshold SecAction workaround
- Update types: mode is now 'Off' | 'On' throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 17:27:08 +01:00
fuomag9
333f7d4733 Revert "fix authentik not being removed when toggle is disabled"
This reverts commit 641ab9ef34.
2026-03-06 09:56:59 +01:00
fuomag9
641ab9ef34 fix authentik not being removed when toggle is disabled 2026-03-06 09:34:26 +01:00
fuomag9
f3358c20cd feat: add mTLS support for proxy hosts
- New `ca_certificates` table for reusable CA certs (migration 0011)
- CA cert CRUD model, server actions, and UI dialogs
- Proxy host create/edit dialogs include mTLS toggle + CA cert selection
- Caddy config generates `client_authentication` TLS policy blocks with
  `require_and_verify` mode for hosts with mTLS enabled
- CA certs sync to slave instances via instance-sync payload
- Certificates page shows CA Certificates section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 20:29:55 +01:00
fuomag9
7341070c0d Fix rule parsing for single reverse proxies 2026-03-04 21:16:11 +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
461df12ae8 fix search crash 2026-02-27 22:28:19 +01:00
fuomag9
a45a156068 fix pages viewing 2026-02-27 19:49:11 +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
f54b7db96f fix: align GeoBlock hydrators with existing patterns in proxy host model
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 19:56:37 +01:00
fuomag9
e6e35646c0 feat: add GeoBlock types and hydration to proxy host model
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 19:56:37 +01:00
fuomag9
bb8a0d1023 implemented upstream pinning 2026-02-22 01:11:56 +01:00
fuomag9
eecacfb271 The static response feature has been completely removed 2026-02-09 01:15:28 +01:00
fuomag9
6d56cf2288 deprecate deadhosts, move it to the GUI as a custom response feature 2026-02-07 00:51:48 +01:00
fuomag9
7f93e9e784 Implement custom dns servers 2026-01-22 20:47:56 +01:00
fuomag9
49cf4f5ed1 added load balancing settings 2026-01-21 22:23:17 +01:00
fuomag9
b17ae54fbd Squashed commit of the following:
commit b5a751005850115c84fd8fddb83f32a52835a422
Author: fuomag9 <1580624+fuomag9@users.noreply.github.com>
Date:   Sat Nov 8 13:54:22 2025 +0100

    Update ProxyHostsClient.tsx

commit c93b3898c31b9c206fba74605dad5a578e326ce4
Author: fuomag9 <1580624+fuomag9@users.noreply.github.com>
Date:   Sat Nov 8 13:43:00 2025 +0100

    test-protected-paths
2025-11-08 13:55:23 +01:00
fuomag9
3be4e1bf7d Rewritten to use drizzle instead of prisma
commit c0894548dac5133bd89da5b68684443748fa2559
Author: fuomag9 <1580624+fuomag9@users.noreply.github.com>
Date:   Fri Nov 7 18:38:30 2025 +0100

    Update config.ts

commit 5a4f1159d2123ada0f698a10011c24720bf6ea6f
Author: fuomag9 <1580624+fuomag9@users.noreply.github.com>
Date:   Fri Nov 7 15:58:13 2025 +0100

    first drizzle rewrite
2025-11-07 19:26:32 +01:00
fuomag9
102bd04d4c Fix auto certificate not showing in GUI when editing proxy host
When editing a proxy host with certificate_id set to null (auto), the
dropdown would not show "Managed by Caddy (Auto)" as selected and it
would revert to another certificate. There were two issues:

1. Form submission: Empty string from dropdown was treated as falsy,
   returning undefined instead of null (means "don't change")

2. Database update: The ?? operator treated null as falsy and fell back
   to existing value instead of saving null

Changes:
- app/(dashboard)/proxy-hosts/actions.ts: Check formData.has() and
  explicitly convert empty string to null for auto mode
- src/lib/models/proxy-hosts.ts: Use !== undefined instead of ?? to
  allow null values to be saved
- app/(dashboard)/proxy-hosts/ProxyHostsClient.tsx: Add Certificate
  column to table showing "Managed by Caddy (Auto)" for auto certs

Applied same fixes to access_list_id for consistency.

Now when users select "Managed by Caddy (Auto)", it correctly sets
certificate_id to null, displays properly on subsequent edits, and
shows in the table view.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 11:51:41 +01:00
fuomag9
668b667fe9 updated a lot of stuff 2025-11-02 22:16:13 +01:00
fuomag9
b064003c34 Updated the UI 2025-10-31 23:25:04 +01:00
fuomag9
315192fb54 first rewrite commit 2025-10-31 20:08:28 +01:00