mirror of
https://github.com/juanfont/headscale.git
synced 2024-11-29 18:33:05 +00:00
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'
This commit is contained in:
parent
b342cf0240
commit
12a50ac8ac
2 changed files with 108 additions and 0 deletions
2
app.go
2
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)
|
||||
|
||||
|
|
|
@ -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(`
|
||||
<html>
|
||||
<body>
|
||||
<h1>headscale</h1>
|
||||
<h2>Windows registry configuration</h2>
|
||||
<p>
|
||||
This page provides Windows registry information for the official Windows Tailscale client.
|
||||
<p>
|
||||
<p>
|
||||
The registry file will configure Tailscale to use <code>{{.URL}}</code> as its control server.
|
||||
<p>
|
||||
<h3>Caution</h3>
|
||||
<p>You should always download and inspect the registry file before installing it:</p>
|
||||
<pre><code>curl {{.URL}}/windows/tailscale.reg</code></pre>
|
||||
|
||||
<h2>Installation</h2>
|
||||
<p>Headscale can be set to the default server by running the registry file:</p>
|
||||
|
||||
<p>
|
||||
<a href="/windows/tailscale.reg" download="tailscale.reg">Windows registry file</a>
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>Download the registry file, then run it</li>
|
||||
<li>Follow the prompts</li>
|
||||
<li>Install and run the official windows Tailscale client</li>
|
||||
<li>When the installation has finished, start Tailscale, and log in by clicking the icon in the system tray</li>
|
||||
</ol>
|
||||
<p>Or</p>
|
||||
<p>Open command prompt with Administrator rights. Issue the following commands to add the required registry entries:</p>
|
||||
<pre>
|
||||
<code>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}}"</code></pre>
|
||||
<p>
|
||||
Restart Tailscale and log in.
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
`))
|
||||
|
||||
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(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
|
|
Loading…
Reference in a new issue