mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-27 00:36:49 +09:00
hscontrol, cli: serve the v2 API on the local socket and add the oauth-clients command
Serve the v2 API over the local unix socket for the CLI and add the oauth-clients command that drives it.
This commit is contained in:
1 parent
84715e976c
commit
b05f8875c3
5 files changed
+4355
-24
No files matched your search
+26
-7
@@ -319,6 +319,11 @@ func (h *Headscale) scheduledTasks(ctx context.Context) {
|
||||
revokedKeyGCChan = revokedKeyTicker.C
|
||||
}
|
||||
|
||||
// OAuth access tokens are short-lived (1h) and re-minted on demand; reap
|
||||
// expired rows hourly so the table stays bounded.
|
||||
accessTokenTicker := time.NewTicker(time.Hour)
|
||||
defer accessTokenTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -335,6 +340,14 @@ func (h *Headscale) scheduledTasks(ctx context.Context) {
|
||||
log.Info().Int("count", reaped).Msg("reaped revoked pre-auth keys")
|
||||
}
|
||||
|
||||
case <-accessTokenTicker.C:
|
||||
reaped, err := h.state.DeleteExpiredAccessTokens(time.Now())
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("reaping expired oauth access tokens")
|
||||
} else if reaped > 0 {
|
||||
log.Debug().Int64("count", reaped).Msg("reaped expired oauth access tokens")
|
||||
}
|
||||
|
||||
case <-expireTicker.C:
|
||||
var (
|
||||
expiredNodeChanges []change.Change
|
||||
@@ -627,20 +640,26 @@ func (h *Headscale) Serve() error {
|
||||
Cfg: h.cfg,
|
||||
})
|
||||
|
||||
// The Headscale v2 API. It is served only over the remote
|
||||
// listener (Basic/Bearer auth); no unix-socket mount yet, as nothing local
|
||||
// calls it — the CLI still speaks v1.
|
||||
// The Headscale v2 API. Served behind Basic/Bearer auth on the remote
|
||||
// listener, and over the local unix socket (local trust) so the CLI can
|
||||
// manage OAuth clients through the same v2 keys handler the Tailscale
|
||||
// ecosystem uses.
|
||||
humaV2Mux, _ := apiv2.Handler(apiv2.Backend{
|
||||
State: h.state,
|
||||
Change: h.Change,
|
||||
Cfg: h.cfg,
|
||||
})
|
||||
|
||||
// Serve the Huma API over the unix socket without TLS or auth: socket access
|
||||
// implies trust. WithLocalTrust marks these requests so the security
|
||||
// middleware skips the API-key check.
|
||||
// Serve both Huma APIs over the unix socket without TLS or auth: socket
|
||||
// access implies trust. WithLocalTrust marks these requests so each API's
|
||||
// security middleware skips the credential check. v2 paths route to the v2
|
||||
// mux; everything else (the v1 paths) to v1.
|
||||
socketHandler := http.NewServeMux()
|
||||
socketHandler.Handle("/api/v2/", apiv2.WithLocalTrust(humaV2Mux))
|
||||
socketHandler.Handle("/", apiv1.WithLocalTrust(humaMux))
|
||||
|
||||
socketServer := &http.Server{
|
||||
Handler: apiv1.WithLocalTrust(humaMux),
|
||||
Handler: socketHandler,
|
||||
ReadTimeout: types.HTTPTimeout,
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user