diff --git a/CHANGELOG.md b/CHANGELOG.md index 1186bad8..dc34ab99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Add support for writing ACL files with YAML [#359](https://github.com/juanfont/headscale/pull/359) - Users can now use emails in ACL's groups [#372](https://github.com/juanfont/headscale/issues/372) - Add shorthand aliases for commands and subcommands [#376](https://github.com/juanfont/headscale/pull/376) +- Add `/windows` endpoint for Windows configuration instructions + registry file download [#392](https://github.com/juanfont/headscale/pull/392) ### Changes diff --git a/app.go b/app.go index 763fdfe8..682d8e49 100644 --- a/app.go +++ b/app.go @@ -456,8 +456,10 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *gin.Engine { router.POST("/machine/:id", h.RegistrationHandler) router.GET("/oidc/register/:mkey", h.RegisterOIDC) router.GET("/oidc/callback", h.OIDCCallback) - router.GET("/apple", h.AppleMobileConfig) + router.GET("/apple", h.AppleConfigMessage) router.GET("/apple/:platform", h.ApplePlatformConfig) + router.GET("/windows", h.WindowsConfigMessage) + router.GET("/windows/tailscale.reg", h.WindowsRegConfig) router.GET("/swagger", SwaggerUI) router.GET("/swagger/v1/openapiv2.json", SwaggerAPIv1) diff --git a/apple_mobileconfig.go b/platform_config.go similarity index 63% rename from apple_mobileconfig.go rename to platform_config.go index 69f61a63..d36a37ce 100644 --- a/apple_mobileconfig.go +++ b/platform_config.go @@ -11,26 +11,118 @@ import ( "github.com/rs/zerolog/log" ) -// AppleMobileConfig shows a simple message in the browser to point to the CLI -// Listens in /register. -func (h *Headscale) AppleMobileConfig(ctx *gin.Context) { +// WindowsConfigMessage shows a simple message in the browser for how to configure the Windows Tailscale client. +func (h *Headscale) WindowsConfigMessage(ctx *gin.Context) { + winTemplate := template.Must(template.New("windows").Parse(` + + +

headscale

+

Windows registry configuration

+

+ This page provides Windows registry information for the official Windows Tailscale client. +

+

+ The registry file will configure Tailscale to use {{.URL}} as its control server. +

+

Caution

+

You should always download and inspect the registry file before installing it:

+
curl {{.URL}}/windows/tailscale.reg
+ +

Installation

+

Headscale can be set to the default server by running the registry file:

+ +

+ Windows registry file +

+ +
    +
  1. Download the registry file, then run it
  2. +
  3. Follow the prompts
  4. +
  5. Install and run the official windows Tailscale client
  6. +
  7. When the installation has finished, start Tailscale, and log in by clicking the icon in the system tray
  8. +
+

Or

+

Open command prompt with Administrator rights. Issue the following commands to add the required registry entries:

+
+REG ADD "HKLM\Software\Tailscale IPN" /v UnattendedMode /t REG_SZ /d always
+REG ADD "HKLM\Software\Tailscale IPN" /v LoginURL /t REG_SZ /d "{{.URL}}"
+

+ Restart Tailscale and log in. +

+ + +`)) + + config := map[string]interface{}{ + "URL": h.cfg.ServerURL, + } + + var payload bytes.Buffer + if err := winTemplate.Execute(&payload, config); err != nil { + log.Error(). + Str("handler", "WindowsRegConfig"). + Err(err). + Msg("Could not render Windows index template") + ctx.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Could not render Windows index template"), + ) + + return + } + + ctx.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes()) +} + +// WindowsRegConfig generates and serves a .reg file configured with the Headscale server address. +func (h *Headscale) WindowsRegConfig(ctx *gin.Context) { + config := WindowsRegistryConfig{ + URL: h.cfg.ServerURL, + } + + var content bytes.Buffer + if err := windowsRegTemplate.Execute(&content, config); err != nil { + log.Error(). + Str("handler", "WindowsRegConfig"). + Err(err). + Msg("Could not render Apple macOS template") + ctx.Data( + http.StatusInternalServerError, + "text/html; charset=utf-8", + []byte("Could not render Windows registry template"), + ) + + return + } + + ctx.Data( + http.StatusOK, + "text/x-ms-regedit; charset=utf-8", + content.Bytes(), + ) +} + +// AppleConfigMessage shows a simple message in the browser to point the user to the iOS/MacOS profile and instructions for how to install it. +func (h *Headscale) AppleConfigMessage(ctx *gin.Context) { appleTemplate := template.Must(template.New("apple").Parse(` -

Apple configuration profiles

+

headscale

+

Apple configuration profiles

This page provides configuration profiles for the official Tailscale clients for iOS and macOS.

- The profiles will configure Tailscale.app to use {{.Url}} as its control server. + The profiles will configure Tailscale.app to use {{.URL}} as its control server.

Caution

-

You should always inspect the profile before installing it:

+

You should always download and inspect the profile before installing it:

-

curl {{.Url}}/apple/macos

+
curl {{.URL}}/apple/macos

Profiles

@@ -192,6 +284,10 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) { ) } +type WindowsRegistryConfig struct { + URL string +} + type AppleMobileConfig struct { UUID uuid.UUID URL string @@ -203,6 +299,14 @@ type AppleMobilePlatformConfig struct { URL string } +var windowsRegTemplate = textTemplate.Must( + textTemplate.New("windowsconfig").Parse(`Windows Registry Editor Version 5.00 + +[HKEY_LOCAL_MACHINE\SOFTWARE\Tailscale IPN] +"UnattendedMode"="always" +"LoginURL"="{{.URL}}" +`)) + var commonTemplate = textTemplate.Must( textTemplate.New("mobileconfig").Parse(`