Route a command to one tailnet
SkillDev toolsSend a command into the namespace of one tailnet rather than to the host network. Use when asked to reach a peer, to run a command against a tailnet address, or to run a tailscale command for one tailnet.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Route a command to one tailnet skill
What this skill tells your AI
The instructions your AI receives, as published by crank-git/hydrascale in skills/tailnet-exec/SKILL.md and read by ahel’s review.
The host joins several tailnets. The daemon holds one namespace per tailnet. A bare command reaches the host network, so its result describes the host rather than a tailnet. A routing form sends the command into the namespace of the tailnet that you name.
Read the state first
Run these two commands before the first routed command:
- Run
hydrascale list. It prints the identifier of each tailnet. - Run
hydrascale status. It prints the desired state and the actual state.
hydrascale list reads the configuration file. It therefore names a tailnet that is not
connected. Read hydrascale status for the state of each tailnet that hydrascale list
names.
If hydrascale status fails, report the failure. The daemon does not run in that case.
Run the routed command anyway, because hydrascale exec needs the namespace rather than
the daemon.
The five routing forms
| Form | Result |
|---|---|
hydrascale exec <id> -- <command> | The command runs inside the namespace of the tailnet <id>. |
hydrascale tailscale <id> -- <arguments> | The tailscale command runs inside the namespace, against the socket of that tailnet. |
hydrascale ping <id> <target> | tailscale ping reaches the peer <target> from that namespace. |
hydrascale ssh <id> <target> | tailscale ssh reaches the peer <target> from that namespace. |
hydrascale wrap <service-name> <tailnet-id> | The command prints a systemd drop-in that runs a service inside the namespace. |
The first four forms take the identifier of the tailnet as the first argument.
hydrascale wrap takes it as the second argument. Read that identifier from
hydrascale list.
The separator --
hydrascale exec and hydrascale tailscale need the separator --. Each command calls
cmd.ArgsLenAtDash(), and each returns an error when the separator is absent:
hydrascale execreturnsexec requires a -- separator before the command.hydrascale tailscalereturnstailscale requires a -- separator before the arguments.
hydrascale ping and hydrascale ssh take positional arguments, and they need no
separator. hydrascale wrap takes two positional arguments, and it needs no separator.
hydrascale exec personal -- curl -s http://peer:8080
hydrascale tailscale personal -- status
hydrascale ping personal peer
hydrascale ssh personal peer
hydrascale wrap nginx personal
hydrascale exec runs ip netns exec, which needs root. When the account holds no root
permission, print the form with sudo for the operator.
hydrascale switch changes no state
hydrascale switch <id> prints the namespace name of the tailnet <id>, and it changes
no state. The shell of the operator stays on the host network. A child process cannot
move its parent shell into a namespace.
Use a routing form for each command instead. One routed command carries no state to the next command.
A tailnet that holds no namespace
When the tailnet holds no namespace, hydrascale exec fails with the message of
ip netns exec. Read hydrascale status for the state of that tailnet, and report that
state to the operator. Start no tailnet yourself.
A daemon on another host
A routing form runs on the host that holds the namespace. Send the form through SSH when the daemon runs on another host:
ssh <host> hydrascale exec <id> -- <command>
Run ssh <host> hydrascale list and ssh <host> hydrascale status first. The reason is
the same as on the local host. The SSH account needs root permission on <host>, because
hydrascale exec runs ip netns exec there.
Signals
- GitHub stars
- 34
- Forks
- 2
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
tailnet-exec- Source
- github.com/crank-git/hydrascale