Skip to content

feat: rebuild inbound Caddy redesign on current main#32

Closed
mikkelchokolate wants to merge 79 commits into
mainfrom
feature/inbound-caddy-redesign
Closed

feat: rebuild inbound Caddy redesign on current main#32
mikkelchokolate wants to merge 79 commits into
mainfrom
feature/inbound-caddy-redesign

Conversation

@mikkelchokolate

Copy link
Copy Markdown
Owner

Rebuilds the inbound/Caddy redesign cleanly on top of the current main instead of merging the stale divergent implementation.

Initial scope:

  • validated TCP/UDP bind-key model;
  • canonical IP address handling;
  • conservative dual-stack overlap detection;
  • deterministic conflict reporting with owner context;
  • focused unit tests.

The previous implementation remains only as a reference in backup/inbound-caddy-redesign-pre-main-sync-20260715. No encoded patch/chunk artifacts are part of this PR.

…schema

- Use Caddy's ACMEIssuer.Challenges JSON tag keys: "http" and "tls-alpn".
- Emit AutomationPolicy.issuers as an array instead of singular issuer.
- Add TestRenderCaddyJSONAcmeChallengeKeys asserting correct keys.
- BuildRenderPlan falls back PanelDomain to Domain and carries BackendPort/WebBasePath
- RenderCaddyJSON renders panel path-matched reverse proxy and uses backend port
- Update panelaccess, api, repair, renderer, and protocol tests to expect
  the consolidated generated/caddy/config.json and veil-caddy.service
- Remove obsolete packaging/systemd/veil-caddy@.service, add single veil-caddy.service
test(e2e): extend TestNaiveInboundCaddyJSON to delete the naive inbound and assert the Caddy JSON no longer references it.

Without this cleanup, deleting an inbound leaves the previously rendered Caddy JSON under the generated root; the next apply only writes the current rendered set, so the stale file persists. The staging writer now removes any regular file under <applyRoot>/generated that is not in the current written set and is not Veil metadata under generated/veil.
…e removal in e2e test

- cleanStaleGeneratedFiles now only walks known managed subdirectories
  (caddy, hysteria2, mieru, olcrtc, sing-box, rules) instead of all of generated/.
- TestNaiveInboundCaddyJSON asserts the Caddy JSON is removed after inbound deletion.
- Add unit test for cleanStaleGeneratedFiles scoping.
- caddyRequired now returns true for hysteria2 inbounds with per-inbound domain.
- CaddyRenderPlan carries DefaultChallengeMode; renderer uses it as fallback.
- CaddyBindOwner carries NaiveUsers populated from profiles/fallback credentials;
  renderer emits forward_proxy basic_auth.
…ad of panel.Caddyfile

The runtime veil-caddy.service and internal/renderer/systemd.go already read
/etc/veil/generated/caddy/config.json, but the installer/panel layers were
still writing panel.Caddyfile. This broke fresh panel-caddy installs.

- internal/panelaccess/profile.go: ProfileMaterial now carries CaddyJSON.
  BuildProfile/NewProfile keep model.Settings and use
  caddyassembly.BuildRenderPlan + renderer.RenderCaddyJSON for panel-only
  JSON instead of renderer.RenderPanelCaddyfile.
- internal/panelmaterial/material.go: Input.CaddyJSON writes
  generated/caddy/config.json.
- internal/installer/install_apply.go: ApplyResult.CaddyJSONPath points to
  generated/caddy/config.json.
- internal/installer/profile_ru.go, repair.go, cliflow/repair/plan_builder.go,
  api/profile_preview_routes.go, cli/install_apply.go: renamed Caddyfile ->
  CaddyJSON and updated JSON generation.
- docs/openapi.yaml + sdk/go/veilclient.gen.go: preview response field is now
  caddyJSON.
- Updated all affected tests to expect config.json / CaddyJSON.

All tests pass: go test ./..., go test -tags e2e ./test/e2e/..., and
make generate-sdk.
mikkelchokolate and others added 28 commits July 5, 2026 22:18
Use caddyassembly.BuildFinalRenderPlan in naiveproxy renderer, panel access, and
apply plan builder so the generated Caddy JSON always includes ACME challenge
servers matching the validated plan. Stop ignoring caddycapabilities.Probe errors
and return a clear diagnostic when the Caddy binary is missing or probing fails.
When PanelAccess is caddy, open settings.PanelPublicPort (default 443) instead
of hardcoding 443. Derive installer PanelHTTPSPort from the profile's public
port. Open TCP :80 for firewall when AcmeChallengeMode is http-01.
- Resolve naiveproxy public port from ProtocolFields[publicPort], falling back to inbound.Port.

- Open TCP port for TLS-ALPN-01 challenges when AcmeChallengeMode is tls-alpn-01.

- Update firewall API test to expect the new TLS-ALPN-01 rule.
- Normalize and validate owner.FallbackRoot before rendering file_server root.

- Reject paths that escape /var/lib/veil, mirroring the legacy Caddyfile check.

- Default empty FallbackRoot to /var/lib/veil/www.
- Only TCP transport is supported in this release; keep the inbound schema select to tcp only.

- Update InboundFieldSchema test to match the reduced option set.
- Rename auto_https to automatic_https in rendered servers.
- Replace forward_proxy basic_auth with auth_credentials base64 array.
- Emit explicit admin.listen = 127.0.0.1:2019 at the top level.
… from Caddy commands

Caddy's native JSON format does not accept 'json' as an adapter name.
Use 'caddy validate --config <path>' and drop --adapter from run/reload.
…ail fallback

Domain-level email resolution for naive inbounds now follows:
explicit inbound emails, DefaultAcmeEmail, PanelEmail, error.
- Assert automatic_https, auth_credentials, and admin.listen.
- Add caddy validate integration test.
- Replace legacy Email with DefaultAcmeEmail where naive inbounds need ACME email.
…l resolution

- NaiveEmail now returns only the inbound ProtocolFields["email"] value.
- ValidateSettings is now a no-op; per-inbound checks live in ValidateInbound.
- livevalidation resolves effective email via inbound → DefaultAcmeEmail → PanelEmail,
  matching the apply-plan builder fallback chain.
…eanup

- Load Caddy JSON config before hysteria2 certificate sync so new
  domains can obtain certificates before hysteria2 services start.
- Add veil-caddy.service runtime when hysteria2 inbounds reference
  domains but no naiveproxy inbound exists.
- Increase default hysteria2 cert sync timeout from 30s to 120s.
- Restore committed management state during rollback so settings like
  PanelAccess are reverted along with generated files.
- Detect and remove legacy per-inbound Caddy Caddyfiles (caddy/*.Caddyfile)
  during promotion and map them back to veil-caddy@<name>.service units
  for stop/disable.
- Allow veil-caddy@*.service template units in privileged policy.
- Detect bind-key ownership conflicts instead of silently overwriting.
- Read inbound.NaiveUsername/NaivePassword in caddyassembly to match
  validation and plugin fallback chain.
- Register Panel direct listener in bind registry for conflict checks.
- Add regression tests for all of the above.
@mikkelchokolate mikkelchokolate deleted the feature/inbound-caddy-redesign branch July 15, 2026 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant