What are you trying to do?
Find out which nodes in a tailnet advertise subnet routes, or act as exit nodes, without leaving the CLI.
I run a tailnet of roughly 50 nodes where a couple dozen are subnet routers fronting branch-office and lab networks, plus a few exit nodes. "Which node advertises the route to X?" and "what does this node actually advertise?" come up constantly, during audits and while debugging routing.
tailscale status is the obvious place to look, but it has no notion of routes: the table shows IP, hostname, owner, OS, and connection status only. The information is present in tailscale status --json as each peer's AllowedIPs, just not surfaced anywhere in the human-readable output.
How should we solve this?
A --routes flag on tailscale status that reuses the existing table, replacing the Status column with a Routes column, and lists only nodes advertising at least one route:
$ tailscale status --routes --header
IP Hostname Owner OS Routes
-- -------- ----- -- ------
100.64.0.10 branch-router-1 tagged-devices freebsd 192.0.2.0/24
100.64.0.11 branch-router-2 tagged-devices linux 198.51.100.0/24 203.0.113.0/24
100.64.0.12 exit-node-1 tagged-devices linux 0.0.0.0/0 ::/0
100.64.0.13 app-host-proxy tagged-devices linux 100.64.0.20/32
100.64.0.14 lab-router tagged-devices linux 192.0.2.128/25
A node's advertised routes are its AllowedIPs minus the single-address prefixes covering its own Tailscale IPs.
I have a working patch and will send it as a PR if the approach sounds reasonable. Open questions I'd want a maintainer's opinion on:
- Is
status --routes the right home for this, or would you rather see it under an existing subcommand (something nearer tailscale exit-node list or a tailscale route-style command)?
- Nodes advertising many prefixes overflow one terminal line; one node on my tailnet advertises 14. My patch space-joins them on a single row. One route per line, or truncation with a count, are both easy alternatives.
- Should the flag also filter, as mine does, or list every node and leave the Routes column blank for those advertising nothing?
What is the impact of not solving this?
Not blocking, there's a workaround, but it's a poor one for something this routine:
tailscale status --json | jq -r '.Peer[] |
select(.AllowedIPs | length > 2) | "\(.HostName): \(.AllowedIPs)"'
It needs jq installed, it needs the reader to know that "more than two AllowedIPs" is standing in for "advertises something", and it prints raw
JSON arrays instead of the status table everyone already reads. The count heuristic is also subtly wrong: it mis-handles nodes with only one Tailscale address, and a node advertising another node's /32 is indistinguishable from one advertising nothing.
Anything else?
Happy to iterate on the design before writing more code, per CONTRIBUTING.md.
What are you trying to do?
Find out which nodes in a tailnet advertise subnet routes, or act as exit nodes, without leaving the CLI.
I run a tailnet of roughly 50 nodes where a couple dozen are subnet routers fronting branch-office and lab networks, plus a few exit nodes. "Which node advertises the route to X?" and "what does this node actually advertise?" come up constantly, during audits and while debugging routing.
tailscale statusis the obvious place to look, but it has no notion of routes: the table shows IP, hostname, owner, OS, and connection status only. The information is present intailscale status --jsonas each peer's AllowedIPs, just not surfaced anywhere in the human-readable output.How should we solve this?
A
--routesflag ontailscale statusthat reuses the existing table, replacing the Status column with a Routes column, and lists only nodes advertising at least one route:A node's advertised routes are its AllowedIPs minus the single-address prefixes covering its own Tailscale IPs.
I have a working patch and will send it as a PR if the approach sounds reasonable. Open questions I'd want a maintainer's opinion on:
status --routesthe right home for this, or would you rather see it under an existing subcommand (something nearertailscale exit-node listor atailscale route-style command)?What is the impact of not solving this?
Not blocking, there's a workaround, but it's a poor one for something this routine:
It needs jq installed, it needs the reader to know that "more than two AllowedIPs" is standing in for "advertises something", and it prints raw
JSON arrays instead of the status table everyone already reads. The count heuristic is also subtly wrong: it mis-handles nodes with only one Tailscale address, and a node advertising another node's /32 is indistinguishable from one advertising nothing.
Anything else?
Happy to iterate on the design before writing more code, per CONTRIBUTING.md.