Skip to main content

Get a map of IP addresses for devices in my tailnet

  • Posted
  • Updated
  • Also filed in jq

Use tailscale status --json and filter the output using jq.

Here’s a jq snippet that prints the hostname and IP addresses of every device in my tailnet (or at least, every device my current machine can see):

$ tailscale status --json \
    | jq '[.Self] + [.Peer[]]
          | sort_by(.DNSName)
          | map({(.DNSName): (.TailscaleIPs)}) 
          | add'
{
  "phaenna-mac-mini.tailfa84dd.ts.net.": [
    "100.76.19.1",
    "fd7a:115c:a1e0::fb01:1301"
  ],

}

How it works:

Here’s a variant that keys the map by MagicDNS name:

$ tailscale status --json \
    | jq '[.Self] + [.Peer[]]
          | sort_by(.DNSName)
          | map({(.DNSName | split(".")[0]): (.TailscaleIPs)}) 
          | add'
{
  "phaenna-mac-mini": [
    "100.76.19.1",
    "fd7a:115c:a1e0::fb01:1301"
  ],

}

Another variant that just extracts the IPv4 address:

$ tailscale status --json \
    | jq '[.Self] + [.Peer[]]
          | sort_by(.DNSName)
          | map({(.DNSName | split(".")[0]): (.TailscaleIPs[0])}) 
          | add'
{
  "linode-vps": "100.98.193.6",
  "palaemon-macbook-air": "100.120.194.127",
  "phaenna-mac-mini": "100.76.19.1",

}

I paste this directly into the hosts section of my policy file.

If you have Mullvad nodes in your Tailnet, you can filter them out of this map with:

$ tailscale status --json \
    | jq '[.Self] + [.Peer[]]
          | map(select(.Tags == null or (.Tags | contains(["tag:mullvad-exit-node"]) | not)))
          | sort_by(.DNSName)
          | map({(.DNSName | split(".")[0]): (.TailscaleIPs[0])}) 
          | add'
{
  "linode-vps": "100.98.193.6",
  "palaemon-macbook-air": "100.120.194.127",
  "phaenna-mac-mini": "100.76.19.1",

}

Tested with Tailscale 1.95.104. Disclaimer: At time of writing, I’m employed by Tailscale.