Commit Graph

28 Commits

Author SHA1 Message Date
fuomag9 2c70f2859a Add multi-provider DNS registry for ACME DNS-01 challenges
Replace hardcoded Cloudflare DNS-01 with a data-driven provider registry
supporting 11 providers (Cloudflare, Route 53, DigitalOcean, Duck DNS,
Hetzner, Vultr, Porkbun, GoDaddy, Namecheap, OVH, Linode). Users can
configure multiple providers with encrypted credentials and select a
default. Per-certificate provider override is supported via providerOptions.

- Add src/lib/dns-providers.ts with provider definitions, credential
  encrypt/decrypt, and Caddy config builder
- Change DnsProviderSettings to multi-provider format with default selection
- Auto-migrate legacy Cloudflare settings on startup (db.ts)
- Normalize old single-provider format on read (getDnsProviderSettings)
- Refactor buildTlsAutomation() to use provider registry
- Add GET /api/v1/dns-providers endpoint for provider discovery
- Add dns-provider settings group to REST API and instance sync
- Replace Cloudflare settings card with multi-provider UI (add/remove
  providers, set default, dynamic credential forms)
- Add 10 DNS provider modules to Caddy Dockerfile
- Update OpenAPI spec, E2E tests, and unit test mocks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 18:01:16 +02:00
fuomag9 66f8e32df5 Fix security issues in Better Auth migration
- Tighten login rate limit from 200/10s to 5/60s to prevent brute-force
- Encrypt OAuth tokens (access/refresh/id) in accounts table via databaseHooks
- Sync password changes to accounts.password so old passwords stop working
- Redact OAuth client secrets in server actions before returning to client
- Add trustHost config (default false) to prevent Host header poisoning
- Add audit logging for successful logins via session create hook
- Add audit logging to OAuth provider update/delete server actions
- Fix provider ID collision by appending name hash suffix to slug
- Fix nullable provider field causing incorrect hasOAuth detection
- Refuse to store plaintext secrets if encryption module fails to load

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 21:50:48 +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 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 264e80ed73 consolidate WAF into unified page, reorder sidebar nav
- Move WAF config (enable, CRS, custom directives, templates) from
  Settings page into a new Settings tab on the WAF page
- WAF page now has three tabs: Events | Suppressed Rules | Settings
- Rename nav item from "WAF Events" to "WAF", route /waf-events → /waf
- Fix excluded_rule_ids preservation: no longer wiped when form field
  is absent (Settings tab omits the hidden field intentionally)
- Allow pre-adding suppressed rules even when WAF is disabled
- Reorder sidebar: Overview, Proxy Hosts, Access Lists, Certificates,
  WAF, Analytics, Audit Log, Settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 23:58:02 +01:00
fuomag9 41c6db3a3f waf suppressed rules: add by ID with lookup, search filter
- Add lookupWafRuleMessageAction server action — queries WAF event
  history for a known message for any rule ID
- Suppressed Rules tab: type a rule ID, look it up to see its
  description (or a "not triggered yet" note), confirm to suppress
- Duplicate-guard: looking up an already-suppressed rule shows an error
- Search field filters the suppressed list by rule ID or message text
- Newly added rules show their message immediately without page reload

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 22:50:21 +01:00
fuomag9 9834fe20c9 simplify global WAF settings: replace toggle+radio with single switch
With DetectionOnly removed, the global WAF had two redundant controls:
an Enable toggle and an Off/On radio, both doing the same thing. Collapse
them into a single labelled switch. Mode is now derived from the enabled
state in the action rather than being a separate form field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 17:30:13 +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 d959fdf836 if waf for a host is not configured, suppressing a rule for a host should automatically set it to "merge with global" and enabled. 2026-03-04 21:27:15 +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 1348c0b4cd fix: add server-side validation for geoblock_mode, access_list_id, redirect_url, response_status, and response_headers keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 09:35:06 +01:00
fuomag9 0758e5b27a feat: support fail_closed option from caddy-blocker-plugin
New field from upstream plugin: when the real client IP is
indeterminate (trusted proxy present but no usable XFF entry),
fail_closed=true blocks the request instead of passing it through.

- Add fail_closed to GeoBlockSettings type
- Include in mergeGeoBlockSettings (OR semantics: either global or host enables it)
- Emit fail_closed in buildBlockerHandler (only when true)
- Parse geoblock_fail_closed from form in both settings and proxy-host actions
- Add Checkbox UI in the Advanced accordion of GeoBlockFields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 09:14:46 +01:00
fuomag9 c5a5c6b743 fix: add syncInstances to updateGeoBlockSettingsAction for consistency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 19:56:39 +01:00
fuomag9 066c2851e4 feat: add global geoblocking section to settings page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 19:56:38 +01:00
fuomag9 bb8a0d1023 implemented upstream pinning 2026-02-22 01:11:56 +01:00
fuomag9 6fb39dc809 Implement slave-master architecture 2026-01-25 01:39:36 +01:00
fuomag9 7f93e9e784 Implement custom dns servers 2026-01-22 20:47:56 +01:00
fuomag9 06dc28fabd Added user logs functionality 2025-11-14 23:27:05 +01:00
fuomag9 58ec7e321e undo loki stuff 2025-11-12 23:22:30 +01:00
fuomag9 ec580d2385 Add the ability to log to loki 2025-11-12 22:07:51 +01:00
fuomag9 88b25cee65 Add Caddy restart detection, auto-recovery, and metrics exposure
- Implemented health monitoring service that detects Caddy restarts/crashes
- Automatically reapplies configuration when Caddy restarts
- Added metrics settings UI for enabling Prometheus/Grafana monitoring
- Caddy metrics exposed on separate port (default: 9090) via reverse proxy
- Admin API (port 2019) kept internal-only for security
- Updated docker-compose.yml with metrics port documentation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 19:36:40 +01:00
fuomag9 70c5fa831c Now when users configure Authentik defaults in Settings, those values will automatically pre-fill when creating new proxy hosts, but can still be customized per host
also allow instant enable/disable of hosts directly from the table/list views without needing to edit each host
2025-11-08 14:15:55 +01:00
fuomag9 ad0225a16e Throttle login attempts and lock admin actions to privileged sessions 2025-11-04 00:00:22 +01:00
fuomag9 668b667fe9 updated a lot of stuff 2025-11-02 22:16:13 +01:00
fuomag9 d9ced96e1b implement oauth2 login 2025-10-31 23:02:30 +01:00
fuomag9 29acf06f75 Swapped the entire UI to Material UI, applied a global dark theme, and removed all of the old styled-jsx/CSS-module styling 2025-10-31 21:03:02 +01:00
fuomag9 315192fb54 first rewrite commit 2025-10-31 20:08:28 +01:00