Просмотр исходного кода

cmd/tailscale: add "tailscale configure-host" to prep a Synology machine at boot

Updates #3761

Change-Id: Ib5ab9a4808ade074f48d3abee22c57d7670f9e21
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 4 лет назад
Родитель
Сommit
3c481d6b18
3 измененных файлов с 90 добавлено и 1 удалено
  1. 4 0
      cmd/tailscale/cli/cli.go
  2. 85 0
      cmd/tailscale/cli/configure-host.go
  3. 1 1
      cmd/tailscale/depaware.txt

+ 4 - 0
cmd/tailscale/cli/cli.go

@@ -29,6 +29,7 @@ import (
 	"tailscale.com/paths"
 	"tailscale.com/safesocket"
 	"tailscale.com/syncs"
+	"tailscale.com/version/distro"
 )
 
 var Stderr io.Writer = os.Stderr
@@ -155,6 +156,9 @@ change in the future.
 	if strSliceContains(args, "debug") {
 		rootCmd.Subcommands = append(rootCmd.Subcommands, debugCmd)
 	}
+	if runtime.GOOS == "linux" && distro.Get() == distro.Synology {
+		rootCmd.Subcommands = append(rootCmd.Subcommands, configureHostCmd)
+	}
 
 	if err := rootCmd.Parse(args); err != nil {
 		if errors.Is(err, flag.ErrHelp) {

+ 85 - 0
cmd/tailscale/cli/configure-host.go

@@ -0,0 +1,85 @@
+// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cli
+
+import (
+	"context"
+	"errors"
+	"flag"
+	"fmt"
+	"os"
+	"os/exec"
+	"runtime"
+	"strings"
+
+	"github.com/peterbourgon/ff/v3/ffcli"
+	"tailscale.com/hostinfo"
+	"tailscale.com/version/distro"
+)
+
+var configureHostCmd = &ffcli.Command{
+	Name:      "configure-host",
+	Exec:      runConfigureHost,
+	ShortHelp: "Configure Synology to enable more Tailscale features",
+	LongHelp: strings.TrimSpace(`
+The 'configure-host' command is intended to run at boot as root
+to create the /dev/net/tun device and give the tailscaled binary
+permission to use it.
+
+See: https://tailscale.com/kb/1152/synology-outbound/
+`),
+	FlagSet: (func() *flag.FlagSet {
+		fs := newFlagSet("configure-host")
+		return fs
+	})(),
+}
+
+var configureHostArgs struct{}
+
+func runConfigureHost(ctx context.Context, args []string) error {
+	if len(args) > 0 {
+		return errors.New("unknown arguments")
+	}
+	if runtime.GOOS != "linux" || distro.Get() != distro.Synology {
+		return errors.New("only implemented on Synology")
+	}
+	if uid := os.Getuid(); uid != 0 {
+		return fmt.Errorf("must be run as root, not %q (%v)", os.Getenv("USER"), uid)
+	}
+	osVer := hostinfo.GetOSVersion()
+	isDSM6 := strings.HasPrefix(osVer, "Synology 6")
+	isDSM7 := strings.HasPrefix(osVer, "Synology 7")
+	if !isDSM6 && !isDSM7 {
+		return fmt.Errorf("unsupported DSM version %q", osVer)
+	}
+	if _, err := os.Stat("/dev/net/tun"); os.IsNotExist(err) {
+		if err := os.MkdirAll("/dev/net", 0755); err != nil {
+			return fmt.Errorf("creating /dev/net: %v", err)
+		}
+		if out, err := exec.Command("/bin/mknod", "/dev/net/tun", "c", "10", "200").CombinedOutput(); err != nil {
+			return fmt.Errorf("creating /dev/net/tun: %v, %s", err, out)
+		}
+	}
+	if err := os.Chmod("/dev/net/tun", 0666); err != nil {
+		return err
+	}
+	if isDSM6 {
+		fmt.Printf("/dev/net/tun exists and has permissions 0666. Skipping setcap on DSM6.\n")
+		return nil
+	}
+
+	const daemonBin = "/var/packages/Tailscale/target/bin/tailscaled"
+	if _, err := os.Stat(daemonBin); err != nil {
+		if os.IsNotExist(err) {
+			return fmt.Errorf("tailscaled binary not found at %s. Is the Tailscale *.spk package installed?", daemonBin)
+		}
+		return err
+	}
+	if out, err := exec.Command("/bin/setcap", "cap_net_admin+eip", daemonBin).CombinedOutput(); err != nil {
+		return fmt.Errorf("setcap: %v, %s", err, out)
+	}
+	fmt.Printf("Done. To restart Tailscale to use the new permissions, run:\n\n  sudo synosystemctl restart pkgctl-Tailscale.service\n\n")
+	return nil
+}

+ 1 - 1
cmd/tailscale/depaware.txt

@@ -39,7 +39,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
    L    tailscale.com/derp/wsconn                                    from tailscale.com/derp/derphttp
         tailscale.com/disco                                          from tailscale.com/derp
         tailscale.com/envknob                                        from tailscale.com/cmd/tailscale/cli+
-        tailscale.com/hostinfo                                       from tailscale.com/net/interfaces
+        tailscale.com/hostinfo                                       from tailscale.com/net/interfaces+
         tailscale.com/ipn                                            from tailscale.com/cmd/tailscale/cli+
         tailscale.com/ipn/ipnstate                                   from tailscale.com/cmd/tailscale/cli+
         tailscale.com/kube                                           from tailscale.com/ipn