Merge branch 'main' into unstable-integration-tests

This commit is contained in:
Juan Font 2022-03-20 12:34:04 +01:00 committed by GitHub
commit 94d910557f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 55 additions and 40 deletions

View file

@ -31,7 +31,7 @@ jobs:
if: steps.changed-files.outputs.any_changed == 'true' if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: "1.17.7" go-version: "1.18.0"
- name: Install dependencies - name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true' if: steps.changed-files.outputs.any_changed == 'true'

View file

@ -18,7 +18,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: 1.17.7 go-version: 1.18.0
- name: Install dependencies - name: Install dependencies
run: | run: |

View file

@ -25,7 +25,7 @@ jobs:
if: steps.changed-files.outputs.any_changed == 'true' if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: "1.17.7" go-version: "1.18.0"
- name: Run Integration tests - name: Run Integration tests
if: steps.changed-files.outputs.any_changed == 'true' if: steps.changed-files.outputs.any_changed == 'true'

View file

@ -25,7 +25,7 @@ jobs:
if: steps.changed-files.outputs.any_changed == 'true' if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: "1.17.7" go-version: "1.18.0"
- name: Install dependencies - name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true' if: steps.changed-files.outputs.any_changed == 'true'

View file

@ -29,6 +29,7 @@
- Fix a limitation in the ACLs that prevented users to write rules with `*` as source [#374](https://github.com/juanfont/headscale/issues/374) - Fix a limitation in the ACLs that prevented users to write rules with `*` as source [#374](https://github.com/juanfont/headscale/issues/374)
- Reduce the overhead of marshal/unmarshal for Hostinfo, routes and endpoints by using specific types in Machine [#371](https://github.com/juanfont/headscale/pull/371) - Reduce the overhead of marshal/unmarshal for Hostinfo, routes and endpoints by using specific types in Machine [#371](https://github.com/juanfont/headscale/pull/371)
- Apply normalization function to FQDN on hostnames when hosts registers and retrieve informations [#363](https://github.com/juanfont/headscale/issues/363) - Apply normalization function to FQDN on hostnames when hosts registers and retrieve informations [#363](https://github.com/juanfont/headscale/issues/363)
- Fix a bug that prevented the use of `tailscale logout` with OIDC [#508](https://github.com/juanfont/headscale/issues/508)
## 0.14.0 (2022-02-24) ## 0.14.0 (2022-02-24)

View file

@ -1,5 +1,5 @@
# Builder image # Builder image
FROM docker.io/golang:1.17.8-bullseye AS build FROM docker.io/golang:1.18.0-bullseye AS build
ENV GOPATH /go ENV GOPATH /go
WORKDIR /go/src/headscale WORKDIR /go/src/headscale

View file

@ -1,5 +1,5 @@
# Builder image # Builder image
FROM docker.io/golang:1.17.8-alpine AS build FROM docker.io/golang:1.18.0-alpine AS build
ENV GOPATH /go ENV GOPATH /go
WORKDIR /go/src/headscale WORKDIR /go/src/headscale

View file

@ -1,5 +1,5 @@
# Builder image # Builder image
FROM docker.io/golang:1.17.8-bullseye AS build FROM docker.io/golang:1.18.0-bullseye AS build
ENV GOPATH /go ENV GOPATH /go
WORKDIR /go/src/headscale WORKDIR /go/src/headscale

23
app.go
View file

@ -47,6 +47,14 @@ import (
"tailscale.com/types/key" "tailscale.com/types/key"
) )
const (
errSTUNAddressNotSet = Error("STUN address not set")
errUnsupportedDatabase = Error("unsupported DB")
errUnsupportedLetsEncryptChallengeType = Error(
"unknown value for Lets Encrypt challenge type",
)
)
const ( const (
AuthPrefix = "Bearer " AuthPrefix = "Bearer "
Postgres = "postgres" Postgres = "postgres"
@ -58,11 +66,6 @@ const (
registerCacheExpiration = time.Minute * 15 registerCacheExpiration = time.Minute * 15
registerCacheCleanup = time.Minute * 20 registerCacheCleanup = time.Minute * 20
errUnsupportedDatabase = Error("unsupported DB")
errUnsupportedLetsEncryptChallengeType = Error(
"unknown value for Lets Encrypt challenge type",
)
DisabledClientAuth = "disabled" DisabledClientAuth = "disabled"
RelaxedClientAuth = "relaxed" RelaxedClientAuth = "relaxed"
EnforcedClientAuth = "enforced" EnforcedClientAuth = "enforced"
@ -124,7 +127,6 @@ type DERPConfig struct {
ServerRegionID int ServerRegionID int
ServerRegionCode string ServerRegionCode string
ServerRegionName string ServerRegionName string
STUNEnabled bool
STUNAddr string STUNAddr string
URLs []url.URL URLs []url.URL
Paths []string Paths []string
@ -500,10 +502,13 @@ func (h *Headscale) Serve() error {
h.DERPMap = GetDERPMap(h.cfg.DERP) h.DERPMap = GetDERPMap(h.cfg.DERP)
if h.cfg.DERP.ServerEnabled { if h.cfg.DERP.ServerEnabled {
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region // When embedded DERP is enabled we always need a STUN server
if h.cfg.DERP.STUNEnabled { if h.cfg.DERP.STUNAddr == "" {
go h.ServeSTUN() return errSTUNAddressNotSet
} }
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
go h.ServeSTUN()
} }
if h.cfg.DERP.AutoUpdate { if h.cfg.DERP.AutoUpdate {

View file

@ -55,6 +55,9 @@ func LoadConfig(path string) error {
viper.SetDefault("dns_config", nil) viper.SetDefault("dns_config", nil)
viper.SetDefault("derp.server.enabled", false)
viper.SetDefault("derp.server.stun.enabled", true)
viper.SetDefault("unix_socket", "/var/run/headscale.sock") viper.SetDefault("unix_socket", "/var/run/headscale.sock")
viper.SetDefault("unix_socket_permission", "0o770") viper.SetDefault("unix_socket_permission", "0o770")
@ -121,8 +124,11 @@ func GetDERPConfig() headscale.DERPConfig {
serverRegionID := viper.GetInt("derp.server.region_id") serverRegionID := viper.GetInt("derp.server.region_id")
serverRegionCode := viper.GetString("derp.server.region_code") serverRegionCode := viper.GetString("derp.server.region_code")
serverRegionName := viper.GetString("derp.server.region_name") serverRegionName := viper.GetString("derp.server.region_name")
stunEnabled := viper.GetBool("derp.server.stun.enabled") stunAddr := viper.GetString("derp.server.stun_listen_addr")
stunAddr := viper.GetString("derp.server.stun.listen_addr")
if serverEnabled && stunAddr == "" {
log.Fatal().Msg("derp.server.stun_listen_addr must be set if derp.server.enabled is true")
}
urlStrs := viper.GetStringSlice("derp.urls") urlStrs := viper.GetStringSlice("derp.urls")
@ -149,7 +155,6 @@ func GetDERPConfig() headscale.DERPConfig {
ServerRegionID: serverRegionID, ServerRegionID: serverRegionID,
ServerRegionCode: serverRegionCode, ServerRegionCode: serverRegionCode,
ServerRegionName: serverRegionName, ServerRegionName: serverRegionName,
STUNEnabled: stunEnabled,
STUNAddr: stunAddr, STUNAddr: stunAddr,
URLs: urls, URLs: urls,
Paths: paths, Paths: paths,

View file

@ -69,11 +69,11 @@ derp:
region_code: "headscale" region_code: "headscale"
region_name: "Headscale Embedded DERP" region_name: "Headscale Embedded DERP"
# If enabled, also listens in UDP at the configured address for STUN connections to help on NAT traversal # Listens in UDP at the configured address for STUN connections to help on NAT traversal.
# When the embedded DERP server is enabled stun_listen_addr MUST be defined.
#
# For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/ # For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/
stun: stun_listen_addr: "0.0.0.0:3478"
enabled: false
listen_addr: "0.0.0.0:3478"
# List of externally available DERP maps encoded in JSON # List of externally available DERP maps encoded in JSON
urls: urls:

View file

@ -148,7 +148,9 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) {
case <-ticker.C: case <-ticker.C:
log.Info().Msg("Fetching DERPMap updates") log.Info().Msg("Fetching DERPMap updates")
h.DERPMap = GetDERPMap(h.cfg.DERP) h.DERPMap = GetDERPMap(h.cfg.DERP)
if h.cfg.DERP.ServerEnabled {
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
}
namespaces, err := h.ListNamespaces() namespaces, err := h.ListNamespaces()
if err != nil { if err != nil {

View file

@ -77,17 +77,15 @@ func (h *Headscale) generateRegionLocalDERP() (tailcfg.DERPRegion, error) {
}, },
} }
if h.cfg.DERP.STUNEnabled { _, portSTUNStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr)
_, portStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr)
if err != nil { if err != nil {
return tailcfg.DERPRegion{}, err return tailcfg.DERPRegion{}, err
} }
port, err := strconv.Atoi(portStr) portSTUN, err := strconv.Atoi(portSTUNStr)
if err != nil { if err != nil {
return tailcfg.DERPRegion{}, err return tailcfg.DERPRegion{}, err
} }
localDERPregion.Nodes[0].STUNPort = port localDERPregion.Nodes[0].STUNPort = portSTUN
}
return localDERPregion, nil return localDERPregion, nil
} }

4
go.mod
View file

@ -1,9 +1,10 @@
module github.com/juanfont/headscale module github.com/juanfont/headscale
go 1.17 go 1.18
require ( require (
github.com/AlecAivazis/survey/v2 v2.3.2 github.com/AlecAivazis/survey/v2 v2.3.2
github.com/ccding/go-stun/stun v0.0.0-20200514191101-4dc67bcdb029
github.com/coreos/go-oidc/v3 v3.1.0 github.com/coreos/go-oidc/v3 v3.1.0
github.com/efekarakus/termcolor v1.0.1 github.com/efekarakus/termcolor v1.0.1
github.com/fatih/set v0.2.1 github.com/fatih/set v0.2.1
@ -49,7 +50,6 @@ require (
github.com/akutz/memconn v0.1.0 // indirect github.com/akutz/memconn v0.1.0 // indirect
github.com/atomicgo/cursor v0.0.1 // indirect github.com/atomicgo/cursor v0.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/ccding/go-stun/stun v0.0.0-20200514191101-4dc67bcdb029 // indirect
github.com/cenkalti/backoff/v4 v4.1.2 // indirect github.com/cenkalti/backoff/v4 v4.1.2 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/containerd/continuity v0.2.2 // indirect github.com/containerd/continuity v0.2.2 // indirect

View file

@ -24,6 +24,5 @@ derp:
region_id: 999 region_id: 999
region_code: "headscale" region_code: "headscale"
region_name: "Headscale Embedded DERP" region_name: "Headscale Embedded DERP"
stun:
enabled: true stun_listen_addr: "0.0.0.0:3478"
listen_addr: "0.0.0.0:3478"

View file

@ -10,6 +10,7 @@ import (
"html/template" "html/template"
"net/http" "net/http"
"strings" "strings"
"time"
"github.com/coreos/go-oidc/v3/oidc" "github.com/coreos/go-oidc/v3/oidc"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -129,6 +130,10 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code)
if err != nil { if err != nil {
log.Error().
Err(err).
Caller().
Msg("Could not exchange code for token")
ctx.String(http.StatusBadRequest, "Could not exchange code for token") ctx.String(http.StatusBadRequest, "Could not exchange code for token")
return return
@ -229,7 +234,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
Str("machine", machine.Name). Str("machine", machine.Name).
Msg("machine already registered, reauthenticating") Msg("machine already registered, reauthenticating")
h.RefreshMachine(machine, *machine.Expiry) h.RefreshMachine(machine, time.Time{})
var content bytes.Buffer var content bytes.Buffer
if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{ if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{