惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
Blog — PlanetScale
Blog — PlanetScale
H
Help Net Security
The GitHub Blog
The GitHub Blog
博客园 - Franky
酷 壳 – CoolShell
酷 壳 – CoolShell
Recent Announcements
Recent Announcements
量子位
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
Microsoft Azure Blog
Microsoft Azure Blog
Martin Fowler
Martin Fowler
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
A
About on SuperTechFans
T
Tailwind CSS Blog
V
V2EX
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
SegmentFault 最新的问题
G
Google Developers Blog
M
MIT News - Artificial intelligence

alexwlchan’s notes

What is WS11 1DB? Blocking referrers with Caddy How to type a Spanish question mark (¿) on a Mac Non-overlapping type comparisons and Python type checkers Why does t.Setenv panic after t.Parallel? Use Path.glob() and Path.rglob() for typed versions of glob.glob() Curious clocks and colourful eyes Track which templates are used by Jinja2 Archeologists distinguish between “sherds” and “shards” A single command to test all my changed Go packages Disable the new message animations in WhatsApp Finding high-churn folders that bother Backblaze Always-on SSH agent forwarding with my Git pushes Managing the caption of a photo with AppleScript (but not PhotoKit) Goodhart’s and Campbell’s Law are different Notes from The Cornishman No. 176 (Spring 2026) Notes from The Cornishman No. 176 (Spring 2026) GitUp can’t diff text files larger than 8MB Home Testing the width of a page on a mobile device using Playwright Disable AirPods charging notifications Start a Caddy server in a subprocess during a Python session Filter a list of JSON object based on a list of tags HOME_GET_ME_HOME is a Citymapper Shortcuts action The FileExistsError exception exposes a filename attribute The red-lined bubble snail Why can’t Python connect to example.com? Useful type hints for Python How to truncate the middle of long command output AirPlay Receiver can interfere with Flask apps
Get a map of IP addresses for devices in my tailnet
2026-02-22 · via alexwlchan’s notes

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:

  • [.Self] + [.Peer[]] combines the .Self object and .Peer array into a single array.
  • sort_by(.DNSName) sorts the array based on the DNSName field.
  • map({(.DNSName): (.TailscaleIPs)}) converts each entry in that array into a map where the DNSName is the key, and the TailscaleIPs array is the value. Now the output is an array of objects, each with a single key-value pair.
  • add combines all those objects into a single object.

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.