Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions homelab/tailscale.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,65 @@ resource "tailscale_dns_nameservers" "global" {
resource "tailscale_dns_preferences" "main" {
magic_dns = true
}

# Tailnet policy file. Codifies the current default-allow stance and adds
# forward-looking structure (tag:homelab, SSH for tagged servers) that no-ops
# until devices actually advertise the tag.
#
# DO NOT tighten the `*:*` rule in the same change that introduces tagging.
# Switching to a restrictive policy before any device wears tag:homelab will
# leave the operator unable to reach gandalf over Tailscale. Sequence:
# 1. (this resource) Codify allow-all + tagOwners + SSH-to-tag-homelab.
# 2. Advertise tag:homelab on gandalf (`tailscale up --advertise-tags=tag:homelab`)
# and approve the tag in the admin UI.
# 3. Replace the `*:*` rule with restrictive admin/tag-scoped rules.
resource "tailscale_acl" "main" {
acl = jsonencode({
tagOwners = {
# Servers in the home lab (gandalf today, Pis later). Only tailnet
# admins can apply this tag — prevents a random tailnet member from
# spoofing a homelab node.
"tag:homelab" = ["autogroup:admin"]
}

acls = [
# Phase 1: keep the default-allow rule so nothing breaks for current
# devices. Replace with restrictive rules in a follow-up PR after
# gandalf is tagged.
{
action = "accept"
src = ["*"]
dst = ["*:*"]
},
]

ssh = [
# Tailscale SSH default: members can SSH into their own devices
# (the "check" action requires reauth). Carried over from the
# admin UI default.
{
action = "check"
src = ["autogroup:member"]
dst = ["autogroup:self"]
users = ["autogroup:nonroot", "root"]
},
# Forward-looking: members can SSH into homelab-tagged servers as
# `nickv` or `root`. No-op until a device wears tag:homelab.
{
action = "accept"
src = ["autogroup:member"]
dst = ["tag:homelab"]
users = ["nickv", "root"]
},
]

nodeAttrs = [
# Tailscale Funnel — let members expose their own devices to the
# public internet. Carried over from the admin UI default.
{
target = ["autogroup:member"]
attr = ["funnel"]
},
]
})
}
Loading