Tailscale CLI
Tailscale ships with a built-in CLI that you can use to manage and troubleshoot your Tailscale network (known as a tailnet).
Using the CLI
The location of the CLI varies depending on your platform:
On Linux, the CLI is your primary interface to Tailscale. The tailscale
binary is likely already in your $PATH
, so you can run commands with:
tailscale <command>
There is no CLI support for iOS and Android.
Tab completion
The Tailscale CLI supports tab-completion for commands, flags, and arguments. You can configure tab-completion with the completion
command.
tailscale completion <shell> [--flags] [--descs]
Select your shell, then follow the instructions to load Tailscale CLI completions.
To load tab-completions for Bash, run the following command.
source <(tailscale completion bash)
Run the following command to load completions for every new session on Linux, then reload your shell.
tailscale completion bash > /etc/bash_completion.d/tailscale
Run the following command to load completions for every new session on macOS, then reload your shell.
tailscale completion bash > $(brew --prefix)/etc/bash_completion.d/tailscale
Command Reference
up
Connect your device to Tailscale and authenticate if needed.
tailscale up [flags]
Running tailscale up
without any flags connects to Tailscale.
Common flags:
--accept-routes
Accept subnet routes that other nodes advertise. Linux devices default to not accepting routes.--advertise-exit-node
Offer to be an exit node for outbound internet traffic from the Tailscale network. Defaults to not offering to be an exit node.--advertise-routes=<ip>
Expose physical subnet routes to your entire Tailscale network.--exit-node=<ip|name>
Provide a Tailscale IP or machine name to use as an exit node. To disable the use of an exit node, pass the flag with an empty argument:--exit-node=
.--exit-node-allow-lan-access
Allow the client node access to its own LAN while connected to an exit node. Defaults to not allowing access while connected to an exit node.--force-reauth
Force re-authentication.--snat-subnet-routes
Disable source NAT. In normal operations, a subnet device sees the traffic originating from the subnet router. This simplifies routing, but does not allow traversing multiple networks. By disabling source NAT, the end machine sees the LAN IP address of the originating machine as the source.--stateful-filtering
Enable stateful filtering for subnet routers and exit nodes. When enabled, inbound packets with another node's destination IP are dropped, unless they are a part of a tracked outbound connection from that node. Defaults to disabled.--shields-up
Block incoming connections from other devices on your Tailscale network. Useful for personal devices that only make outgoing connections.--ssh
Run a Tailscale SSH server, permitting access per the tailnet admin's declared access policy, or the default policy if none is defined. Defaults to false.
For a complete list of available flags, refer to the tailscale up
article.
down
Disconnect from Tailscale. Running this command is the same as choosing to disconnect from or quit a Tailscale client.
tailscale down
When disconnected, you cannot reach devices over Tailscale. To reconnect, re-run tailscale up
without any flags.
Available flags:
--accept-risk=<risk>
Accept risk and skip confirmation for risk type. This can be eitherlose-ssh
orall
, or an empty string to not accept risk.
bugreport
The bugreport
command is available in Tailscale v1.8 or later. If you don't see this command, consider updating your Tailscale client.
Generate a bug report with diagnostic information.
The bugreport
command makes it easier to report bugs to the Tailscale team by marking diagnostic logs with indicators to make triage easier.
If you encounter a connectivity issue, run tailscale bugreport
on the device experiencing the issue at the time you encounter it. This command prints a random identifier into diagnostic logs, which you can share with our team.
Identifiers look like this:
$ tailscale bugreport
BUG-1b7641a16971a9cd75822c0ed8043fee70ae88cf05c52981dc220eb96a5c49a8-20210427151443Z-fbcd4fd3a4b7ad94
This command shares no personally identifiable information and is unused unless you share the bug identifier with our team.
Available flags:
--diagnose
Prints additional verbose information about the system to the Tailscale logs after generating abugreport
identifier, which can then be viewed by our support team. Defaults tofalse
.--record
Pause and then write anotherbugreport
. Use this flag to create an initialbugreport
identifier. During the pause, perform the action that reproduces your issue. Then, press Enter to create a secondbugreport
identifier. Share both bug identifiers with our team. Defaults tofalse
.
cert
Generate Let's Encrypt certificate and key files on the host for HTTPS certificates in your tailnet.
If you are trying to serve a folder of files or reverse proxy to an HTTP service, use the tailscale serve
command instead.
tailscale cert hostname.tails-scales.ts.net
Alternatively, if you want to save the certificate and private key to files, you can use the --cert-file
and --key-file
arguments:
tailscale cert --cert-file=cert.pem --key-file=key.pem hostname.tails-scales.ts.net
The certificates provided by Let's Encrypt have a 90-day expiry and require periodic renewal. When a certificate is delivered as files on disk which you then move to an install location, such as when using tailscale cert
, the tailscaled
daemon doesn't know where to place a renewed certificate or how to install it. As a result, you are responsible for renewing any certificates that you create using tailscale cert
.
If a certificate is handled without the user initiating any file-based certificate installation (such as when using the Caddy integration of Tailscale) then the certificate will automatically renew without the user doing anything.
Available flags:
--cert-file=<cert>
Specify the certificate output path.--key-file=<key>
Specify the private key output path.--min-validity=<duration>
Request a specified minimum remaining validity on the returned certificate.duration
can be any value parseable bytime.ParseDuration()
. For example, use120h
to set the duration to five days.
The --min-validity
flag lets you ensure that the returned certificate is valid for at least the specified duration. If you specify a duration longer than the certification lifetime set by Let's Encyrpt, it uses the maximum lifetime set by Let's Encrypt.
dns
The dns
command lets you access Tailscale DNS settings. It's available in Tailscale v1.74.0 and later.
Sub-commands:
status
Print the configuration of the local DNS forwarder and the tailnet-wide MagicDNS configuration.
completion
Configure tab-completion for the Tailscale CLI.
tailscale completion <sub-command> [flags]
Sub-commands:
bash
Configure tab-completion for thebash
shell.zsh
Configure tab-completion for thezsh
shell.fish
Configure tab-completion for thefish
shell.powershell
Configure tab-completion for PowerShell.
Available flags:
--flags=<true|false>
Configure whether to suggest flags (in addition to sub-commands). Set totrue
by default.--descs=<true|false>
Configure whether to include descriptions of sub-commands in the suggestions. Set totrue
by default.
configure (alpha)
Configure resources that you want to include in your tailnet.
tailscale configure <sub-commands>
Common sub-commands:
kubeconfig
Configure kubectl to connect to a Kubernetes cluster using Tailscale.synology
Configure Synology to enable outbound connections needed for Tailscale.
Examples:
- To configure your local
kubeconfig
file for authentication with a Kubernetes auth proxy:
tailscale configure kubeconfig <hostname-or-fqdn>
- To configure Synology to enable outbound connections:
tailscale configure synology
exit-node
Get information about exit-nodes in your tailnet.
tailscale exit-node <sub-commands>
Available sub-commands:
list
Lists the exit nodes in your tailnet.suggest
Suggests a recommended exit node.
file
Access and make files available to Taildrop.
Available flags:
cp
Copy files to a hostget
Move files out of the Tailscale file inbox
funnel
Serve content and local servers from your Tailscale node to the internet.
To limit local service access to your tailnet, use the serve
command.
tailscale funnel <target>
tailscale funnel <sub-command> [sub-flags] <args>
Sub-commands:
For more information, refer to the tailscale funnel
article.
ip
Get a device's Tailscale IP address.
tailscale ip [flags] [<hostname>]
By default, this command returns both an 100.x.y.z
IPv4 address and an IPv6 address for the current device. You can return only an IPv4 or IPv6 address by passing either the -4
or -6
flags.
$ tailscale ip -4
100.121.112.23
You can also find the Tailscale IP for other devices on your network by adding the device hostname after the command. For example:
$ tailscale ip raspberrypi
100.126.153.111
fd7a:115c:a1e0:ab12:4843:cd96:627e:9975
Available flags:
-4
Only return an IPv4 address-6
Only return an IPv6 address-1
Only return one address, preferring IPv4
lock
Manage tailnet lock for your tailnet.
tailscale lock <sub-command> [sub-flags] <args>
Common sub-commands:
init
Initializes tailnet lock.status
Outputs the state of tailnet lock.add
Adds one or more trusted signing keys to tailnet lock.remove
Removes one or more trusted signing keys from tailnet lock.sign
Signs a node key and transmits the signature to the coordination server.
Running tailnet lock
with no sub-command and no arguments is equivalent to running tailscale lock status
.
For a complete list of sub-commands and flags, refer to the tailscale lock
article.
login
Log into Tailscale (and add this device to your Tailscale network). For more information about logging in, refer to fast-user-switching.
tailscale login [flags]
Available flags:
--accept-dns
Accept DNS configuration from the admin console. Defaults to accepting DNS settings.--accept-routes
Accept subnet routes that other nodes advertise. Linux devices default to not accepting routes.--advertise-exit-node
Offer to be an exit node for outbound internet traffic from the Tailscale network. Defaults to not offering to be an exit node.--advertise-routes=<ip>
Expose physical subnet routes to your entire Tailscale network.--advertise-tags=<tags>
Give tagged permissions to this device. You must be listed in"TagOwners"
to be able to apply tags.--auth-key=<key>
Provide an auth key to automatically authenticate the node as your user account.--exit-node=<ip|name>
Provide a Tailscale IP or machine name to use as an exit node. To disable the use of an exit node, pass the flag with an empty argument:--exit-node=
.--exit-node-allow-lan-access
Allow the client node access to its own LAN while connected to an exit node. Defaults to not allowing access while connected to an exit node.--hostname=<name>
Provide a hostname to use for the device instead of the one provided by the OS. Note that this will change the machine name used in MagicDNS.--login-server=<url>
Provide the base URL of a control server instead ofhttps://controlplane.tailscale.com
. If you are using Headscale for your control server, use your Headscale instance's URL.--nickname=<name>
Nickname for the current account.--operator=<user>
Provide a Unix username other thanroot
to operatetailscaled
.--qr
Generate a QR code for the web login URL. Defaults to not showing a QR code.--stateful-filtering
Enable stateful filtering for subnet routers and exit nodes. When enabled, inbound packets with another node's destination IP are dropped, unless they are a part of a tracked outbound connection from that node. Defaults to disabled.--shields-up
Block incoming connections from other devices on your Tailscale network. Useful for personal devices that only make outgoing connections.--ssh
Run a Tailscale SSH server, permitting access per the tailnet admin's declared access policy, or the default policy if none is defined. Defaults to false.--timeout=<duration>
Maximum amount of time to wait for the Tailscale service to initialize.duration
can be any value parseable bytime.ParseDuration()
. Defaults to0s
, which blocks forever.--unattended
(Windows only) Run in unattended mode where Tailscale keeps running even after the current user logs out.
logout
Disconnect from Tailscale and expire the current log in. The next time you run tailscale up
, you'll need to reauthenticate your device.
tailscale logout
If you run tailscale logout
on an ephemeral node, the node will be removed from your tailnet immediately.
netcheck
Get a report on your current physical network conditions. This command is provided to help debug connection troubles.
tailscale netcheck
Netcheck will output a report like this:
Report:
* UDP: true
* IPv4: yes, <ip-address>
* IPv6: no
* MappingVariesByDestIP: false
* HairPinning: false
* PortMapping: false
* Nearest DERP: 1 (nyc)
* DERP latency:
- 1, nyc = 43.6ms
- 2, sfo = 67.4ms
- 3, sin = 202.5ms
- 4, fra = 91.9ms
- 5, syd = 218.5ms
- UDP shows whether UDP traffic is enabled on the current network. If this is false, it's unlikely Tailscale will be able to make point-to-point connections, and will instead rely on our encrypted TCP relays (DERP)
- IPv4 and IPv6 show your network public IP addresses and support for both protocols.
- MappingVariesByDestIP describes whether your device is behind a difficult NAT that varies the device's IP address depending on the destination.
- HairPinning describes whether your router can route connections from endpoints on your LAN back to your LAN using those endpoints' globally-mapped IPv4 addresses/ports.
- PortMapping describes a list of which three port-mapping services exist on your router. Possible values are "UPnP", "NAT-PMP", and "PCP".
- DERP latency and Nearest DERP describe latency from our encrypted TCP relays (DERP). The lowest latency ("nearest") server is used for traffic.
If any fields are blank, it means Tailscale wasn't able to measure that network property.
All the information from tailscale netcheck
is also available in the admin console, by selecting a particular machine.
version
Print the version of Tailscale.
tailscale version [flags]
Available flags:
--daemon
Also print local node's daemon version. Defaults to false.--json
Return a machine-readable JSON response.--upstream
Print the latest upstream release version from pkgs.tailscale.com. Defaults to false.
Running tailscale version
also prints other information, including the Go version. Here's an example of the output:
tailscale version
1.72.0
tailscale commit: 9a0f00ea8ed08d1a94b357fb232ac9d44a512664
other commit: 387e0b40ad87031fb4444372ee80a97156e8deb9
go version: go1.22.5
ping
Attempt to ping another device exclusively over Tailscale.
The regular ping
command often works fine over Tailscale, but tailscale ping
provides more details about the connection over Tailscale that can be helpful when troubleshooting connectivity.
tailscale ping <hostname-or-ip>
You can call tailscale ping
using either a 100.x.y.z address or a machine name.
Available flags:
--c
Maximum number of pings to send. Defaults to 10.--icmp
,--icmp=false
Perform an ICMP-level ping (through WireGuard, but not the local host OS stack). Defaults to false.--peerapi
,--peerapi=false
Try hitting the peer's PeerAPI HTTP server. Defaults to false.--tsmp
,--tsmp=false
Perform a TSMP-level ping (through WireGuard, but not either host's OS stack). Defaults to false.--timeout=<duration>
Maximum amount of time to wait before giving up on a ping.duration
can be any value parseable bytime.ParseDuration()
. Defaults to5s
.--until-direct
,--until-direct=false
Stop once a direct path is established. Defaults to true.--verbose
,--verbose=false
Show verbose output. Defaults to false.
serve
Serve content and local servers from your Tailscale node to your tailnet.
To publicly share the local service to the internet, use the funnel
command.
tailscale serve <target>
tailscale serve <sub-command> [sub-flags] <args>
Sub-commands:
For more information, refer to the tailscale serve
article.
set
Change specified preferences.
Unlike tailscale up
, this command does not require the complete set of desired settings. It only updates the settings you explicitly set. There are no default values. Note that when using Fast User Switching, changes made are only for the currently connected tailnet.
tailscale set [flags]
Available flags:
--accept-dns
Accept DNS configuration from the admin console.--accept-risk=<risk>
Accept risk and skip confirmation for risk type. This can be eitherlose-ssh
orall
, or an empty string to not accept risk.--accept-routes
,--accept-routes=false
Accept subnet routes that other nodes advertise.--advertise-exit-node
,--advertise-exit-node=false
Offer to be an exit node for internet traffic for the tailnet.--advertise-routes=<ip>
Expose physical subnet routes to your entire Tailscale network. This is a comma-separated string, such as "10.0.0.0/8,192.168.0.0/24"), or an empty string to not advertise routes.--auto-update
,--auto-update=false
Enable or disable auto-updates for the client.--exit-node <ip|name>
A Tailscale IP or machine name to use as an exit node, or an empty string to not use an exit node.--exit-node-allow-lan-access
,--exit-node-allow-lan-access=false
Allow the client node access to its own LAN while connected to an exit node.--hostname=<name>
Hostname to use for the device instead of the one provided by the OS. Note that this will change the machine name used in MagicDNS.--nickname=<name>
Nickname for the current account.--operator=<user>
A Unix username other thanroot
to operatetailscaled
.--shields-up
,--shields-up=false
Block incoming connections from other devices on your Tailscale network. Useful for personal devices that only make outgoing connections.--ssh
,--ssh=false
Run a Tailscale SSH server, permitting access per the tailnet admin's declared access policy, or the default policy if none is defined.--webclient
,--webclient=false
Expose the web interface to your tailnet persistently in the background on port:5252.
ssh
Establish a Tailscale SSH session to a Tailscale machine.
You can often use the regular ssh
command or another SSH client to make an SSH session to a Tailscale machine. However, when your local node is in userspace-networking mode and can't make a direct connection, use tailscale ssh
. This sets up an SSH ProxyCommand
to connect through the local tailscaled
daemon. You can also use tailscale ssh
when your local node is in kernel mode.
The tailscale ssh
command automatically checks the destination server's SSH host key against the node's SSH host key as advertised via the Tailscale coordination server.
tailscale ssh <args>
<args>
is one of the following forms:
host
The destination server. An interactive session will prompt you for the user name to use for the session.user@host
The user name for the session and the destination server.
For both forms, host
can be the destination server's MagicDNS name (even if --accept-dns=false
was set on the local node) or the destination server's Tailscale IP address.
tailscale ssh
is not available on sandboxed macOS builds—use the regular ssh
client instead.
status
Get the status of your connections to other Tailscale devices.
tailscale status
This command returns a table of information like so:
1 2 3 4 5
100.1.2.3 device-a apenwarr@ linux active; direct <ip-port>, tx 1116 rx 1124
100.4.5.6 device-b crawshaw@ macOS active; relay <relay-server>, tx 1351 rx 4262
100.7.8.9 device-c danderson@ windows idle; tx 1214 rx 50
100.0.1.2 device-d ross@ iOS —
From left-to-right, these columns represent:
- Column 1 is a Tailscale IP, which you can use to connect to the device.
- Column 2 is the machine name of the device. If you use MagicDNS, you can also use this name to connect.
- Column 3 is the email address for the owner of the device.
- Column 4 is the device OS.
- Column 5 shows the current connection status.
Connection status (column 5) is shown using three terms:
active
means traffic is currently being sent/received from this device. You'll also see either (a) "direct" for peer-to-peer connections, along with the IP address used to connect or (b) "relay" for connections using a relay server along with a city code (nyc, fra, tok, syd) for the respective location.idle
means traffic is not currently being sent/received from this device.–
means no traffic has ever been sent/received from this device.
active
and idle
connection statuses will also include tx/rx values indicating the number of bytes sent (tx) and received (rx) from this device.
You can filter this list to only active connections by running tailscale status --active
.
Running tailscale status
with the --json
flag returns a machine-readable JSON response.
tailscale status --json
Combine this with jq
to automate data collection about your network. For example, the following command counts and sorts the relay servers your Tailscale peers are connected to.
tailscale status --json | jq -r '.Peer[].Relay | select(.!="")' | sort | uniq -c | sort -nr
switch
Switch to a different Tailscale account. For more information about switching accounts, refer to fast-user-switching.
tailscale switch <account> [flags]
Examples:
-
To switch to the [email protected] account:
tailscale switch [email protected]
-
To switch to the account that has the nickname "work":
tailscale switch work
Available flags:
--list
Lists available accounts.
update
The update
command is available in Tailscale v1.36 or later for Windows and Ubuntu/Debian Linux, in v1.48.0 or later for the Mac Apple Store version and Synology, and in v1.54.0 or later for QNAP and the standalone macOS application. If you don't see this command and you are running one of these operating systems, consider updating your Tailscale client.
Update the Tailscale client version to the latest version, or to a different version.
tailscale update [flags]
Available flags:
--dry-run
Show what update would do, without performing the update and without prompting to start the update.--track
The track to check for updates, either "stable" or "unstable". If not specified, the update uses the track currently in effect for the client.--version
An explicit version to use for the update or downgrade. You cannot specify both--track
and--version
.--yes
Perform the update without interactive prompts. Defaults to false.
If you downgrade to a version that does not have the tailscale update
functionality, you won't be able to run tailscale update
to return to the prior version. You would need to perform an update without using the Tailscale CLI.
To determine the current version on a client, run tailscale version
.
Examples:
Update to the latest version within your current track (stable or unstable, depending on what you're running):
tailscale update
Update to the latest version within your current track without using interactive prompts:
tailscale update --yes
Update to Tailscale v1.34:
tailscale update --version=1.34.0
Update to the latest unstable version:
tailscale update --track=unstable
web
Start a web server for controlling the tailscaled
daemon. Starting a web server is useful when the CLI or a native app is impractical (such as on NAS devices).
tailscale web [flags]
Available flags:
--cgi=<true|false>
Run the web server as a CGI script. Defaults to false.--listen=<ip|name>
Set the listen address. Use port0
for automatic. Defaults tolocalhost:8088
.--prefix=<string>
Set the URL prefix added to requests (for CGI or reverse proxies)--read-only
Run the web server in read-only mode
whois
Get the machine and user associated with a Tailscale IP.
tailscale whois ip[:port]
For user devices, this command returns:
Machine:
Name:
ID:
Addresses:
AllowedIPs:
User:
Name:
ID:
Capabilities:
For devices that are tagged, this command returns:
Machine:
Name:
ID:
Addresses:
AllowedIPs:
Tags:
Capabilities:
For each of these fields:
Machine
,Name
is the machine name of the device. If you use MagicDNS, you can also use this name to connect.Machine
,ID
is the node id of the device.Machine
,Addresses
are the Tailscale IP, which you can use to connect to the device.Machine
,AllowedIPs
are the subnet routes available to the device.Machine
,Tags
are the tags to which the device belongs.User
,Name
is the email address for the owner of the device.User
,ID
is the unique ID of the userCapabilities
show the grants for the device.
Running tailscale whois
with the --json
flag will return a machine-readable JSON response. (Note that the --json
option must come before the ip[:port]
argument.)
tailscale whois --json ip[:port]