- update to 1.80.0:
* Hostname system policy is added for overriding the device hostname configured by the operating system, using an MDM solution. * Web interface displays a Login button instead of the Reauthenticate button when adding a new device to your tailnet. * Tailscale Funnel configuration on devices displays errors when incoming connections are not permitted and connections are disallowed. * Connections to a custom coordination server that does not support HTTPS will no longer fail when a custom port number is specified. * TLS certificate requests from Let’s Encrypt include the device's DNS name in the CSR’s SAN extension and set the Common Name field. * Tailscale Funnel disabled on a device no longer displays enabled in the admin console. * GitHub username change automatically updates tailnet name * 4via6 subnet routers GA * Auto approvers GA * Node attributes GA * Download invoices GA * Fast user switching GA * Configuration log streaming integration with S3 buckets GA * Network flow log streaming integration with S3 buckets GA * NextDNS profiles per device GA * GitHub secret scanning - remove fix-CVE-2024-45337.patch, as it's now included OBS-URL: https://build.opensuse.org/package/show/network:vpn/tailscale?expand=0&rev=63
This commit is contained in:
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
## Default LFS
|
||||
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.zst filter=lfs diff=lfs merge=lfs -text
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.osc
|
17
_service
Normal file
17
_service
Normal file
@@ -0,0 +1,17 @@
|
||||
<services>
|
||||
<service name="tar_scm" mode="manual">
|
||||
<param name="url">https://github.com/tailscale/tailscale.git</param>
|
||||
<param name="scm">git</param>
|
||||
<param name="package-meta">yes</param>
|
||||
<param name="revision">refs/tags/v1.80.0</param>
|
||||
<param name="versionformat">@PARENT_TAG@</param>
|
||||
<param name="versionrewrite-pattern">v(.*)</param>
|
||||
<param name="changesgenerate">disable</param>
|
||||
</service>
|
||||
<service name="recompress" mode="manual">
|
||||
<param name="file">*.tar</param>
|
||||
<param name="compression">gz</param>
|
||||
</service>
|
||||
<service name="go_modules" mode="manual">
|
||||
</service>
|
||||
</services>
|
4
_servicedata
Normal file
4
_servicedata
Normal file
@@ -0,0 +1,4 @@
|
||||
<servicedata>
|
||||
<service name="tar_scm">
|
||||
<param name="url">https://github.com/tailscale/tailscale.git</param>
|
||||
<param name="changesrevision">aa448d5a9985378af04966c6d7aec8d9f4a166ca</param></service></servicedata>
|
13
build-verbose.patch
Normal file
13
build-verbose.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/build_dist.sh b/build_dist.sh
|
||||
index 0c757c26..9639d596 100755
|
||||
--- a/build_dist.sh
|
||||
+++ b/build_dist.sh
|
||||
@@ -9,7 +9,7 @@
|
||||
# this script, or executing equivalent commands in your
|
||||
# distro-specific build system.
|
||||
|
||||
-set -eu
|
||||
+set -eux
|
||||
|
||||
go="go"
|
||||
if [ -n "${TS_USE_TOOLCHAIN:-}" ]; then
|
25
disable-auto-update.patch
Normal file
25
disable-auto-update.patch
Normal file
@@ -0,0 +1,25 @@
|
||||
diff -rub tailscale/clientupdate/clientupdate.go tailscale-patched/clientupdate/clientupdate.go
|
||||
--- tailscale/clientupdate/clientupdate.go 2024-06-16 15:26:31.323022871 +0200
|
||||
+++ tailscale-patched/clientupdate/clientupdate.go 2024-06-16 15:57:08.732315446 +0200
|
||||
@@ -205,6 +205,8 @@
|
||||
// The distro.Debian switch case above should catch most apt-based
|
||||
// systems, but add this fallback just in case.
|
||||
return up.updateDebLike, true
|
||||
+ case haveExecutable("zypper"):
|
||||
+ return up.updateSUSE, false
|
||||
case haveExecutable("dnf"):
|
||||
return up.updateFedoraLike("dnf"), true
|
||||
case haveExecutable("yum"):
|
||||
@@ -526,6 +528,12 @@
|
||||
you can use "pacman --sync --refresh --sysupgrade" or "pacman -Syu" to upgrade the system, including Tailscale.`)
|
||||
}
|
||||
|
||||
+func (up *Updater) updateSUSE() error {
|
||||
+ // SUSE-based distros should update manually.
|
||||
+ // The package can come from official Tailscale repos or not and the system can be transactional or not.
|
||||
+ return errors.New(`Use Zypper or transactional-update (on applicable systems) to update Tailscale on openSUSE or SUSE Linux Enterprise installations.`)
|
||||
+}
|
||||
+
|
||||
func (up *Updater) updateNixos() error {
|
||||
// NixOS package updates are managed on a system level and not individually.
|
||||
// Direct users to update their nix channel or nixpkgs flake input to
|
727
fix-CVE-2024-45337.patch
Normal file
727
fix-CVE-2024-45337.patch
Normal file
@@ -0,0 +1,727 @@
|
||||
From 73128e25230fda8c82696ed0ffef991bce68cecc Mon Sep 17 00:00:00 2001
|
||||
From: Brad Fitzpatrick <bradfitz@tailscale.com>
|
||||
Date: Thu, 12 Dec 2024 09:38:07 -0800
|
||||
Subject: [PATCH] ssh/tailssh: remove unused public key support
|
||||
|
||||
When we first made Tailscale SSH, we assumed people would want public
|
||||
key support soon after. Turns out that hasn't been the case; people
|
||||
love the Tailscale identity authentication and check mode.
|
||||
|
||||
In light of CVE-2024-45337, just remove all our public key code to not
|
||||
distract people, and to make the code smaller. We can always get it
|
||||
back from git if needed.
|
||||
|
||||
Updates tailscale/corp#25131
|
||||
Updates golang/go#70779
|
||||
|
||||
Co-authored-by: Percy Wegmann <percy@tailscale.com>
|
||||
Change-Id: I87a6e79c2215158766a81942227a18b247333c22
|
||||
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
|
||||
---
|
||||
Makefile | 1 -
|
||||
ssh/tailssh/tailssh.go | 277 ++++--------------------------------
|
||||
ssh/tailssh/tailssh_test.go | 88 +-----------
|
||||
tailcfg/tailcfg.go | 18 ++-
|
||||
tailcfg/tailcfg_clone.go | 12 +-
|
||||
tailcfg/tailcfg_view.go | 22 +--
|
||||
6 files changed, 54 insertions(+), 364 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 960f13885c11c..d3e50af0571b7 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -116,7 +116,6 @@ sshintegrationtest: ## Run the SSH integration tests in various Docker container
|
||||
GOOS=linux GOARCH=amd64 ./tool/go build -o ssh/tailssh/testcontainers/tailscaled ./cmd/tailscaled && \
|
||||
echo "Testing on ubuntu:focal" && docker build --build-arg="BASE=ubuntu:focal" -t ssh-ubuntu-focal ssh/tailssh/testcontainers && \
|
||||
echo "Testing on ubuntu:jammy" && docker build --build-arg="BASE=ubuntu:jammy" -t ssh-ubuntu-jammy ssh/tailssh/testcontainers && \
|
||||
- echo "Testing on ubuntu:mantic" && docker build --build-arg="BASE=ubuntu:mantic" -t ssh-ubuntu-mantic ssh/tailssh/testcontainers && \
|
||||
echo "Testing on ubuntu:noble" && docker build --build-arg="BASE=ubuntu:noble" -t ssh-ubuntu-noble ssh/tailssh/testcontainers && \
|
||||
echo "Testing on alpine:latest" && docker build --build-arg="BASE=alpine:latest" -t ssh-alpine-latest ssh/tailssh/testcontainers
|
||||
|
||||
diff --git a/ssh/tailssh/tailssh.go b/ssh/tailssh/tailssh.go
|
||||
index 7cb99c3813104..7f21ccd1182ee 100644
|
||||
--- a/ssh/tailssh/tailssh.go
|
||||
+++ b/ssh/tailssh/tailssh.go
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
- "encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -45,7 +44,6 @@ import (
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/httpm"
|
||||
"tailscale.com/util/mak"
|
||||
- "tailscale.com/util/slicesx"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -80,16 +78,14 @@ type server struct {
|
||||
logf logger.Logf
|
||||
tailscaledPath string
|
||||
|
||||
- pubKeyHTTPClient *http.Client // or nil for http.DefaultClient
|
||||
- timeNow func() time.Time // or nil for time.Now
|
||||
+ timeNow func() time.Time // or nil for time.Now
|
||||
|
||||
sessionWaitGroup sync.WaitGroup
|
||||
|
||||
// mu protects the following
|
||||
- mu sync.Mutex
|
||||
- activeConns map[*conn]bool // set; value is always true
|
||||
- fetchPublicKeysCache map[string]pubKeyCacheEntry // by https URL
|
||||
- shutdownCalled bool
|
||||
+ mu sync.Mutex
|
||||
+ activeConns map[*conn]bool // set; value is always true
|
||||
+ shutdownCalled bool
|
||||
}
|
||||
|
||||
func (srv *server) now() time.Time {
|
||||
@@ -204,7 +200,6 @@ func (srv *server) OnPolicyChange() {
|
||||
//
|
||||
// Do the user auth
|
||||
// - NoClientAuthHandler
|
||||
-// - PublicKeyHandler (only if NoClientAuthHandler returns errPubKeyRequired)
|
||||
//
|
||||
// Once auth is done, the conn can be multiplexed with multiple sessions and
|
||||
// channels concurrently. At which point any of the following can be called
|
||||
@@ -234,10 +229,9 @@ type conn struct {
|
||||
finalAction *tailcfg.SSHAction // set by doPolicyAuth or resolveNextAction
|
||||
finalActionErr error // set by doPolicyAuth or resolveNextAction
|
||||
|
||||
- info *sshConnInfo // set by setInfo
|
||||
- localUser *userMeta // set by doPolicyAuth
|
||||
- userGroupIDs []string // set by doPolicyAuth
|
||||
- pubKey gossh.PublicKey // set by doPolicyAuth
|
||||
+ info *sshConnInfo // set by setInfo
|
||||
+ localUser *userMeta // set by doPolicyAuth
|
||||
+ userGroupIDs []string // set by doPolicyAuth
|
||||
acceptEnv []string
|
||||
|
||||
// mu protects the following fields.
|
||||
@@ -268,9 +262,6 @@ func (c *conn) isAuthorized(ctx ssh.Context) error {
|
||||
action := c.currentAction
|
||||
for {
|
||||
if action.Accept {
|
||||
- if c.pubKey != nil {
|
||||
- metricPublicKeyAccepts.Add(1)
|
||||
- }
|
||||
return nil
|
||||
}
|
||||
if action.Reject || action.HoldAndDelegate == "" {
|
||||
@@ -293,10 +284,6 @@ func (c *conn) isAuthorized(ctx ssh.Context) error {
|
||||
// policy.
|
||||
var errDenied = errors.New("ssh: access denied")
|
||||
|
||||
-// errPubKeyRequired is returned by NoClientAuthCallback to make the client
|
||||
-// resort to public-key auth; not user visible.
|
||||
-var errPubKeyRequired = errors.New("ssh publickey required")
|
||||
-
|
||||
// NoClientAuthCallback implements gossh.NoClientAuthCallback and is called by
|
||||
// the ssh.Server when the client first connects with the "none"
|
||||
// authentication method.
|
||||
@@ -305,13 +292,12 @@ var errPubKeyRequired = errors.New("ssh publickey required")
|
||||
// starting it afresh). It returns an error if the policy evaluation fails, or
|
||||
// if the decision is "reject"
|
||||
//
|
||||
-// It either returns nil (accept) or errPubKeyRequired or errDenied
|
||||
-// (reject). The errors may be wrapped.
|
||||
+// It either returns nil (accept) or errDenied (reject). The errors may be wrapped.
|
||||
func (c *conn) NoClientAuthCallback(ctx ssh.Context) error {
|
||||
if c.insecureSkipTailscaleAuth {
|
||||
return nil
|
||||
}
|
||||
- if err := c.doPolicyAuth(ctx, nil /* no pub key */); err != nil {
|
||||
+ if err := c.doPolicyAuth(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.isAuthorized(ctx); err != nil {
|
||||
@@ -332,8 +318,6 @@ func (c *conn) nextAuthMethodCallback(cm gossh.ConnMetadata, prevErrors []error)
|
||||
switch {
|
||||
case c.anyPasswordIsOkay:
|
||||
nextMethod = append(nextMethod, "password")
|
||||
- case slicesx.LastEqual(prevErrors, errPubKeyRequired):
|
||||
- nextMethod = append(nextMethod, "publickey")
|
||||
}
|
||||
|
||||
// The fake "tailscale" method is always appended to next so OpenSSH renders
|
||||
@@ -353,41 +337,20 @@ func (c *conn) fakePasswordHandler(ctx ssh.Context, password string) bool {
|
||||
return c.anyPasswordIsOkay
|
||||
}
|
||||
|
||||
-// PublicKeyHandler implements ssh.PublicKeyHandler is called by the
|
||||
-// ssh.Server when the client presents a public key.
|
||||
-func (c *conn) PublicKeyHandler(ctx ssh.Context, pubKey ssh.PublicKey) error {
|
||||
- if err := c.doPolicyAuth(ctx, pubKey); err != nil {
|
||||
- // TODO(maisem/bradfitz): surface the error here.
|
||||
- c.logf("rejecting SSH public key %s: %v", bytes.TrimSpace(gossh.MarshalAuthorizedKey(pubKey)), err)
|
||||
- return err
|
||||
- }
|
||||
- if err := c.isAuthorized(ctx); err != nil {
|
||||
- return err
|
||||
- }
|
||||
- c.logf("accepting SSH public key %s", bytes.TrimSpace(gossh.MarshalAuthorizedKey(pubKey)))
|
||||
- return nil
|
||||
-}
|
||||
-
|
||||
-// doPolicyAuth verifies that conn can proceed with the specified (optional)
|
||||
-// pubKey. It returns nil if the matching policy action is Accept or
|
||||
-// HoldAndDelegate. If pubKey is nil, there was no policy match but there is a
|
||||
-// policy that might match a public key it returns errPubKeyRequired. Otherwise,
|
||||
-// it returns errDenied.
|
||||
-func (c *conn) doPolicyAuth(ctx ssh.Context, pubKey ssh.PublicKey) error {
|
||||
+// doPolicyAuth verifies that conn can proceed.
|
||||
+// It returns nil if the matching policy action is Accept or
|
||||
+// HoldAndDelegate. Otherwise, it returns errDenied.
|
||||
+func (c *conn) doPolicyAuth(ctx ssh.Context) error {
|
||||
if err := c.setInfo(ctx); err != nil {
|
||||
c.logf("failed to get conninfo: %v", err)
|
||||
return errDenied
|
||||
}
|
||||
- a, localUser, acceptEnv, err := c.evaluatePolicy(pubKey)
|
||||
+ a, localUser, acceptEnv, err := c.evaluatePolicy()
|
||||
if err != nil {
|
||||
- if pubKey == nil && c.havePubKeyPolicy() {
|
||||
- return errPubKeyRequired
|
||||
- }
|
||||
return fmt.Errorf("%w: %v", errDenied, err)
|
||||
}
|
||||
c.action0 = a
|
||||
c.currentAction = a
|
||||
- c.pubKey = pubKey
|
||||
c.acceptEnv = acceptEnv
|
||||
if a.Message != "" {
|
||||
if err := ctx.SendAuthBanner(a.Message); err != nil {
|
||||
@@ -448,7 +411,6 @@ func (srv *server) newConn() (*conn, error) {
|
||||
ServerConfigCallback: c.ServerConfig,
|
||||
|
||||
NoClientAuthHandler: c.NoClientAuthCallback,
|
||||
- PublicKeyHandler: c.PublicKeyHandler,
|
||||
PasswordHandler: c.fakePasswordHandler,
|
||||
|
||||
Handler: c.handleSessionPostSSHAuth,
|
||||
@@ -516,34 +478,6 @@ func (c *conn) mayForwardLocalPortTo(ctx ssh.Context, destinationHost string, de
|
||||
return false
|
||||
}
|
||||
|
||||
-// havePubKeyPolicy reports whether any policy rule may provide access by means
|
||||
-// of a ssh.PublicKey.
|
||||
-func (c *conn) havePubKeyPolicy() bool {
|
||||
- if c.info == nil {
|
||||
- panic("havePubKeyPolicy called before setInfo")
|
||||
- }
|
||||
- // Is there any rule that looks like it'd require a public key for this
|
||||
- // sshUser?
|
||||
- pol, ok := c.sshPolicy()
|
||||
- if !ok {
|
||||
- return false
|
||||
- }
|
||||
- for _, r := range pol.Rules {
|
||||
- if c.ruleExpired(r) {
|
||||
- continue
|
||||
- }
|
||||
- if mapLocalUser(r.SSHUsers, c.info.sshUser) == "" {
|
||||
- continue
|
||||
- }
|
||||
- for _, p := range r.Principals {
|
||||
- if len(p.PubKeys) > 0 && c.principalMatchesTailscaleIdentity(p) {
|
||||
- return true
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- return false
|
||||
-}
|
||||
-
|
||||
// sshPolicy returns the SSHPolicy for current node.
|
||||
// If there is no SSHPolicy in the netmap, it returns a debugPolicy
|
||||
// if one is defined.
|
||||
@@ -620,117 +554,19 @@ func (c *conn) setInfo(ctx ssh.Context) error {
|
||||
}
|
||||
|
||||
// evaluatePolicy returns the SSHAction and localUser after evaluating
|
||||
-// the SSHPolicy for this conn. The pubKey may be nil for "none" auth.
|
||||
-func (c *conn) evaluatePolicy(pubKey gossh.PublicKey) (_ *tailcfg.SSHAction, localUser string, acceptEnv []string, _ error) {
|
||||
+// the SSHPolicy for this conn.
|
||||
+func (c *conn) evaluatePolicy() (_ *tailcfg.SSHAction, localUser string, acceptEnv []string, _ error) {
|
||||
pol, ok := c.sshPolicy()
|
||||
if !ok {
|
||||
return nil, "", nil, fmt.Errorf("tailssh: rejecting connection; no SSH policy")
|
||||
}
|
||||
- a, localUser, acceptEnv, ok := c.evalSSHPolicy(pol, pubKey)
|
||||
+ a, localUser, acceptEnv, ok := c.evalSSHPolicy(pol)
|
||||
if !ok {
|
||||
return nil, "", nil, fmt.Errorf("tailssh: rejecting connection; no matching policy")
|
||||
}
|
||||
return a, localUser, acceptEnv, nil
|
||||
}
|
||||
|
||||
-// pubKeyCacheEntry is the cache value for an HTTPS URL of public keys (like
|
||||
-// "https://github.com/foo.keys")
|
||||
-type pubKeyCacheEntry struct {
|
||||
- lines []string
|
||||
- etag string // if sent by server
|
||||
- at time.Time
|
||||
-}
|
||||
-
|
||||
-const (
|
||||
- pubKeyCacheDuration = time.Minute // how long to cache non-empty public keys
|
||||
- pubKeyCacheEmptyDuration = 15 * time.Second // how long to cache empty responses
|
||||
-)
|
||||
-
|
||||
-func (srv *server) fetchPublicKeysURLCached(url string) (ce pubKeyCacheEntry, ok bool) {
|
||||
- srv.mu.Lock()
|
||||
- defer srv.mu.Unlock()
|
||||
- // Mostly don't care about the size of this cache. Clean rarely.
|
||||
- if m := srv.fetchPublicKeysCache; len(m) > 50 {
|
||||
- tooOld := srv.now().Add(pubKeyCacheDuration * 10)
|
||||
- for k, ce := range m {
|
||||
- if ce.at.Before(tooOld) {
|
||||
- delete(m, k)
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- ce, ok = srv.fetchPublicKeysCache[url]
|
||||
- if !ok {
|
||||
- return ce, false
|
||||
- }
|
||||
- maxAge := pubKeyCacheDuration
|
||||
- if len(ce.lines) == 0 {
|
||||
- maxAge = pubKeyCacheEmptyDuration
|
||||
- }
|
||||
- return ce, srv.now().Sub(ce.at) < maxAge
|
||||
-}
|
||||
-
|
||||
-func (srv *server) pubKeyClient() *http.Client {
|
||||
- if srv.pubKeyHTTPClient != nil {
|
||||
- return srv.pubKeyHTTPClient
|
||||
- }
|
||||
- return http.DefaultClient
|
||||
-}
|
||||
-
|
||||
-// fetchPublicKeysURL fetches the public keys from a URL. The strings are in the
|
||||
-// the typical public key "type base64-string [comment]" format seen at e.g.
|
||||
-// https://github.com/USER.keys
|
||||
-func (srv *server) fetchPublicKeysURL(url string) ([]string, error) {
|
||||
- if !strings.HasPrefix(url, "https://") {
|
||||
- return nil, errors.New("invalid URL scheme")
|
||||
- }
|
||||
-
|
||||
- ce, ok := srv.fetchPublicKeysURLCached(url)
|
||||
- if ok {
|
||||
- return ce.lines, nil
|
||||
- }
|
||||
-
|
||||
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
- defer cancel()
|
||||
- req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||
- if err != nil {
|
||||
- return nil, err
|
||||
- }
|
||||
- if ce.etag != "" {
|
||||
- req.Header.Add("If-None-Match", ce.etag)
|
||||
- }
|
||||
- res, err := srv.pubKeyClient().Do(req)
|
||||
- if err != nil {
|
||||
- return nil, err
|
||||
- }
|
||||
- defer res.Body.Close()
|
||||
- var lines []string
|
||||
- var etag string
|
||||
- switch res.StatusCode {
|
||||
- default:
|
||||
- err = fmt.Errorf("unexpected status %v", res.Status)
|
||||
- srv.logf("fetching public keys from %s: %v", url, err)
|
||||
- case http.StatusNotModified:
|
||||
- lines = ce.lines
|
||||
- etag = ce.etag
|
||||
- case http.StatusOK:
|
||||
- var all []byte
|
||||
- all, err = io.ReadAll(io.LimitReader(res.Body, 4<<10))
|
||||
- if s := strings.TrimSpace(string(all)); s != "" {
|
||||
- lines = strings.Split(s, "\n")
|
||||
- }
|
||||
- etag = res.Header.Get("Etag")
|
||||
- }
|
||||
-
|
||||
- srv.mu.Lock()
|
||||
- defer srv.mu.Unlock()
|
||||
- mak.Set(&srv.fetchPublicKeysCache, url, pubKeyCacheEntry{
|
||||
- at: srv.now(),
|
||||
- lines: lines,
|
||||
- etag: etag,
|
||||
- })
|
||||
- return lines, err
|
||||
-}
|
||||
-
|
||||
// handleSessionPostSSHAuth runs an SSH session after the SSH-level authentication,
|
||||
// but not necessarily before all the Tailscale-level extra verification has
|
||||
// completed. It also handles SFTP requests.
|
||||
@@ -832,18 +668,6 @@ func (c *conn) expandDelegateURLLocked(actionURL string) string {
|
||||
).Replace(actionURL)
|
||||
}
|
||||
|
||||
-func (c *conn) expandPublicKeyURL(pubKeyURL string) string {
|
||||
- if !strings.Contains(pubKeyURL, "$") {
|
||||
- return pubKeyURL
|
||||
- }
|
||||
- loginName := c.info.uprof.LoginName
|
||||
- localPart, _, _ := strings.Cut(loginName, "@")
|
||||
- return strings.NewReplacer(
|
||||
- "$LOGINNAME_EMAIL", loginName,
|
||||
- "$LOGINNAME_LOCALPART", localPart,
|
||||
- ).Replace(pubKeyURL)
|
||||
-}
|
||||
-
|
||||
// sshSession is an accepted Tailscale SSH session.
|
||||
type sshSession struct {
|
||||
ssh.Session
|
||||
@@ -894,7 +718,7 @@ func (c *conn) newSSHSession(s ssh.Session) *sshSession {
|
||||
|
||||
// isStillValid reports whether the conn is still valid.
|
||||
func (c *conn) isStillValid() bool {
|
||||
- a, localUser, _, err := c.evaluatePolicy(c.pubKey)
|
||||
+ a, localUser, _, err := c.evaluatePolicy()
|
||||
c.vlogf("stillValid: %+v %v %v", a, localUser, err)
|
||||
if err != nil {
|
||||
return false
|
||||
@@ -1277,9 +1101,9 @@ func (c *conn) ruleExpired(r *tailcfg.SSHRule) bool {
|
||||
return r.RuleExpires.Before(c.srv.now())
|
||||
}
|
||||
|
||||
-func (c *conn) evalSSHPolicy(pol *tailcfg.SSHPolicy, pubKey gossh.PublicKey) (a *tailcfg.SSHAction, localUser string, acceptEnv []string, ok bool) {
|
||||
+func (c *conn) evalSSHPolicy(pol *tailcfg.SSHPolicy) (a *tailcfg.SSHAction, localUser string, acceptEnv []string, ok bool) {
|
||||
for _, r := range pol.Rules {
|
||||
- if a, localUser, acceptEnv, err := c.matchRule(r, pubKey); err == nil {
|
||||
+ if a, localUser, acceptEnv, err := c.matchRule(r); err == nil {
|
||||
return a, localUser, acceptEnv, true
|
||||
}
|
||||
}
|
||||
@@ -1296,7 +1120,7 @@ var (
|
||||
errInvalidConn = errors.New("invalid connection state")
|
||||
)
|
||||
|
||||
-func (c *conn) matchRule(r *tailcfg.SSHRule, pubKey gossh.PublicKey) (a *tailcfg.SSHAction, localUser string, acceptEnv []string, err error) {
|
||||
+func (c *conn) matchRule(r *tailcfg.SSHRule) (a *tailcfg.SSHAction, localUser string, acceptEnv []string, err error) {
|
||||
defer func() {
|
||||
c.vlogf("matchRule(%+v): %v", r, err)
|
||||
}()
|
||||
@@ -1326,9 +1150,7 @@ func (c *conn) matchRule(r *tailcfg.SSHRule, pubKey gossh.PublicKey) (a *tailcfg
|
||||
return nil, "", nil, errUserMatch
|
||||
}
|
||||
}
|
||||
- if ok, err := c.anyPrincipalMatches(r.Principals, pubKey); err != nil {
|
||||
- return nil, "", nil, err
|
||||
- } else if !ok {
|
||||
+ if !c.anyPrincipalMatches(r.Principals) {
|
||||
return nil, "", nil, errPrincipalMatch
|
||||
}
|
||||
return r.Action, localUser, r.AcceptEnv, nil
|
||||
@@ -1345,30 +1167,20 @@ func mapLocalUser(ruleSSHUsers map[string]string, reqSSHUser string) (localUser
|
||||
return v
|
||||
}
|
||||
|
||||
-func (c *conn) anyPrincipalMatches(ps []*tailcfg.SSHPrincipal, pubKey gossh.PublicKey) (bool, error) {
|
||||
+func (c *conn) anyPrincipalMatches(ps []*tailcfg.SSHPrincipal) bool {
|
||||
for _, p := range ps {
|
||||
if p == nil {
|
||||
continue
|
||||
}
|
||||
- if ok, err := c.principalMatches(p, pubKey); err != nil {
|
||||
- return false, err
|
||||
- } else if ok {
|
||||
- return true, nil
|
||||
+ if c.principalMatchesTailscaleIdentity(p) {
|
||||
+ return true
|
||||
}
|
||||
}
|
||||
- return false, nil
|
||||
-}
|
||||
-
|
||||
-func (c *conn) principalMatches(p *tailcfg.SSHPrincipal, pubKey gossh.PublicKey) (bool, error) {
|
||||
- if !c.principalMatchesTailscaleIdentity(p) {
|
||||
- return false, nil
|
||||
- }
|
||||
- return c.principalMatchesPubKey(p, pubKey)
|
||||
+ return false
|
||||
}
|
||||
|
||||
// principalMatchesTailscaleIdentity reports whether one of p's four fields
|
||||
// that match the Tailscale identity match (Node, NodeIP, UserLogin, Any).
|
||||
-// This function does not consider PubKeys.
|
||||
func (c *conn) principalMatchesTailscaleIdentity(p *tailcfg.SSHPrincipal) bool {
|
||||
ci := c.info
|
||||
if p.Any {
|
||||
@@ -1388,42 +1200,6 @@ func (c *conn) principalMatchesTailscaleIdentity(p *tailcfg.SSHPrincipal) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
-func (c *conn) principalMatchesPubKey(p *tailcfg.SSHPrincipal, clientPubKey gossh.PublicKey) (bool, error) {
|
||||
- if len(p.PubKeys) == 0 {
|
||||
- return true, nil
|
||||
- }
|
||||
- if clientPubKey == nil {
|
||||
- return false, nil
|
||||
- }
|
||||
- knownKeys := p.PubKeys
|
||||
- if len(knownKeys) == 1 && strings.HasPrefix(knownKeys[0], "https://") {
|
||||
- var err error
|
||||
- knownKeys, err = c.srv.fetchPublicKeysURL(c.expandPublicKeyURL(knownKeys[0]))
|
||||
- if err != nil {
|
||||
- return false, err
|
||||
- }
|
||||
- }
|
||||
- for _, knownKey := range knownKeys {
|
||||
- if pubKeyMatchesAuthorizedKey(clientPubKey, knownKey) {
|
||||
- return true, nil
|
||||
- }
|
||||
- }
|
||||
- return false, nil
|
||||
-}
|
||||
-
|
||||
-func pubKeyMatchesAuthorizedKey(pubKey ssh.PublicKey, wantKey string) bool {
|
||||
- wantKeyType, rest, ok := strings.Cut(wantKey, " ")
|
||||
- if !ok {
|
||||
- return false
|
||||
- }
|
||||
- if pubKey.Type() != wantKeyType {
|
||||
- return false
|
||||
- }
|
||||
- wantKeyB64, _, _ := strings.Cut(rest, " ")
|
||||
- wantKeyData, _ := base64.StdEncoding.DecodeString(wantKeyB64)
|
||||
- return len(wantKeyData) > 0 && bytes.Equal(pubKey.Marshal(), wantKeyData)
|
||||
-}
|
||||
-
|
||||
func randBytes(n int) []byte {
|
||||
b := make([]byte, n)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
@@ -1749,7 +1525,6 @@ func envEq(a, b string) bool {
|
||||
var (
|
||||
metricActiveSessions = clientmetric.NewGauge("ssh_active_sessions")
|
||||
metricIncomingConnections = clientmetric.NewCounter("ssh_incoming_connections")
|
||||
- metricPublicKeyAccepts = clientmetric.NewCounter("ssh_publickey_accepts") // accepted subset of ssh_publickey_connections
|
||||
metricTerminalAccept = clientmetric.NewCounter("ssh_terminalaction_accept")
|
||||
metricTerminalReject = clientmetric.NewCounter("ssh_terminalaction_reject")
|
||||
metricTerminalMalformed = clientmetric.NewCounter("ssh_terminalaction_malformed")
|
||||
diff --git a/ssh/tailssh/tailssh_test.go b/ssh/tailssh/tailssh_test.go
|
||||
index ad9cb1e57b53d..9f3616d8ca8ab 100644
|
||||
--- a/ssh/tailssh/tailssh_test.go
|
||||
+++ b/ssh/tailssh/tailssh_test.go
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"context"
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
- "crypto/sha256"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -229,7 +228,7 @@ func TestMatchRule(t *testing.T) {
|
||||
info: tt.ci,
|
||||
srv: &server{logf: t.Logf},
|
||||
}
|
||||
- got, gotUser, gotAcceptEnv, err := c.matchRule(tt.rule, nil)
|
||||
+ got, gotUser, gotAcceptEnv, err := c.matchRule(tt.rule)
|
||||
if err != tt.wantErr {
|
||||
t.Errorf("err = %v; want %v", err, tt.wantErr)
|
||||
}
|
||||
@@ -348,7 +347,7 @@ func TestEvalSSHPolicy(t *testing.T) {
|
||||
info: tt.ci,
|
||||
srv: &server{logf: t.Logf},
|
||||
}
|
||||
- got, gotUser, gotAcceptEnv, match := c.evalSSHPolicy(tt.policy, nil)
|
||||
+ got, gotUser, gotAcceptEnv, match := c.evalSSHPolicy(tt.policy)
|
||||
if match != tt.wantMatch {
|
||||
t.Errorf("match = %v; want %v", match, tt.wantMatch)
|
||||
}
|
||||
@@ -1129,89 +1128,6 @@ func parseEnv(out []byte) map[string]string {
|
||||
return e
|
||||
}
|
||||
|
||||
-func TestPublicKeyFetching(t *testing.T) {
|
||||
- var reqsTotal, reqsIfNoneMatchHit, reqsIfNoneMatchMiss int32
|
||||
- ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
- atomic.AddInt32((&reqsTotal), 1)
|
||||
- etag := fmt.Sprintf("W/%q", sha256.Sum256([]byte(r.URL.Path)))
|
||||
- w.Header().Set("Etag", etag)
|
||||
- if v := r.Header.Get("If-None-Match"); v != "" {
|
||||
- if v == etag {
|
||||
- atomic.AddInt32(&reqsIfNoneMatchHit, 1)
|
||||
- w.WriteHeader(304)
|
||||
- return
|
||||
- }
|
||||
- atomic.AddInt32(&reqsIfNoneMatchMiss, 1)
|
||||
- }
|
||||
- io.WriteString(w, "foo\nbar\n"+string(r.URL.Path)+"\n")
|
||||
- }))
|
||||
- ts.StartTLS()
|
||||
- defer ts.Close()
|
||||
- keys := ts.URL
|
||||
-
|
||||
- clock := &tstest.Clock{}
|
||||
- srv := &server{
|
||||
- pubKeyHTTPClient: ts.Client(),
|
||||
- timeNow: clock.Now,
|
||||
- }
|
||||
- for range 2 {
|
||||
- got, err := srv.fetchPublicKeysURL(keys + "/alice.keys")
|
||||
- if err != nil {
|
||||
- t.Fatal(err)
|
||||
- }
|
||||
- if want := []string{"foo", "bar", "/alice.keys"}; !reflect.DeepEqual(got, want) {
|
||||
- t.Errorf("got %q; want %q", got, want)
|
||||
- }
|
||||
- }
|
||||
- if got, want := atomic.LoadInt32(&reqsTotal), int32(1); got != want {
|
||||
- t.Errorf("got %d requests; want %d", got, want)
|
||||
- }
|
||||
- if got, want := atomic.LoadInt32(&reqsIfNoneMatchHit), int32(0); got != want {
|
||||
- t.Errorf("got %d etag hits; want %d", got, want)
|
||||
- }
|
||||
- clock.Advance(5 * time.Minute)
|
||||
- got, err := srv.fetchPublicKeysURL(keys + "/alice.keys")
|
||||
- if err != nil {
|
||||
- t.Fatal(err)
|
||||
- }
|
||||
- if want := []string{"foo", "bar", "/alice.keys"}; !reflect.DeepEqual(got, want) {
|
||||
- t.Errorf("got %q; want %q", got, want)
|
||||
- }
|
||||
- if got, want := atomic.LoadInt32(&reqsTotal), int32(2); got != want {
|
||||
- t.Errorf("got %d requests; want %d", got, want)
|
||||
- }
|
||||
- if got, want := atomic.LoadInt32(&reqsIfNoneMatchHit), int32(1); got != want {
|
||||
- t.Errorf("got %d etag hits; want %d", got, want)
|
||||
- }
|
||||
- if got, want := atomic.LoadInt32(&reqsIfNoneMatchMiss), int32(0); got != want {
|
||||
- t.Errorf("got %d etag misses; want %d", got, want)
|
||||
- }
|
||||
-
|
||||
-}
|
||||
-
|
||||
-func TestExpandPublicKeyURL(t *testing.T) {
|
||||
- c := &conn{
|
||||
- info: &sshConnInfo{
|
||||
- uprof: tailcfg.UserProfile{
|
||||
- LoginName: "bar@baz.tld",
|
||||
- },
|
||||
- },
|
||||
- }
|
||||
- if got, want := c.expandPublicKeyURL("foo"), "foo"; got != want {
|
||||
- t.Errorf("basic: got %q; want %q", got, want)
|
||||
- }
|
||||
- if got, want := c.expandPublicKeyURL("https://example.com/$LOGINNAME_LOCALPART.keys"), "https://example.com/bar.keys"; got != want {
|
||||
- t.Errorf("localpart: got %q; want %q", got, want)
|
||||
- }
|
||||
- if got, want := c.expandPublicKeyURL("https://example.com/keys?email=$LOGINNAME_EMAIL"), "https://example.com/keys?email=bar@baz.tld"; got != want {
|
||||
- t.Errorf("email: got %q; want %q", got, want)
|
||||
- }
|
||||
- c.info = new(sshConnInfo)
|
||||
- if got, want := c.expandPublicKeyURL("https://example.com/keys?email=$LOGINNAME_EMAIL"), "https://example.com/keys?email="; got != want {
|
||||
- t.Errorf("on empty: got %q; want %q", got, want)
|
||||
- }
|
||||
-}
|
||||
-
|
||||
func TestAcceptEnvPair(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go
|
||||
index 897e8d27f7f7b..be6c4f0be6b82 100644
|
||||
--- a/tailcfg/tailcfg.go
|
||||
+++ b/tailcfg/tailcfg.go
|
||||
@@ -152,7 +152,8 @@ type CapabilityVersion int
|
||||
// - 107: 2024-10-30: add App Connector to conffile (PR #13942)
|
||||
// - 108: 2024-11-08: Client sends ServicesHash in Hostinfo, understands c2n GET /vip-services.
|
||||
// - 109: 2024-11-18: Client supports filtertype.Match.SrcCaps (issue #12542)
|
||||
-const CurrentCapabilityVersion CapabilityVersion = 109
|
||||
+// - 110: 2024-12-12: removed never-before-used Tailscale SSH public key support (#14373)
|
||||
+const CurrentCapabilityVersion CapabilityVersion = 110
|
||||
|
||||
type StableID string
|
||||
|
||||
@@ -2525,16 +2526,13 @@ type SSHPrincipal struct {
|
||||
Any bool `json:"any,omitempty"` // if true, match any connection
|
||||
// TODO(bradfitz): add StableUserID, once that exists
|
||||
|
||||
- // PubKeys, if non-empty, means that this SSHPrincipal only
|
||||
- // matches if one of these public keys is presented by the user.
|
||||
+ // UnusedPubKeys was public key support. It never became an official product
|
||||
+ // feature and so as of 2024-12-12 is being removed.
|
||||
+ // This stub exists to remind us not to re-use the JSON field name "pubKeys"
|
||||
+ // in the future if we bring it back with different semantics.
|
||||
//
|
||||
- // As a special case, if len(PubKeys) == 1 and PubKeys[0] starts
|
||||
- // with "https://", then it's fetched (like https://github.com/username.keys).
|
||||
- // In that case, the following variable expansions are also supported
|
||||
- // in the URL:
|
||||
- // * $LOGINNAME_EMAIL ("foo@bar.com" or "foo@github")
|
||||
- // * $LOGINNAME_LOCALPART (the "foo" from either of the above)
|
||||
- PubKeys []string `json:"pubKeys,omitempty"`
|
||||
+ // Deprecated: do not use. It does nothing.
|
||||
+ UnusedPubKeys []string `json:"pubKeys,omitempty"`
|
||||
}
|
||||
|
||||
// SSHAction is how to handle an incoming connection.
|
||||
diff --git a/tailcfg/tailcfg_clone.go b/tailcfg/tailcfg_clone.go
|
||||
index f4f02c01721dc..bf9bac2980df9 100644
|
||||
--- a/tailcfg/tailcfg_clone.go
|
||||
+++ b/tailcfg/tailcfg_clone.go
|
||||
@@ -556,17 +556,17 @@ func (src *SSHPrincipal) Clone() *SSHPrincipal {
|
||||
}
|
||||
dst := new(SSHPrincipal)
|
||||
*dst = *src
|
||||
- dst.PubKeys = append(src.PubKeys[:0:0], src.PubKeys...)
|
||||
+ dst.UnusedPubKeys = append(src.UnusedPubKeys[:0:0], src.UnusedPubKeys...)
|
||||
return dst
|
||||
}
|
||||
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _SSHPrincipalCloneNeedsRegeneration = SSHPrincipal(struct {
|
||||
- Node StableNodeID
|
||||
- NodeIP string
|
||||
- UserLogin string
|
||||
- Any bool
|
||||
- PubKeys []string
|
||||
+ Node StableNodeID
|
||||
+ NodeIP string
|
||||
+ UserLogin string
|
||||
+ Any bool
|
||||
+ UnusedPubKeys []string
|
||||
}{})
|
||||
|
||||
// Clone makes a deep copy of ControlDialPlan.
|
||||
diff --git a/tailcfg/tailcfg_view.go b/tailcfg/tailcfg_view.go
|
||||
index f275a6a9da5f2..6c21e5f450340 100644
|
||||
--- a/tailcfg/tailcfg_view.go
|
||||
+++ b/tailcfg/tailcfg_view.go
|
||||
@@ -1260,19 +1260,21 @@ func (v *SSHPrincipalView) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
-func (v SSHPrincipalView) Node() StableNodeID { return v.ж.Node }
|
||||
-func (v SSHPrincipalView) NodeIP() string { return v.ж.NodeIP }
|
||||
-func (v SSHPrincipalView) UserLogin() string { return v.ж.UserLogin }
|
||||
-func (v SSHPrincipalView) Any() bool { return v.ж.Any }
|
||||
-func (v SSHPrincipalView) PubKeys() views.Slice[string] { return views.SliceOf(v.ж.PubKeys) }
|
||||
+func (v SSHPrincipalView) Node() StableNodeID { return v.ж.Node }
|
||||
+func (v SSHPrincipalView) NodeIP() string { return v.ж.NodeIP }
|
||||
+func (v SSHPrincipalView) UserLogin() string { return v.ж.UserLogin }
|
||||
+func (v SSHPrincipalView) Any() bool { return v.ж.Any }
|
||||
+func (v SSHPrincipalView) UnusedPubKeys() views.Slice[string] {
|
||||
+ return views.SliceOf(v.ж.UnusedPubKeys)
|
||||
+}
|
||||
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _SSHPrincipalViewNeedsRegeneration = SSHPrincipal(struct {
|
||||
- Node StableNodeID
|
||||
- NodeIP string
|
||||
- UserLogin string
|
||||
- Any bool
|
||||
- PubKeys []string
|
||||
+ Node StableNodeID
|
||||
+ NodeIP string
|
||||
+ UserLogin string
|
||||
+ Any bool
|
||||
+ UnusedPubKeys []string
|
||||
}{})
|
||||
|
||||
// View returns a readonly view of ControlDialPlan.
|
3
tailscale-1.70.0.tar.gz
Normal file
3
tailscale-1.70.0.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:294d6df3f4585152bd612eed9b34a6c2062589c8989f86ee25e750c37164fcd5
|
||||
size 55014834
|
3
tailscale-1.72.1.tar.gz
Normal file
3
tailscale-1.72.1.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:03e15ea076362eda1a44712351ba2a19bf746970fee8ddc4013513a07337cbe0
|
||||
size 11331158
|
3
tailscale-1.74.0.tar.gz
Normal file
3
tailscale-1.74.0.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:65adec42c6b6c42a107d63b5c9eb2c10ae0e87f4d701aa5e35c4e31a81bcd381
|
||||
size 11323679
|
3
tailscale-1.74.1.tar.gz
Normal file
3
tailscale-1.74.1.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7357c9fe3b0dabbb35847d8181f8500007299ec93586c23cd1c50af4183ccd19
|
||||
size 11462868
|
3
tailscale-1.76.1.tar.gz
Normal file
3
tailscale-1.76.1.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:87ebf950ec15274f6e7105acfe3d5565ea39bfc7cdd9762248df26da9874d9fc
|
||||
size 11842133
|
3
tailscale-1.76.3.tar.gz
Normal file
3
tailscale-1.76.3.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dab7ef3240df51e7b51238d4239822ac8dec8106282acf1f07208bd699da99b7
|
||||
size 12050220
|
3
tailscale-1.76.6.tar.gz
Normal file
3
tailscale-1.76.6.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:627769855263d35d26e3b855efdf79167d42f08a3087f5a678b7aa5298e30a72
|
||||
size 12438906
|
3
tailscale-1.78.1.tar.gz
Normal file
3
tailscale-1.78.1.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a035f99f9bdc8c0a3de278a538c1e8df1e886d8f2bfe0bd4567a3c2850e31d48
|
||||
size 11935577
|
3
tailscale-1.78.3.tar.gz
Normal file
3
tailscale-1.78.3.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1b10020e1b94fce5556f7ef67e5bd529fd1a209dcb7694bf13c1edafbce097cd
|
||||
size 12121603
|
3
tailscale-1.80.0.tar.gz
Normal file
3
tailscale-1.80.0.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3c7a09a5a96c0c21f70aa4e1a1a934c8d5b1ef3db80e8aab98d53ee664585277
|
||||
size 12573438
|
454
tailscale.changes
Normal file
454
tailscale.changes
Normal file
@@ -0,0 +1,454 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 31 17:20:29 UTC 2025 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.80.0:
|
||||
* Hostname system policy is added for overriding the device hostname
|
||||
configured by the operating system, using an MDM solution.
|
||||
* Web interface displays a Login button instead of the Reauthenticate button
|
||||
when adding a new device to your tailnet.
|
||||
* Tailscale Funnel configuration on devices displays errors when incoming
|
||||
connections are not permitted and connections are disallowed.
|
||||
* Connections to a custom coordination server that does not support HTTPS
|
||||
will no longer fail when a custom port number is specified.
|
||||
* TLS certificate requests from Let’s Encrypt include the device's DNS name
|
||||
in the CSR’s SAN extension and set the Common Name field.
|
||||
* Tailscale Funnel disabled on a device no longer displays enabled in the
|
||||
admin console.
|
||||
* GitHub username change automatically updates tailnet name
|
||||
* 4via6 subnet routers GA
|
||||
* Auto approvers GA
|
||||
* Node attributes GA
|
||||
* Download invoices GA
|
||||
* Fast user switching GA
|
||||
* Configuration log streaming integration with S3 buckets GA
|
||||
* Network flow log streaming integration with S3 buckets GA
|
||||
* NextDNS profiles per device GA
|
||||
* GitHub secret scanning
|
||||
- remove fix-CVE-2024-45337.patch, as it's now included
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Dec 18 17:33:23 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- add patch fix-CVE-2024-45337.patch, to circumevent a possibility
|
||||
of exploiting the golang-x-crypto security hole. (fix #1234506)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 13 05:06:26 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.78.3:
|
||||
* cmd/containerboot: fix nil pointer exception
|
||||
* hostinfo: fix testing in container
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 6 01:22:05 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.78.1:
|
||||
* health: fix TestHealthMetric
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Dec 5 22:10:32 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.78.0:
|
||||
* Client metrics have been added, to provide insights into Tailscale client
|
||||
behavior, health, and performance.
|
||||
* tailscale metrics command has been added, to expose and collect client
|
||||
metrics for use with third-party monitoring systems.
|
||||
* tailscale syspolicy command has been added, to list system policies, reload
|
||||
system policies, or view errors related to the system policies configured
|
||||
on the device.
|
||||
* Tailscale system policies are applied immediately when pushed via mobile
|
||||
device management (MDM) or Group Policy, without requiring a client restart.
|
||||
* Tailscale SSH session recording detects the disappearance of the recorder
|
||||
node sooner. This fix addresses a security vulnerability described
|
||||
in TS-2024-013.
|
||||
* New scopes for OAuth clients have been added with more granular permissions.
|
||||
Existing OAuth clients using the previous set of scopes, and keys generated
|
||||
using these clients, are still valid.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Nov 8 03:46:50 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.76.6:
|
||||
* Logging for when clients move home DERP regions is improved.
|
||||
* Tailscale clients no longer move their home DERP server prematurely in
|
||||
response to unusual latency at very specific times.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Oct 22 18:34:42 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.76.3:
|
||||
* no relevant changelog
|
||||
- update to 1.76.2:
|
||||
* no relevant changelog
|
||||
- switch over to the new %{default_fw_backend} macro
|
||||
- create old init file only for < leap 16
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 16 20:40:31 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.76.1:
|
||||
* tailscale netcheck CLI command no longer crashes when performing diagnostics
|
||||
on networks lacking UDP connectivity.
|
||||
* Improperly formatted SERVFAIL responses no longer cause DNS timeouts when using an exit node.
|
||||
* dbus login sessions no longer fail on systems where /bin/login is missing.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Oct 14 13:06:13 UTC 2024 - Alexandre Vicenzi <alexandre.vicenzi@suse.com>
|
||||
|
||||
- Require a firewall backend (boo#1228829)
|
||||
- Add simple test check to ensure binaries are working
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Oct 11 06:07:28 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.76.0:
|
||||
* Clients lacking UDP connectivity no longer skip performing fallback latency
|
||||
measurements with DERP servers.
|
||||
* Warnings no longer display unnecessarily.
|
||||
* Tailscale connectivity on in-flight internet on airplanes (such as Alaska Airlines) no longer fails.
|
||||
* Service-related processes no longer run unnecessarily when services are disabled on the tailnet.
|
||||
* Error messages include explanations in addition to the HTTP status code.
|
||||
* Tailscale SSH supports sending environment variables to hosts. It's also possible to specify
|
||||
permitted environment variables using the acceptEnv field.
|
||||
* Tailscale SSH no longer breaks some terminal applications by omitting pixel width and height when
|
||||
resizing the application window.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Sep 21 05:28:42 UTC 2024 - Eric Torres <eric.torres@its-et.me>
|
||||
|
||||
- Change path of zsh completion file to make zsh properly recognize completions
|
||||
* /usr/share/zsh/site-functions/tailscale moved to /usr/share/zsh/site-functions/_tailscale
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Sep 18 19:10:19 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.74.1:
|
||||
* wgengine/magicsock: disable raw disco by default; add envknob to enable
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Sep 13 10:48:17 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.74.0
|
||||
* AuthKey system policy can be used to authenticate a device with Tailscale using an MDM solution.
|
||||
* tailscale dns CLI command is added for accessing Tailscale DNS settings and status.
|
||||
* Tailnet Lock long rotation signatures are truncated automatically to avoid excessive growth.
|
||||
* Log In option in the client works as expected.
|
||||
* TCP generic receive offload (GRO) support is added for improved userspace mode throughput.
|
||||
* TCP generic segmentation offload (GSO) is re-introduced for supporting improved userspace mode throughput.
|
||||
This was initially introduced in Tailscale v1.72.0 and then rolled back in v1.72.1.
|
||||
* Device posture integration with CrowdStrike Falcon can now use MAC addresses to match devices that lack serial numbers.
|
||||
When Falcon integration is configured, Device Identity Collection will automatically collect MAC addresses.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Aug 22 22:08:51 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.72.1:
|
||||
* DNS over TCP failures when querying the Tailscale-internal resolver are fixed.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Aug 21 16:05:02 UTC 2024 - rrahl0@opensuse.org
|
||||
|
||||
- Update to version 1.72.0:
|
||||
* posture: deduplicate MAC addresses before returning them
|
||||
* health/dns: reduce severity of DNS unavailable warning
|
||||
* safeweb: add Server.Close method
|
||||
* go.mod.sri: update SRI hash for go.mod changes
|
||||
* go.{mod,sum}: migrate from nhooyr.io/websocket to github.com/coder/websocket
|
||||
* cmd/viewer: add support for map-like container types
|
||||
- update golang(API) to 1.23
|
||||
- export version variables, to circumvent a bug
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jul 18 06:31:58 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.70.0:
|
||||
* New: Restrict recommended and automatically selected exit nodes using the
|
||||
new AllowedSuggestedExitNodes system policy. Applies only to platforms that
|
||||
support system policies.
|
||||
* Changed: Improved NAT traversal for some uncommon scenarios.
|
||||
* Changed: Optimized sending firewall rules to clients more efficiently.
|
||||
* Fixed: Exit node suggestion CLI command now prints the hostname.
|
||||
* Fixed: Taildrive share paths configured through the CLI resolve relative
|
||||
to where you run the tailscale command.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Jul 2 20:35:35 UTC 2024 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- update to 1.68.2:
|
||||
* Fixed: Tailnet lock validation of rotation signatures now permits multiple nodes
|
||||
signed by the same pre-signed reusable auth key.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sun Jun 16 13:30:20 UTC 2024 - Richard Rahl <rrahl0@disroot.org>
|
||||
|
||||
- update to 1.68.1:
|
||||
* Fixed: 4via6 subnet router advertisement works as expected.
|
||||
* Fixed: Tailscale SSH access to Security-Enhanced Linux (SELinux) machines works as expected.
|
||||
- update to 1.68.0:
|
||||
* New: Auto-updates are allowed in containers, but ignore the tailnet-wide default
|
||||
* New: Apply auto-updates even if the node is down or disconnected from the coordination server.
|
||||
* New: tailscale lock status now prints the node's signature.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed May 22 08:36:37 UTC 2024 - Richard Rahl <rrahl0@disroot.org>
|
||||
|
||||
- update to 1.66.4:
|
||||
* Fixed: Restored UDP connectivity through Mullvad exit nodes
|
||||
* Stateful filtering is now off by default
|
||||
|
||||
- update to 1.66.3:
|
||||
* Login URLs did not always appear in the console when running tailscale up
|
||||
* Starting with v1.66, the Kubernetes operator must always run the same or later version
|
||||
as the proxies it manages.
|
||||
* Expose cloud services on cluster network to the tailnet, using Kubernetes ExternalName Services
|
||||
* Expose tailnet services that use Tailscale HTTPS to cluster workloads
|
||||
* Cluster workloads can now refer to Tailscale Ingress resources by their MagicDNS names
|
||||
* Configure environment variables for Tailscale Kubernetes operator proxies using ProxyClass CRD
|
||||
* Expose tailscaled metrics endpoint for Tailscale Kubernetes operator proxies through ProxyClass CRD
|
||||
* Configure labels for the Kubernetes operator Pods with Helm chart values
|
||||
* Configure affinity rules for Kubernetes operator proxy Pods with ProxyClass
|
||||
* Kubernetes operator proxy init container no longer attempts to enable IPv6 forwarding on systems
|
||||
that don't have IPv6 module loaded
|
||||
* Tailscale containers running on Kubernetes no longer error if an empty Kubernetes Secret is
|
||||
pre-created for the tailscaled state
|
||||
* Improved the ambiguous error messages when Tailscale running on Kubernetes does not have the right
|
||||
permissions to perform actions against the tailscaled state Secret
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri May 10 15:16:33 UTC 2024 - Richard Rahl <rrahl0@disroot.org>
|
||||
|
||||
- update to 1.66.1:
|
||||
* Resolved issues with nftables rules for stateful filtering,
|
||||
introduced in v1.66.0.
|
||||
* tailscale set command flags --netfilter-mode, --snat-subnet-routes,
|
||||
and --stateful-filtering are added.
|
||||
|
||||
- update to 1.66.0:
|
||||
* Implemented client-side quarantining for shared-in exit nodes,
|
||||
as a mitigation for a security vulnerability described in TS-2024-005.
|
||||
* Use the --stateful-filtering flag for the tailscale up to enable stateful filtering for
|
||||
subnet routers and exit nodes, as a mitigation for a security vulnerability described
|
||||
in TS-2024-005.
|
||||
* Added tab completions
|
||||
* Use the tailscale exit-node suggest command to automatically pick an available exit node
|
||||
that is likely to perform best.
|
||||
* Site-to-site networking now also requires --stateful-filtering=false in addition to
|
||||
--snat-subnet-routes=false on new subnet routers. Existing subnet routers with --snat-subnet-routes=false
|
||||
will default to --stateful-filtering=false.
|
||||
|
||||
- update to 1.64.2:
|
||||
* nothing relevant for linux
|
||||
|
||||
- update to 1.64.1:
|
||||
* nothing relevant for linux
|
||||
|
||||
- update to 1.64.0:
|
||||
* New: tailscale configure kubeconfig now respects KUBECONFIG environment variable.
|
||||
* Fixed: tailscale configure kubeconfig now works with partially empty kubeconfig.
|
||||
* Fixed: MSS clamping for Kubernetes operator proxies using nftables.
|
||||
* Fixed: Containers on hosts with partial support for ip6tables no longer crash.
|
||||
|
||||
- turn of changelog generation
|
||||
- add completions for bash
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Mar 30 08:28:56 UTC 2024 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- update to 1.62.1:
|
||||
* Send load balancing hint HTTP request header
|
||||
* Fixed: Kubernetes operator proxies should not accept subnet routes
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Mar 14 03:13:54 UTC 2024 - rrahl0@proton.me
|
||||
|
||||
- update to 1.62.0:
|
||||
* IPv6 support detection in a container environment is improved
|
||||
* New: Web interface now uses ACL grants to manage access on tagged devices
|
||||
* Tailscale SSH connections now disable unnecessary hostname canonicalization
|
||||
* tailscale bugreport command for generating diagnostic logs now contain ethtool information
|
||||
* Mullvad's family-friendly server is added to the list of well known DNS over HTTPS (DoH) servers
|
||||
* DNS over HTTP requests now contain a timeout
|
||||
* TCP forwarding attempts in userspace mode now have a per-client limit
|
||||
* Endpoints with link-local IPv6 addresses is preferred over private addresses
|
||||
* WireGuard logs are less verbose
|
||||
* Go min. version 1.22.1
|
||||
* DERP server region no longer changes if connectivity to the new DERP region is degraded
|
||||
|
||||
- update to 1.60.1:
|
||||
* Exposing port 8080 to other devices on your tailnet works as expected
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Feb 20 22:10:41 UTC 2024 - Alexandre Vicenzi <alexandre.vicenzi@suse.com>
|
||||
|
||||
- Add disable-auto-update.patch to prevent auto updates and instead
|
||||
ask users to use Zypper to update manually
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Feb 20 14:52:46 UTC 2024 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- change to the non deprecated manualrun
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Feb 16 14:38:14 UTC 2024 - alexandre.vicenzi@suse.com
|
||||
|
||||
- Spec cleanup
|
||||
* Use tar_scm to avoid commit hashes in the spec
|
||||
* Use tailscale build scripts
|
||||
* Drop ProtectClock fix for Leap, DeviceAllow fixes it
|
||||
- Add build-verbose.patch to get go flags into build log
|
||||
- Enable PrivateDevices but allow access to /dev/net/tun in tailscaled.service
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Feb 16 00:50:26 UTC 2024 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- update to 1.60.0:
|
||||
* minimum go version 1.22
|
||||
* authentication: present users with a valid login page when
|
||||
attempting to login even after leaving device unattended for several days
|
||||
* networking: mute noisy peer mtu discovery errors
|
||||
* networking: expose gVisor metrics in debug mode
|
||||
* port mapper: support legacy "urn:dslforum-org" port mapping services
|
||||
* port mapper: fix crash when no support mapping services found
|
||||
* ssh: log warning when unable to find SSH host keys
|
||||
* serve: improve error message when running as non-root
|
||||
* Detect when Tailscale is running on Digital Ocean and automatically
|
||||
use Digital Ocean's DNS resolvers
|
||||
* enable app connectors to install routes for domains that resolve to CNAME
|
||||
records
|
||||
* support pre-configured routes from control server
|
||||
* add new read-only mode
|
||||
* tailscale status command: fix output formatting Tailnet
|
||||
includes location-based exit nodes
|
||||
* a new ProxyClass custom resource that allows to provide custom
|
||||
configuration for cluster resources that the operator creates
|
||||
* ACL tags for the operator can now be configured via Helm chart values
|
||||
* routing to Ingress backends that require an exact path without a slash
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Feb 7 14:52:53 UTC 2024 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- make rpm not overwrite /etc/default/taiscaled
|
||||
- defattr everything to root
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Feb 3 11:18:05 UTC 2024 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- no stripping of binaries
|
||||
- add commitID to binaries for upstream
|
||||
- add directory for saved configs
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Jan 23 23:54:36 UTC 2024 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- switch services to manual
|
||||
- update to version 1.58.2:
|
||||
* Fixed: [App connectors][app-connectors] have improved scheduling
|
||||
and merging of route changes under some conditions
|
||||
* Fixed: Crash when performing UPnP portmapping on older routers
|
||||
with no supported portmapping services
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 19 08:06:27 UTC 2024 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- update to version 1.58.0:
|
||||
* portmap: check the epoch from NAT-PMP & PCP, establish new portmapping if it changes
|
||||
* portmap: better handle multiple interfaces
|
||||
* portmap: handle multiple UPnP discovery responses
|
||||
* increase the number of 4via6 site IDs from 256 to 65,536
|
||||
* taildrop: allow category Z unicode characters
|
||||
* increased binary size with 1.56 is resolved in 1.58
|
||||
* Reduce home DERP flapping when there's still an active connection
|
||||
* device web ui: fixed issue when accessing shared devices
|
||||
* device web ui: fixed login issue when accessed over https
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jan 10 02:17:57 UTC 2024 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- fix an issue with Leap, where ProtectClock prevents to connect to
|
||||
/dev/net/tun
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 15 21:22:39 UTC 2023 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- update to version 1.56.1:
|
||||
* Fixed: Web interface redirects to the correct self IP known by source peer
|
||||
* Fixed: Usage of slices.Compact from app connector domains list
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 15 13:48:28 UTC 2023 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- fix version output to what upstream expects
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Dec 13 22:08:30 UTC 2023 - rrahl0@proton.me
|
||||
|
||||
- Update to version 1.56.0:
|
||||
* improve responsiveness under load, especially with bidirectional traffic
|
||||
* improve UPnP portmapping
|
||||
* add tailscale whois subcommand to observe metadata associated with a Tailscale IP
|
||||
* include tailnet name and profile ID in tailscale switch --list to disambiguate
|
||||
profiles with common login names
|
||||
* improve tailscale web interface for configuring some device settings such as exit nodes,
|
||||
subnet routers, and Tailscale SSH
|
||||
* improve containerboot to symlink its socket file if possible,
|
||||
making the tailscale CLI work without --socket=/tmp/tailscale.sock
|
||||
* add support in Kubernetes operator cluster egress for referring to a tailnet service
|
||||
by its MagicDNS name
|
||||
|
||||
|
||||
- Update to version 1.54.1:
|
||||
* no relevant updates to the linux version
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Nov 24 21:59:11 UTC 2023 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- tailscale couldn't connect to /dev/net/tun
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 23 06:51:24 UTC 2023 - rrahl0@proton.me
|
||||
|
||||
- Update to version 1.54.0:
|
||||
* improve throughput substantially for UDP packets over TUN device with recent Linux kernels
|
||||
|
||||
|
||||
- Update to version 1.52.1:
|
||||
* no linux improvements
|
||||
|
||||
- Update to version 1.52.0:
|
||||
* tailscale set command flag --auto-update is added to opt in to automatic client updates
|
||||
* tailscale serve and tailscale funnel commands are updated for improved usability
|
||||
* tailscale update command for manual updates is now in beta
|
||||
* Taildrop file transfer displays a progress meter
|
||||
* nftables auto-detection is improved when TS_DEBUG_FIREWALL_MODE=auto is used
|
||||
* DNS detection of NetworkManager with configured but absent systemd-resolved
|
||||
* Taildrop now resumes file transfers after partial transfers are interrupted
|
||||
* tailscale up command displays a message about client updates when newer versions are available
|
||||
* tailscale status command displays a message about client updates when newer versions are available
|
||||
* tailscale cert command renews in the background. The current certificate only displays if it has expired.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Oct 02 23:51:03 UTC 2023 - rrahl0@proton.me
|
||||
|
||||
- Update to version 1.50.1:
|
||||
* fix bug where serve config could get wiped
|
||||
* Funnel support for tsnet apps
|
||||
* fix potential crash with UPnP
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Sep 30 19:38:50 UTC 2023 - rrahl0@proton.me
|
||||
|
||||
- Update to version 1.50.0:
|
||||
* Update tailscale{,d} licenses
|
||||
* Update Quad9 addresses and references
|
||||
* Adds support for Wikimedia DNS using DNS-over-HTTPS
|
||||
|
||||
- Update to version 1.48.1:
|
||||
* no relevant updates
|
||||
|
||||
- Update to version 1.48.2:
|
||||
* Improvements to Mullvad exit nodes
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Aug 18 15:56:24 UTC 2023 - Richard Rahl <rrahl0@proton.me>
|
||||
|
||||
- Initial revision
|
143
tailscale.spec
Normal file
143
tailscale.spec
Normal file
@@ -0,0 +1,143 @@
|
||||
#
|
||||
# spec file for package tailscale
|
||||
#
|
||||
# Copyright (c) 2025 SUSE LLC
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
# upon. The license for this file, and modifications and additions to the
|
||||
# file, is the same license as for the pristine package itself (unless the
|
||||
# license for the pristine package is not an Open Source License, in which
|
||||
# case the license is the MIT License). An "Open Source License" is a
|
||||
# license that conforms to the Open Source Definition (Version 1.9)
|
||||
# published by the Open Source Initiative.
|
||||
|
||||
# Please submit bugfixes or comments via https://bugs.opensuse.org/
|
||||
#
|
||||
|
||||
|
||||
Name: tailscale
|
||||
Version: 1.80.0
|
||||
Release: 0
|
||||
Summary: The easiest, most secure way to use WireGuard and 2FA
|
||||
License: BSD-3-Clause
|
||||
URL: https://github.com/tailscale/tailscale
|
||||
Source: %{name}-%{version}.tar.gz
|
||||
Source1: vendor.tar.gz
|
||||
Source2: %{name}d.service
|
||||
Source3: %{name}d.defaults
|
||||
Patch0: build-verbose.patch
|
||||
Patch1: disable-auto-update.patch
|
||||
BuildRequires: bash-completion
|
||||
BuildRequires: fish
|
||||
BuildRequires: git-core
|
||||
BuildRequires: golang-packaging
|
||||
BuildRequires: zsh
|
||||
BuildRequires: golang(API) = 1.23
|
||||
Requires: %{default_firewall_backend}
|
||||
ExcludeArch: i586
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
Tailscale is a modern VPN built on top of Wireguard. It works like an overlay
|
||||
network between the computers of your networks using NAT traversal.
|
||||
|
||||
%package bash-completion
|
||||
Summary: Tailscale bash completion
|
||||
Supplements: (%{name} and bash-completion)
|
||||
BuildArch: noarch
|
||||
|
||||
%description bash-completion
|
||||
bash completions for %{name}
|
||||
|
||||
%package zsh-completion
|
||||
Summary: Tailsacle zsh completion
|
||||
Supplements: (%{name} and zsh)
|
||||
BuildArch: noarch
|
||||
|
||||
%description zsh-completion
|
||||
zsh completion for %{name}
|
||||
|
||||
%package fish-completion
|
||||
Summary: Tailscale fish completion
|
||||
Supplements: (%{name} and fish)
|
||||
BuildArch: noarch
|
||||
|
||||
%description fish-completion
|
||||
fish completion for %{name}
|
||||
|
||||
%prep
|
||||
%autosetup -a1 -p1
|
||||
|
||||
%build
|
||||
%ifnarch ppc64
|
||||
export GOFLAGS="-buildmode=pie"
|
||||
%endif
|
||||
export VERSION_SHORT=%{version}
|
||||
export VERSION_LONG=%{version}
|
||||
export VERSION_GIT_HASH='$(git rev-parse v%{version})'
|
||||
./build_dist.sh ./cmd/%{name}
|
||||
./build_dist.sh ./cmd/%{name}d
|
||||
|
||||
#generate completions
|
||||
./%{name} completion bash > ./%{name}.bash
|
||||
./%{name} completion zsh > ./%{name}.zsh
|
||||
./%{name} completion fish > ./%{name}.fish
|
||||
|
||||
%check
|
||||
./%{name} version
|
||||
./%{name}d -version
|
||||
|
||||
%install
|
||||
mkdir -p %{buildroot}%{_sharedstatedir}/%{name}
|
||||
|
||||
install -D -p -m 0755 %{name} %{buildroot}%{_bindir}/%{name}
|
||||
install -D -p -m 0755 %{name}d %{buildroot}%{_sbindir}/%{name}d
|
||||
|
||||
# service
|
||||
install -D -p -m 0644 %{SOURCE2} %{buildroot}%{_unitdir}/%{name}d.service
|
||||
%if 0%{?suse_version} < 1600
|
||||
ln -sf %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{name}d
|
||||
%endif
|
||||
|
||||
# defaults
|
||||
install -D -p -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/default/%{name}d
|
||||
|
||||
install -D -p -m 0644 ./%{name}.bash %{buildroot}%{_datadir}/bash-completion/completions/%{name}
|
||||
install -D -p -m 0644 ./%{name}.zsh %{buildroot}%{_datadir}/zsh/site-functions/_%{name}
|
||||
install -D -p -m 0644 ./%{name}.fish %{buildroot}%{_datadir}/fish/vendor_completions.d/%{name}
|
||||
|
||||
%pre
|
||||
%service_add_pre %{name}d.service
|
||||
|
||||
%post
|
||||
%service_add_post %{name}d.service
|
||||
|
||||
%preun
|
||||
%service_del_preun %{name}d.service
|
||||
|
||||
%postun
|
||||
%service_del_postun %{name}d.service
|
||||
|
||||
%files
|
||||
%license LICENSE PATENTS
|
||||
%doc README.md SECURITY.md
|
||||
%config(noreplace) %{_sysconfdir}/default/%{name}d
|
||||
%dir %{_sharedstatedir}/%{name}
|
||||
%{_bindir}/%{name}
|
||||
%{_sbindir}/%{name}d
|
||||
%{_unitdir}/%{name}d.service
|
||||
%if 0%{?suse_version} < 1600
|
||||
%{_sbindir}/rc%{name}d
|
||||
%endif
|
||||
|
||||
%files bash-completion
|
||||
%{_datadir}/bash-completion/completions/%{name}
|
||||
|
||||
%files zsh-completion
|
||||
%{_datadir}/zsh/site-functions/_%{name}
|
||||
|
||||
%files fish-completion
|
||||
%{_datadir}/fish/vendor_completions.d/%{name}
|
||||
|
||||
%changelog
|
8
tailscaled.defaults
Normal file
8
tailscaled.defaults
Normal file
@@ -0,0 +1,8 @@
|
||||
# Set the port to listen on for incoming VPN packets.
|
||||
# Remote nodes will automatically be informed about the new port number,
|
||||
# but you might want to configure this in order to set external firewall
|
||||
# settings.
|
||||
PORT="41641"
|
||||
|
||||
# Extra flags you might want to pass to tailscaled.
|
||||
FLAGS=""
|
35
tailscaled.service
Normal file
35
tailscaled.service
Normal file
@@ -0,0 +1,35 @@
|
||||
[Unit]
|
||||
Description=Tailscale node agent
|
||||
Documentation=https://tailscale.com/kb/
|
||||
Wants=network-pre.target
|
||||
After=network-pre.target NetworkManager.service systemd-resolved.service
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/etc/default/tailscaled
|
||||
ExecStartPre=/usr/sbin/tailscaled --cleanup
|
||||
ExecStart=/usr/sbin/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=${PORT} $FLAGS
|
||||
ExecStopPost=/usr/sbin/tailscaled --cleanup
|
||||
Restart=on-failure
|
||||
RuntimeDirectory=tailscale
|
||||
RuntimeDirectoryMode=0755
|
||||
StateDirectory=tailscale
|
||||
StateDirectoryMode=0700
|
||||
CacheDirectory=tailscale
|
||||
CacheDirectoryMode=0750
|
||||
Type=notify
|
||||
# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
|
||||
PrivateDevices=true
|
||||
ProtectClock=true
|
||||
ProtectControlGroups=true
|
||||
ProtectHome=true
|
||||
ProtectHostname=true
|
||||
ProtectKernelLogs=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelTunables=true
|
||||
RestrictRealtime=true
|
||||
# give permission to TUN
|
||||
BindPaths=/dev/net/tun
|
||||
DeviceAllow=/dev/net/tun rw
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
3
vendor.tar.gz
Normal file
3
vendor.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:67f60a722b71f96f7ba6519f96f9217c9885a17a7216ec0184af1be61467f0a9
|
||||
size 19236295
|
Reference in New Issue
Block a user