mirror of
https://github.com/juanfont/headscale.git
synced 2025-08-11 18:17:40 +00: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:
@@ -2,9 +2,11 @@ package server
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
@@ -28,7 +30,10 @@ import (
|
||||
// server that the DERP HTTP client does not want the HTTP 101 response
|
||||
// headers and it will begin writing & reading the DERP protocol immediately
|
||||
// following its HTTP request.
|
||||
const fastStartHeader = "Derp-Fast-Start"
|
||||
const (
|
||||
fastStartHeader = "Derp-Fast-Start"
|
||||
DerpVerifyScheme = "headscale-derp-verify"
|
||||
)
|
||||
|
||||
type DERPServer struct {
|
||||
serverURL string
|
||||
@@ -45,6 +50,11 @@ func NewDERPServer(
|
||||
log.Trace().Caller().Msg("Creating new embedded DERP server")
|
||||
server := derp.NewServer(derpKey, util.TSLogfWrapper()) // nolint // zerolinter complains
|
||||
|
||||
if cfg.ServerVerifyClients {
|
||||
server.SetVerifyClientURL(DerpVerifyScheme + "://verify")
|
||||
server.SetVerifyClientURLFailOpen(false)
|
||||
}
|
||||
|
||||
return &DERPServer{
|
||||
serverURL: serverURL,
|
||||
key: derpKey,
|
||||
@@ -360,3 +370,29 @@ func serverSTUNListener(ctx context.Context, packetConn *net.UDPConn) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewDERPVerifyTransport(handleVerifyRequest func(*http.Request, io.Writer) error) *DERPVerifyTransport {
|
||||
return &DERPVerifyTransport{
|
||||
handleVerifyRequest: handleVerifyRequest,
|
||||
}
|
||||
}
|
||||
|
||||
type DERPVerifyTransport struct {
|
||||
handleVerifyRequest func(*http.Request, io.Writer) error
|
||||
}
|
||||
|
||||
func (t *DERPVerifyTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := t.handleVerifyRequest(req, buf); err != nil {
|
||||
log.Error().Caller().Err(err).Msg("Failed to handle client verify request: ")
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(buf),
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user