mirror of
https://github.com/juanfont/headscale.git
synced 2025-11-09 21:49:39 -05:00
feat: add verify client config for embedded DERP (#2260)
* feat: add verify client config for embedded DERP * refactor: embedded DERP no longer verify clients via HTTP - register the `headscale://` protocol in `http.DefaultTransport` to intercept network requests - update configuration to use a single boolean option `verify_clients` * refactor: use `http.HandlerFunc` for type definition * refactor: some renaming and restructuring * chore: some renaming and fix lint * test: fix TestDERPVerifyEndpoint - `tailscale debug derp` use random node private key * test: add verify clients integration test for embedded DERP server * fix: apply code review suggestions * chore: merge upstream changes * fix: apply code review suggestions --------- Co-authored-by: Kristoffer Dalby <kristoffer@dalby.cc>
This commit is contained in:
@@ -81,28 +81,33 @@ func parseCabailityVersion(req *http.Request) (tailcfg.CapabilityVersion, error)
|
||||
return tailcfg.CapabilityVersion(clientCapabilityVersion), nil
|
||||
}
|
||||
|
||||
func (h *Headscale) derpRequestIsAllowed(
|
||||
func (h *Headscale) handleVerifyRequest(
|
||||
req *http.Request,
|
||||
) (bool, error) {
|
||||
writer io.Writer,
|
||||
) error {
|
||||
body, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("cannot read request body: %w", err)
|
||||
return fmt.Errorf("cannot read request body: %w", err)
|
||||
}
|
||||
|
||||
var derpAdmitClientRequest tailcfg.DERPAdmitClientRequest
|
||||
if err := json.Unmarshal(body, &derpAdmitClientRequest); err != nil {
|
||||
return false, fmt.Errorf("cannot parse derpAdmitClientRequest: %w", err)
|
||||
return fmt.Errorf("cannot parse derpAdmitClientRequest: %w", err)
|
||||
}
|
||||
|
||||
nodes, err := h.db.ListNodes()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("cannot list nodes: %w", err)
|
||||
return fmt.Errorf("cannot list nodes: %w", err)
|
||||
}
|
||||
|
||||
return nodes.ContainsNodeKey(derpAdmitClientRequest.NodePublic), nil
|
||||
resp := &tailcfg.DERPAdmitClientResponse{
|
||||
Allow: nodes.ContainsNodeKey(derpAdmitClientRequest.NodePublic),
|
||||
}
|
||||
return json.NewEncoder(writer).Encode(resp)
|
||||
}
|
||||
|
||||
// see https://github.com/tailscale/tailscale/blob/964282d34f06ecc06ce644769c66b0b31d118340/derp/derp_server.go#L1159, Derp use verifyClientsURL to verify whether a client is allowed to connect to the DERP server.
|
||||
// VerifyHandler see https://github.com/tailscale/tailscale/blob/964282d34f06ecc06ce644769c66b0b31d118340/derp/derp_server.go#L1159
|
||||
// DERP use verifyClientsURL to verify whether a client is allowed to connect to the DERP server.
|
||||
func (h *Headscale) VerifyHandler(
|
||||
writer http.ResponseWriter,
|
||||
req *http.Request,
|
||||
@@ -112,18 +117,12 @@ func (h *Headscale) VerifyHandler(
|
||||
return
|
||||
}
|
||||
|
||||
allow, err := h.derpRequestIsAllowed(req)
|
||||
err := h.handleVerifyRequest(req, writer)
|
||||
if err != nil {
|
||||
httpError(writer, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp := tailcfg.DERPAdmitClientResponse{
|
||||
Allow: allow,
|
||||
}
|
||||
|
||||
writer.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(writer).Encode(resp)
|
||||
}
|
||||
|
||||
// KeyHandler provides the Headscale pub key
|
||||
|
||||
Reference in New Issue
Block a user