mirror of
https://github.com/juanfont/headscale.git
synced 2025-03-25 15:04:19 -04:00
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`
This commit is contained in:
parent
55980d6427
commit
1541fa4d8a
@ -87,11 +87,8 @@ derp:
|
|||||||
region_code: "headscale"
|
region_code: "headscale"
|
||||||
region_name: "Headscale Embedded DERP"
|
region_name: "Headscale Embedded DERP"
|
||||||
|
|
||||||
# If non-empty, an admission controller URL for permitting client connections
|
# Verify clients to this DERP server using the Headscale node list
|
||||||
verify_client_url: "http://127.0.0.1:8080/verify"
|
verify_clients: true
|
||||||
|
|
||||||
# Whether derp fail open if verify_client_url is unreachable
|
|
||||||
verify_client_url_fail_open: false
|
|
||||||
|
|
||||||
# Listens over UDP at the configured address for STUN connections - to help with NAT traversal.
|
# Listens over UDP at the configured address for STUN connections - to help with NAT traversal.
|
||||||
# When the embedded DERP server is enabled stun_listen_addr MUST be defined.
|
# When the embedded DERP server is enabled stun_listen_addr MUST be defined.
|
||||||
|
@ -221,6 +221,7 @@ func NewHeadscale(cfg *types.Config) (*Headscale, error) {
|
|||||||
|
|
||||||
embeddedDERPServer, err := derpServer.NewDERPServer(
|
embeddedDERPServer, err := derpServer.NewDERPServer(
|
||||||
cfg.ServerURL,
|
cfg.ServerURL,
|
||||||
|
app.VerifyHandler,
|
||||||
key.NodePrivate(*derpServerKey),
|
key.NodePrivate(*derpServerKey),
|
||||||
&cfg.DERP,
|
&cfg.DERP,
|
||||||
)
|
)
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -39,14 +40,20 @@ type DERPServer struct {
|
|||||||
|
|
||||||
func NewDERPServer(
|
func NewDERPServer(
|
||||||
serverURL string,
|
serverURL string,
|
||||||
|
verifyHandler func(writer http.ResponseWriter, req *http.Request),
|
||||||
derpKey key.NodePrivate,
|
derpKey key.NodePrivate,
|
||||||
cfg *types.DERPConfig,
|
cfg *types.DERPConfig,
|
||||||
) (*DERPServer, error) {
|
) (*DERPServer, error) {
|
||||||
log.Trace().Caller().Msg("Creating new embedded DERP server")
|
log.Trace().Caller().Msg("Creating new embedded DERP server")
|
||||||
server := derp.NewServer(derpKey, util.TSLogfWrapper()) // nolint // zerolinter complains
|
server := derp.NewServer(derpKey, util.TSLogfWrapper()) // nolint // zerolinter complains
|
||||||
if cfg.ServerVerifyClientURL != "" {
|
|
||||||
server.SetVerifyClientURL(cfg.ServerVerifyClientURL)
|
if cfg.ServerVerifyClients {
|
||||||
server.SetVerifyClientURLFailOpen(cfg.ServerVerifyFailOpen)
|
t := http.DefaultTransport.(*http.Transport)
|
||||||
|
t.RegisterProtocol("headscale", &HeadscaleTransport{
|
||||||
|
verifyHandler: verifyHandler,
|
||||||
|
})
|
||||||
|
server.SetVerifyClientURL("headscale://verify")
|
||||||
|
server.SetVerifyClientURLFailOpen(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &DERPServer{
|
return &DERPServer{
|
||||||
@ -364,3 +371,14 @@ func serverSTUNListener(ctx context.Context, packetConn *net.UDPConn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HeadscaleTransport struct {
|
||||||
|
verifyHandler func(writer http.ResponseWriter, req *http.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HeadscaleTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
t.verifyHandler(recorder, req)
|
||||||
|
resp := recorder.Result()
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
@ -185,8 +185,7 @@ type DERPConfig struct {
|
|||||||
ServerRegionCode string
|
ServerRegionCode string
|
||||||
ServerRegionName string
|
ServerRegionName string
|
||||||
ServerPrivateKeyPath string
|
ServerPrivateKeyPath string
|
||||||
ServerVerifyClientURL string
|
ServerVerifyClients bool
|
||||||
ServerVerifyFailOpen bool
|
|
||||||
STUNAddr string
|
STUNAddr string
|
||||||
URLs []url.URL
|
URLs []url.URL
|
||||||
Paths []string
|
Paths []string
|
||||||
@ -433,8 +432,7 @@ func derpConfig() DERPConfig {
|
|||||||
serverRegionID := viper.GetInt("derp.server.region_id")
|
serverRegionID := viper.GetInt("derp.server.region_id")
|
||||||
serverRegionCode := viper.GetString("derp.server.region_code")
|
serverRegionCode := viper.GetString("derp.server.region_code")
|
||||||
serverRegionName := viper.GetString("derp.server.region_name")
|
serverRegionName := viper.GetString("derp.server.region_name")
|
||||||
serverVerifyClientURL := viper.GetString("derp.server.verify_client_url")
|
serverVerifyClients := viper.GetBool("derp.server.verify_clients")
|
||||||
serverVerifyFailOpen := viper.GetBool("derp.server.verify_client_url_fail_open")
|
|
||||||
stunAddr := viper.GetString("derp.server.stun_listen_addr")
|
stunAddr := viper.GetString("derp.server.stun_listen_addr")
|
||||||
privateKeyPath := util.AbsolutePathFromConfigPath(
|
privateKeyPath := util.AbsolutePathFromConfigPath(
|
||||||
viper.GetString("derp.server.private_key_path"),
|
viper.GetString("derp.server.private_key_path"),
|
||||||
@ -479,8 +477,7 @@ func derpConfig() DERPConfig {
|
|||||||
ServerRegionID: serverRegionID,
|
ServerRegionID: serverRegionID,
|
||||||
ServerRegionCode: serverRegionCode,
|
ServerRegionCode: serverRegionCode,
|
||||||
ServerRegionName: serverRegionName,
|
ServerRegionName: serverRegionName,
|
||||||
ServerVerifyClientURL: serverVerifyClientURL,
|
ServerVerifyClients: serverVerifyClients,
|
||||||
ServerVerifyFailOpen: serverVerifyFailOpen,
|
|
||||||
ServerPrivateKeyPath: privateKeyPath,
|
ServerPrivateKeyPath: privateKeyPath,
|
||||||
STUNAddr: stunAddr,
|
STUNAddr: stunAddr,
|
||||||
URLs: urls,
|
URLs: urls,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user