|
|
|
@ -18,6 +18,7 @@ import (
|
|
|
|
|
|
|
|
|
|
"github.com/peterbourgon/ff/v2/ffcli"
|
|
|
|
|
"github.com/tailscale/wireguard-go/wgcfg"
|
|
|
|
|
"inet.af/netaddr"
|
|
|
|
|
"tailscale.com/ipn"
|
|
|
|
|
"tailscale.com/tailcfg"
|
|
|
|
|
"tailscale.com/version"
|
|
|
|
@ -110,7 +111,7 @@ func isBSD(s string) bool {
|
|
|
|
|
return s == "dragonfly" || s == "freebsd" || s == "netbsd" || s == "openbsd"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func warning(format string, args ...interface{}) {
|
|
|
|
|
func warnf(format string, args ...interface{}) {
|
|
|
|
|
fmt.Printf("Warning: "+format+"\n", args...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -129,16 +130,16 @@ func checkIPForwarding() {
|
|
|
|
|
|
|
|
|
|
bs, err := exec.Command("sysctl", "-n", key).Output()
|
|
|
|
|
if err != nil {
|
|
|
|
|
warning("couldn't check %s (%v).\nSubnet routes won't work without IP forwarding.", key, err)
|
|
|
|
|
warnf("couldn't check %s (%v).\nSubnet routes won't work without IP forwarding.", key, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
on, err := strconv.ParseBool(string(bytes.TrimSpace(bs)))
|
|
|
|
|
if err != nil {
|
|
|
|
|
warning("couldn't parse %s (%v).\nSubnet routes won't work without IP forwarding.", key, err)
|
|
|
|
|
warnf("couldn't parse %s (%v).\nSubnet routes won't work without IP forwarding.", key, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if !on {
|
|
|
|
|
warning("%s is disabled. Subnet routes won't work.", key)
|
|
|
|
|
warnf("%s is disabled. Subnet routes won't work.", key)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -149,15 +150,19 @@ func runUp(ctx context.Context, args []string) error {
|
|
|
|
|
|
|
|
|
|
var routes []wgcfg.CIDR
|
|
|
|
|
if upArgs.advertiseRoutes != "" {
|
|
|
|
|
checkIPForwarding()
|
|
|
|
|
advroutes := strings.Split(upArgs.advertiseRoutes, ",")
|
|
|
|
|
for _, s := range advroutes {
|
|
|
|
|
cidr, ok := parseIPOrCIDR(s)
|
|
|
|
|
if !ok {
|
|
|
|
|
log.Fatalf("%q is not a valid IP address or CIDR prefix", s)
|
|
|
|
|
ipp, err := netaddr.ParseIPPrefix(s) // parse it with other pawith both packages
|
|
|
|
|
if !ok || err != nil {
|
|
|
|
|
fatalf("%q is not a valid IP address or CIDR prefix", s)
|
|
|
|
|
}
|
|
|
|
|
if ipp != ipp.Masked() {
|
|
|
|
|
fatalf("%s has non-address bits set; expected %s", ipp, ipp.Masked())
|
|
|
|
|
}
|
|
|
|
|
routes = append(routes, cidr)
|
|
|
|
|
}
|
|
|
|
|
checkIPForwarding()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var tags []string
|
|
|
|
@ -166,13 +171,13 @@ func runUp(ctx context.Context, args []string) error {
|
|
|
|
|
for _, tag := range tags {
|
|
|
|
|
err := tailcfg.CheckTag(tag)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("tag: %q: %s", tag, err)
|
|
|
|
|
fatalf("tag: %q: %s", tag, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(upArgs.hostname) > 256 {
|
|
|
|
|
log.Fatalf("hostname too long: %d bytes (max 256)", len(upArgs.hostname))
|
|
|
|
|
fatalf("hostname too long: %d bytes (max 256)", len(upArgs.hostname))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO(apenwarr): fix different semantics between prefs and uflags
|
|
|
|
@ -195,12 +200,12 @@ func runUp(ctx context.Context, args []string) error {
|
|
|
|
|
prefs.NetfilterMode = router.NetfilterOn
|
|
|
|
|
case "nodivert":
|
|
|
|
|
prefs.NetfilterMode = router.NetfilterNoDivert
|
|
|
|
|
warning("netfilter=nodivert; add iptables calls to ts-* chains manually.")
|
|
|
|
|
warnf("netfilter=nodivert; add iptables calls to ts-* chains manually.")
|
|
|
|
|
case "off":
|
|
|
|
|
prefs.NetfilterMode = router.NetfilterOff
|
|
|
|
|
warning("netfilter=off; configure iptables yourself.")
|
|
|
|
|
warnf("netfilter=off; configure iptables yourself.")
|
|
|
|
|
default:
|
|
|
|
|
log.Fatalf("invalid value --netfilter-mode: %q", upArgs.netfilterMode)
|
|
|
|
|
fatalf("invalid value --netfilter-mode: %q", upArgs.netfilterMode)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -215,7 +220,7 @@ func runUp(ctx context.Context, args []string) error {
|
|
|
|
|
AuthKey: upArgs.authKey,
|
|
|
|
|
Notify: func(n ipn.Notify) {
|
|
|
|
|
if n.ErrMessage != nil {
|
|
|
|
|
log.Fatalf("backend error: %v\n", *n.ErrMessage)
|
|
|
|
|
fatalf("backend error: %v\n", *n.ErrMessage)
|
|
|
|
|
}
|
|
|
|
|
if s := n.State; s != nil {
|
|
|
|
|
switch *s {
|
|
|
|
|