Deploy a Tailscale subnet router and controlled exit node
Build a tagged Ubuntu Tailscale router, advertise and approve a private subnet, authorize users with least-privilege grants, test optional internet egress, and rehearse failure, withdrawal, and replacement.
Provide identity-aware remote access to one private IPv4 subnet and optional, user-selected internet egress without opening a public VPN listener or granting the entire tailnet implicit LAN access.
- Ubuntu Server 24.04 LTS
- Tailscale 1.86+, current stable
- Linux kernel networking 6.8+
- Tailnet administration Use a controlled administrator session that can review node tags, policy, route approval, and device lifecycle; prepare a second reviewer for production policy changes.
- Dedicated routed host Provide a patched Ubuntu Server with stable addressing, known LAN and uplink interfaces, synchronized time, working DNS, console recovery, and sufficient capacity for expected encrypted traffic.
hostnamectl && timedatectl status && ip -brief address && ip route - Prefix and overlap review Document {{subnetCidr}}, its authoritative gateway, every competing tailnet route, and representative client LAN, cloud, container, Kubernetes, and VPN prefixes.
ip route get {{testHost}} - Firewall ownership Identify whether nftables, UFW, firewalld, cloud-init, a configuration manager, or another platform owns forwarding and NAT; export the current policy and its supported restore command.
sudo nft list ruleset - Policy identities Prepare {{routerTag}}, a narrow tagOwners group, {{allowedGroup}}, a denied test identity, exact service ports, and separate approval for internet egress.
- Recovery and monitoring Keep console access, a second session, the saved network baseline, a route-withdrawal procedure, and monitoring for daemon, route, forwarding, and host health.
OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.
Full guide
What you will build
- A dedicated Ubuntu Server 24.04 Tailscale node that advertises one reviewed private IPv4 subnet and can optionally provide an internet exit path without exposing an inbound public listener.
- A least-privilege tailnet policy that treats the router as a tagged service identity, limits who may administer it, controls who may reach the routed subnet, and separately controls exit-node use.
- An observable and reversible operating procedure covering route overlap, forwarding, route approval, client selection, high availability, log collection, key expiry, upgrades, and removal.
- A permitted remote client reaches an approved service through the subnet route, while an unpermitted identity fails the same test and receives no broader network access.
- A client that explicitly selects the node as its exit node reaches the internet with the expected public address and can return to direct connectivity without losing tailnet access.
- The router survives a reboot, reports a healthy kernel-mode data path, retains only the intended advertisements, and can be withdrawn without changing the destination LAN.
Architecture
How the parts fit together
The router joins a Tailscale coordination domain as a non-human, tagged node. Tailscale distributes encrypted peer information and route advertisements, while the Linux kernel forwards packets between the Tailscale interface and the private LAN or internet uplink. Advertisement, administrative approval, policy authorization, and client route selection are separate gates: all must agree before traffic flows. This separation prevents a command typed on one host from silently granting organization-wide access. The design keeps the destination LAN unchanged by using Tailscale subnet routing and its default source NAT behavior, then validates identity policy from both an allowed and a denied client.
- Inventory the intended subnet, every client-side route, the router uplink, existing VPNs, forwarding policy, and recovery access before joining a node.
- Install the signed distribution package from Tailscale's official repository and inspect the service without placing an authentication credential in shell history.
- Join interactively, assign the reviewed service tag in the administrative control plane, and confirm that the node identity is not attached to a personal lifecycle.
- Persist only the required kernel forwarding setting and prove that the host firewall still enforces the documented forwarding boundary.
- Advertise the private prefix and optional exit-node capability, then approve those advertisements or let narrowly scoped autoApprovers approve only the tagged router.
- Apply policy that separates router administration, subnet access, and exit-node access. Validate the policy before relying on connectivity tests.
- Test allowed and denied clients, DNS, MTU-sensitive traffic, route selection, exit egress, reboot persistence, and withdrawal.
- Monitor the node, rehearse replacement with a second router, and keep removal steps available before the first production dependency is accepted.
Assumptions
- The router is a dedicated or clearly owned Ubuntu Server 24.04 LTS host with console access, stable LAN addressing, synchronized time, current security updates, and no unsupported kernel or container isolation that prevents creation of the tailscale0 interface.
- The private prefix is a real routed network behind the node, not a host address, default route, multicast range, link-local range, or prefix that overlaps a remote client's local network.
- An administrator can review the tailnet policy and route approval state. The guide does not place reusable auth keys, OAuth credentials, API tokens, or recovery secrets in commands, screenshots, configuration files, or logs.
- The existing firewall owner is known. If nftables, UFW, firewalld, cloud security policy, or another orchestrator owns forwarding, its rules are reviewed rather than replaced by an unrelated example ruleset.
- The default kernel networking mode is available. Userspace networking is useful for unprivileged or proxy-oriented deployments, but it does not provide the same transparent layer-3 subnet-router behavior.
- The LAN may see connections translated to the router address. Preserving original client source addresses requires a separate routing design and is not enabled casually because the LAN must know a return route to Tailscale addresses.
- The examples use one IPv4 subnet. IPv6 advertisement requires an intentional addressing, forwarding, firewall, DNS, and leak-testing design; it must not be inferred from the IPv4 example.
Key concepts
- Subnet router
- A Tailscale node that advertises reachability to a network not running Tailscale itself. Clients learn the approved route and send matching traffic through the encrypted tailnet to that node.
- Exit node
- A node that advertises a route for general internet access. Clients opt in explicitly, and policy must allow access to the internet destination group.
- Advertisement
- A node-side statement that it can forward a prefix or act as an exit node. An advertisement alone does not approve the route, authorize users, or force clients to use it.
- Route approval
- An administrative decision that makes an advertised route eligible for distribution. Approval can be manual or performed by narrowly scoped autoApprovers in policy.
- Grant
- A policy rule expressing which source identities may reach which destination identities, prefixes, or internet targets and on which protocols or ports.
- Tag
- A non-human identity attached to infrastructure. Tag owners control who may assign it, and tagged nodes are governed by policy independently from the user who enrolled them.
- Source NAT
- Address translation that makes routed LAN traffic appear to originate from the subnet router. It avoids adding a return route on the LAN but reduces original client-address visibility at the destination.
- Kernel networking mode
- The normal Linux data path in which tailscaled creates tailscale0 and the kernel routes layer-3 traffic. It supports transparent subnet and exit routing better than the userspace proxy-oriented netstack.
- Route overlap
- A condition where a remote client's local network already owns the same prefix as the advertised network. The operating system may choose the local route, making the remote subnet unreachable or ambiguous.
Before you copy
Values used in this guide
{{lanInterface}}Stable Linux interface carrying the destination LAN. Verify it from addresses and routes instead of assuming an eth0-style name.
Example: ens18{{uplinkInterface}}Stable interface used for ordinary internet egress when the node acts as an exit node. It may be the same physical interface as the LAN only when the routing and firewall design explicitly permits that.
Example: ens19{{subnetCidr}}Reviewed private IPv4 prefix located behind the router. Do not use 0.0.0.0/0 here.
Example: 10.44.0.0/16{{testHost}}Stable, non-sensitive LAN address that answers a safe verification request and represents the advertised prefix.
Example: 10.44.10.20{{testPort}}TCP port on the test host permitted by the intended tailnet policy.
Example: 443{{routerHostname}}Unique operational node name visible in the tailnet inventory and monitoring.
Example: ts-router-waw-01{{routerTag}}Reviewed infrastructure tag configured in tagOwners and assigned through the approved enrollment process.
Example: tag:subnet-router{{allowedGroup}}Existing identity group permitted to use the private route and, if intended, the exit node.
Example: group:network-admins{{routerTailscaleIp}}Stable Tailscale IPv4 address shown by the enrolled router and used only for diagnostics.
Example: 100.86.42.17{{expectedExitIp}}Public address expected when a test client deliberately uses the exit node.
Example: 203.0.113.42Security and production boundaries
- A subnet router expands the tailnet's reach into systems that may not have host-level Tailscale policy. Treat route approval as a security-boundary change, review destination sensitivity, and grant only the protocols and identities required.
- An exit node can observe destination metadata and unencrypted traffic just like another network gateway. Operate it under the same patching, logging, access-control, and privacy requirements as a managed perimeter device.
- Do not paste reusable authentication keys into a shell command, automation log, ticket, guide variable, or process argument. Use the interactive browser flow or a secret manager and short-lived, tagged provisioning method designed for automation.
- Never replace an existing host firewall with an example policy. Identify the owning subsystem, export the current ruleset, keep console access, and integrate the tailscale0 forwarding path into the documented policy.
- Tag ownership is privileged. A principal able to assign a route-bearing tag may create infrastructure with the policy rights of that tag, so tagOwners must be narrower than the population allowed to use the route.
- Default source NAT simplifies return routing but changes audit visibility on the destination LAN. If source identity matters, use application identity, Tailscale on the destination, or a deliberately engineered no-SNAT route with return paths and filtering.
- Exit-node permission and subnet permission are different capabilities. Do not grant autogroup:internet merely because a user needs one internal prefix.
Stop before continuing if
- Stop if the advertised prefix overlaps any client LAN, other approved route, Kubernetes or container network, cloud network, VPN route, or reserved address range and no explicit disambiguation exists.
- Stop if the router has no console path or if the current firewall owner and rollback command are unknown.
- Stop if enabling forwarding would make an existing interface pair forward traffic outside the approved tailscale0-to-LAN or tailscale0-to-uplink boundary.
- Stop if the node is enrolled as a departing employee's personal identity and cannot be converted to a reviewed service tag.
- Stop if policy validation cannot distinguish allowed subnet users, denied users, router administrators, and exit-node users.
- Stop if the allowed client test succeeds but the denied client also reaches the protected service.
- Stop if exit-node selection causes DNS leakage, IPv6 leakage, loss of tailnet control connectivity, or an unexpected public egress address.
- Stop after any reboot that loses advertisements, forwarding, firewall rules, routes, or monitoring. Restore the previous path before retrying.
verification
Inventory routes, interfaces, firewall state, and the destination
Capture a pre-change network baseline and prove that the future router already reaches the intended LAN service without Tailscale.
Why this step matters
Routing changes are safe only when the operator understands every competing prefix and forwarding owner. The inventory creates a baseline that distinguishes an unreachable destination from a Tailscale failure and makes rollback measurable.
What to understand
Record interface names, stable addresses, route metrics, policy rules, nftables ownership, forwarding state, listening services, failed units, current VPN interfaces, and the exact path to the test host.
Collect client-side route tables from representative office, home, mobile, cloud, and VPN environments. A server-side inventory cannot reveal a remote user's overlapping 10.0.0.0/8 or 192.168.1.0/24.
Choose a narrow real destination prefix. Advertising a convenient supernet can capture traffic for networks the router cannot reach and expands the policy boundary unnecessarily.
Store the baseline under change control, excluding tokens and personal data. The later reboot and rollback checkpoints compare against this evidence.
System changes
- Writes only a local text inventory; it does not change routes, forwarding, firewall state, Tailscale enrollment, or remote policy.
Syntax explained
ip -brief address- Shows compact interface state and addresses for LAN/uplink mapping.
ip rule show; ip route show table all- Captures policy routing and every table, not only the main table.
nft list ruleset- Records the active packet-filter and forwarding ownership.
Values stay on this page and are never sent or saved.
sudo sh -c "{ date -u; hostnamectl; ip -brief address; ip rule show; ip route show table all; sysctl net.ipv4.ip_forward; nft list ruleset; systemctl --failed --no-pager; } > /root/tailscale-router-baseline.txt" && sudo cat /root/tailscale-router-baseline.txt && ip route get {{testHost}} && nc -vz -w 3 {{testHost}} {{testPort}}Tue Jul 28 10:15:00 UTC 2026
{{testHost}} via 10.44.0.1 dev {{lanInterface}} src 10.44.0.10 uid 0
Connection to {{testHost}} {{testPort}} port [tcp/https] succeeded!Checkpoint: Prove the destination is locally reachable before adding Tailscale
ip route get {{testHost}} && nc -vz -w 3 {{testHost}} {{testPort}}Continue whenThe route uses {{lanInterface}} and the selected non-sensitive verification service accepts the connection.
Stop whenThe destination is not locally reachable, the prefix is ambiguous, or another VPN already owns the intended route.
If this step fails
The test host is unreachable from the future router.
Likely causeThe LAN route, VLAN, gateway, service, or host firewall is already incorrect before Tailscale is introduced.
ip route get {{testHost}}ping -c 3 {{testHost}}nc -vz -w 3 {{testHost}} {{testPort}}
ResolutionRepair and document ordinary LAN reachability first. Do not use the overlay to conceal an unresolved underlay fault.
Security notes
- Inventory output can contain internal addresses and interface descriptions. Store it as operational evidence, not in a public issue.
Alternatives
- Use the organization's existing network source of truth if it is current, then confirm the live host still matches it.
Stop conditions
- Do not continue without a narrow prefix, a safe test endpoint, console access, and a known firewall owner.
command
Install Tailscale from its official Ubuntu repository
Follow the current official Ubuntu installation path, then record package origin, version, and service health before enrollment.
Why this step matters
Using the official repository provides signed packages and a maintainable update path. Separating installation from enrollment lets the operator inspect the service before introducing an identity or route.
What to understand
Use the official distribution-specific instructions and review the generated repository file and signing-key placement. Do not pipe an unfamiliar script into a privileged shell without first reading the documented installation method.
Installation starts tailscaled but does not need an inbound public firewall opening. The daemon coordinates outbound and attempts direct encrypted paths, using relays when necessary.
Record the installed version and package origin. A reproducible version baseline is necessary when investigating changed routing behavior after upgrades.
System changes
- Adds the official Tailscale APT source and signing material, installs tailscale, creates tailscaled service state, and enables the systemd unit.
Syntax explained
apt-cache policy tailscale- Shows the selected package version and repository origin.
systemctl is-enabled --quiet tailscaled- Proves the daemon is configured to start after reboot.
tailscale version- Records client and daemon build information for support evidence.
curl -fsSL https://tailscale.com/install.sh -o /tmp/tailscale-install.sh && less /tmp/tailscale-install.sh && sudo sh /tmp/tailscale-install.sh && apt-cache policy tailscale && tailscale version && systemctl is-enabled tailscaled && systemctl is-active tailscaledtailscale: Installed: 1.86.2 Candidate: 1.86.2 1.86.2 tailscale commit: 91f9f5b4c enabled active
Checkpoint: Verify package provenance and a healthy unenrolled daemon
apt-cache policy tailscale && tailscale version && systemctl is-enabled tailscaled && systemctl is-active tailscaledContinue whenThe package candidate comes from the official Tailscale repository, a concrete version is printed, and tailscaled is enabled and active.
Stop whenThe package origin is unexpected, signature verification failed, or the service repeatedly crashes.
If this step fails
APT reports a signing or repository error.
Likely causeThe wrong distribution path, an expired or misplaced signing key, a TLS interception problem, or stale package metadata is present.
cat /etc/os-releasegrep -R tailscale /etc/apt/sources.list /etc/apt/sources.list.dapt-cache policy tailscale
ResolutionRemove only the incorrect Tailscale source, repeat the current official Ubuntu instructions, and preserve apt signature validation.
Security notes
- Do not disable TLS or APT signature verification to work around repository errors.
Alternatives
- Use an organization-maintained mirror only when it mirrors current signed packages and its ownership and update delay are documented.
Stop conditions
- Stop if the binary cannot be attributed to the official or approved mirrored repository.
command
Enroll interactively and assign the reviewed service identity
Authenticate through a controlled browser session, verify the target tailnet, and convert the node to the approved infrastructure tag before route advertisement.
Why this step matters
Interactive enrollment avoids placing a reusable credential in process arguments or shell history. The identity is reviewed before any route is advertised, keeping node admission separate from network authorization.
What to understand
Set a unique hostname that communicates location and role without embedding a person's identity. Confirm no retired node already uses the same operational name.
Run the interactive login from a controlled console, open the displayed URL in the intended administrator session, and confirm the destination tailnet before approval.
Assign the infrastructure tag through the reviewed control-plane process. A tagged node stops inheriting a person's identity and receives only the rights attached to the service tag.
Review node key expiry policy. Disabling expiry increases operational continuity but also makes revocation and host protection more important; record the explicit decision.
System changes
- Changes the host's Tailscale state from unenrolled to an authenticated node and records its coordination identity locally and in the tailnet.
Syntax explained
--hostname={{routerHostname}}- Assigns a unique operational display name to the node.
tailscale up- Starts an interactive authentication flow without embedding a reusable auth key.
tailscale ip -4- Prints the node's assigned Tailscale IPv4 address after enrollment.
Values stay on this page and are never sent or saved.
sudo hostnamectl hostname {{routerHostname}} && sudo tailscale up --hostname={{routerHostname}} && tailscale status && tailscale ip -4To authenticate, visit:
https://login.tailscale.com/a/0123456789abcdef
Success.
100.86.42.17 {{routerHostname}} {{routerTag}} linux -Checkpoint: Confirm the correct tailnet and service identity
tailscale status && tailscale ip -4 && tailscale debug prefsContinue whenThe node is online under {{routerHostname}}, has one Tailscale IPv4 address, and shows no subnet or exit advertisement yet.
Stop whenThe node joined the wrong organization, inherited an inappropriate personal identity, or already advertises an unreviewed route.
If this step fails
The browser approval succeeds but the CLI remains unauthenticated.
Likely causeThe approval was completed for an expired login URL, another tailnet, or a different pending node.
tailscale statusjournalctl -u tailscaled -b --no-pager | tail -n 100hostnamectl status
ResolutionCancel the stale attempt, run a new interactive login, verify the displayed node and tailnet before approval, and revoke any accidental duplicate.
Security notes
- Never copy the login URL into a public ticket or share it with an untrusted person; it is part of an active authentication ceremony.
Alternatives
- For automated replacement, use a short-lived, reusable-disabled, preauthorized key or OAuth-based provisioning flow kept in a secret manager and restricted to the reviewed tag.
Stop conditions
- Do not advertise routes until the node identity, tag ownership, expiry policy, and administrative owner are correct.
decision
Reject overlapping or overbroad route advertisements
Compare the exact private prefix with the router and every representative client route table before making it eligible for tailnet distribution.
Why this step matters
A route that overlaps a client LAN can fail selectively and is often misdiagnosed as an overlay outage. Testing representative client routes before approval avoids publishing a prefix that cannot be used reliably.
What to understand
Compare the proposed prefix with route tables from every important client class and with other tailnet advertisements, cloud VPCs, container pools, Kubernetes service and pod ranges, site VPNs, and disaster-recovery networks.
Use longest-prefix reasoning: a narrower local route may win over a broad advertised route, while an overly broad Tailscale route may capture unrelated traffic.
Document known overlaps as design blockers, not support footnotes. Renumbering a managed subnet is usually more reliable than relying on platform-specific route precedence.
System changes
- Creates review evidence only; no route is advertised or approved.
Syntax explained
ip route get {{testHost}}- Shows the effective interface, next hop, and source chosen for the representative destination.
ip route show table all- Exposes routes outside the main table that could override ordinary lookup.
{{subnetCidr}}- Represents the exact advertised prefix whose boundaries must match reachable LAN addresses.
Values stay on this page and are never sent or saved.
ip route get {{testHost}} && ip route show table all | sed -n '1,160p'{{testHost}} via 10.44.0.1 dev {{lanInterface}} src 10.44.0.10 uid 1000
10.44.0.0/16 via 10.44.0.1 dev {{lanInterface}} proto static metric 100Checkpoint: Approve a non-overlapping routing plan
ip route get {{testHost}} && ip route show table all | grep -F '{{subnetCidr}}' || trueContinue whenThe router reaches the test host through {{lanInterface}}, and the reviewed client inventories contain no conflicting local prefix.
Stop whenAny critical client or existing network owns an equal or more-specific conflicting prefix.
If this step fails
Only clients at one location fail to use the future route.
Likely causeThat location uses the same RFC1918 prefix locally.
ip route get {{testHost}}ip routetailscale status
ResolutionRecord the overlapping prefix and renumber, narrow, or install Tailscale directly on the destination. Do not declare the router healthy for that client class.
Security notes
- Broad route advertisements can redirect sensitive traffic unexpectedly. Advertise only prefixes the router owns and policy intends.
Alternatives
- Publish a narrower service subnet if it accurately represents the LAN architecture and removes the overlap.
Stop conditions
- No route should be advertised while critical overlaps remain unresolved.
config
Enable IPv4 forwarding under the existing firewall owner
Persist the kernel forwarding setting in one owned file, reload it, and integrate only the intended tailscale0 path into the reviewed firewall policy.
Why this step matters
Linux drops transit packets unless forwarding is enabled, but global forwarding also changes the host's role from endpoint to router. The change must be paired with a reviewed interface boundary and recoverable firewall state.
What to understand
Export the current sysctl and nftables state before changing anything. A second console session proves that a policy error has not removed administrative access.
Persist IPv4 forwarding in a dedicated file with ownership documented. Avoid duplicate definitions spread across vendor, cloud-init, network manager, and local files.
Do not paste a replacement nftables ruleset. Integrate the tailscale0 path through the system that already owns filtering and preserve unrelated forwarding and NAT behavior.
For an exit node, validate the uplink path separately from the private LAN path. Enabling forwarding alone does not authorize or safely NAT arbitrary interface pairs.
System changes
- Persists net.ipv4.ip_forward=1 and changes the running kernel to forward IPv4 packets; firewall integration may authorize selected tailscale0 transit traffic.
Syntax explained
sysctl -w net.ipv4.ip_forward=1- Enables IPv4 forwarding immediately for verification.
/etc/sysctl.d/99-tailscale-router.conf- Stores one owned persistent setting loaded during boot.
sysctl --system- Reloads sysctl configuration and exposes conflicting definitions.
/etc/sysctl.d/99-tailscale-router.confnet.ipv4.ip_forward = 1printf '%s
' 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale-router.conf && sudo sysctl --system && sysctl net.ipv4.ip_forward && sudo nft list ruleset* Applying /etc/sysctl.d/99-tailscale-router.conf ...
net.ipv4.ip_forward = 1
net.ipv4.ip_forward = 1
table inet filter { ... }Checkpoint: Prove forwarding and the intended firewall boundary
sysctl net.ipv4.ip_forward && sudo nft list ruleset && ip route get {{testHost}}Continue whenIPv4 forwarding is 1, the ruleset explicitly accounts for the intended tailscale0 path without replacing unrelated policy, and the LAN route is unchanged.
Stop whenA broad accept rule appears, console access is lost, or any unapproved interface pair can now forward.
If this step fails
Forwarding returns to zero after reboot or network reload.
Likely causeA later sysctl file, cloud-init, or network manager overrides the setting.
systemd-sysctl --cat-config | grep -n ip_forwardsysctl net.ipv4.ip_forwardjournalctl -u systemd-sysctl -b --no-pager
ResolutionRemove conflicting local definitions, configure the actual owner, reload once, and verify after a controlled reboot.
Security notes
- Forwarding is a host-wide capability. Firewall policy, cloud controls, and monitoring must prevent the node from becoming an unintended bridge.
Alternatives
- Install Tailscale on the destination and avoid host-wide forwarding when only a few services require access.
Stop conditions
- Restore the saved sysctl and firewall baseline immediately if the change enables traffic outside the approved interface and destination boundary.
command
Advertise the reviewed subnet and optional exit capability
Publish only the exact private prefix and explicit exit-node capability, then inspect local preferences before any control-plane approval.
Why this step matters
The node should advertise exactly the reviewed capabilities and nothing else. Using tailscale set after enrollment avoids re-specifying unrelated preferences and makes the route change easy to inspect and withdraw.
What to understand
Advertise the private prefix and exit capability only after the host can reach the destination and forwarding is safe. The command does not by itself approve or authorize either capability.
Inspect local preferences immediately after the command. A typographical prefix can be syntactically valid yet operationally dangerous.
Keep subnet and exit validation separate even when one command advertises both. They have different users, destinations, privacy implications, and rollback triggers.
System changes
- Updates persistent tailscaled preferences to advertise {{subnetCidr}} and the exit-node capability to the control plane.
Syntax explained
--advertise-routes={{subnetCidr}}- Declares that this node can route the exact reviewed private prefix.
--advertise-exit-node- Declares optional general internet egress capability; clients still opt in.
tailscale set- Changes selected preferences without resetting unrelated tailscale up options.
Values stay on this page and are never sent or saved.
sudo tailscale set --advertise-routes={{subnetCidr}} --advertise-exit-node && tailscale debug prefs && tailscale status"AdvertiseRoutes": [
"10.44.0.0/16",
"0.0.0.0/0",
"::/0"
]
100.86.42.17 {{routerHostname}} {{routerTag}} linux activeCheckpoint: Match local advertisements to the change record
tailscale debug prefs && tailscale status && journalctl -u tailscaled -b --no-pager | tail -n 60Continue whenLocal preferences show only {{subnetCidr}} plus exit-node advertisement, the node remains online, and no forwarding error is logged.
Stop whenAny additional prefix appears, the prefix is mistyped, or tailscaled reports forwarding unavailable.
If this step fails
The command reports an IP forwarding warning.
Likely causeThe persistent sysctl was not loaded, a namespace isolates tailscaled, or IPv6 advertisement requires additional forwarding configuration.
sysctl net.ipv4.ip_forwardsystemctl status tailscaled --no-pagertailscale debug prefs
ResolutionWithdraw advertisements, restore the intended kernel-mode host configuration, and repeat forwarding verification before trying again.
Security notes
- Do not advertise 0.0.0.0/0 as a subnet route; use the explicit exit-node capability with separate policy and client consent.
Alternatives
- Advertise only the subnet initially and add exit-node capability in a second reviewed change after private routing is stable.
Stop conditions
- Withdraw the route if its exact boundaries cannot be reconciled with the inventory.
config
Apply least-privilege tag, route, subnet, and exit policy
Use the tailnet policy editor to restrict tag assignment, exact route approval, private service access, and internet egress as separate capabilities.
Why this step matters
Routing availability and authorization are intentionally independent. A least-privilege policy prevents route approval from granting every tailnet member access to an entire private network or internet egress.
What to understand
Define tagOwners before relying on the service tag. Only a narrow infrastructure-administrator group should be able to assign the router identity.
Use grants to express permitted sources, private destinations, protocols, and ports. Add explicit policy tests for one allowed and one denied identity whenever the policy format supports them.
Configure autoApprovers only for the exact prefix and reviewed router tag. A broad group-based approver can let unrelated nodes publish sensitive routes.
Authorize autogroup:internet only for identities allowed to use exit nodes. This is separate from access to {{subnetCidr}}.
System changes
- Changes tailnet-wide authorization and optional automatic route approval; an error can broaden or interrupt access for multiple nodes.
Syntax explained
tagOwners- Controls which principals may assign {{routerTag}} to infrastructure nodes.
grants- Defines allowed source, destination, and IP protocol/port combinations.
autoApprovers.routes- Allows only matching identities to approve the exact private prefix automatically.
autoApprovers.exitNode- Allows matching identities to approve exit-node advertisements.
Tailnet policy fileValues stay on this page and are never sent or saved.
{
"tagOwners": {
"{{routerTag}}": ["{{allowedGroup}}"]
},
"autoApprovers": {
"routes": {
"{{subnetCidr}}": ["{{routerTag}}"]
},
"exitNode": ["{{routerTag}}"]
},
"grants": [
{
"src": ["{{allowedGroup}}"],
"dst": ["{{subnetCidr}}"],
"ip": ["tcp:{{testPort}}"]
},
{
"src": ["{{allowedGroup}}"],
"dst": ["autogroup:internet"],
"ip": ["*"]
}
]
}Policy validation succeeded
Tests: 4 passed, 0 failed
Auto-approver {{routerTag}} matched {{subnetCidr}} and exit nodeCheckpoint: Validate policy with positive and negative identities
Continue whenThe policy editor accepts the document, the router tag owns only intended capabilities, an allowed identity matches, and a denied identity does not.
Stop whenA wildcard or unrelated group can assign the tag, use the subnet, publish the route, or use internet egress.
If this step fails
Policy validation passes but the wrong user can reach the subnet.
Likely causeGroup membership, another grant, a legacy ACL, or a broader prefix rule also matches.
Review all grants and legacy ACLs in the policy editorConfirm the test user's current groupsTest the exact destination and port from a denied client
ResolutionWithdraw the route when exposure is material, remove or narrow the competing rule, add a regression test, and repeat denied-client validation.
Security notes
- Policy source is security-sensitive configuration. Require peer review and avoid copying organization identity data into public examples.
Alternatives
- Use manual route approval during the pilot, then add narrowly scoped autoApprovers after tag ownership and replacement behavior are proven.
Stop conditions
- Do not approve production advertisements until policy tests establish least privilege.
verification
Verify route and exit-node approval in the control plane
Confirm that manual approval or autoApprovers matched the correct tagged node, exact private prefix, and exit capability before client testing.
Why this step matters
Approval turns an advertisement into a distributable route. Treating it as a separate checkpoint ensures the control-plane object matches the node, prefix, tag, change record, and authorization policy.
What to understand
Open the route approval view directly from the trusted administrative console, not from a link received in chat. Confirm node identity, owner or tag, last-seen state, exact prefix, and exit capability.
If autoApprovers are configured, verify why they matched. Automatic approval is a policy decision, not evidence that the host-side route is correct.
Approve subnet and exit capabilities only when their respective tests and owners are ready. A staged rollout may approve the subnet first.
System changes
- Makes approved routes eligible for distribution to permitted clients and may make the node selectable as an exit node.
Syntax explained
Subnet route approval- Enables distribution of {{subnetCidr}} from this node.
Exit-node approval- Makes this node eligible for explicit general egress selection.
autoApprovers- Policy mechanism that can perform approval when the advertising identity and prefix match.
tailscale debug prefs && tailscale status && journalctl -u tailscaled -b --no-pager | tail -n 60"AdvertiseRoutes": ["10.44.0.0/16", "0.0.0.0/0", "::/0"]
100.86.42.17 {{routerHostname}} {{routerTag}} linux active
router: configuring userspace WireGuard config (with 6/42 peers)Checkpoint: Confirm approved state without yet accepting production
tailscale status && tailscale debug prefsContinue whenThe router remains healthy, advertises only the reviewed capabilities, and the administrative console shows those exact capabilities approved.
Stop whenApproval applies to another node, route, tag, or capability.
If this step fails
The route remains pending after policy deployment.
Likely causeThe prefix key, router tag, tag owner, or autoApprover identity does not match the advertisement.
tailscale debug prefstailscale statusReview autoApprovers and current node tags
ResolutionCorrect the identity or exact autoApprover mapping; do not broaden approval to a wildcard merely to clear the pending state.
Security notes
- Approval is a privileged network change. Record approver, timestamp, prefix, node identity, and policy revision.
Alternatives
- Keep manual approval for rare or high-sensitivity routes even when lower-risk prefixes use autoApprovers.
Stop conditions
- Remove approval immediately if a denied identity gains reachability.
verification
Test allowed and denied subnet clients
Prove effective route selection and application reachability from an allowed client, then prove the identical request fails for a denied identity.
Why this step matters
A successful ping is insufficient evidence. Acceptance must prove route selection, authorized application traffic, denial, name resolution where intended, and an MTU-sensitive transfer without creating a new inbound exposure.
What to understand
Use a representative allowed client and record its local routes before enabling route acceptance. Linux clients may require the documented accept-routes setting.
Test the exact application protocol and port, not only ICMP. Compare destination logs or application identity where available.
Repeat the same connection from a deliberately denied identity and require failure. A denied test is the evidence that policy—not only routing—is working.
Transfer a response large enough to expose MTU problems and compare DNS answers through the intended resolver path.
System changes
- May enable acceptance of tailnet routes on the test client; it does not alter the destination LAN.
Syntax explained
--accept-routes- Allows a Linux client to install approved subnet routes from the tailnet.
ip route get {{testHost}}- Proves the test destination follows the Tailscale route instead of a local overlap.
nc -vz -w 5- Performs a bounded TCP reachability test against the intended service port.
Values stay on this page and are never sent or saved.
sudo tailscale set --accept-routes=true && ip route get {{testHost}} && nc -vz -w 5 {{testHost}} {{testPort}} && tailscale ping {{routerHostname}}{{testHost}} dev tailscale0 table 52 src 100.101.22.8 uid 1000
Connection to {{testHost}} {{testPort}} port [tcp/https] succeeded!
pong from {{routerHostname}} (100.86.42.17) via 198.51.100.42:41641 in 24msCheckpoint: Accept private routing only after allowed and denied tests
ip route get {{testHost}} && nc -vz -w 5 {{testHost}} {{testPort}} && tailscale ping {{routerHostname}}Continue whenThe allowed client routes through Tailscale, reaches {{testHost}}:{{testPort}}, and identifies the router path; the denied client fails the same application request.
Stop whenTraffic uses an overlapping local route, the denied client succeeds, or large transfers stall.
If this step fails
The allowed client has no route despite approval.
Likely causeThe client platform does not accept routes by default, policy denies it, or a local route takes precedence.
tailscale statustailscale debug prefsip route get {{testHost}}
ResolutionEnable route acceptance only on the intended client, correct policy if required, and resolve overlap rather than deleting unrelated local routes.
Security notes
- Use a non-sensitive test service and do not weaken its authentication just to demonstrate network reachability.
Alternatives
- Install Tailscale directly on the test destination to compare node-to-node policy with subnet-routed behavior.
Stop conditions
- Any successful denied test blocks rollout and requires immediate policy correction.
verification
Select and verify the exit node from one test client
Measure the client's original path, select the router explicitly, verify egress and DNS behavior, then deselect it and prove the baseline returns.
Why this step matters
Exit-node use changes a client's default internet path and may change DNS, privacy, geolocation, latency, and local-LAN reachability. The client must opt in and verify all of those effects explicitly.
What to understand
Record the client's public IPv4, IPv6, DNS resolvers, routes, and access to local services before selecting the node. This baseline prevents a successful HTTP request from hiding an IPv6 or DNS leak.
Select the exit node by reviewed name or stable Tailscale address, then confirm the expected public address and a functioning HTTPS request.
Test tailnet destinations, the private routed subnet, DNS, IPv4, any intended IPv6 behavior, and local-LAN access according to policy.
Deselect the exit node and verify the original public path returns. This is both rollback rehearsal and proof that the client is not stuck behind an unavailable gateway.
System changes
- Temporarily changes the test client's default egress path to {{routerHostname}} and may intentionally suppress access to the client's local LAN.
Syntax explained
--exit-node={{routerHostname}}- Selects the reviewed node for this client's general internet traffic.
--exit-node-allow-lan-access- Optionally preserves access to the client's local LAN; enable only when the threat model permits it.
--exit-node=- Clears exit-node selection and returns the client to direct egress.
Values stay on this page and are never sent or saved.
sudo tailscale set --exit-node={{routerHostname}} && curl -4 --fail --max-time 10 https://check.tailscale.com/api/ip && tailscale status && sudo tailscale set --exit-node={"TailscaleIPs":["100.101.22.8"],"IP":"203.0.113.42","IsTailscaleIP":false}
100.86.42.17 {{routerHostname}} {{routerTag}} linux active; exit nodeCheckpoint: Prove egress identity, DNS behavior, and reversible selection
curl -4 --fail --max-time 10 https://check.tailscale.com/api/ip && tailscale status && ip routeContinue whenThe selected test shows {{expectedExitIp}}, intended DNS and tailnet access work, and clearing selection restores the baseline public path.
Stop whenThe address is unexpected, IPv6 or DNS bypasses the intended boundary, or deselection does not restore direct connectivity.
If this step fails
Internet works through the exit node but DNS answers come from an unexpected resolver.
Likely causeClient DNS policy, MagicDNS, split DNS, DHCP, or a local resolver retains precedence outside the intended egress design.
resolvectl statustailscale statusdig example.comip route
ResolutionDecide the authoritative DNS design, correct tailnet or client resolver policy, and repeat leak tests before offering the exit node to users.
Security notes
- The exit node is an egress trust point, not an anonymity guarantee. Retain access logging only according to organizational policy and applicable law.
Alternatives
- Use an established managed egress gateway when inspection, compliance logging, or fixed-provider controls are required.
Stop conditions
- Do not release exit-node use when DNS, IPv6, privacy, and deselection behavior are unverified.
verification
Reboot and repeat the complete acceptance matrix
Perform a controlled restart, verify persistent forwarding and advertisements, and repeat allowed, denied, subnet, exit, DNS, and withdrawal tests.
Why this step matters
A router that works only until reboot is not production-ready. The reboot checkpoint validates systemd ordering, persistent sysctl, firewall ownership, advertisements, policy distribution, and client recovery.
What to understand
Schedule a controlled reboot while an alternate administrative path remains available. Observe the node disappearing and returning rather than assuming a successful SSH reconnection proves forwarding.
Compare service, sysctl, route, firewall, advertisement, allowed-client, denied-client, and exit tests with the saved baseline.
Review the entire boot journal for tailscaled, sysctl, network, nftables, and time errors. A transient route that repairs itself minutes later may still violate availability requirements.
Record recovery time and whether peer paths are direct or relayed. Establish an alert threshold based on the service objective.
System changes
- Reboots the router, interrupting routed traffic for the duration; no configuration is intended to change.
Syntax explained
systemctl reboot- Performs the controlled availability test after a console path and rollback are ready.
journalctl -b -u tailscaled- Shows daemon behavior from the new boot only.
tailscale netcheck- Summarizes current NAT, UDP, IPv6, and nearest relay conditions.
sudo systemctl rebootBroadcast message from root@{{routerHostname}}:
The system will reboot now!
# after reconnect
active
net.ipv4.ip_forward = 1
100.86.42.17 {{routerHostname}} {{routerTag}} linux activeCheckpoint: Accept persistent routing after a cold state transition
systemctl is-active tailscaled && sysctl net.ipv4.ip_forward && tailscale status && tailscale netcheck && sudo nft list rulesetContinue whentailscaled is active, forwarding is 1, exact advertisements remain approved, firewall policy is restored, and allowed/denied client tests behave identically.
Stop whenAny configuration is missing, a route takes excessive time to recover, or denied access changes after reboot.
If this step fails
The node returns online but routed clients fail after reboot.
Likely causePersistent forwarding or firewall policy did not load, or network readiness delayed the LAN route.
journalctl -b -u tailscaled --no-pagerjournalctl -b -u systemd-sysctl --no-pagersysctl net.ipv4.ip_forwardsudo nft list ruleset
ResolutionWithdraw the route or fail over, correct the owning persistent configuration and ordering, then repeat the complete reboot test.
Security notes
- Do not bypass a failed firewall restore by inserting an unconditional forwarding accept rule.
Alternatives
- Stage a second healthy router before reboot testing when the service cannot tolerate the single-node interruption.
Stop conditions
- A failed reboot checkpoint blocks production acceptance even if a manual command restores service.
instruction
Monitor, rehearse withdrawal, and stage safe replacement
Record normal health, prove that advertisements can be removed without touching the LAN, and define a second-router and credential-review lifecycle.
Why this step matters
Operational readiness includes withdrawal, replacement, monitoring, and access review. Rehearsing those actions before production prevents an unhealthy or compromised router from becoming irremovable.
What to understand
Monitor node presence, tailscaled state, advertised route set, approval state, peer path type, forwarding counters, interface errors, underlay reachability, system resources, and security updates.
Stage a second tagged router without changing the prefix, approve it through the same policy, and test that traffic survives withdrawal of one advertisement.
Review route users, exit users, tag owners, node expiry, automation credentials, and policy revisions on a defined schedule.
Document removal order: stop client use where appropriate, clear advertisements, confirm routes disappear, remove approvals and grants, revoke the node, restore host forwarding/firewall baseline, then uninstall.
System changes
- Exercises route withdrawal and may stage a redundant router; permanent removal clears advertisements and returns the host to its pre-router network role.
Syntax explained
--advertise-routes=- Clears subnet route advertisements from the node.
--advertise-exit-node=false- Withdraws exit-node capability while leaving the node joined.
tailscale logout- Revokes the local node session; use only after routes and dependencies are withdrawn.
tailscale status && tailscale netcheck && tailscale debug prefs && systemctl is-active tailscaled && ip -s link show tailscale0Report:
* UDP: true
* IPv4: yes, 203.0.113.42:41641
* Nearest DERP: Warsaw
active
5: tailscale0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280 state UNKNOWNCheckpoint: Prove safe withdrawal and documented recovery
tailscale debug prefs && tailscale status && sysctl net.ipv4.ip_forward && sudo nft list rulesetContinue whenThe current route set matches the operating record, monitoring is healthy, and a rehearsed withdrawal removes client routes without changing the destination LAN.
Stop whenThe organization cannot identify dependencies, route users, a replacement owner, or a rollback path.
If this step fails
Clients continue to show a route after this node withdraws it.
Likely causeAnother approved router advertises the prefix, client state is stale, or a non-Tailscale route exists.
tailscale statusip route get {{testHost}}Review all nodes advertising {{subnetCidr}}
ResolutionIdentify the actual route owner, preserve intended redundancy, remove only unapproved advertisements, and confirm client state after control-plane convergence.
Security notes
- Node removal is not complete until policy, approvals, credentials, local state, monitoring, and inventory are reconciled.
Alternatives
- Keep a warm second router and withdraw nodes one at a time for upgrades to reduce availability risk.
Stop conditions
- Do not decommission the last healthy router while a production dependency remains or rollback has not been tested.
Finish line
Verification checklist
systemctl is-active tailscaled && tailscale status && tailscale ip -4tailscaled is active and {{routerHostname}} is online under {{routerTag}} with {{routerTailscaleIp}}.sysctl net.ipv4.ip_forward && ip route get {{testHost}} && nc -vz -w 3 {{testHost}} {{testPort}}IPv4 forwarding is enabled and the router reaches the approved test service through {{lanInterface}}.tailscale debug prefsShows {{subnetCidr}} and exit-node defaults only, with no unintended private prefix.ip route get {{testHost}} && nc -vz -w 5 {{testHost}} {{testPort}}The allowed client selects tailscale0 and reaches the intended TCP port.nc -vz -w 5 {{testHost}} {{testPort}}The deliberately denied identity cannot establish the same application connection.curl -4 --fail --max-time 10 https://check.tailscale.com/api/ipWhile explicitly selected, the client observes {{expectedExitIp}}; after deselection it returns to its recorded baseline.systemctl is-active tailscaled && sysctl net.ipv4.ip_forward && tailscale status && sudo nft list rulesetService, forwarding, intended firewall policy, approval, and client behavior survive a controlled reboot.Recovery guidance
Common problems and safe checks
The router appears offline immediately after installation.
Likely causetailscaled is not running, system time or DNS is broken, outbound control traffic is blocked, or the host was enrolled into a different tailnet.
systemctl status tailscaled --no-pagerjournalctl -u tailscaled -b --no-pager | tail -n 100timedatectl statustailscale status
ResolutionRestore time, DNS, and required outbound connectivity without weakening inbound policy; restart only tailscaled, repeat interactive enrollment if the tailnet is wrong, and verify the node identity before advertising routes.
The node is online but the advertised subnet is not visible to clients.
Likely causeThe command did not retain the advertisement, route approval is pending, autoApprovers do not match the tagged identity, or a client does not accept routes.
tailscale debug prefstailscale statusip route get {{testHost}}journalctl -u tailscaled -b --no-pager | tail -n 100
ResolutionConfirm the exact prefix in local preferences, inspect its control-plane approval, correct the tag-to-autoApprover mapping or approve manually, then enable route acceptance only on the intended client platform.
The client route exists but the LAN host is unreachable.
Likely causeIPv4 forwarding is disabled, the forwarding firewall drops traffic, the LAN route is wrong, the host is down, or the target port is not listening.
sysctl net.ipv4.ip_forwardip route get {{testHost}}sudo nft list rulesetnc -vz -w 3 {{testHost}} {{testPort}}
ResolutionTest from the router first. Restore the correct LAN route or service, then add only the reviewed tailscale0 forwarding allowance to the owning firewall policy and prove it with counters.
A client on a hotel or home network cannot reach the routed prefix, while other clients can.
Likely causeThe client's local LAN overlaps the advertised prefix and its local route wins or creates ambiguous routing.
ip routeip route get {{testHost}}tailscale statustailscale netcheck
ResolutionDo not force a broad route blindly. Renumber the managed subnet, advertise a narrower non-overlapping prefix when truthful, or use Tailscale directly on the destination. Record the conflicting client prefix.
Small requests work but large TLS transfers stall or reset.
Likely causePath MTU discovery is blocked, an underlay encapsulation reduces usable MTU, or a firewall drops required ICMP feedback.
tailscale netcheckping -M do -s 1200 {{testHost}}tracepath {{testHost}}journalctl -u tailscaled -b --no-pager | tail -n 100
ResolutionRestore ICMP feedback where policy permits, identify the actual underlay MTU, and fix the network path rather than applying an unexplained global MSS or interface MTU reduction.
The client selects the exit node but still shows its original public address.
Likely causeExit-node advertisement or approval is absent, policy does not allow internet destinations, the client did not select the node, or forwarding/uplink NAT is blocked.
tailscale statustailscale debug prefsip routecurl -4 --max-time 10 https://check.tailscale.com/api/ip
ResolutionVerify advertisement, approval, autogroup:internet policy, and explicit client selection independently; then inspect router forwarding and the existing uplink firewall without opening inbound services.
Exit-node clients lose access to their local printer or local management network.
Likely causeThe client's exit-node mode intentionally routes general traffic away from its local LAN and local-network access was not enabled.
tailscale statustailscale debug prefsip route
ResolutionDecide whether local-LAN access is acceptable for the threat model. If it is, enable the client's documented allow-LAN-access option; otherwise deselect the exit node while using local devices.
A user who should be denied can reach the subnet.
Likely causeA broad grant, group nesting, tag rule, legacy ACL, shared account, or unintended route matches the flow.
tailscale statusip route get {{testHost}}sudo nft list ruleset
ResolutionWithdraw the advertisement if exposure is material, inspect policy tests and identity membership, narrow the matching grant, validate a denied test identity, and only then restore the route.
The router works until reboot and then stops forwarding.
Likely causeForwarding was changed only at runtime, tailscaled is disabled, firewall state is not persistent, or another boot-time manager overwrites sysctl or nftables state.
systemctl is-enabled tailscaledsysctl net.ipv4.ip_forwardsystemd-sysctl --cat-config | grep -n ip_forwardsudo nft list ruleset
ResolutionPersist the setting in the owning configuration, remove conflicting duplicate definitions, validate the firewall's supported persistence mechanism, and repeat a controlled reboot before acceptance.
The router remains online but traffic is relayed and performance is unexpectedly poor.
Likely causePeer-to-peer UDP connectivity is restricted, NAT mapping is difficult, a firewall blocks direct paths, or the underlay is lossy.
tailscale ping {{routerHostname}}tailscale netchecktailscale statusip -s link show
ResolutionUse netcheck and ping evidence to correct outbound UDP or underlay problems. A relay is functional and safer than opening arbitrary inbound ports; optimize only through documented network changes.
Route approval disappears when replacing or re-enrolling the router.
Likely causeThe replacement has a different node identity or lacks the expected tag, and manual approval or autoApprovers do not cover it.
tailscale statustailscale debug prefshostnamectl status
ResolutionEnroll the replacement with the reviewed service identity, verify tag ownership, stage it without removing the healthy router, approve only matching prefixes, and test failover before decommissioning the old node.
LAN services see every remote connection as originating from the router.
Likely causeSubnet routing uses source NAT by default so destinations can return traffic without a route to Tailscale addresses.
sudo nft list rulesetss -tnip route
ResolutionKeep the safe default unless original source addresses are a documented requirement. For source preservation, design return routes and anti-spoofing controls first, or install Tailscale on the destination.
Reference
Frequently asked questions
Does advertising a route immediately expose the subnet?
No. The node advertises capability, an administrator or autoApprover approves the route, policy authorizes the source-to-destination flow, and the client must accept or select the route. Treat each gate as necessary and test both an allowed and denied identity.
Why use a tag instead of leaving the router owned by the enrolling user?
A router is infrastructure with a lifecycle longer than a person or browser session. A restricted service tag makes policy intent explicit, supports controlled automation, and avoids losing or changing access when a user leaves.
Should I disable source NAT to preserve client addresses?
Not by default. Source NAT makes return traffic work without modifying the LAN. Disabling it requires routes back to Tailscale client addresses, filtering against spoofing, and validation across every return path. Direct Tailscale installation often provides cleaner identity.
Can the same node be both subnet router and exit node?
Yes, but it combines two blast radii. Review LAN forwarding and internet egress independently, use separate policy grants, monitor capacity, and consider separate nodes when ownership, privacy, availability, or compliance requirements differ.
Why not open a public VPN port?
Tailscale coordinates encrypted peer connections and can relay when direct connectivity is unavailable, so this design does not require a new inbound public listener. Do not add port forwards unless official diagnostics identify a justified network optimization.
Will clients automatically use an exit node?
No. Exit-node use is an explicit client decision and is also subject to policy. This avoids silently changing every user's internet path when a node starts advertising the capability.
Recovery
Rollback
Withdraw subnet and exit advertisements first, confirm clients no longer receive the route, then restore the saved forwarding and firewall baseline before revoking or uninstalling the node.
- From console or a non-dependent administrative path, run `sudo tailscale set --advertise-routes= --advertise-exit-node=false` and confirm local preferences no longer advertise the prefix or exit routes.
- In the administrative console, confirm the route and exit capability are no longer active; remove stale approval and narrowly scoped policy entries only after no other healthy router depends on them.
- From representative clients, confirm `ip route get {{testHost}}` no longer selects tailscale0 and deselect {{routerHostname}} as exit node where necessary.
- Restore `/etc/sysctl.d/99-tailscale-router.conf` and the owned firewall configuration from the pre-change baseline, reload them, and prove unapproved interface forwarding is disabled.
- Revoke or log out the node after advertisements are gone. Remove the package only if the host has no remaining Tailscale purpose and preserve sanitized logs for the change record.
- Verify ordinary LAN routing, console/SSH administration, existing VPNs, DNS, and monitoring match the saved baseline. Re-enable the prior service path if this router replaced one.
Evidence