net/tsaddr: new package to hold Tailscale-specific IPs/ranges
And update existing callers with (near) duplicated cases.
This commit is contained in:
parent
5c6d8e3053
commit
742b8b44a8
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/net/tsaddr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tailscale returns the current machine's Tailscale interface, if any.
|
// Tailscale returns the current machine's Tailscale interface, if any.
|
||||||
|
@ -52,7 +53,7 @@ func maybeTailscaleInterfaceName(s string) bool {
|
||||||
// Tailscale virtual network interfaces.
|
// Tailscale virtual network interfaces.
|
||||||
func IsTailscaleIP(ip net.IP) bool {
|
func IsTailscaleIP(ip net.IP) bool {
|
||||||
nip, _ := netaddr.FromStdIP(ip) // TODO: push this up to caller, change func signature
|
nip, _ := netaddr.FromStdIP(ip) // TODO: push this up to caller, change func signature
|
||||||
return cgNAT.Contains(nip)
|
return tsaddr.IsTailscaleIP(nip)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isUp(nif *net.Interface) bool { return nif.Flags&net.FlagUp != 0 }
|
func isUp(nif *net.Interface) bool { return nif.Flags&net.FlagUp != 0 }
|
||||||
|
@ -95,7 +96,7 @@ func LocalAddresses() (regular, loopback []string, err error) {
|
||||||
// very well be something we can route to
|
// very well be something we can route to
|
||||||
// directly, because both nodes are
|
// directly, because both nodes are
|
||||||
// behind the same CGNAT router.
|
// behind the same CGNAT router.
|
||||||
if cgNAT.Contains(ip) {
|
if tsaddr.IsTailscaleIP(ip) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if linkLocalIPv4.Contains(ip) {
|
if linkLocalIPv4.Contains(ip) {
|
||||||
|
@ -283,7 +284,6 @@ var (
|
||||||
private2 = mustCIDR("172.16.0.0/12")
|
private2 = mustCIDR("172.16.0.0/12")
|
||||||
private3 = mustCIDR("192.168.0.0/16")
|
private3 = mustCIDR("192.168.0.0/16")
|
||||||
privatev4s = []netaddr.IPPrefix{private1, private2, private3}
|
privatev4s = []netaddr.IPPrefix{private1, private2, private3}
|
||||||
cgNAT = mustCIDR("100.64.0.0/10")
|
|
||||||
linkLocalIPv4 = mustCIDR("169.254.0.0/16")
|
linkLocalIPv4 = mustCIDR("169.254.0.0/16")
|
||||||
v6Global1 = mustCIDR("2000::/3")
|
v6Global1 = mustCIDR("2000::/3")
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright (c) 2020 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 tsaddr handles Tailscale-specific IPs and ranges.
|
||||||
|
package tsaddr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"inet.af/netaddr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ChromeOSVMRange returns the subset of the CGNAT IPv4 range used by
|
||||||
|
// ChromeOS to interconnect the host OS to containers and VMs. We
|
||||||
|
// avoid allocating Tailscale IPs from it, to avoid conflicts.
|
||||||
|
func ChromeOSVMRange() netaddr.IPPrefix {
|
||||||
|
chromeOSRange.Do(func() { mustPrefix(&chromeOSRange.v, "100.115.92.0/23") })
|
||||||
|
return chromeOSRange.v
|
||||||
|
}
|
||||||
|
|
||||||
|
var chromeOSRange oncePrefix
|
||||||
|
|
||||||
|
// CGNATRange returns the Carrier Grade NAT address range that
|
||||||
|
// is the superset range that Tailscale assigns out of.
|
||||||
|
// See https://tailscale.com/kb/1015/100.x-addresses.
|
||||||
|
// Note that Tailscale does not assign out of the ChromeOSVMRange.
|
||||||
|
func CGNATRange() netaddr.IPPrefix {
|
||||||
|
cgnatRange.Do(func() { mustPrefix(&cgnatRange.v, "100.64.0.0/10") })
|
||||||
|
return cgnatRange.v
|
||||||
|
}
|
||||||
|
|
||||||
|
var cgnatRange oncePrefix
|
||||||
|
|
||||||
|
// IsTailscaleIP reports whether ip is an IP address in a range that
|
||||||
|
// Tailscale assigns from.
|
||||||
|
func IsTailscaleIP(ip netaddr.IP) bool {
|
||||||
|
return CGNATRange().Contains(ip) && !ChromeOSVMRange().Contains(ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustPrefix(v *netaddr.IPPrefix, prefix string) {
|
||||||
|
var err error
|
||||||
|
*v, err = netaddr.ParseIPPrefix(prefix)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type oncePrefix struct {
|
||||||
|
sync.Once
|
||||||
|
v netaddr.IPPrefix
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright (c) 2020 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 tsaddr
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestChromeOSVMRange(t *testing.T) {
|
||||||
|
if got, want := ChromeOSVMRange().String(), "100.115.92.0/23"; got != want {
|
||||||
|
t.Errorf("got %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCGNATRange(t *testing.T) {
|
||||||
|
if got, want := CGNATRange().String(), "100.64.0.0/10"; got != want {
|
||||||
|
t.Errorf("got %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/tailscale/wireguard-go/tun"
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/atomicfile"
|
"tailscale.com/atomicfile"
|
||||||
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,11 +51,6 @@ const (
|
||||||
tailscaleBypassMark = "0x20000"
|
tailscaleBypassMark = "0x20000"
|
||||||
)
|
)
|
||||||
|
|
||||||
// chromeOSVMRange is the subset of the CGNAT IPv4 range used by
|
|
||||||
// ChromeOS to interconnect the host OS to containers and VMs. We
|
|
||||||
// avoid allocating Tailscale IPs from it, to avoid conflicts.
|
|
||||||
const chromeOSVMRange = "100.115.92.0/23"
|
|
||||||
|
|
||||||
// netfilterRunner abstracts helpers to run netfilter commands. It
|
// netfilterRunner abstracts helpers to run netfilter commands. It
|
||||||
// exists purely to swap out go-iptables for a fake implementation in
|
// exists purely to swap out go-iptables for a fake implementation in
|
||||||
// tests.
|
// tests.
|
||||||
|
@ -666,11 +662,11 @@ func (r *linuxRouter) addNetfilterBase() error {
|
||||||
//
|
//
|
||||||
// Note, this will definitely break nodes that end up using the
|
// Note, this will definitely break nodes that end up using the
|
||||||
// CGNAT range for other purposes :(.
|
// CGNAT range for other purposes :(.
|
||||||
args := []string{"!", "-i", r.tunname, "-s", chromeOSVMRange, "-j", "RETURN"}
|
args := []string{"!", "-i", r.tunname, "-s", tsaddr.ChromeOSVMRange().String(), "-j", "RETURN"}
|
||||||
if err := r.ipt4.Append("filter", "ts-input", args...); err != nil {
|
if err := r.ipt4.Append("filter", "ts-input", args...); err != nil {
|
||||||
return fmt.Errorf("adding %v in filter/ts-input: %w", args, err)
|
return fmt.Errorf("adding %v in filter/ts-input: %w", args, err)
|
||||||
}
|
}
|
||||||
args = []string{"!", "-i", r.tunname, "-s", "100.64.0.0/10", "-j", "DROP"}
|
args = []string{"!", "-i", r.tunname, "-s", tsaddr.CGNATRange().String(), "-j", "DROP"}
|
||||||
if err := r.ipt4.Append("filter", "ts-input", args...); err != nil {
|
if err := r.ipt4.Append("filter", "ts-input", args...); err != nil {
|
||||||
return fmt.Errorf("adding %v in filter/ts-input: %w", args, err)
|
return fmt.Errorf("adding %v in filter/ts-input: %w", args, err)
|
||||||
}
|
}
|
||||||
|
@ -694,7 +690,7 @@ func (r *linuxRouter) addNetfilterBase() error {
|
||||||
if err := r.ipt4.Append("filter", "ts-forward", args...); err != nil {
|
if err := r.ipt4.Append("filter", "ts-forward", args...); err != nil {
|
||||||
return fmt.Errorf("adding %v in filter/ts-forward: %w", args, err)
|
return fmt.Errorf("adding %v in filter/ts-forward: %w", args, err)
|
||||||
}
|
}
|
||||||
args = []string{"-o", r.tunname, "-s", "100.64.0.0/10", "-j", "DROP"}
|
args = []string{"-o", r.tunname, "-s", tsaddr.CGNATRange().String(), "-j", "DROP"}
|
||||||
if err := r.ipt4.Append("filter", "ts-forward", args...); err != nil {
|
if err := r.ipt4.Append("filter", "ts-forward", args...); err != nil {
|
||||||
return fmt.Errorf("adding %v in filter/ts-forward: %w", args, err)
|
return fmt.Errorf("adding %v in filter/ts-forward: %w", args, err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue