Compare commits

...

11 Commits

Author SHA1 Message Date
David Crawshaw
0d7ae3146c VERSION.txt: this is v1.2.3 2020-11-08 10:00:12 -05:00
David Anderson
76c2982d88 VERSION.txt: this is 1.2.2. 2020-11-05 12:25:25 -08:00
Brad Fitzpatrick
3d64eef37b control/controlclient: send warning flag in map request when IP forwarding off
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
(cherry picked from commit 782e07c0ae)
2020-11-04 14:53:01 -08:00
Brad Fitzpatrick
4f292740b0 ipn: clean up Prefs logging at start
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
(cherry picked from commit 4f4e84236a)
2020-11-04 12:06:25 -08:00
Brad Fitzpatrick
e1327154bb ipn: disambiguate how machine key was initialized
Seeing "frontend-provided legacy machine key" was weird (and not quite
accurate) on Linux machines where it comes from the _daemon key's
persist prefs, not the "frontend".

Make the log message distinguish between the cases.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
(cherry picked from commit 6bcb466096)
2020-11-04 12:06:16 -08:00
Brad Fitzpatrick
a702921620 cmd/tailscale/cli: fix double tag: prefix in tailscale up
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
(cherry picked from commit 696e160cfc)
2020-11-04 08:19:39 -08:00
David Anderson
b9b7fbdd21 build_dist: fix after version refactor.
(cherry picked from commit 39bbb86b09)
2020-11-03 14:50:27 -08:00
Avery Pennarun
9446e5c170 VERSION.txt: this is v1.2.1. 2020-11-03 17:34:05 -05:00
Avery Pennarun
75cd82791e Merge remote-tracking branch 'origin/main' into HEAD
* origin/main:
  wgengine/router/dns: run ipconfig /registerdns async, log timing
  net/tshttpproxy: aggressively rate-limit error logs in Transport.Proxy path
  ipn: only use Prefs, not computed stateKey, to determine server mode
  VERSION: rename to version.txt to work around macOS limitations.
  version: greatly simplify redo nonsense, now that we use VERSION.
  ipn, ipn/ipnserver: add IPN state for server in use, handle explicitly
  version: calculate version info without using git tags.
  version: use -g as the "other" suffix, so that `git show` works.
  ipn/ipnserver: remove "Server mode" from a user-visible error message
  ipn: fix crash generating machine key on new installs
  Change some os.IsNotExist to errors.Is(err, os.ErrNotExist) for non-os errors.
  .github/workflows: use cache to speed up Windows tests
  tsweb: add StatusCodeCounters to HandlerOptions
  tsweb: add StdHandlerOpts that accepts an options struct
  ipn: don't temporarilySetMachineKeyInPersist for Android clients
2020-11-03 17:33:23 -05:00
David Anderson
4d5d5f89a3 version: calculate version info without using git tags.
This makes it easier to integrate this version math into a submodule-ful
world. We'll continue to have regular git tags that parallel the information
in VERSION, so that builds out of this repository behave the same.

Signed-off-by: David Anderson <danderson@tailscale.com>
(cherry picked from commit 437142daa5)
(altered VERSION to reflect correct information for this release branch)
2020-11-02 15:24:36 -08:00
Avery Pennarun
bb058703ee Meaningless change so that v1.2.0 tag doesn't match the "main" branch. 2020-10-30 04:04:50 -04:00
8 changed files with 115 additions and 24 deletions

View File

@@ -1 +1 @@
1.1.0 f81233524fddeec450940af8dc1a0dd8841bf28c
1.2.3

View File

@@ -9,12 +9,8 @@
# this script, or executing equivalent commands in your
# distro-specific build system.
set -euo pipefail
set -eu
describe=$(./version/describe.sh)
commit=$(git rev-parse --verify --quiet HEAD)
eval $(./version/version.sh)
long=$(./version/mkversion.sh long "$describe" "")
short=$(./version/mkversion.sh short "$describe" "")
exec go build -tags xversion -ldflags "-X tailscale.com/version.Long=${long} -X tailscale.com/version.Short=${short} -X tailscale.com/version.GitCommit=${commit}" "$@"
exec go build -tags xversion -ldflags "-X tailscale.com/version.Long=${VERSION_LONG} -X tailscale.com/version.Short=${VERSION_SHORT} -X tailscale.com/version.GitCommit=${VERSION_GIT_HASH}" "$@"

View File

@@ -186,11 +186,12 @@ func runUp(ctx context.Context, args []string) error {
if strings.HasPrefix(tag, "tag:") {
// Accept fully-qualified tags (starting with
// "tag:"), as we do in the ACL file.
err := tailcfg.CheckTag(tag)
if err != nil {
if err := tailcfg.CheckTag(tag); err != nil {
fatalf("tag: %q: %v", tag, err)
}
} else if err := tailcfg.CheckTagSuffix(tag); err != nil {
continue
}
if err := tailcfg.CheckTagSuffix(tag); err != nil {
fatalf("tag: %q: %v", tag, err)
}
tags[i] = "tag:" + tag

View File

@@ -21,6 +21,7 @@ import (
"net/http"
"net/url"
"os"
"os/exec"
"reflect"
"runtime"
"sort"
@@ -91,9 +92,14 @@ func (p *Persist) Pretty() string {
if !p.PrivateNodeKey.IsZero() {
nk = p.PrivateNodeKey.Public()
}
ss := func(k wgcfg.Key) string {
if k.IsZero() {
return ""
}
return k.ShortString()
}
return fmt.Sprintf("Persist{lm=%v, o=%v, n=%v u=%#v}",
mk.ShortString(), ok.ShortString(), nk.ShortString(),
p.LoginName)
ss(mk), ss(ok), ss(nk), p.LoginName)
}
// Direct is the client that connects to a tailcontrol server for a node.
@@ -539,6 +545,10 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
Hostinfo: hostinfo,
DebugFlags: c.debugFlags,
}
if hostinfo != nil && ipForwardingBroken(hostinfo.RoutableIPs) {
old := request.DebugFlags
request.DebugFlags = append(old[:len(old):len(old)], "warn-ip-forwarding-off")
}
if c.newDecompressor != nil {
request.Compress = "zstd"
}
@@ -1051,3 +1061,34 @@ func TrimWGConfig() opt.Bool {
v, _ := controlTrimWGConfig.Load().(opt.Bool)
return v
}
// ipForwardingBroken reports whether the system's IP forwarding is disabled
// and will definitely not work for the routes provided.
//
// It should not return false positives.
func ipForwardingBroken(routes []wgcfg.CIDR) bool {
if len(routes) == 0 {
// Nothing to route, so no need to warn.
return false
}
if runtime.GOOS != "linux" {
// We only do subnet routing on Linux for now.
// It might work on darwin/macOS when building from source, so
// don't return true for other OSes. We can OS-based warnings
// already in the admin panel.
return false
}
out, err := ioutil.ReadFile("/proc/sys/net/ipv4/ip_forward")
if err != nil {
// Try another way.
out, err = exec.Command("sysctl", "-n", "net.ipv4.ip_forward").Output()
}
if err != nil {
// Oh well, we tried. This is just for debugging.
// We don't want false positives.
// TODO: maybe we want a different warning for inability to check?
return false
}
return strings.TrimSpace(string(out)) == "0"
// TODO: also check IPv6 if 'routes' contains any IPv6 routes
}

View File

@@ -419,7 +419,9 @@ func (b *LocalBackend) Start(opts Options) error {
b.serverURL = b.prefs.ControlURL
hostinfo.RoutableIPs = append(hostinfo.RoutableIPs, b.prefs.AdvertiseRoutes...)
hostinfo.RequestTags = append(hostinfo.RequestTags, b.prefs.AdvertiseTags...)
b.logf("Start: serverMode=%v; stateKey=%q; tags=%q; routes=%v; url=%v", b.inServerMode, b.stateKey, b.prefs.AdvertiseTags, b.prefs.AdvertiseRoutes, b.prefs.ControlURL)
if b.inServerMode || runtime.GOOS == "windows" {
b.logf("Start: serverMode=%v", b.inServerMode)
}
applyPrefsToHostinfo(hostinfo, b.prefs)
b.notify = opts.Notify
@@ -704,6 +706,7 @@ func (b *LocalBackend) popBrowserAuthNow() {
// initMachineKeyLocked is called to initialize b.machinePrivKey.
//
// b.prefs must already be initialized.
// b.stateKey should be set too, but just for nicer log messages.
// b.mu must be held.
func (b *LocalBackend) initMachineKeyLocked() (err error) {
if temporarilySetMachineKeyInPersist() {
@@ -748,7 +751,11 @@ func (b *LocalBackend) initMachineKeyLocked() (err error) {
// have a legacy machine key, use that. Otherwise generate a
// new one.
if !legacyMachineKey.IsZero() {
b.logf("using frontend-provided legacy machine key")
if b.stateKey == "" {
b.logf("using frontend-provided legacy machine key")
} else {
b.logf("using legacy machine key from state key %q", b.stateKey)
}
b.machinePrivKey = legacyMachineKey
} else {
b.logf("generating new machine key")
@@ -801,23 +808,32 @@ func (b *LocalBackend) writeServerModeStartState(userID string, prefs *Prefs) {
// loadStateLocked sets b.prefs and b.stateKey based on a complex
// combination of key, prefs, and legacyPath. b.mu must be held when
// calling.
func (b *LocalBackend) loadStateLocked(key StateKey, prefs *Prefs, legacyPath string) error {
func (b *LocalBackend) loadStateLocked(key StateKey, prefs *Prefs, legacyPath string) (err error) {
if prefs == nil && key == "" {
panic("state key and prefs are both unset")
}
// Optimistically set stateKey (for initMachineKeyLocked's
// logging), but revert it if we return an error so a later SetPrefs
// call can't pick it up if it's bogus.
b.stateKey = key
defer func() {
if err != nil {
b.stateKey = ""
}
}()
if key == "" {
// Frontend owns the state, we just need to obey it.
//
// If the frontend (e.g. on Windows) supplied the
// optional/legacy machine key then it's used as the
// value instead of making up a new one.
b.logf("Using frontend prefs")
b.logf("using frontend prefs: %s", prefs.Pretty())
b.prefs = prefs.Clone()
if err := b.initMachineKeyLocked(); err != nil {
return fmt.Errorf("initMachineKeyLocked: %w", err)
}
b.stateKey = ""
b.writeServerModeStartState(b.userID, b.prefs)
return nil
}
@@ -825,13 +841,13 @@ func (b *LocalBackend) loadStateLocked(key StateKey, prefs *Prefs, legacyPath st
if prefs != nil {
// Backend owns the state, but frontend is trying to migrate
// state into the backend.
b.logf("Importing frontend prefs into backend store")
b.logf("importing frontend prefs into backend store; frontend prefs: %s", prefs.Pretty())
if err := b.store.WriteState(key, prefs.ToBytes()); err != nil {
return fmt.Errorf("store.WriteState: %v", err)
}
}
b.logf("Using backend prefs")
b.logf("using backend prefs")
bs, err := b.store.ReadState(key)
if err != nil {
if errors.Is(err, ErrStateNotExist) {
@@ -843,16 +859,15 @@ func (b *LocalBackend) loadStateLocked(key StateKey, prefs *Prefs, legacyPath st
}
b.prefs = NewPrefs()
} else {
b.logf("Imported state from relaynode for %q", key)
b.logf("imported prefs from relaynode for %q: %v", key, b.prefs.Pretty())
}
} else {
b.prefs = NewPrefs()
b.logf("Created empty state for %q", key)
b.logf("created empty state for %q: %s", key, b.prefs.Pretty())
}
if err := b.initMachineKeyLocked(); err != nil {
return fmt.Errorf("initMachineKeyLocked: %w", err)
}
b.stateKey = key
return nil
}
return fmt.Errorf("store.ReadState(%q): %v", key, err)
@@ -861,7 +876,7 @@ func (b *LocalBackend) loadStateLocked(key StateKey, prefs *Prefs, legacyPath st
if err != nil {
return fmt.Errorf("PrefsFromBytes: %v", err)
}
b.stateKey = key
b.logf("backend prefs for %q: %s", key, b.prefs.Pretty())
if err := b.initMachineKeyLocked(); err != nil {
return fmt.Errorf("initMachineKeyLocked: %w", err)
}

View File

@@ -152,9 +152,15 @@ func (p *Prefs) pretty(goos string) string {
if len(p.AdvertiseRoutes) > 0 || p.NoSNAT {
fmt.Fprintf(&sb, "snat=%v ", !p.NoSNAT)
}
if len(p.AdvertiseTags) > 0 {
fmt.Fprintf(&sb, "tags=%s ", strings.Join(p.AdvertiseTags, ","))
}
if goos == "linux" {
fmt.Fprintf(&sb, "nf=%v ", p.NetfilterMode)
}
if p.ControlURL != "" && p.ControlURL != "https://login.tailscale.com" {
fmt.Fprintf(&sb, "url=%q ", p.ControlURL)
}
if p.Persist != nil {
sb.WriteString(p.Persist.Pretty())
} else {

View File

@@ -326,6 +326,32 @@ func TestPrefsPretty(t *testing.T) {
"windows",
"Prefs{ra=false dns=false want=true server=true Persist=nil}",
},
{
Prefs{
AllowSingleHosts: true,
WantRunning: true,
ControlURL: "http://localhost:1234",
AdvertiseTags: []string{"tag:foo", "tag:bar"},
},
"darwin",
`Prefs{ra=false dns=false want=true tags=tag:foo,tag:bar url="http://localhost:1234" Persist=nil}`,
},
{
Prefs{
Persist: &controlclient.Persist{},
},
"linux",
`Prefs{ra=false mesh=false dns=false want=false routes=[] nf=off Persist{lm=, o=, n= u=""}}`,
},
{
Prefs{
Persist: &controlclient.Persist{
PrivateNodeKey: wgcfg.PrivateKey{1: 1},
},
},
"linux",
`Prefs{ra=false mesh=false dns=false want=false routes=[] nf=off Persist{lm=, o=, n=[B1VKl] u=""}}`,
},
}
for i, tt := range tests {
got := tt.p.pretty(tt.os)

View File

@@ -509,6 +509,12 @@ type MapRequest struct {
// added and removed all the time during development, and offer no
// compatibility promise. To roll out semantic changes, bump
// Version instead.
//
// Current DebugFlags values are:
// * "warn-ip-forwarding-off": client is trying to be a subnet
// router but their IP forwarding is broken.
// * "v6-overlay": IPv6 development flag to have control send
// v6 node addrs
DebugFlags []string `json:",omitempty"`
}