Skip to content

Refactor MagicDNS support to properly handle appconnectors and exit nodes - #667

Open
lmagyar wants to merge 25 commits into
hassio-addons:mainfrom
lmagyar:pr-fix-proxies
Open

Refactor MagicDNS support to properly handle appconnectors and exit nodes#667
lmagyar wants to merge 25 commits into
hassio-addons:mainfrom
lmagyar:pr-fix-proxies

Conversation

@lmagyar

@lmagyar lmagyar commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

Note: 2 users reported that it works.

Proposed Changes

  • Move egress and ingress proxies to non-default ports (port 53 caused some real or false positive conflicts/error messages)
    • They are moved to port 51100 and 53127 and they made accessible on port 53 with iptables forwarding for HA's DNS, SU and tailscaled itself
    • If these ports are allocated, they search for free ports
  • Always start up the internal proxy services if MagicDNS is active (userspace networking is disabled), and reconfigure them when the tailnet's DNS related configuration is changed (checked in each 30s)
    • during startup no limit on egress side, the ingress is blocked
    • when local accept_dns is off
      • no change, works as before
      • ingress: MagicDNS resolves only tailnet addresses
      • egress: tailscaled can freely call HA's DNS for anything else
    • when local accept_dns is on, global Override DNS servers is off
      • new situation
      • ingress: MagicDNS resolves only tailnet + SplitDNSRoutes addresses
      • egress: tailscaled can freely call HA's DNS for anything else
    • when both local accept_dns and global Override DNS servers is on
      • no change, works as before
      • ingress: MagicDNS can resolve nearly everything
      • egress: tailscaled can call HA's DNS for login server, letsencrypt, log-server, but normally eg. goes to the configured global DNS servers

The whole internal structure got much clearer and logical:

  user
  |  ˅
  |  magicdns-proxies-reconfigurator
  ˅  ˅
  magicdns-ingress-proxy
  |  ˅
  |  magicdns-proxies-configurator
  |  ˅
  |  post-tailscaled
  |  ˅
  |  tailscaled
  |  ˅
  |  magicdns-egress-proxy
  ˅  ˅
  init-magicdns-proxies

Related Issues

fixes #661 #666

Summary by CodeRabbit

  • New Features

    • DNS ingress and egress proxies now select available ports automatically.
    • Added restricted and unrestricted MagicDNS modes with improved forwarding and NXDOMAIN handling.
    • Added automatic proxy reconfiguration when Tailscale DNS settings change.
    • Added forwarding management with optional suppression during proxy restarts.
  • Bug Fixes

    • Improved resolver startup readiness, forwarding cleanup, and service shutdown behavior.
    • Health checks now account for proxy reconfiguration health.
  • Chores

    • Updated service wiring and DNS configuration handling.

@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Dynamic port allocation replaces fixed port 53 for both DNS proxies. Runtime configuration computes MAGICDNS_MODE and dnsmasq domain lists. A reconfigurator watches Tailscale DNS changes and coordinates proxy restarts with forwarding suppression and health tracking.

Changes

MagicDNS configuration

Layer / File(s) Summary
Mode detection and list generation
tailscale/rootfs/usr/bin/configure-magicdns-proxies
The new script reads Tailscale DNS status, computes MAGICDNS_MODE, writes the dnsmasq domain list, and persists status for test comparisons.

Proxy runtime and orchestration

Layer / File(s) Summary
Dynamic ports and mode filtering
tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/run, tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/run
Both proxies select available ports and apply restricted or unrestricted dnsmasq filtering. Ingress forwarding uses the selected port and can be suppressed during restarts.
Reconfigurator and service lifecycle
tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/*, tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish, tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/finish
The reconfigurator processes SelfChange events, tests configuration, tracks health, restarts proxies, and restores forwarding. Finish handlers clean up forwarding and apply startup-aware exit handling.

Estimated code review effort: 4 (Complex) | ~50 minutes

Possibly related PRs

Suggested labels: refactor

Suggested reviewers: frenck

Poem

🐰 Ports hop to open ground,
DNS rules turn without a sound.
Proxies pause, then start anew,
While forwarding follows through. ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes refactor MagicDNS DNS proxies but provide no evidence of restoring IPv4/IPv6 forwarding or subnet-routing rules required by #661. Add or reference code that restores and validates IPv4/IPv6 forwarding, subnet routing, and relevant CONNMARK or rp_filter handling for #661.
Out of Scope Changes check ⚠️ Warning Most changes concern MagicDNS proxy ports, DNS policy, service lifecycle, and reconfiguration rather than the forwarding and subnet-routing requirements in #661. Limit this PR to #661 requirements or link separate issues that define the broader MagicDNS proxy refactor scope.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary MagicDNS refactor for app connectors and exit nodes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lmagyar lmagyar added the bugfix Inconsistencies or issues which will cause a problem for users or implementors. label Apr 15, 2026
@lmagyar

This comment was marked as outdated.

@coderabbitai

This comment was marked as outdated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tailscale/rootfs/usr/bin/magicdns-egress-proxy-forwarding`:
- Around line 42-47: The loop that parses proto and port uses non-POSIX regex
tokens in the grep and sed patterns; update the grep -E pattern to replace \s
with [[:space:]] and \d with [0-9], and replace the non-greedy .*? with greedy
constructs that limit scope (e.g., use [^[:space:]]+ or [^:]+ where appropriate)
so the pattern reliably matches "-p <proto>" and the destination port; likewise
change the sed -nr pattern to capture the protocol and port with
POSIX-compatible groups like ([^[:space:]]+) and ([0-9]+) instead of \S and \d,
keeping the same capture order used by IFS='|' read -r proto to_port.

In `@tailscale/rootfs/usr/bin/magicdns-ingress-proxy-forwarding`:
- Around line 63-68: The grep -E and sed -r patterns in the for loop use PCRE
constructs (.*?, \s, \S, \d) which sed/grep POSIX ERE don't support; update the
grep pattern and the sed substitution to use POSIX ERE classes and greedy
matching (e.g. replace \s with [[:space:]], \S with [^[:space:]] or [[:graph:]]
and \d with [0-9]+, and change .*? to .*). Specifically modify the ${cmd} ... |
{ grep -E "..."; } ... | sed -r 's/^.*?-p\s(\S+).*?:(\d+)$/\1|\2/p' pipeline so
the grep uses [[:space:]] and [0-9]+ and the sed uses -r (or -E) with a pattern
like 's/^.*-p[[:space:]]+([^[:space:]]+).*:([0-9]+)$/\1|\2/p' so that the for
variables loop and the IFS='|' read -r proto to_port correctly extract proto and
to_port.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0c3c44cb-ea76-4e91-b514-8f55ebf7a674

📥 Commits

Reviewing files that changed from the base of the PR and between 02fbebc and 155244f.

📒 Files selected for processing (6)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/tailscaled/run
  • tailscale/rootfs/usr/bin/magicdns-egress-proxy-forwarding
  • tailscale/rootfs/usr/bin/magicdns-ingress-proxy-forwarding

Comment thread tailscale/rootfs/usr/bin/magicdns-egress-proxy-forwarding
Comment thread tailscale/rootfs/usr/bin/magicdns-ingress-proxy-forwarding
@lmagyar
lmagyar marked this pull request as draft May 1, 2026 21:16
@lmagyar lmagyar changed the title Move MagicDNS egress and ingress proxies to non-default ports Refactor MagicDNS support to properly handle appconnectors May 1, 2026
@lmagyar

This comment was marked as outdated.

@coderabbitai

This comment was marked as outdated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/run`:
- Around line 46-55: The loop that searches for a free egress port skips the
upper bound because it exits when ++dnsmasq_egress_port equals
DNSMASQ_EGRESS_DEFAULT_PORT + 1000, so that boundary port is never tested;
modify the exit check in the while loop to only abort after the candidate has
moved past the upper bound (e.g., change the equality check to a greater-than
comparison), keeping references to dnsmasq_egress_port and
DNSMASQ_EGRESS_DEFAULT_PORT inside the same while loop block so the final
boundary port is actually attempted before failing.
- Around line 78-105: Check MAGICDNS_MODE explicitly and fail fast: replace the
current if bashio::var.equals "${MAGICDNS_MODE}" "RESTRICTED" ... else ... fi
pattern with explicit checks for allowed values (e.g., bashio::var.equals
"${MAGICDNS_MODE}" "RESTRICTED" and bashio::var.equals "${MAGICDNS_MODE}"
"UNRESTRICTED"); keep the existing logic that reads
DNSMASQ_BLACK_WHITE_LIST_LOCATION into black_list/white_list (readarray -t) and
populates options+=(...) for servers or NXDOMAIN, but add a final else branch
that logs a clear error including the invalid MAGICDNS_MODE value via
bashio::log.error and terminates with a non-zero exit (e.g., exit 1) to avoid
silently falling back to the wrong behavior.

In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run`:
- Around line 25-34: The probe failure path for configure-magicdns-proxies
currently leaves magicdns_proxies_configuration unset/invalid so the later
change-detection branch can wrongly treat it as "changed" and trigger restarts;
modify the logic in the run loop (inspect the configure-magicdns-proxies call
and the magicdns_proxies_configuration variable usage) so that when
configure-magicdns-proxies test fails you either explicitly set
magicdns_proxies_configuration='unchanged' or skip the restart branch entirely
(only enter the "Restart dnsmasq proxies" block when the probe succeeded and
magicdns_proxies_configuration is a valid non-empty value and not 'unchanged').
Ensure health-state handling with MAGICDNS_PROXIES_RECONFIGURATOR_HEALTH_STATE
remains unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 802ab648-2ef7-4c57-b53d-3d12fadab999

📥 Commits

Reviewing files that changed from the base of the PR and between ae0ccd7 and f79be40.

📒 Files selected for processing (31)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-ingress-proxy/down
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-ingress-proxy/up
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies-upstream-list/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies-upstream-list/up
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies/dependencies.d/base
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies/down
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies/type
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies/up
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/dependencies.d/init-magicdns-proxies
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/dependencies.d/init-magicdns-proxies-upstream-list
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/dependencies.d/magicdns-proxies-configurator
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/dependencies.d/post-tailscaled
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-configurator/dependencies.d/post-tailscaled
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-configurator/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-configurator/type
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-configurator/up
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/dependencies.d/magicdns-ingress-proxy
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/type
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/tailscaled/dependencies.d/init-magicdns-ingress-proxy
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/tailscaled/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/magicdns-proxies-reconfigurator
  • tailscale/rootfs/etc/s6-overlay/scripts/stage2_hook.sh
  • tailscale/rootfs/usr/bin/configure-magicdns-proxies
  • tailscale/rootfs/usr/bin/healthcheck
💤 Files with no reviewable changes (4)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-ingress-proxy/down
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies-upstream-list/up
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-ingress-proxy/up
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies-upstream-list/run
✅ Files skipped from review due to trivial changes (4)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-configurator/up
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/type
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies/down
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-magicdns-proxies/up
🚧 Files skipped from review as they are similar to previous changes (2)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/tailscaled/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/run

Comment thread tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/run
Comment thread tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/run
Comment thread tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run Outdated
@lmagyar

This comment was marked as outdated.

@coderabbitai

This comment was marked as outdated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run (1)

37-50: 🏗️ Heavy lift

No error handling in the reconfiguration block leaves the system in an inconsistent state on partial failure.

Every command in the restart sequence (lines 38–50) runs unconditionally with no exit-code checks and no rollback:

  • If magicdns-ingress-proxy-forwarding setup drop fails, the drop rule is absent but forwarding is subsequently removed (line 39) — there is a brief window where queries pass through unconstrained.
  • If s6-svc -ruwR /run/service/magicdns-ingress-proxy were to return before the ingress proxy writes the port file (see the companion issue above), the forwarding setup call silently misfires.
  • If magicdns-ingress-proxy-forwarding remove drop (line 48) fails after forwarding setup (line 47) also failed, the drop rule lingers but forwarding is absent — DNS is permanently blocked.

Because none of these failures update MAGICDNS_PROXIES_RECONFIGURATOR_HEALTH_STATE to UNHEALTHY, the healthcheck (context snippet 4) continues to update LAST_ONLINE_TIMESTAMP even while DNS is broken.

Consider wrapping the reconfiguration sequence in a helper function that tracks success end-to-end and sets UNHEALTHY if any critical step fails, keeping the SUPPRESS marker in place so that a subsequent loop iteration (after the next config change) can re-attempt cleanly:

function reconfigure_proxies() {
  ...
  magicdns-ingress-proxy-forwarding setup drop || return 1
  magicdns-ingress-proxy-forwarding remove forwarding || return 1
  s6-svc -ruwR /run/service/magicdns-egress-proxy || return 1
  s6-svc -ruwR /run/service/magicdns-ingress-proxy || return 1
  [[ -s "${DNSMASQ_INGRESS_PORT_LOCATION}" ]] || return 1
  magicdns-ingress-proxy-forwarding setup forwarding "$(<"${DNSMASQ_INGRESS_PORT_LOCATION}")" || return 1
  magicdns-ingress-proxy-forwarding remove drop || return 1
  rm -r -f "${MAGICDNS_INGRESS_PROXY_SUPPRESS_FORWARDING_CONFIGURATION_LOCATION}"
  rm -r -f "${DNSMASQ_INGRESS_PORT_LOCATION}"
}

if ! reconfigure_proxies; then
  printf "UNHEALTHY" > /var/run/s6/container_environment/MAGICDNS_PROXIES_RECONFIGURATOR_HEALTH_STATE
  healthy=false
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run`
around lines 37 - 50, Wrap the reconfiguration sequence into a helper function
(e.g., reconfigure_proxies) that runs each step with exit-code checks and
returns non-zero on any failure: run magicdns-ingress-proxy-forwarding setup
drop, magicdns-ingress-proxy-forwarding remove forwarding, s6-svc -ruwR for both
/run/service/magicdns-egress-proxy and /run/service/magicdns-ingress-proxy,
verify DNSMASQ_INGRESS_PORT_LOCATION is present and non-empty before calling
magicdns-ingress-proxy-forwarding setup forwarding with its value, then call
magicdns-ingress-proxy-forwarding remove drop and only on full success remove
the SUPPRESS file and DNSMASQ_INGRESS_PORT_LOCATION; if the helper fails, write
"UNHEALTHY" to MAGICDNS_PROXIES_RECONFIGURATOR_HEALTH_STATE and avoid removing
the suppress marker so the next loop can retry, ensuring each command
(magicdns-ingress-proxy-forwarding, s6-svc) is checked and failure
short-circuits the rest.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run`:
- Around line 46-50: The restore sequence must guard against a missing/empty
DNSMASQ_INGRESS_PORT_LOCATION and must not remove the drop rule or cleanup the
SUPPRESS marker if forwarding setup cannot run; change the block around
magicdns-ingress-proxy-forwarding so it first tests that
DNSMASQ_INGRESS_PORT_LOCATION exists and is non-empty (e.g. [[ -s
"${DNSMASQ_INGRESS_PORT_LOCATION}" ]]) and only then calls
magicdns-ingress-proxy-forwarding setup forwarding
"$(<"${DNSMASQ_INGRESS_PORT_LOCATION}")"; if the file is missing/empty or the
setup command fails, log an error via bashio::log.error and exit non-zero (or
return) so the subsequent magicdns-ingress-proxy-forwarding remove drop and rm
of
MAGICDNS_INGRESS_PROXY_SUPPRESS_FORWARDING_CONFIGURATION_LOCATION/DNSMASQ_INGRESS_PORT_LOCATION
are not executed; ensure the magicdns-ingress-proxy-forwarding failure is
propagated (do not swallow its exit code).

---

Nitpick comments:
In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run`:
- Around line 37-50: Wrap the reconfiguration sequence into a helper function
(e.g., reconfigure_proxies) that runs each step with exit-code checks and
returns non-zero on any failure: run magicdns-ingress-proxy-forwarding setup
drop, magicdns-ingress-proxy-forwarding remove forwarding, s6-svc -ruwR for both
/run/service/magicdns-egress-proxy and /run/service/magicdns-ingress-proxy,
verify DNSMASQ_INGRESS_PORT_LOCATION is present and non-empty before calling
magicdns-ingress-proxy-forwarding setup forwarding with its value, then call
magicdns-ingress-proxy-forwarding remove drop and only on full success remove
the SUPPRESS file and DNSMASQ_INGRESS_PORT_LOCATION; if the helper fails, write
"UNHEALTHY" to MAGICDNS_PROXIES_RECONFIGURATOR_HEALTH_STATE and avoid removing
the suppress marker so the next loop can retry, ensuring each command
(magicdns-ingress-proxy-forwarding, s6-svc) is checked and failure
short-circuits the rest.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6dba5b25-d941-431b-912a-54ad8b3b4d42

📥 Commits

Reviewing files that changed from the base of the PR and between f79be40 and 96d786e.

📒 Files selected for processing (3)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run
✅ Files skipped from review due to trivial changes (1)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/run
🚧 Files skipped from review as they are similar to previous changes (1)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/run

Comment thread tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run Outdated
@lmagyar

This comment was marked as outdated.

@coderabbitai

This comment was marked as outdated.

@lmagyar

This comment was marked as outdated.

@coderabbitai

This comment was marked as outdated.

@lmagyar
lmagyar marked this pull request as ready for review May 2, 2026 10:53
@lmagyar

lmagyar commented May 3, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented May 3, 2026

Copy link
Copy Markdown
✅ Actions performed

Reviews resumed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run`:
- Around line 74-99: The current logic updates previous_ipn_dns_config before
attempting the probe, which suppresses retries on transient failures; change it
so previous_ipn_dns_config is only set after a successful probe by moving the
assignment into the successful-branch (i.e., inside the else of the
configure-magicdns-proxies test where magicdns_proxies_configuration is
available), keep the existing health-state updates and restart_proxies handling
as-is, and ensure you still compare current_ipn_dns_config vs
previous_ipn_dns_config at the top to gate the probe; referenced symbols:
previous_ipn_dns_config, current_ipn_dns_config, configure-magicdns-proxies,
magicdns_proxies_configuration, restart_proxies.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e5625df6-c623-4eb8-ae41-8542a25aa86d

📥 Commits

Reviewing files that changed from the base of the PR and between 96d786e and c240649.

📒 Files selected for processing (1)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run

Comment thread tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/run Outdated
@lmagyar lmagyar added the no-stale This issue or PR is exempted from the stable bot. label May 8, 2026
@lmagyar lmagyar changed the title Refactor MagicDNS support to properly handle appconnectors Refactor MagicDNS support to properly handle appconnectors and exit nodes Jul 8, 2026
@lmagyar lmagyar mentioned this pull request Jul 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish`:
- Around line 28-33: Replace the broad s6-rc list failure check in the finish
handlers with an explicit pre-initialization-state check that only uses exit 125
during startup; for unexpected s6-rc-db/list failures, preserve and emit the
original stderr before halting. Apply this change in
tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish:28-33,
magicdns-ingress-proxy/finish:34-39, and
magicdns-proxies-reconfigurator/finish:26-31.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: adfdd2b7-39b7-467d-9a90-01cb15337d82

📥 Commits

Reviewing files that changed from the base of the PR and between 1c11291 and 19bf7b8.

📒 Files selected for processing (3)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/finish

Comment on lines +28 to +33
if ! s6-rc list &>/dev/null; then
# Required during startup
exit 125
else
exec /run/s6/basedir/bin/halt
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
for f in \
  tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish \
  tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/finish \
  tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/finish
do
  echo "--- $f ---"
  if [ -f "$f" ]; then
    nl -ba "$f" | sed -n '1,80p'
  else
    echo "missing"
  fi
done

echo "== related s6 service/finish references =="
rg -n "finish|s6-rc list|exit 125|/run/s6/basedir/bin/halt|magicdns-(egress|ingress)-proxy|magicdns-proxies-reconfigurator" tailscale -S || true

echo "== current branch from git =="
git diff --stat || true
git diff -- tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/finish tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/finish || true

Repository: hassio-addons/app-tailscale

Length of output: 295


🌐 Web query:

skarnet s6-rc list help exit codes invalid-state busy-state database-error usage-error

💡 Result:

The skarnet s6-rc suite does not use specific exit codes labeled "invalid-state," "busy-state," or "database-error" in its documentation [1][2][3][4]. Instead, it uses standard numerical exit codes to represent these conditions [1][3]. Common s6-rc exit codes corresponding to your request include: - Database/State Errors: Exit code 4 is consistently used across s6-rc tools (such as s6-rc, s6-rc-db, s6-rc-update) to indicate an "invalid or corrupted service database" or an invalid live state [1][3][5][4]. - Usage Errors: Exit code 100 is the standard code for "wrong usage" across the s6-rc suite [1][2][3][4]. - Busy State: While there is no specific "busy-state" exit code, tools like s6-rc-db, s6-rc-update, and s6-rc-bundle default to failing with an error message if the database is currently in use (locked) [1][6][7][8]. Users can typically override this behavior using the -b (blocking lock) option, which causes the program to wait instead of failing [1][6][7][8]. For the s6-rc-db list subcommand specifically, it follows the standard exit codes for the s6-rc-db program: 0 for success, 3 for identifier not found, 4 for an invalid or corrupted database, 5 for wrong identifier type, 100 for usage errors, and 111 for system call failures [1][6]. Help messages are accessed via the help subcommand, which prints to stdout and exits 0 [1][6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish \
  tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/finish \
  tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/finish
do
  echo "--- $f ---"
  if [ -f "$f" ]; then
    awk '{printf "%6d  %s\n", NR, $0}' "$f" | sed -n '1,80p'
  else
    echo "missing"
  fi
done

echo "== related s6 service/finish references =="
grep -RInE "finish|s6-rc list|exit 125|/run/s6/basedir/bin/halt|magicdns-(egress|ingress)-proxy|magicdns-proxies-reconfigurator" tailscale || true

echo "== current branch git diff summary =="
git diff --stat || true
git diff -- tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/finish tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/finish || true

Repository: hassio-addons/app-tailscale

Length of output: 12595


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== lock behavior probe from s6/locks source if present =="
(
  if command -v find >/dev/null 2>&1; then
    find . -type f \( -name 'lock.c' -o -name '*lock*' \) | grep -E 's6|libposix' | head -20 || true
  fi
) || true

echo "== s6-rc-db source availability probe =="
python3 - <<'PY'
import os, subprocess
candidates = []
for root in [os.getcwd()]:
    for dirpath, dirs, files in os.walk('.'):
        for f in files:
            if f == 's6-rc-db.c' or f == 's6-rc.c':
                candidates.append(os.path.join(dirpath, f))
print("\n".join(candidates[:20]) if candidates else "no local candidate files found")

# Read-only model of documented/exhaustive-listed s6-rc-db list exit codes and
# the "every nonzero list failure maps to supervisor halt" current branch.
nonzero_list_error_codes = {3, 4, 5, 100, 111}
for code in nonzero_list_error_codes:
    current = code != 0
    # s6-halt via exec /run/s6/basedir/bin/halt stops the supervision tree by default.
    supervisor_halts = current
    print(f"s6-rc-db list code {code}: nonzero={current} halt_on_current_branch={supervisor_halts}")
PY

Repository: hassio-addons/app-tailscale

Length of output: 614


Check explicit startup state before using exit 125 in finish handlers.

The if ! s6-rc list &>/dev/null guard applies to all three MagicDNS finish scripts and treats any non-zero s6-rc list result as startup time. s6-rc-db list also returns non-zero for wrong identifier types, invalid/corrupt databases, usage errors, and system-call failures, which can stop S6 supervision instead of leaving the service resolvable for retries. Use an explicit pre-initialization-state check at each site and preserve the original stderr for unexpected failures.

📍 Affects 3 files
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish#L28-L33 (this comment)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-ingress-proxy/finish#L34-L39
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-proxies-reconfigurator/finish#L26-L31
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish` around
lines 28 - 33, Replace the broad s6-rc list failure check in the finish handlers
with an explicit pre-initialization-state check that only uses exit 125 during
startup; for unexpected s6-rc-db/list failures, preserve and emit the original
stderr before halting. Apply this change in
tailscale/rootfs/etc/s6-overlay/s6-rc.d/magicdns-egress-proxy/finish:28-33,
magicdns-ingress-proxy/finish:34-39, and
magicdns-proxies-reconfigurator/finish:26-31.

Source: MCP tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Inconsistencies or issues which will cause a problem for users or implementors. no-stale This issue or PR is exempted from the stable bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Broken app connectors and subnets from disabled IP forwarding

1 participant