Bug Fixes
- Core/Build: Restore agent release binaries and container images for Linux amd64 and arm64. (73453ba)
- Agent CI verifies its own dependency metadata before building.
- Core/Provider: Docker label routes inherit configured health-check and idlewatcher defaults. (20da17b)
- Explicit per-route health-check settings continue to override configured defaults.
- Core/Health: Agent health checks honor configured paths and request methods. (36f9c3d)
- HTTP, HTTPS and H2C probes honor healthcheck.path and healthcheck.use_get.
- Upgrade remote agents to enable GET probes; older agents continue using HEAD.
- Core/Entrypoint: Mixed-case hostnames select the correct route. (ea63b55)
- Mixed-case match_domains values work for HTTP routing and SNI matching.
- WebUI/Config: The configuration editor accepts supported access-log status filters. (yusing/godoxy-webui@ece7878)
- The status_codes filter validates in root, route and Docker route configurations.
New Features
- Core/API: Dry-run route access decisions without contacting the upstream. (4072b5a, yusing/godoxy-webui@c1859ab)
- GET /api/v1/route/explain reports ACL and middleware decisions for a supplied peer IP, host and request headers.
- Unsupported checks return conditional results rather than guessed outcomes.
- Route rules and upstream behavior are not simulated.
- The endpoint requires an authenticated browser session and rejects read-only bearer tokens.
- Core/Access Logs: Access logs explain denied requests. (3ca2a36)
- JSON and console output include denied_by and deny_reason when middleware or rules reject a request.
- The peer_ip field preserves the original connection address when real-IP middleware changes the client address.
- Enable entrypoint access logging to capture denials that never reach the upstream.
- Core/Address Policies: Address policies can follow dynamic hostnames. (c4a32cc, yusing/goutils@e4dc8ec, yusing/godoxy-webui@8749cb7)
- Use host: in supported ACL, middleware, remote-rule and access-log address filters.
- A and AAAA addresses refresh asynchronously every minute.
- Hostname sources match nothing until their first successful lookup.
- Failed DNS refreshes retain the last successful addresses indefinitely until resolution succeeds.
- Core/Config: Reuse named address sets across address policies. (438cad1, yusing/godoxy-webui@82c69fd)
- Define address_sets in the root configuration and reference them with set:.
- Sets accept IP addresses, CIDRs and host: entries but cannot contain other sets.
- Invalid set definitions or undefined references reject the candidate configuration without replacing the active configuration.
Improvements
- Core/Provider: File-provider reloads keep unchanged routes running. (0dd435b)
- Unrelated route edits no longer interrupt unchanged routes or reset their health state.
- Force reloads still restart every route.
- Routes referencing rule or TLS files are rebuilt on matching route-file reloads.
- Reload the route file after changing a referenced rule or TLS file because those files do not gain automatic watchers.
Breaking Changes
- Core/Address Policies: Bare IPv6 policy entries match one host instead of a /32 subnet. (dc30636)
- Use an explicit CIDR such as 2001:db8::/32 wherever subnet matching is intended.
Security
- Core/Middleware: Client-IP access checks no longer mistake the proxy for the visitor. (9d9a5e3, yusing/goutils@bf7b601, dc30636)
- Remote bypass rules use the rewritten client IP rather than a cached proxy address. (9d9a5e3, yusing/goutils@bf7b601)
- Route middleware with equal priorities runs real-IP resolution before client-IP checks. (dc30636)
- Entrypoint and compose chains warn when client-IP checks precede a resolver without changing their declared order. (dc30636)
- Core/ACL: UDP responses to ACL-denied destinations are blocked before transmission. (5bfa972)
- Core/Entrypoint: Optional strict SNI checks reject mismatched HTTPS routing. (ef600ee, yusing/godoxy-webui@1287e20)
- Enable entrypoint.strict_sni to return 421 for missing SNI or Host and SNI selecting different routes.
- Different hostnames remain accepted when they select the same route.
- Proxies and tunnels must send matching SNI when strict mode is enabled.
- Cloudflared deployments can use originRequest.matchSNItoHost: true.
Full Changelog
- 73453ba8 ci(agent): fix dependency metadata for release builds
- 20da17b fix(provider): apply config defaults to Docker label routes
- 36f9c3d fix(health): honor agent probe methods and health paths
- 0dd435b feat(provider): preserve unchanged file routes on reload (#294)
- 4072b5a feat(api): explain route access decisions without side effects (#293)
- 3ca2a36 feat(accesslog): record denial reasons and peer addresses (#292)
- 438cad1 feat(config): add reusable named address sets (#291)
- c4a32cc feat(net): match dynamic hostnames in address policies (#290)
- ef600ee feat(entrypoint): reject Host and TLS SNI mismatches (#289)
- dc30636 fix(middleware): make client IP handling deterministic (#288)
- 19ffbfc fix(build): propagate WebUI schema generation failures
- 626529e fix(accesslog): correct config schemas and ACL guidance
- 8fb036a fix(build): stop API generation after Swagger failures
- 60e6efa docs(provider): correct route file and rule path examples
- ea63b55 fix(entrypoint): match hostnames without case sensitivity
- 5bfa972 fix(acl): reject denied UDP writes before sending
- 9d9a5e3 fix(middleware): use rewritten client IP for bypass rules
- e4dc8ec feat(cache): support explicit refresh and generation invalidation
- bf7b601 fix(http): refresh cached client IP after address rewrites
- 24719f9 Merge remote-tracking branch 'origin/main' into local/pr-integration
- 255926a Merge commit '4c4867aa2b6d4c0dae75ebeb56474c83d7b2ae8a' into local/pr-integration
- a862ab0 Merge branch 'local/pr-291' into local/pr-integration
- a5ddcbb Merge branch 'local/pr-289' into local/pr-integration
- ecdd373 Merge branch 'local/pr-293' into local/pr-integration
- e9af082 Merge branch 'local/pr-291' into local/pr-integration
- 3d4b91c Merge branch 'local/pr-293' into local/pr-integration
- 9af9a72 Merge branch 'local/pr-294' into local/pr-integration
- 3ba041f Merge branch 'local/pr-292' into local/pr-integration
- d865b9c Merge branch 'local/pr-290' into local/pr-integration
- 62fc85a Merge branch 'local/pr-289' into local/pr-integration
- 83a795b docs(rules): refresh exact-host remote matcher help (#288)
- 1118668 docs(wiki): reference corrected route configuration examples
- 1287e20 fix(config): expose optional strict SNI configuration
- b190c22 Merge branch 'local/pr-288' into local/pr-290
- 5ed0fa7 docs(wiki): correct real IP header selection guidance
- 8749cb7 fix(net): expose hostname address sources in frontend contracts
- 1a4037d docs(wiki): include access log denial metadata
- 9001ed3 docs(wiki): reference incremental reload lifecycle guidance
- 3a2dd9f Merge commit '1a4037dd402c0f315a6161151b40070232450e38' into local/pr-293
- c1859ab fix(api): generate typed access explanations (#293)
- ec3ab40 Merge commit 'b190c22279b8c9f8c4c006f4d26b7837ea4958ee' into local/pr-291
- 82c69fd fix(config): accept named address sets in editor schemas (#291)
- 0e5818a docs(api): refresh explain request and listener guidance (#293)
- 18fc4b5 docs(wiki): update strict SNI guidance
- 2e2d5ca Merge branch 'local/pr-290' into local/pr-291
- 8a72af7 docs(wiki): update cache ownership and invalidation guidance
- 4c4867a docs(middleware): refresh proxy patching example
- 46dd6c3 fix(build): propagate schema generation failures
- ece7878 fix(accesslog): align frontend filters with backend configuration