All four droplets were deleted by mistake on 2026-10-17 and rebuilt as two: Gatus and signal-api now share spacey with headscale, and arbret moves onto vipy. The old IPs were recycled to strangers within a day. - inventory: [observability] is spacey. Left as it was, the bare name `monitoring` resolved through ~/.ssh/config to an IP that now belongs to someone else. [arbret]/prd-arbret is gone. - inventory: lan_ip fallbacks corrected from the Proxmox guest agent - memos-box is .130 (was .145) and arbret-staging-box .145 (was .147). - spacey: gatus_port 8081. headscale already holds 0.0.0.0:8080, and the two never shared a host before. - 402: status.<domain> is expected to resolve to spacey. - headscale ACL: prd-arbret, prd-monitoring and stalwart-box removed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
128 lines
3.2 KiB
Django/Jinja
128 lines
3.2 KiB
Django/Jinja
{#
|
|
Headscale ACL policy.
|
|
|
|
CAPTURED FROM THE LIVE FILE on spacey, 2026-09-19. Until then this playbook
|
|
wrote `{}` here - an empty policy - while the real rules were maintained by
|
|
hand on the box. Ansible had already flattened them once:
|
|
/etc/headscale/acl.json.937464.2026-09-12@14:03:08~ is its own backup of a
|
|
1596-byte policy it replaced with {}. The next full site.yml run would have
|
|
done it again, taking the whole tailnet's access rules with it.
|
|
|
|
So this is the source of truth now. It is a template and not inline `content:`
|
|
(the style used elsewhere in this playbook) precisely because it needs to be
|
|
diffable in review - an empty policy is the kind of change that must never
|
|
again slip through as three invisible characters.
|
|
|
|
ADDING A HOST: it needs a tagOwners entry, and an acls rule naming the exact
|
|
ports its peers may reach. A node with no rule is INVISIBLE to the others -
|
|
it will not appear in `tailscale status` and MagicDNS will not resolve it,
|
|
which surfaces as a Caddy 502 with "no such host" rather than as a refused
|
|
connection.
|
|
#}
|
|
{
|
|
"acls": [
|
|
{
|
|
"action": "accept",
|
|
"dst": [
|
|
"*:22",
|
|
"tag:arbret-staging-box:4117",
|
|
"tag:prd-arbret:4117",
|
|
"tag:nodito:8006"
|
|
],
|
|
"src": [
|
|
"tag:framie"
|
|
]
|
|
},
|
|
{
|
|
"action": "accept",
|
|
"dst": [
|
|
"tag:knots-box:8333",
|
|
"tag:knots-box:7152",
|
|
"tag:knots-box:23334",
|
|
"tag:fulcrum-box:50002",
|
|
"tag:mempool-box:8080",
|
|
"tag:memos-box:5230",
|
|
"tag:music-box:4533",
|
|
"tag:jar-lid-archive-staging-box:8000",
|
|
"tag:monerod-box:18089",
|
|
"tag:monerod-box:8081",
|
|
"tag:arbret-staging-box:80"
|
|
],
|
|
"src": [
|
|
"tag:prd-vipy"
|
|
]
|
|
},
|
|
{
|
|
"action": "accept",
|
|
"dst": [
|
|
"tag:knots-box:8332",
|
|
"tag:knots-box:28332-28335"
|
|
],
|
|
"src": [
|
|
"tag:fulcrum-box"
|
|
]
|
|
},
|
|
{
|
|
"action": "accept",
|
|
"dst": [
|
|
"tag:knots-box:8332",
|
|
"tag:fulcrum-box:50001"
|
|
],
|
|
"src": [
|
|
"tag:mempool-box"
|
|
]
|
|
},
|
|
{
|
|
"action": "accept",
|
|
"dst": [
|
|
"tag:prd-vipy:22",
|
|
"tag:memos-box:22",
|
|
"tag:jar-lid-archive-staging-box:22"
|
|
],
|
|
"src": [
|
|
"tag:small-backups-box"
|
|
]
|
|
}
|
|
],
|
|
"tagOwners": {
|
|
"tag:arbret-staging-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:forgejo-runner-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:framie": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:fulcrum-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:jar-lid-archive-staging-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:knots-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:memos-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:mempool-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:monerod-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:music-box": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:nodito": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:prd-vipy": [
|
|
"{{ headscale_namespace }}@"
|
|
],
|
|
"tag:small-backups-box": [
|
|
"{{ headscale_namespace }}@"
|
|
]
|
|
}
|
|
}
|