From b342cf0240eac731db756399130d62382ca7ad28 Mon Sep 17 00:00:00 2001 From: e-zk Date: Fri, 4 Mar 2022 17:56:54 +1000 Subject: [PATCH 1/5] feat(windows): cleanup /apple endpoint - rename the gin function to AppleConfigMessage - use
 +  for code blocks
- add headscale heading
- reword some sections
---
 app.go                |  2 +-
 apple_mobileconfig.go | 17 +++++++++--------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/app.go b/app.go
index 763fdfe8..4c1d2015 100644
--- a/app.go
+++ b/app.go
@@ -456,7 +456,7 @@ 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("/swagger", SwaggerUI)
 	router.GET("/swagger/v1/openapiv2.json", SwaggerAPIv1)
diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go
index 69f61a63..137276d4 100644
--- a/apple_mobileconfig.go
+++ b/apple_mobileconfig.go
@@ -11,26 +11,27 @@ 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) {
+// 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

From 12a50ac8ac79d05a5f896633b4809fea32034810 Mon Sep 17 00:00:00 2001 From: e-zk Date: Fri, 4 Mar 2022 19:37:55 +1000 Subject: [PATCH 2/5] feat(windows): add /windows endpoint for Windows configuration - registry file /windows/tailscale.reg is generated, filling in the associated control server URL - also includes CLI instructions - fix /apple incorrect template: 'Url' is supposed to be '.URL' --- app.go | 2 + apple_mobileconfig.go | 106 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/app.go b/app.go index 4c1d2015..682d8e49 100644 --- a/app.go +++ b/app.go @@ -458,6 +458,8 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *gin.Engine { router.GET("/oidc/callback", h.OIDCCallback) 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/apple_mobileconfig.go index 137276d4..86273e78 100644 --- a/apple_mobileconfig.go +++ b/apple_mobileconfig.go @@ -11,6 +11,100 @@ import ( "github.com/rs/zerolog/log" ) +// 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 the .reg file +// pre-configured to 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) { @@ -193,6 +287,10 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) { ) } +type WindowsRegistryConfig struct { + URL string +} + type AppleMobileConfig struct { UUID uuid.UUID URL string @@ -204,6 +302,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(` From f9e0c13890891b3696b5587824c96077ff65f717 Mon Sep 17 00:00:00 2001 From: e-zk Date: Fri, 4 Mar 2022 19:52:42 +1000 Subject: [PATCH 3/5] docs: update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) 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 From d69dada8ff7be8c2e13cd4e6c67e97481b2810d7 Mon Sep 17 00:00:00 2001 From: e-zk Date: Fri, 4 Mar 2022 20:03:49 +1000 Subject: [PATCH 4/5] feat(windows): rename apple_mobileconfig.go => platform_config.go rename apple_mobileconfig.go to platform_config.go since the file includes configuration info for multiple platforms now. --- apple_mobileconfig.go => platform_config.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apple_mobileconfig.go => platform_config.go (100%) diff --git a/apple_mobileconfig.go b/platform_config.go similarity index 100% rename from apple_mobileconfig.go rename to platform_config.go From 575f33d18326df526214f58949a5834738b0dbaa Mon Sep 17 00:00:00 2001 From: e-zk Date: Fri, 4 Mar 2022 20:35:09 +1000 Subject: [PATCH 5/5] docs: fix comments to comply with golangci-lint --- platform_config.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/platform_config.go b/platform_config.go index 86273e78..d36a37ce 100644 --- a/platform_config.go +++ b/platform_config.go @@ -11,8 +11,7 @@ import ( "github.com/rs/zerolog/log" ) -// WindowsConfigMessage shows a simple message in the browser for how to -// configure the Windows tailscale client. +// 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(` @@ -76,8 +75,7 @@ REG ADD "HKLM\Software\Tailscale IPN" /v LoginURL /t REG_SZ /d "{{.URL}}" ctx.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes()) } -// WindowsRegConfig generates and serves the .reg file -// pre-configured to the headscale server address +// 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, @@ -105,8 +103,7 @@ func (h *Headscale) WindowsRegConfig(ctx *gin.Context) { ) } -// AppleConfigMessage shows a simple message in the browser to point the user -// to the iOS/MacOS profile and instructions for how to install it +// 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(`