Commit Graph
4845 Commits
Author SHA1 Message Date
Kristoffer Dalby 1b184cd2c7 hscontrol: cancel ephemeral GC timer when a node is deleted
API and logout deletes left the disconnect timer armed; it fired later
and logged a bogus ERR for the missing node.
2026-10-23 18:23:53 +02:00
Michael LopezandClaude Fable 5.1 494e2a6808 db: quote postgres connection parameters (#3477)
* db: quote postgres connection parameters

The DSN was built by string concatenation, so a password containing a
space, quote or backslash truncated it or injected extra parameters.
Build it with libpq keyword/value quoting and keep the password out of
the startup log line.

* db: mark the DSN test fixture password as not a credential

gosec G101 flags the literal assigned to Pass in TestBuildPostgresDSN.
The value exists to exercise quoting of spaces, quotes and backslashes
and is not a secret.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* types, db: build the postgres DSN as a URL from PostgresConfig

Review feedback: move the DSN construction onto types.PostgresConfig as
DSN(), so the database layer calls cfg.Postgres.DSN() and logs
redacted.DSN(), and build it as a postgres:// URL with net/url instead
of hand-rolled libpq quoting. Unix socket directories travel as the
host query parameter; bare IPv6 literals are bracketed. Tests parse the
URL back and check each component rather than the encoded string.

* types: silence gosec on the whole DSN test fixtures

gosec reports G101 on the composite literal that holds a Pass value, not
on the Pass line itself, so the previous nolint did not cover it. Place
the directive before each fixture element.

* db: drop imports left unused by the merge with main

The merge of main reintroduced the slices and strconv imports in db.go,
but the postgres DSN is now built by PostgresConfig.DSN and nothing in
the file uses them, so the package failed to compile and every CI check
failed on typecheck.

Also link the CHANGELOG entry to the PR.

* db: restore tests and formatting lost in the rebase onto main

Resolving the rebase conflicts in db_test.go kept this branch's side and
dropped the credential tests main had added, including the
requireCredentialConstraints helper another test still calls, so the db
test package no longer compiled. Restore the file from main; this branch
does not change it.

The resolution also indented the package clause in db.go and removed the
blank line between the standard library and module imports.

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-22 22:36:04 +02:00
Igor Serganov 8d65201a93 db: check errors in openDB
On the SQLite path openDB called db.DB() and configured the pool
before looking at the error from gorm.Open, and both backends
discarded the error from db.DB(). A failed open returned a
half-initialised *gorm.DB alongside the error, and a nil *sql.DB
from db.DB() would have been dereferenced.

Return early on either error so callers get a nil handle and the
original error.
2026-10-22 22:33:03 +02:00
Kristoffer Dalby 7414c276f6 mapper: limit capability copies to requested peers
Small peer updates should not copy capabilities for the entire tailnet.
2026-10-22 22:17:36 +02:00
Kristoffer Dalby 6489054805 mapper: enqueue broadcasts without refiltering recipients
Broadcast recipients already share the same changes.
2026-10-22 22:17:36 +02:00
Kristoffer Dalby 068711518f mapper: store user views directly in profile maps
Avoid allocating an owner pointer for every peer during profile generation.
2026-10-22 22:17:36 +02:00
Kristoffer Dalby 65ac7af595 policy/v2: reuse grant destination resolutions
Avoid resolving the same destination for each protocol and capability rule.
2026-10-22 22:17:36 +02:00
Kristoffer Dalby 893b7fd908 servertest: exercise control plane at explicit scales
Cover policy, updates and reconnects with convergence and resource reports.
2026-10-22 22:17:27 +02:00
Kristoffer Dalby 543e3b7b08 servertest: close server state during cleanup
Release the NodeStore and database after clients and background workers stop.
2026-10-22 22:17:27 +02:00
Kristoffer Dalby 54eedce658 all: build with Go 1.27.3
crypto/x509 security fixes.
2026-10-22 14:37:00 +02:00
Kristoffer Dalby 244129064d go.mod: update tailscale.com dropped by the bump bot
tailscale.com now requires go 1.27.3.
2026-10-22 14:37:00 +02:00
Kristoffer Dalby 79ae38f0af mapper: stop shadowing predeclared cap
golangci-lint 2.15 predeclared check flags it.
2026-10-22 14:37:00 +02:00
Kristoffer Dalby 123dcd9df4 flake.lock: update nixpkgs
go_latest now 1.27.3.
2026-10-22 14:37:00 +02:00
github-actions[bot] 1e3bbae3d1 .github: bump 1 action pins 2026-10-22 14:37:00 +02:00
github-actions[bot] 10ec0657cb Dockerfile: bump golang builders to 1.27.3 / 1.27.2 2026-10-22 14:37:00 +02:00
github-actions[bot] 5dd638e9a7 go.mod: update dependencies 2026-10-22 14:37:00 +02:00
Kristoffer Dalby cc66979b16 policy/v2: benchmark peer-map index alternatives
Updates #3549
2026-10-20 11:55:11 +02:00
Serhii Matsyshyn ce9e226994 policy/v2: explain the matcher bitset layout 2026-10-20 11:55:11 +02:00
Serhii Matsyshyn 8003de63a6 CHANGELOG: peer map build speed-up 2026-10-20 11:55:11 +02:00
Serhii Matsyshyn d11d392152 policy/v2: index matchers per node in BuildPeerMap
BuildPeerMap checked every pair of nodes against every matcher. With many nodes and many rules this takes seconds, and it runs on every policy write and node registration.

Now each node's source and destination matchers are found once, and two nodes are peers when those sets share a matcher. The peer map is the same as before. A test compares the new code with the old loop on random networks.

Part of #3549
2026-10-20 11:55:11 +02:00
Kristoffer Dalby 691ef56329 AGENTS: keep libdns providers and certmagic on one libdns major
Updates #2137
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 2ba21d2f8d CHANGELOG: add tls block and certmagic
Updates #2527
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 2e8611c159 docs: use tls block keys and describe CertMagic
Updates #2527
2026-10-18 20:53:18 +02:00
Kristoffer Dalby ed854650f0 nix: declare nested tls options
Old settings.tls_* keys pass through to headscale, which still reads them;
new options default to null so they do not shadow them.

Updates #2527
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 5d15cc930d hscontrol: replace autocert with certmagic
Adds DNS-01 for headscale's own certificate through dns.challenge.provider,
with the same propagation check as node certificates. Storage format
changes: first start gets a new account and certificate.

Updates #2527
Updates #504
2026-10-18 20:53:18 +02:00
Kristoffer Dalby dcc01dc2b0 types: move TLS config under tls with legacy fallback
tls.cert_path, tls.key_path and tls.acme.* replace the flat keys, which
still work. Warn on them only when they turn TLS on: NixOS always sets them.

Updates #2527
2026-10-18 20:53:18 +02:00
Kristoffer Dalby ee47638787 CHANGELOG: add TLS certificates for nodes
Updates #2137
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 7ed3dead3e nix: add dns.certificates and dns.challenge options
Updates #2137
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 694587bfa0 docs: mark Serve as supported
HTTPS serve needs dns.certificates; Funnel and Services stay unsupported.

Updates #1921
2026-10-18 20:53:18 +02:00
Kristoffer Dalby d8bcaca066 github: add TestTailscaleCert to integration workflow
Updates #2137
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 2a30fb6b3b integration: add tailscale cert test
Every client version gets a certificate from Pebble through rfc2136 and
a TSIG-checked DNS server in the test process, then runs each serve
mode; identity headers name the requesting user.

Updates #2137
Updates #1921
2026-10-18 20:53:18 +02:00
Kristoffer Dalby eef0d1fe47 dns: add acme-dns provider
_acme-challenge is CNAMEd once to an acme-dns registration, so headscale
needs no DNS credentials. Node certificates need one registration per
name; CNAME chains are followed and writes never evict a live value.

Updates #2137
2026-10-18 20:53:18 +02:00
Kristoffer Dalby f16d5e1857 noise: implement /machine/set-dns
A node may publish only its own _acme-challenge TXT value; any other
request is rejected before the provider is called. Answers once all
authoritative nameservers serve the value; 503 while shutting down.

Fixes #2137
Fixes #1921
Fixes #2527
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 3f6e54cbd5 mapper: send CertDomains and https cap when certificates are enabled
Both gate tailscale cert and serve HTTPS on the client; httpsEnabled
follows, as in Tailscale. No certificate when an operator extra record
sits at or below the name: a wildcard would cover it.

Updates #2137
Updates #1921
2026-10-18 20:53:18 +02:00
Kristoffer Dalby a928125afa state: lowercase renames and refresh self DNS config on rename
"Foo" and "foo" could share one DNS name; collisions now ignore case.
A rename never resent the node its own DNS config, so CertDomains lagged.

Updates #2137
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 0efe4b7798 types: add dns.challenge and dns.certificates config
dns.challenge.provider builds a libdns provider at load, so configtest
catches typos. dns.certificates gates node certs; zone defaults to base_domain.

Updates #2137
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 6cb950cd9e dns: add ACME challenge tracker and propagation check
Exact appends and deletes; values go 10m after last use or on Close.
Limits per node, one lock for provider writes. Waits for every
authoritative NS and holds a new value until the CA cache has expired.

Updates #2137
2026-10-18 20:53:18 +02:00
Kristoffer Dalby 24cf63294c dns: add libdns provider registry
Curated cloudflare, gigahost, hetzner, powerdns and rfc2136.
Settings decode via json tags; env per field, <field>_path for secrets.

Updates #2137
2026-10-18 20:53:18 +02:00
Serhii Matsyshyn a777969027 CHANGELOG: one peer map build per policy write 2026-10-18 13:18:48 +02:00
Serhii Matsyshyn 8f3ba2d8cd state: rebuild peer maps in ReloadPolicy only when the policy changed
The SetPolicy API handler calls State.SetPolicy, which already rebuilds the peer map when the policy changed, and then ReloadPolicy, which rebuilt it again even when nothing changed. So every policy write built the peer map twice.

ReloadPolicy now rebuilds only when the policy really changed. A test checks one build per changed write and none for an unchanged reload.

Part of #3549
2026-10-18 13:18:48 +02:00
github-actions[bot] 362cdaeef8 Update VOUCHED list
https://github.com/juanfont/headscale/issues/3562#issuecomment-6249089869
2026-10-18 13:10:17 +02:00
github-actions[bot] 9314f4e778 Update VOUCHED list
https://github.com/juanfont/headscale/issues/3559#issuecomment-6249075866
2026-10-18 13:09:02 +02:00
github-actions[bot] fc97593bce Update VOUCHED list
https://github.com/juanfont/headscale/issues/3549#issuecomment-6193920631
2026-10-15 16:04:19 +02:00
Kristoffer Dalby 9f074ac15b policy/v2: keep comments in a policy set through the v2 API
hujson.Parse aliases its input, so Standardize blanked the comments in
the caller's buffer, which api/v2 then stored.
2026-10-15 13:28:12 +02:00
Kristoffer Dalby 380d1b0d0a tools/bump: carry hand-pushed commits instead of pausing
Open PR with commits by others: rebase onto base, build on top, push
with lease. Rebase conflict pauses and comments once.
2026-10-15 10:50:32 +02:00
Kristoffer Dalby 920b6fb8cd CHANGELOG: raise minimum Tailscale client to v1.84.0 2026-10-15 10:50:32 +02:00
Kristoffer Dalby 1077a9ff6a capver: regenerate for Tailscale v1.104 2026-10-15 10:50:32 +02:00
Kristoffer Dalby 3e5c07c95c go.mod: update dependencies dropped by the bump bot
tailscale.com (gvisor), sqlite (libc), x/net, x/tools and friends.
tailscale.com now requires go 1.27.2.
2026-10-15 10:50:32 +02:00
Kristoffer Dalby 89be098f76 integration/tsic: drop unused watchIPN
ipn.Notify.NetMap is gone upstream; nothing called it.
2026-10-15 10:50:32 +02:00
Kristoffer Dalby 627145644e noise: serve ts2021 via net/http unencrypted HTTP/2
x/net/http2.Server is deprecated and now wraps net/http anyway.
2026-10-15 10:50:32 +02:00