mirror of
https://github.com/juanfont/headscale.git
synced 2025-02-08 10:18:01 +09:00
initial capver packet tracking version (#2391)
Some checks failed
Build / build-nix (push) Has been cancelled
Build / build-cross (GOARCH=386 GOOS=linux) (push) Has been cancelled
Build / build-cross (GOARCH=amd64 GOOS=darwin) (push) Has been cancelled
Build / build-cross (GOARCH=amd64 GOOS=linux) (push) Has been cancelled
Build / build-cross (GOARCH=arm GOOS=linux GOARM=5) (push) Has been cancelled
Build / build-cross (GOARCH=arm GOOS=linux GOARM=6) (push) Has been cancelled
Build / build-cross (GOARCH=arm GOOS=linux GOARM=7) (push) Has been cancelled
Build / build-cross (GOARCH=arm64 GOOS=darwin) (push) Has been cancelled
Build / build-cross (GOARCH=arm64 GOOS=linux) (push) Has been cancelled
Tests / test (push) Has been cancelled
Some checks failed
Build / build-nix (push) Has been cancelled
Build / build-cross (GOARCH=386 GOOS=linux) (push) Has been cancelled
Build / build-cross (GOARCH=amd64 GOOS=darwin) (push) Has been cancelled
Build / build-cross (GOARCH=amd64 GOOS=linux) (push) Has been cancelled
Build / build-cross (GOARCH=arm GOOS=linux GOARM=5) (push) Has been cancelled
Build / build-cross (GOARCH=arm GOOS=linux GOARM=6) (push) Has been cancelled
Build / build-cross (GOARCH=arm GOOS=linux GOARM=7) (push) Has been cancelled
Build / build-cross (GOARCH=arm64 GOOS=darwin) (push) Has been cancelled
Build / build-cross (GOARCH=arm64 GOOS=linux) (push) Has been cancelled
Tests / test (push) Has been cancelled
* initial capver packet tracking version Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * Log the minimum version as client version, not only capver Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * remove old versions Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * use capver for integration tests Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * changelog Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * patch through m and n key Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> --------- Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
parent
cd3b8e68ff
commit
e172c29360
8 changed files with 397 additions and 68 deletions
32
CHANGELOG.md
32
CHANGELOG.md
|
@ -6,6 +6,8 @@
|
|||
|
||||
- `oidc.map_legacy_users` is now `false` by default
|
||||
[#2350](https://github.com/juanfont/headscale/pull/2350)
|
||||
- Print Tailscale version instead of capability versions for outdated nodes
|
||||
[#2391](https://github.com/juanfont/headscale/pull/2391)
|
||||
|
||||
## 0.24.2 (2025-01-30)
|
||||
|
||||
|
@ -24,8 +26,8 @@
|
|||
[#2367](https://github.com/juanfont/headscale/pull/2367)
|
||||
- Relax username validation to allow emails
|
||||
[#2364](https://github.com/juanfont/headscale/pull/2364)
|
||||
- Remove invalid routes and add stronger constraints for routes to avoid API panic
|
||||
[#2371](https://github.com/juanfont/headscale/pull/2371)
|
||||
- Remove invalid routes and add stronger constraints for routes to avoid API
|
||||
panic [#2371](https://github.com/juanfont/headscale/pull/2371)
|
||||
- Fix panic when `derp.update_frequency` is 0
|
||||
[#2368](https://github.com/juanfont/headscale/pull/2368)
|
||||
|
||||
|
@ -60,8 +62,7 @@ and have it populate to Headscale automatically the next time they log in.
|
|||
However, this may affect the way you reference users in policies.
|
||||
|
||||
Headscale v0.23.0 and earlier never recorded the `iss` and `sub` fields, so all
|
||||
legacy (existing) OIDC accounts _need to be migrated_ to be properly
|
||||
secured.
|
||||
legacy (existing) OIDC accounts _need to be migrated_ to be properly secured.
|
||||
|
||||
#### What do I need to do to migrate?
|
||||
|
||||
|
@ -73,8 +74,8 @@ The migration will mostly be done automatically, with one exception. If your
|
|||
OIDC does not provide an `email_verified` claim, Headscale will ignore the
|
||||
`email`. This means that either the administrator will have to mark the user
|
||||
emails as verified, or ensure the users verify their emails. Any unverified
|
||||
emails will be ignored, meaning that the users will get new accounts instead
|
||||
of being migrated.
|
||||
emails will be ignored, meaning that the users will get new accounts instead of
|
||||
being migrated.
|
||||
|
||||
After this exception is ensured, make all users log into Headscale with their
|
||||
account, and Headscale will automatically update the account record. This will
|
||||
|
@ -175,7 +176,8 @@ This will also affect the way you
|
|||
- User gRPC/API [#2261](https://github.com/juanfont/headscale/pull/2261):
|
||||
- If you depend on a Headscale Web UI, you should wait with this update until
|
||||
the UI have been updated to match the new API.
|
||||
- `GET /api/v1/user/{name}` and `GetUser` have been removed in favour of `ListUsers` with an ID parameter
|
||||
- `GET /api/v1/user/{name}` and `GetUser` have been removed in favour of
|
||||
`ListUsers` with an ID parameter
|
||||
- `RenameUser` and `DeleteUser` now require an ID instead of a name.
|
||||
|
||||
### Changes
|
||||
|
@ -197,9 +199,12 @@ This will also affect the way you
|
|||
- CLI for managing users now accepts `--identifier` in addition to `--name`,
|
||||
usage of `--identifier` is recommended
|
||||
[#2261](https://github.com/juanfont/headscale/pull/2261)
|
||||
- Add `dns.extra_records_path` configuration option [#2262](https://github.com/juanfont/headscale/issues/2262)
|
||||
- Support client verify for DERP [#2046](https://github.com/juanfont/headscale/pull/2046)
|
||||
- Add PKCE Verifier for OIDC [#2314](https://github.com/juanfont/headscale/pull/2314)
|
||||
- Add `dns.extra_records_path` configuration option
|
||||
[#2262](https://github.com/juanfont/headscale/issues/2262)
|
||||
- Support client verify for DERP
|
||||
[#2046](https://github.com/juanfont/headscale/pull/2046)
|
||||
- Add PKCE Verifier for OIDC
|
||||
[#2314](https://github.com/juanfont/headscale/pull/2314)
|
||||
|
||||
## 0.23.0 (2024-09-18)
|
||||
|
||||
|
@ -730,8 +735,8 @@ behaviour.
|
|||
- All machines can communicate with all machines by default
|
||||
- Tags should now work correctly and adding a host to Headscale should now
|
||||
reload the rules.
|
||||
- The documentation have a [fictional example](./docs/ref/acls.md) that should cover
|
||||
some use cases of the ACLs features
|
||||
- The documentation have a [fictional example](./docs/ref/acls.md) that should
|
||||
cover some use cases of the ACLs features
|
||||
|
||||
### Features
|
||||
|
||||
|
@ -749,7 +754,8 @@ behaviour.
|
|||
|
||||
- Add IPv6 support to the prefix assigned to namespaces
|
||||
- Add API Key support
|
||||
- Enable remote control of `headscale` via CLI [docs](./docs/ref/remote-cli.md)
|
||||
- Enable remote control of `headscale` via CLI
|
||||
[docs](./docs/ref/remote-cli.md)
|
||||
- Enable HTTP API (beta, subject to change)
|
||||
- OpenID Connect users will be mapped per namespaces
|
||||
- Each user will get its own namespace, created if it does not exist
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
grpcRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol/capver"
|
||||
"github.com/juanfont/headscale/hscontrol/db"
|
||||
"github.com/juanfont/headscale/hscontrol/derp"
|
||||
derpServer "github.com/juanfont/headscale/hscontrol/derp/server"
|
||||
|
@ -560,6 +561,11 @@ func (h *Headscale) Serve() error {
|
|||
spew.Dump(h.cfg)
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Caller().
|
||||
Str("minimum_version", capver.TailscaleVersion(MinimumCapVersion)).
|
||||
Msg("Clients with a lower minimum version will be rejected")
|
||||
|
||||
// Fetch an initial DERP Map before we start serving
|
||||
h.DERPMap = derp.GetDERPMap(h.cfg.DERP)
|
||||
h.mapper = mapper.NewMapper(h.db, h.cfg, h.DERPMap, h.nodeNotifier, h.polMan)
|
||||
|
|
92
hscontrol/capver/capver.go
Normal file
92
hscontrol/capver/capver.go
Normal file
|
@ -0,0 +1,92 @@
|
|||
package capver
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
xmaps "golang.org/x/exp/maps"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/util/set"
|
||||
)
|
||||
|
||||
func tailscaleVersSorted() []string {
|
||||
vers := xmaps.Keys(tailscaleToCapVer)
|
||||
sort.Strings(vers)
|
||||
return vers
|
||||
}
|
||||
|
||||
func capVersSorted() []tailcfg.CapabilityVersion {
|
||||
capVers := xmaps.Keys(capVerToTailscaleVer)
|
||||
sort.Slice(capVers, func(i, j int) bool {
|
||||
return capVers[i] < capVers[j]
|
||||
})
|
||||
return capVers
|
||||
}
|
||||
|
||||
// TailscaleVersion returns the Tailscale version for the given CapabilityVersion.
|
||||
func TailscaleVersion(ver tailcfg.CapabilityVersion) string {
|
||||
return capVerToTailscaleVer[ver]
|
||||
}
|
||||
|
||||
// CapabilityVersion returns the CapabilityVersion for the given Tailscale version.
|
||||
func CapabilityVersion(ver string) tailcfg.CapabilityVersion {
|
||||
if !strings.HasPrefix(ver, "v") {
|
||||
ver = "v" + ver
|
||||
}
|
||||
return tailscaleToCapVer[ver]
|
||||
}
|
||||
|
||||
// TailscaleLatest returns the n latest Tailscale versions.
|
||||
func TailscaleLatest(n int) []string {
|
||||
if n <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
tsSorted := tailscaleVersSorted()
|
||||
|
||||
if n > len(tsSorted) {
|
||||
return tsSorted
|
||||
}
|
||||
|
||||
return tsSorted[len(tsSorted)-n:]
|
||||
}
|
||||
|
||||
// TailscaleLatestMajorMinor returns the n latest Tailscale versions (e.g. 1.80).
|
||||
func TailscaleLatestMajorMinor(n int, stripV bool) []string {
|
||||
if n <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
majors := set.Set[string]{}
|
||||
for _, vers := range tailscaleVersSorted() {
|
||||
if stripV {
|
||||
vers = strings.TrimPrefix(vers, "v")
|
||||
}
|
||||
v := strings.Split(vers, ".")
|
||||
majors.Add(v[0] + "." + v[1])
|
||||
}
|
||||
|
||||
majorSl := majors.Slice()
|
||||
sort.Strings(majorSl)
|
||||
|
||||
if n > len(majorSl) {
|
||||
return majorSl
|
||||
}
|
||||
|
||||
return majorSl[len(majorSl)-n:]
|
||||
}
|
||||
|
||||
// CapVerLatest returns the n latest CapabilityVersions.
|
||||
func CapVerLatest(n int) []tailcfg.CapabilityVersion {
|
||||
if n <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
s := capVersSorted()
|
||||
|
||||
if n > len(s) {
|
||||
return s
|
||||
}
|
||||
|
||||
return s[len(s)-n:]
|
||||
}
|
54
hscontrol/capver/capver_generated.go
Normal file
54
hscontrol/capver/capver_generated.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package capver
|
||||
|
||||
//Generated DO NOT EDIT
|
||||
|
||||
import "tailscale.com/tailcfg"
|
||||
|
||||
var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{
|
||||
"v1.44.3": 63,
|
||||
"v1.56.1": 82,
|
||||
"v1.58.0": 85,
|
||||
"v1.58.1": 85,
|
||||
"v1.58.2": 85,
|
||||
"v1.60.0": 87,
|
||||
"v1.60.1": 87,
|
||||
"v1.62.0": 88,
|
||||
"v1.62.1": 88,
|
||||
"v1.64.0": 90,
|
||||
"v1.64.1": 90,
|
||||
"v1.64.2": 90,
|
||||
"v1.66.0": 95,
|
||||
"v1.66.1": 95,
|
||||
"v1.66.2": 95,
|
||||
"v1.66.3": 95,
|
||||
"v1.66.4": 95,
|
||||
"v1.68.0": 97,
|
||||
"v1.68.1": 97,
|
||||
"v1.68.2": 97,
|
||||
"v1.70.0": 102,
|
||||
"v1.72.0": 104,
|
||||
"v1.72.1": 104,
|
||||
"v1.74.0": 106,
|
||||
"v1.74.1": 106,
|
||||
"v1.76.0": 106,
|
||||
"v1.76.1": 106,
|
||||
"v1.76.6": 106,
|
||||
"v1.78.0": 109,
|
||||
"v1.78.1": 109,
|
||||
}
|
||||
|
||||
|
||||
var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{
|
||||
63: "v1.44.3",
|
||||
82: "v1.56.1",
|
||||
85: "v1.58.0",
|
||||
87: "v1.60.0",
|
||||
88: "v1.62.0",
|
||||
90: "v1.64.0",
|
||||
95: "v1.66.0",
|
||||
97: "v1.68.0",
|
||||
102: "v1.70.0",
|
||||
104: "v1.72.0",
|
||||
106: "v1.74.0",
|
||||
109: "v1.78.0",
|
||||
}
|
53
hscontrol/capver/capver_test.go
Normal file
53
hscontrol/capver/capver_test.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package capver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
func TestTailscaleLatestMajorMinor(t *testing.T) {
|
||||
tests := []struct {
|
||||
n int
|
||||
stripV bool
|
||||
expected []string
|
||||
}{
|
||||
{3, false, []string{"v1.74", "v1.76", "v1.78"}},
|
||||
{2, true, []string{"1.76", "1.78"}},
|
||||
{0, false, nil},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run("", func(t *testing.T) {
|
||||
output := TailscaleLatestMajorMinor(test.n, test.stripV)
|
||||
if diff := cmp.Diff(output, test.expected); diff != "" {
|
||||
t.Errorf("TailscaleLatestMajorMinor(%d, %v) mismatch (-want +got):\n%s", test.n, test.stripV, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapVerMinimumTailscaleVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
input tailcfg.CapabilityVersion
|
||||
expected string
|
||||
}{
|
||||
{85, "v1.58.0"},
|
||||
{90, "v1.64.0"},
|
||||
{95, "v1.66.0"},
|
||||
{106, "v1.74.0"},
|
||||
{109, "v1.78.0"},
|
||||
{9001, ""}, // Test case for a version higher than any in the map
|
||||
{60, ""}, // Test case for a version lower than any in the map
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run("", func(t *testing.T) {
|
||||
output := TailscaleVersion(test.input)
|
||||
if output != test.expected {
|
||||
t.Errorf("CapVerFromTailscaleVersion(%d) = %s; want %s", test.input, output, test.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
157
hscontrol/capver/gen/main.go
Normal file
157
hscontrol/capver/gen/main.go
Normal file
|
@ -0,0 +1,157 @@
|
|||
package main
|
||||
|
||||
//go:generate go run main.go
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
xmaps "golang.org/x/exp/maps"
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
const (
|
||||
releasesURL = "https://api.github.com/repos/tailscale/tailscale/releases"
|
||||
rawFileURL = "https://github.com/tailscale/tailscale/raw/refs/tags/%s/tailcfg/tailcfg.go"
|
||||
outputFile = "../capver_generated.go"
|
||||
)
|
||||
|
||||
type Release struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func getCapabilityVersions() (map[string]tailcfg.CapabilityVersion, error) {
|
||||
// Fetch the releases
|
||||
resp, err := http.Get(releasesURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching releases: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
var releases []Release
|
||||
err = json.Unmarshal(body, &releases)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error unmarshalling JSON: %w", err)
|
||||
}
|
||||
|
||||
// Regular expression to find the CurrentCapabilityVersion line
|
||||
re := regexp.MustCompile(`const CurrentCapabilityVersion CapabilityVersion = (\d+)`)
|
||||
|
||||
versions := make(map[string]tailcfg.CapabilityVersion)
|
||||
|
||||
for _, release := range releases {
|
||||
version := strings.TrimSpace(release.Name)
|
||||
if !strings.HasPrefix(version, "v") {
|
||||
version = "v" + version
|
||||
}
|
||||
|
||||
// Fetch the raw Go file
|
||||
rawURL := fmt.Sprintf(rawFileURL, version)
|
||||
resp, err := http.Get(rawURL)
|
||||
if err != nil {
|
||||
fmt.Printf("Error fetching raw file for version %s: %v\n", version, err)
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading raw file for version %s: %v\n", version, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Find the CurrentCapabilityVersion
|
||||
matches := re.FindStringSubmatch(string(body))
|
||||
if len(matches) > 1 {
|
||||
capabilityVersionStr := matches[1]
|
||||
capabilityVersion, _ := strconv.Atoi(capabilityVersionStr)
|
||||
versions[version] = tailcfg.CapabilityVersion(capabilityVersion)
|
||||
} else {
|
||||
fmt.Printf("Version: %s, CurrentCapabilityVersion not found\n", version)
|
||||
}
|
||||
}
|
||||
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
func writeCapabilityVersionsToFile(versions map[string]tailcfg.CapabilityVersion) error {
|
||||
// Open the output file
|
||||
file, err := os.Create(outputFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Write the package declaration and variable
|
||||
file.WriteString("package capver\n\n")
|
||||
file.WriteString("//Generated DO NOT EDIT\n\n")
|
||||
file.WriteString(`import "tailscale.com/tailcfg"`)
|
||||
file.WriteString("\n\n")
|
||||
file.WriteString("var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{\n")
|
||||
|
||||
sortedVersions := xmaps.Keys(versions)
|
||||
sort.Strings(sortedVersions)
|
||||
for _, version := range sortedVersions {
|
||||
file.WriteString(fmt.Sprintf("\t\"%s\": %d,\n", version, versions[version]))
|
||||
}
|
||||
file.WriteString("}\n")
|
||||
|
||||
file.WriteString("\n\n")
|
||||
file.WriteString("var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{\n")
|
||||
|
||||
capVarToTailscaleVer := make(map[tailcfg.CapabilityVersion]string)
|
||||
for _, v := range sortedVersions {
|
||||
cap := versions[v]
|
||||
log.Printf("cap for v: %d, %s", cap, v)
|
||||
|
||||
// If it is already set, skip and continue,
|
||||
// we only want the first tailscale vsion per
|
||||
// capability vsion.
|
||||
if _, ok := capVarToTailscaleVer[cap]; ok {
|
||||
log.Printf("Skipping %d, %s", cap, v)
|
||||
continue
|
||||
}
|
||||
log.Printf("Storing %d, %s", cap, v)
|
||||
capVarToTailscaleVer[cap] = v
|
||||
}
|
||||
|
||||
capsSorted := xmaps.Keys(capVarToTailscaleVer)
|
||||
sort.Slice(capsSorted, func(i, j int) bool {
|
||||
return capsSorted[i] < capsSorted[j]
|
||||
})
|
||||
for _, capVer := range capsSorted {
|
||||
file.WriteString(fmt.Sprintf("\t%d:\t\t\"%s\",\n", capVer, capVarToTailscaleVer[capVer]))
|
||||
}
|
||||
file.WriteString("}\n")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
versions, err := getCapabilityVersions()
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = writeCapabilityVersionsToFile(versions)
|
||||
if err != nil {
|
||||
fmt.Println("Error writing to file:", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Capability versions written to", outputFile)
|
||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/juanfont/headscale/hscontrol/capver"
|
||||
"github.com/juanfont/headscale/hscontrol/types"
|
||||
"github.com/rs/zerolog/log"
|
||||
"golang.org/x/net/http2"
|
||||
|
@ -155,10 +156,19 @@ func isSupportedVersion(version tailcfg.CapabilityVersion) bool {
|
|||
return version >= MinimumCapVersion
|
||||
}
|
||||
|
||||
func rejectUnsupported(writer http.ResponseWriter, version tailcfg.CapabilityVersion) bool {
|
||||
func rejectUnsupported(writer http.ResponseWriter, version tailcfg.CapabilityVersion, mkey key.MachinePublic, nkey key.NodePublic) bool {
|
||||
// Reject unsupported versions
|
||||
if !isSupportedVersion(version) {
|
||||
httpError(writer, nil, "unsupported client version", http.StatusBadRequest)
|
||||
log.Error().
|
||||
Caller().
|
||||
Int("minimum_cap_ver", int(MinimumCapVersion)).
|
||||
Int("client_cap_ver", int(version)).
|
||||
Str("minimum_version", capver.TailscaleVersion(MinimumCapVersion)).
|
||||
Str("client_version", capver.TailscaleVersion(version)).
|
||||
Str("node_key", nkey.ShortString()).
|
||||
Str("machine_key", mkey.ShortString()).
|
||||
Msg("unsupported client connected")
|
||||
http.Error(writer, "unsupported client version", http.StatusBadRequest)
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -188,7 +198,7 @@ func (ns *noiseServer) NoisePollNetMapHandler(
|
|||
}
|
||||
|
||||
// Reject unsupported versions
|
||||
if rejectUnsupported(writer, mapRequest.Version) {
|
||||
if rejectUnsupported(writer, mapRequest.Version, ns.machineKey, mapRequest.NodeKey) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -233,7 +243,7 @@ func (ns *noiseServer) NoiseRegistrationHandler(
|
|||
}
|
||||
|
||||
// Reject unsupported versions
|
||||
if rejectUnsupported(writer, registerRequest.Version) {
|
||||
if rejectUnsupported(writer, registerRequest.Version, ns.machineKey, registerRequest.NodeKey) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"time"
|
||||
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol/capver"
|
||||
"github.com/juanfont/headscale/hscontrol/util"
|
||||
"github.com/juanfont/headscale/integration/dockertestutil"
|
||||
"github.com/juanfont/headscale/integration/dsic"
|
||||
|
@ -51,53 +52,6 @@ var (
|
|||
errNoUserAvailable = errors.New("no user available")
|
||||
errNoClientFound = errors.New("client not found")
|
||||
|
||||
// Tailscale started adding TS2021 support in CapabilityVersion>=28 (v1.24.0), but
|
||||
// proper support in Headscale was only added for CapabilityVersion>=39 clients (v1.30.0).
|
||||
tailscaleVersions2021 = map[string]bool{
|
||||
"head": true,
|
||||
"unstable": true,
|
||||
"1.74": true, // CapVer: 106
|
||||
"1.72": true, // CapVer: 104
|
||||
"1.70": true, // CapVer: 102
|
||||
"1.68": true, // CapVer: 97
|
||||
"1.66": true, // CapVer: 95
|
||||
"1.64": true, // CapVer: 90
|
||||
"1.62": true, // CapVer: 88
|
||||
"1.60": true, // CapVer: 87
|
||||
"1.58": true, // CapVer: 85
|
||||
"1.56": true, // Oldest supported version, CapVer: 82
|
||||
"1.54": false, // CapVer: 79
|
||||
"1.52": false, // CapVer: 79
|
||||
"1.50": false, // CapVer: 74
|
||||
"1.48": false, // CapVer: 68
|
||||
"1.46": false, // CapVer: 65
|
||||
"1.44": false, // CapVer: 63
|
||||
"1.42": false, // CapVer: 61
|
||||
"1.40": false, // CapVer: 61
|
||||
"1.38": false, // CapVer: 58
|
||||
"1.36": false, // CapVer: 56
|
||||
"1.34": false, // CapVer: 51
|
||||
"1.32": false, // CapVer: 46
|
||||
"1.30": false,
|
||||
}
|
||||
|
||||
tailscaleVersions2019 = map[string]bool{
|
||||
"1.28": false,
|
||||
"1.26": false,
|
||||
"1.24": false, // Tailscale SSH
|
||||
"1.22": false,
|
||||
"1.20": false,
|
||||
"1.18": false,
|
||||
}
|
||||
|
||||
// tailscaleVersionsUnavailable = []string{
|
||||
// // These versions seem to fail when fetching from apt.
|
||||
// "1.14.6",
|
||||
// "1.12.4",
|
||||
// "1.10.2",
|
||||
// "1.8.7",
|
||||
// }.
|
||||
|
||||
// AllVersions represents a list of Tailscale versions the suite
|
||||
// uses to test compatibility with the ControlServer.
|
||||
//
|
||||
|
@ -107,10 +61,7 @@ var (
|
|||
//
|
||||
// The rest of the version represents Tailscale versions that can be
|
||||
// found in Tailscale's apt repository.
|
||||
AllVersions = append(
|
||||
enabledVersions(tailscaleVersions2021),
|
||||
enabledVersions(tailscaleVersions2019)...,
|
||||
)
|
||||
AllVersions = append([]string{"head", "unstable"}, capver.TailscaleLatestMajorMinor(10, true)...)
|
||||
|
||||
// MustTestVersions is the minimum set of versions we should test.
|
||||
// At the moment, this is arbitrarily chosen as:
|
||||
|
|
Loading…
Reference in a new issue