summaryrefslogtreecommitdiffhomepage
path: root/cmd
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@tailscale.com>2022-02-07 15:56:56 -0800
committerBrad Fitzpatrick <brad@danga.com>2022-02-08 09:26:26 -0800
commit3c481d6b1892d0de7c19b500eb443cdfc995033e (patch)
treec96b7664cea228773765d0b312e20eac88cc19ae /cmd
parentb3d268c5a199da28d6cc1e2057e1486375e754ab (diff)
downloadtailscale-3c481d6b1892d0de7c19b500eb443cdfc995033e.tar.xz
tailscale-3c481d6b1892d0de7c19b500eb443cdfc995033e.zip
cmd/tailscale: add "tailscale configure-host" to prep a Synology machine at boot
Updates #3761 Change-Id: Ib5ab9a4808ade074f48d3abee22c57d7670f9e21 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/tailscale/cli/cli.go4
-rw-r--r--cmd/tailscale/cli/configure-host.go85
-rw-r--r--cmd/tailscale/depaware.txt2
3 files changed, 90 insertions, 1 deletions
diff --git a/cmd/tailscale/cli/cli.go b/cmd/tailscale/cli/cli.go
index a049b7291..fb63c318d 100644
--- a/cmd/tailscale/cli/cli.go
+++ b/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) {
diff --git a/cmd/tailscale/cli/configure-host.go b/cmd/tailscale/cli/configure-host.go
new file mode 100644
index 000000000..9281cf7e1
--- /dev/null
+++ b/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
+}
diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt
index cbc65aa61..30e7aa87f 100644
--- a/cmd/tailscale/depaware.txt
+++ b/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