Enable remote gRPC and HTTP API

This commit enables the existing gRPC and HTTP API from remote locations
as long as the user can provide a valid API key. This allows users to
control their headscale with the CLI from a workstation. 🎉
This commit is contained in:
Kristoffer Dalby 2022-01-25 22:11:15 +00:00
parent a6e22387fd
commit 00c69ce50c

70
app.go
View file

@ -339,26 +339,26 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context,
) )
} }
// TODO(kradalby): Implement API key backend: valid, err := h.ValidateAPIKey(strings.TrimPrefix(token, AuthPrefix))
// - Table in the DB if err != nil {
// - Key name log.Error().
// - Encrypted Caller().
// - Expiry Err(err).
// Str("client_address", client.Addr.String()).
// Currently all other than localhost traffic is unauthorized, this is intentional to allow Msg("failed to validate token")
// us to make use of gRPC for our CLI, but not having to implement any of the remote capabilities
// and API key auth
return ctx, status.Error(
codes.Unauthenticated,
"Authentication is not implemented yet",
)
// if strings.TrimPrefix(token, AUTH_PREFIX) != a.Token { return ctx, status.Error(codes.Internal, "failed to validate token")
// log.Error().Caller().Str("client_address", p.Addr.String()).Msg("invalid token") }
// return ctx, status.Error(codes.Unauthenticated, "invalid token")
// }
// return handler(ctx, req) if !valid {
log.Info().
Str("client_address", client.Addr.String()).
Msg("invalid token")
return ctx, status.Error(codes.Unauthenticated, "invalid token")
}
return handler(ctx, req)
} }
func (h *Headscale) httpAuthenticationMiddleware(ctx *gin.Context) { func (h *Headscale) httpAuthenticationMiddleware(ctx *gin.Context) {
@ -381,19 +381,30 @@ func (h *Headscale) httpAuthenticationMiddleware(ctx *gin.Context) {
ctx.AbortWithStatus(http.StatusUnauthorized) ctx.AbortWithStatus(http.StatusUnauthorized)
// TODO(kradalby): Implement API key backend valid, err := h.ValidateAPIKey(strings.TrimPrefix(authHeader, AuthPrefix))
// Currently all traffic is unauthorized, this is intentional to allow if err != nil {
// us to make use of gRPC for our CLI, but not having to implement any of the remote capabilities log.Error().
// and API key auth Caller().
// Err(err).
// if strings.TrimPrefix(authHeader, AUTH_PREFIX) != a.Token { Str("client_address", ctx.ClientIP()).
// log.Error().Caller().Str("client_address", c.ClientIP()).Msg("invalid token") Msg("failed to validate token")
// c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error", "unauthorized"})
// return ctx.AbortWithStatus(http.StatusInternalServerError)
// }
// c.Next() return
}
if !valid {
log.Info().
Str("client_address", ctx.ClientIP()).
Msg("invalid token")
ctx.AbortWithStatus(http.StatusUnauthorized)
return
}
ctx.Next()
} }
// ensureUnixSocketIsAbsent will check if the given path for headscales unix socket is clear // ensureUnixSocketIsAbsent will check if the given path for headscales unix socket is clear
@ -630,6 +641,7 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) {
// service, which can be configured to run on any other port. // service, which can be configured to run on any other port.
go func() { go func() {
log.Fatal(). log.Fatal().
Caller().
Err(http.ListenAndServe(h.cfg.TLSLetsEncryptListen, certManager.HTTPHandler(http.HandlerFunc(h.redirect)))). Err(http.ListenAndServe(h.cfg.TLSLetsEncryptListen, certManager.HTTPHandler(http.HandlerFunc(h.redirect)))).
Msg("failed to set up a HTTP server") Msg("failed to set up a HTTP server")
}() }()