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/Dockerfile b/Dockerfile index 86f5bd4d..3ab9c1d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Builder image -FROM docker.io/golang:1.17.7-bullseye AS build +FROM docker.io/golang:1.17.8-bullseye AS build ENV GOPATH /go WORKDIR /go/src/headscale diff --git a/Dockerfile.alpine b/Dockerfile.alpine index af884344..1f0d6353 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,5 +1,5 @@ # Builder image -FROM docker.io/golang:1.17.7-alpine AS build +FROM docker.io/golang:1.17.8-alpine AS build ENV GOPATH /go WORKDIR /go/src/headscale diff --git a/Dockerfile.debug b/Dockerfile.debug index 38385cef..e73c0647 100644 --- a/Dockerfile.debug +++ b/Dockerfile.debug @@ -1,5 +1,5 @@ # Builder image -FROM docker.io/golang:1.17.7-bullseye AS build +FROM docker.io/golang:1.17.8-bullseye AS build ENV GOPATH /go WORKDIR /go/src/headscale diff --git a/README.md b/README.md index d9d050f6..1b97b1aa 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,13 @@ make build Alessandro (Ale) Segala + + + e-zk/ +
+ e-zk +
+ unreality/ @@ -206,10 +213,10 @@ make build - - e-zk/ + + Nico/
- e-zk + Nico
@@ -226,6 +233,8 @@ make build Aaron Bieber + + Fernando @@ -233,8 +242,6 @@ make build Fernando De Lucchi - - Hoàng @@ -270,6 +277,8 @@ make build Silver Bullet + + Stefan @@ -277,13 +286,11 @@ make build Stefan Majer - - - - fincac/ + + lachy2849/
- fincac + lachy2849
@@ -314,6 +321,8 @@ make build Arthur Woimbée + + Bryan @@ -321,8 +330,6 @@ make build Bryan Stenson - - Felix @@ -358,6 +365,8 @@ make build Jim Tittsler + + Pierre @@ -365,8 +374,6 @@ make build Pierre Carru - - rcursaru/ @@ -402,6 +409,8 @@ make build Teteros + + The @@ -409,8 +418,6 @@ make build The Gitter Badger - - Tianon @@ -446,6 +453,8 @@ make build derelm + + ignoramous/ @@ -453,8 +462,6 @@ make build ignoramous - - lion24/ 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/config-example.yaml b/config-example.yaml index c28b6089..a8c3f289 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -123,7 +123,7 @@ tls_client_auth_mode: relaxed tls_letsencrypt_cache_dir: /var/lib/headscale/cache # Type of ACME challenge to use, currently supported types: -# HTTP-01 or TLS_ALPN-01 +# HTTP-01 or TLS-ALPN-01 # See [docs/tls.md](docs/tls.md) for more information tls_letsencrypt_challenge_type: HTTP-01 # When HTTP-01 challenge is chosen, letsencrypt must set up a 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(`