Learn Tailscale - Security Hardening & Advanced ACL
Episode 14 of 23

Learn Tailscale - Security Hardening & Advanced ACL

This episode covers advanced ACLs: granular per-node and per-user rules, tag-based policies with the least privilege principle, plus a hardening checklist like key expiry, device monitoring, Taildrop and SSH restrictions, and securing public server nodes.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Introduction

In episode 6 you used basic ACLs, and in episode 13 you built the identity layer. Now it's time to combine everything into a tailnet that's genuinely hard against attacks. Episode 14 is the most practical security episode in this series.

We cover advanced ACLs: granular per-node and per-user rules, tag-based policies with the least privilege principle, plus a hardening checklist you can apply right away — key expiry, device monitoring, Taildrop and SSH restrictions, and securing publicly exposed server nodes.

Advanced ACL

Granular Rules per Node and per User

Tailscale ACLs can be granular down to one user accessing one node on specific ports:

Granular ACL
{
  "acls": [
    { "action": "accept",
      "src": ["user1@example.com"],
      "dst": ["nas-home:22,80,443"] },
    { "action": "accept",
      "src": ["group:devops"],
      "dst": ["tag:server:*"] }
  ]
}

The first rule restricts user1@example.com to just three ports on the NAS. The second gives group:devops full access to all server nodes. The port detail in the first rule is the kind of granularity you want to replicate.

Tag-Based Policies and Least Privilege

The least privilege principle: grant the minimum access a task requires. Combining tags and groups makes it easy:

Least privilege with tags
{
  "tagOwners": {
    "tag:db": ["group:devops"],
    "tag:web": ["group:devops"]
  },
  "acls": [
    { "action": "accept",
      "src": ["tag:web"],
      "dst": ["tag:db:5432"] },
    { "action": "accept",
      "src": ["group:devops"],
      "dst": ["tag:web:22"] }
  ]
}

Above, web nodes may only touch port 5432 of database nodes, and humans only come in via port 22. There's no open *:* rule — every path is considered explicitly.

Hardening Checklist

Deactivating Unused Devices

  • Set a short key expiry (30-90 days) so forgotten nodes require re-authentication.
  • tailscale logout or remove from the admin console for retired devices.
  • Review tailscale status regularly to spot strange nodes.
Quick audit of active nodes
tailscale status
tailscale status --json | grep -c '"Online"'

The combination of tailscale status with a JSON filter helps count currently online nodes.

Monitoring Devices in the Admin Console

The admin console provides the device list, connection status, and activity logs. Make this monitoring routine: unknown devices, status changes, and suspicious activity should be spotted quickly. Combine with the audit log (episode 21) for a complete trail.

Restricting Taildrop and SSH

Two features that are often left wide open but should be restricted:

Restrict Taildrop and SSH
{
  "acls": [
    { "action": "accept",
      "src": ["group:devops"],
      "dst": ["tag:server:5201"] }
  ],
  "ssh": [
    { "action": "check",
      "src": ["group:devops"],
      "dst": ["tag:server"],
      "users": ["autogroup:nonroot"] }
  ]
}

Taildrop is restricted via port 5201, SSH is limited to non-root only. With the group:devops and autogroup:nonroot pattern, the attack surface shrinks dramatically.

Securing Public Server Nodes

Nodes also exposed to the internet (VPS, web servers) need extra attention:

  • Don't expose Tailscale ports to the public firewall.
  • Disable SSH passwords on the server.
  • Use Tailscale SSH or OpenSSH with keys only.
  • Enable auto-update so security patches arrive automatically.
Auto-update for public servers
sudo tailscale set --auto-update

Continuous Review Practices

Security Routine

  • Review the ACL file monthly and version it in a repository.
  • Audit the device list and remove inactive ones.
  • Check login and connection logs regularly.
  • Test ACLs with tailscale ping from nodes that should be denied.
Hardening cycle
Review ACL -> Test access -> Audit devices -> Update policy -> Repeat

Summary

Hardening isn't a one-time event; it's a habit. With granular ACLs, least privilege, and a disciplined checklist, your tailnet stays secure even as it keeps growing.

Closing

Episode 14 closed out the security foundation: you can assemble granular ACLs, apply least privilege with tags, and run a hardening checklist that keeps the tailnet safe.

Key takeaways:

  • ACL granularity down to one user, one port.
  • Least privilege principle: open only what the task requires.
  • Short key expiry and regular device reviews.
  • Restrict Taildrop (port 5201) and SSH to only what's needed.
  • Public nodes need auto-update and strict firewalls.
  • Hardening is a cycle, not a one-time event.

In the next episode, episode 15, we'll cover Tailscale Serve and Funnel — exposing a local service only to the tailnet with automatic TLS via MagicDNS, plus exposing it securely to the public internet with Funnel, complete with the differences between the two.

Learn Tailscale - Security Hardening & Advanced ACL | Learn Tailscale