mirror of
https://github.com/juanfont/headscale.git
synced 2024-12-26 17:57:46 +00:00
Merge branch 'main' into web-auth-flow-tests
This commit is contained in:
commit
58c8633cc1
@ -20,6 +20,8 @@ builds:
|
|||||||
- -mod=readonly
|
- -mod=readonly
|
||||||
ldflags:
|
ldflags:
|
||||||
- -s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=v{{.Version}}
|
- -s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=v{{.Version}}
|
||||||
|
tags:
|
||||||
|
- ts2019
|
||||||
|
|
||||||
- id: darwin-arm64
|
- id: darwin-arm64
|
||||||
main: ./cmd/headscale/headscale.go
|
main: ./cmd/headscale/headscale.go
|
||||||
@ -34,6 +36,8 @@ builds:
|
|||||||
- -mod=readonly
|
- -mod=readonly
|
||||||
ldflags:
|
ldflags:
|
||||||
- -s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=v{{.Version}}
|
- -s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=v{{.Version}}
|
||||||
|
tags:
|
||||||
|
- ts2019
|
||||||
|
|
||||||
- id: linux-amd64
|
- id: linux-amd64
|
||||||
mod_timestamp: "{{ .CommitTimestamp }}"
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
@ -46,6 +50,8 @@ builds:
|
|||||||
main: ./cmd/headscale/headscale.go
|
main: ./cmd/headscale/headscale.go
|
||||||
ldflags:
|
ldflags:
|
||||||
- -s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=v{{.Version}}
|
- -s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=v{{.Version}}
|
||||||
|
tags:
|
||||||
|
- ts2019
|
||||||
|
|
||||||
- id: linux-arm64
|
- id: linux-arm64
|
||||||
mod_timestamp: "{{ .CommitTimestamp }}"
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
@ -58,6 +64,8 @@ builds:
|
|||||||
main: ./cmd/headscale/headscale.go
|
main: ./cmd/headscale/headscale.go
|
||||||
ldflags:
|
ldflags:
|
||||||
- -s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=v{{.Version}}
|
- -s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=v{{.Version}}
|
||||||
|
tags:
|
||||||
|
- ts2019
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
- id: golang-cross
|
- id: golang-cross
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
- Remove `ip_prefix` configuration option and warning [#899](https://github.com/juanfont/headscale/pull/899)
|
- Remove `ip_prefix` configuration option and warning [#899](https://github.com/juanfont/headscale/pull/899)
|
||||||
- Add `dns_config.override_local_dns` option [#905](https://github.com/juanfont/headscale/pull/905)
|
- Add `dns_config.override_local_dns` option [#905](https://github.com/juanfont/headscale/pull/905)
|
||||||
- Fix some DNS config issues [#660](https://github.com/juanfont/headscale/issues/660)
|
- Fix some DNS config issues [#660](https://github.com/juanfont/headscale/issues/660)
|
||||||
|
- Make it possible to disable TS2019 with build flag [#928](https://github.com/juanfont/headscale/pull/928)
|
||||||
|
|
||||||
## 0.16.4 (2022-08-21)
|
## 0.16.4 (2022-08-21)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ RUN go mod download
|
|||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go install -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale
|
RUN CGO_ENABLED=0 GOOS=linux go install -tags ts2019 -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale
|
||||||
RUN strip /go/bin/headscale
|
RUN strip /go/bin/headscale
|
||||||
RUN test -e /go/bin/headscale
|
RUN test -e /go/bin/headscale
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ RUN go mod download
|
|||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go install -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale
|
RUN CGO_ENABLED=0 GOOS=linux go install -tags ts2019 -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale
|
||||||
RUN test -e /go/bin/headscale
|
RUN test -e /go/bin/headscale
|
||||||
|
|
||||||
# Debug image
|
# Debug image
|
||||||
|
14
Makefile
14
Makefile
@ -10,6 +10,8 @@ ifeq ($(filter $(GOOS), openbsd netbsd soloaris plan9), )
|
|||||||
else
|
else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
TAGS = -tags ts2019
|
||||||
|
|
||||||
# GO_SOURCES = $(wildcard *.go)
|
# GO_SOURCES = $(wildcard *.go)
|
||||||
# PROTO_SOURCES = $(wildcard **/*.proto)
|
# PROTO_SOURCES = $(wildcard **/*.proto)
|
||||||
GO_SOURCES = $(call rwildcard,,*.go)
|
GO_SOURCES = $(call rwildcard,,*.go)
|
||||||
@ -17,12 +19,12 @@ PROTO_SOURCES = $(call rwildcard,,*.proto)
|
|||||||
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
GOOS=$(GOOS) CGO_ENABLED=0 go build -trimpath $(pieflags) -mod=readonly -ldflags "-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$(version)" cmd/headscale/headscale.go
|
nix build
|
||||||
|
|
||||||
dev: lint test build
|
dev: lint test build
|
||||||
|
|
||||||
test:
|
test:
|
||||||
@go test -short -coverprofile=coverage.out ./...
|
@go test $(TAGS) -short -coverprofile=coverage.out ./...
|
||||||
|
|
||||||
test_integration: test_integration_cli test_integration_derp test_integration_oidc test_integration_v2_general
|
test_integration: test_integration_cli test_integration_derp test_integration_oidc test_integration_v2_general
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ test_integration_cli:
|
|||||||
-v ~/.cache/hs-integration-go:/go \
|
-v ~/.cache/hs-integration-go:/go \
|
||||||
-v $$PWD:$$PWD -w $$PWD \
|
-v $$PWD:$$PWD -w $$PWD \
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock golang:1 \
|
-v /var/run/docker.sock:/var/run/docker.sock golang:1 \
|
||||||
go test -failfast -timeout 30m -count=1 -run IntegrationCLI ./...
|
go test $(TAGS) -failfast -timeout 30m -count=1 -run IntegrationCLI ./...
|
||||||
|
|
||||||
test_integration_derp:
|
test_integration_derp:
|
||||||
docker network rm $$(docker network ls --filter name=headscale --quiet) || true
|
docker network rm $$(docker network ls --filter name=headscale --quiet) || true
|
||||||
@ -44,7 +46,7 @@ test_integration_derp:
|
|||||||
-v ~/.cache/hs-integration-go:/go \
|
-v ~/.cache/hs-integration-go:/go \
|
||||||
-v $$PWD:$$PWD -w $$PWD \
|
-v $$PWD:$$PWD -w $$PWD \
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock golang:1 \
|
-v /var/run/docker.sock:/var/run/docker.sock golang:1 \
|
||||||
go test -failfast -timeout 30m -count=1 -run IntegrationDERP ./...
|
go test $(TAGS) -failfast -timeout 30m -count=1 -run IntegrationDERP ./...
|
||||||
|
|
||||||
test_integration_oidc:
|
test_integration_oidc:
|
||||||
docker network rm $$(docker network ls --filter name=headscale --quiet) || true
|
docker network rm $$(docker network ls --filter name=headscale --quiet) || true
|
||||||
@ -54,7 +56,7 @@ test_integration_oidc:
|
|||||||
-v ~/.cache/hs-integration-go:/go \
|
-v ~/.cache/hs-integration-go:/go \
|
||||||
-v $$PWD:$$PWD -w $$PWD \
|
-v $$PWD:$$PWD -w $$PWD \
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock golang:1 \
|
-v /var/run/docker.sock:/var/run/docker.sock golang:1 \
|
||||||
go test -failfast -timeout 30m -count=1 -run IntegrationOIDC ./...
|
go test $(TAGS) -failfast -timeout 30m -count=1 -run IntegrationOIDC ./...
|
||||||
|
|
||||||
test_integration_v2_general:
|
test_integration_v2_general:
|
||||||
docker run \
|
docker run \
|
||||||
@ -64,7 +66,7 @@ test_integration_v2_general:
|
|||||||
-v $$PWD:$$PWD -w $$PWD/integration \
|
-v $$PWD:$$PWD -w $$PWD/integration \
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
golang:1 \
|
golang:1 \
|
||||||
go test ./... -timeout 60m -parallel 6
|
go test $(TAGS) -failfast ./... -timeout 60m -parallel 6
|
||||||
|
|
||||||
|
|
||||||
test_integration_v2_auth_web_flow:
|
test_integration_v2_auth_web_flow:
|
||||||
|
5
app.go
5
app.go
@ -454,9 +454,8 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *mux.Router {
|
|||||||
router.HandleFunc("/health", h.HealthHandler).Methods(http.MethodGet)
|
router.HandleFunc("/health", h.HealthHandler).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/key", h.KeyHandler).Methods(http.MethodGet)
|
router.HandleFunc("/key", h.KeyHandler).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/register/{nkey}", h.RegisterWebAPI).Methods(http.MethodGet)
|
router.HandleFunc("/register/{nkey}", h.RegisterWebAPI).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/machine/{mkey}/map", h.PollNetMapHandler).
|
h.addLegacyHandlers(router)
|
||||||
Methods(http.MethodPost)
|
|
||||||
router.HandleFunc("/machine/{mkey}", h.RegistrationHandler).Methods(http.MethodPost)
|
|
||||||
router.HandleFunc("/oidc/register/{nkey}", h.RegisterOIDC).Methods(http.MethodGet)
|
router.HandleFunc("/oidc/register/{nkey}", h.RegisterOIDC).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/oidc/callback", h.OIDCCallback).Methods(http.MethodGet)
|
router.HandleFunc("/oidc/callback", h.OIDCCallback).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/apple", h.AppleConfigMessage).Methods(http.MethodGet)
|
router.HandleFunc("/apple", h.AppleConfigMessage).Methods(http.MethodGet)
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
version = headscaleVersion;
|
version = headscaleVersion;
|
||||||
src = pkgs.lib.cleanSource self;
|
src = pkgs.lib.cleanSource self;
|
||||||
|
|
||||||
|
tags = ["ts2019"];
|
||||||
|
|
||||||
# Only run unit tests when testing a build
|
# Only run unit tests when testing a build
|
||||||
checkFlags = ["-short"];
|
checkFlags = ["-short"];
|
||||||
|
|
||||||
@ -135,7 +137,7 @@
|
|||||||
buildInputs = devDeps;
|
buildInputs = devDeps;
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
export GOFLAGS=-tags="integration,integration_general,integration_oidc,integration_cli,integration_derp"
|
export GOFLAGS=-tags="ts2019"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
15
handler_legacy.go
Normal file
15
handler_legacy.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//go:build ts2019
|
||||||
|
|
||||||
|
package headscale
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *Headscale) addLegacyHandlers(router *mux.Router) {
|
||||||
|
router.HandleFunc("/machine/{mkey}/map", h.PollNetMapHandler).
|
||||||
|
Methods(http.MethodPost)
|
||||||
|
router.HandleFunc("/machine/{mkey}", h.RegistrationHandler).Methods(http.MethodPost)
|
||||||
|
}
|
8
handler_placeholder.go
Normal file
8
handler_placeholder.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//go:build !ts2019
|
||||||
|
|
||||||
|
package headscale
|
||||||
|
|
||||||
|
import "github.com/gorilla/mux"
|
||||||
|
|
||||||
|
func (h *Headscale) addLegacyHandlers(router *mux.Router) {
|
||||||
|
}
|
@ -2,6 +2,7 @@ package headscale
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
_ "embed"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
textTemplate "text/template"
|
textTemplate "text/template"
|
||||||
@ -11,51 +12,18 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed templates/apple.html
|
||||||
|
var appleTemplate string
|
||||||
|
|
||||||
|
//go:embed templates/windows.html
|
||||||
|
var windowsTemplate string
|
||||||
|
|
||||||
// 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(
|
func (h *Headscale) WindowsConfigMessage(
|
||||||
writer http.ResponseWriter,
|
writer http.ResponseWriter,
|
||||||
req *http.Request,
|
req *http.Request,
|
||||||
) {
|
) {
|
||||||
winTemplate := template.Must(template.New("windows").Parse(`
|
winTemplate := template.Must(template.New("windows").Parse(windowsTemplate))
|
||||||
<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{}{
|
config := map[string]interface{}{
|
||||||
"URL": h.cfg.ServerURL,
|
"URL": h.cfg.ServerURL,
|
||||||
}
|
}
|
||||||
@ -136,55 +104,7 @@ func (h *Headscale) AppleConfigMessage(
|
|||||||
writer http.ResponseWriter,
|
writer http.ResponseWriter,
|
||||||
req *http.Request,
|
req *http.Request,
|
||||||
) {
|
) {
|
||||||
appleTemplate := template.Must(template.New("apple").Parse(`
|
appleTemplate := template.Must(template.New("apple").Parse(appleTemplate))
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
<h1>headscale</h1>
|
|
||||||
<h2>Apple configuration profiles</h2>
|
|
||||||
<p>
|
|
||||||
This page provides <a href="https://support.apple.com/guide/mdm/mdm-overview-mdmbf9e668/web">configuration profiles</a> for the official Tailscale clients for <a href="https://apps.apple.com/us/app/tailscale/id1470499037?ls=1">iOS</a> and <a href="https://apps.apple.com/ca/app/tailscale/id1475387142?mt=12">macOS</a>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The profiles will configure Tailscale.app to use <code>{{.URL}}</code> as its control server.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Caution</h3>
|
|
||||||
<p>You should always download and inspect the profile before installing it:</p>
|
|
||||||
<!--
|
|
||||||
<pre><code>curl {{.URL}}/apple/ios</code></pre>
|
|
||||||
-->
|
|
||||||
<pre><code>curl {{.URL}}/apple/macos</code></pre>
|
|
||||||
|
|
||||||
<h2>Profiles</h2>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<h3>iOS</h3>
|
|
||||||
<p>
|
|
||||||
<a href="/apple/ios" download="headscale_ios.mobileconfig">iOS profile</a>
|
|
||||||
</p>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<h3>macOS</h3>
|
|
||||||
<p>Headscale can be set to the default server by installing a Headscale configuration profile:</p>
|
|
||||||
<p>
|
|
||||||
<a href="/apple/macos" download="headscale_macos.mobileconfig">macOS profile</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li>Download the profile, then open it. When it has been opened, there should be a notification that a profile can be installed</li>
|
|
||||||
<li>Open System Preferences and go to "Profiles"</li>
|
|
||||||
<li>Find and install the Headscale profile</li>
|
|
||||||
<li>Restart Tailscale.app and log in</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<p>Or</p>
|
|
||||||
<p>Use your terminal to configure the default setting for Tailscale by issuing:</p>
|
|
||||||
<code>defaults write io.tailscale.ipn.macos ControlURL {{.URL}}</code>
|
|
||||||
|
|
||||||
<p>Restart Tailscale.app and log in.</p>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>`))
|
|
||||||
|
|
||||||
config := map[string]interface{}{
|
config := map[string]interface{}{
|
||||||
"URL": h.cfg.ServerURL,
|
"URL": h.cfg.ServerURL,
|
||||||
@ -282,24 +202,33 @@ func (h *Headscale) ApplePlatformConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
var payload bytes.Buffer
|
var payload bytes.Buffer
|
||||||
|
handleMacError := func(ierr error) {
|
||||||
|
log.Error().
|
||||||
|
Str("handler", "ApplePlatformConfig").
|
||||||
|
Err(ierr).
|
||||||
|
Msg("Could not render Apple macOS template")
|
||||||
|
|
||||||
|
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
|
writer.WriteHeader(http.StatusInternalServerError)
|
||||||
|
_, err := writer.Write([]byte("Could not render Apple macOS template"))
|
||||||
|
if err != nil {
|
||||||
|
log.Error().
|
||||||
|
Caller().
|
||||||
|
Err(err).
|
||||||
|
Msg("Failed to write response")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch platform {
|
switch platform {
|
||||||
case "macos":
|
case "macos-standlone":
|
||||||
if err := macosTemplate.Execute(&payload, platformConfig); err != nil {
|
if err := macosStandloneTemplate.Execute(&payload, platformConfig); err != nil {
|
||||||
log.Error().
|
handleMacError(err)
|
||||||
Str("handler", "ApplePlatformConfig").
|
|
||||||
Err(err).
|
|
||||||
Msg("Could not render Apple macOS template")
|
|
||||||
|
|
||||||
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
return
|
||||||
writer.WriteHeader(http.StatusInternalServerError)
|
}
|
||||||
_, err := writer.Write([]byte("Could not render Apple macOS template"))
|
case "macos-app-store":
|
||||||
if err != nil {
|
if err := macosAppStoreTemplate.Execute(&payload, platformConfig); err != nil {
|
||||||
log.Error().
|
handleMacError(err)
|
||||||
Caller().
|
|
||||||
Err(err).
|
|
||||||
Msg("Failed to write response")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -444,7 +373,7 @@ var iosTemplate = textTemplate.Must(textTemplate.New("iosTemplate").Parse(`
|
|||||||
</dict>
|
</dict>
|
||||||
`))
|
`))
|
||||||
|
|
||||||
var macosTemplate = template.Must(template.New("macosTemplate").Parse(`
|
var macosAppStoreTemplate = template.Must(template.New("macosTemplate").Parse(`
|
||||||
<dict>
|
<dict>
|
||||||
<key>PayloadType</key>
|
<key>PayloadType</key>
|
||||||
<string>io.tailscale.ipn.macos</string>
|
<string>io.tailscale.ipn.macos</string>
|
||||||
@ -456,7 +385,23 @@ var macosTemplate = template.Must(template.New("macosTemplate").Parse(`
|
|||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<key>PayloadEnabled</key>
|
<key>PayloadEnabled</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>ControlURL</key>
|
||||||
|
<string>{{.URL}}</string>
|
||||||
|
</dict>
|
||||||
|
`))
|
||||||
|
|
||||||
|
var macosStandloneTemplate = template.Must(template.New("macosStandloneTemplate").Parse(`
|
||||||
|
<dict>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>io.tailscale.ipn.macsys</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>{{.UUID}}</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.github.juanfont.headscale</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>PayloadEnabled</key>
|
||||||
|
<true/>
|
||||||
<key>ControlURL</key>
|
<key>ControlURL</key>
|
||||||
<string>{{.URL}}</string>
|
<string>{{.URL}}</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build ts2019
|
||||||
|
|
||||||
package headscale
|
package headscale
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build ts2019
|
||||||
|
|
||||||
package headscale
|
package headscale
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
102
templates/apple.html
Normal file
102
templates/apple.html
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>headscale</h1>
|
||||||
|
<h2>Apple configuration profiles</h2>
|
||||||
|
<p>
|
||||||
|
This page provides
|
||||||
|
<a href="https://support.apple.com/guide/mdm/mdm-overview-mdmbf9e668/web">
|
||||||
|
configuration profiles
|
||||||
|
</a>
|
||||||
|
for the official Tailscale clients for
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://apps.apple.com/us/app/tailscale/id1470499037?ls=1"
|
||||||
|
>iOS</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://apps.apple.com/ca/app/tailscale/id1475387142?mt=12"
|
||||||
|
>macOS - AppStore Client</a
|
||||||
|
>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://pkgs.tailscale.com/stable/#macos"
|
||||||
|
>macOS - Standalone Client</a
|
||||||
|
>.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
The profiles will configure Tailscale.app to use <code>{{.URL}}</code> as
|
||||||
|
its control server.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Caution</h3>
|
||||||
|
<p>
|
||||||
|
You should always download and inspect the profile before installing it:
|
||||||
|
</p>
|
||||||
|
<!--
|
||||||
|
<pre><code>curl {{.URL}}/apple/ios</code></pre>
|
||||||
|
-->
|
||||||
|
<pre><code>curl {{.URL}}/apple/macos</code></pre>
|
||||||
|
|
||||||
|
<h2>Profiles</h2>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<h3>iOS</h3>
|
||||||
|
<p>
|
||||||
|
<a href="/apple/ios" download="headscale_ios.mobileconfig">iOS profile</a>
|
||||||
|
</p>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<h3>macOS</h3>
|
||||||
|
<p>
|
||||||
|
Headscale can be set to the default server by installing a Headscale
|
||||||
|
configuration profile:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="/apple/macos-app-store" download="headscale_macos.mobileconfig"
|
||||||
|
>macOS AppStore profile</a
|
||||||
|
>
|
||||||
|
<a href="/apple/macos-standalone" download="headscale_macos.mobileconfig"
|
||||||
|
>macOS Standalone profile</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
Download the profile, then open it. When it has been opened, there
|
||||||
|
should be a notification that a profile can be installed
|
||||||
|
</li>
|
||||||
|
<li>Open System Preferences and go to "Profiles"</li>
|
||||||
|
<li>Find and install the Headscale profile</li>
|
||||||
|
<li>Restart Tailscale.app and log in</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>Or</p>
|
||||||
|
<p>
|
||||||
|
Use your terminal to configure the default setting for Tailscale by
|
||||||
|
issuing:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
for app store client:
|
||||||
|
<code>defaults write io.tailscale.ipn.macos ControlURL {{.URL}}</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
for standlone client:
|
||||||
|
<code>defaults write io.tailscale.ipn.macsys ControlURL {{.URL}}</code>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Restart Tailscale.app and log in.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
64
templates/windows.html
Normal file
64
templates/windows.html
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>headscale</h1>
|
||||||
|
<h2>Windows registry configuration</h2>
|
||||||
|
<p>
|
||||||
|
This page provides Windows registry information for the official Windows
|
||||||
|
Tailscale client.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p></p>
|
||||||
|
<p>
|
||||||
|
The registry file will configure Tailscale to use <code>{{.URL}}</code> as
|
||||||
|
its control server.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p></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>
|
||||||
|
|
||||||
|
<p></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
2
utils.go
2
utils.go
@ -347,7 +347,7 @@ func IsStringInSlice(slice []string, str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AbsolutePathFromConfigPath(path string) string {
|
func AbsolutePathFromConfigPath(path string) string {
|
||||||
// If a relative path is provided, prefix it with the the directory where
|
// If a relative path is provided, prefix it with the directory where
|
||||||
// the config file was found.
|
// the config file was found.
|
||||||
if (path != "") && !strings.HasPrefix(path, string(os.PathSeparator)) {
|
if (path != "") && !strings.HasPrefix(path, string(os.PathSeparator)) {
|
||||||
dir, _ := filepath.Split(viper.ConfigFileUsed())
|
dir, _ := filepath.Split(viper.ConfigFileUsed())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user