mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-16 03:31:39 +00:00
wgengine/wgcfg/nmcfg: split control/controlclient/netmap.go into own package
It couldn't move to ipnlocal due to test dependency cycles. Updates #1278 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
138055dd70
commit
6064b6ff47
@ -7,16 +7,6 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
L github.com/mdlayher/sdnotify from tailscale.com/util/systemd
|
L github.com/mdlayher/sdnotify from tailscale.com/util/systemd
|
||||||
github.com/peterbourgon/ff/v2 from github.com/peterbourgon/ff/v2/ffcli
|
github.com/peterbourgon/ff/v2 from github.com/peterbourgon/ff/v2/ffcli
|
||||||
github.com/peterbourgon/ff/v2/ffcli from tailscale.com/cmd/tailscale/cli
|
github.com/peterbourgon/ff/v2/ffcli from tailscale.com/cmd/tailscale/cli
|
||||||
💣 github.com/tailscale/wireguard-go/conn from github.com/tailscale/wireguard-go/device
|
|
||||||
💣 github.com/tailscale/wireguard-go/device from tailscale.com/wgengine/wgcfg
|
|
||||||
💣 github.com/tailscale/wireguard-go/ipc from github.com/tailscale/wireguard-go/device
|
|
||||||
W 💣 github.com/tailscale/wireguard-go/ipc/winpipe from github.com/tailscale/wireguard-go/ipc
|
|
||||||
github.com/tailscale/wireguard-go/ratelimiter from github.com/tailscale/wireguard-go/device
|
|
||||||
github.com/tailscale/wireguard-go/replay from github.com/tailscale/wireguard-go/device
|
|
||||||
github.com/tailscale/wireguard-go/rwcancel from github.com/tailscale/wireguard-go/device+
|
|
||||||
github.com/tailscale/wireguard-go/tai64n from github.com/tailscale/wireguard-go/device
|
|
||||||
💣 github.com/tailscale/wireguard-go/tun from github.com/tailscale/wireguard-go/device
|
|
||||||
W 💣 github.com/tailscale/wireguard-go/tun/wintun from github.com/tailscale/wireguard-go/tun
|
|
||||||
github.com/tcnksm/go-httpstat from tailscale.com/net/netcheck
|
github.com/tcnksm/go-httpstat from tailscale.com/net/netcheck
|
||||||
github.com/toqueteos/webbrowser from tailscale.com/cmd/tailscale/cli
|
github.com/toqueteos/webbrowser from tailscale.com/cmd/tailscale/cli
|
||||||
💣 go4.org/intern from inet.af/netaddr
|
💣 go4.org/intern from inet.af/netaddr
|
||||||
@ -45,7 +35,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
tailscale.com/net/packet from tailscale.com/wgengine/filter
|
tailscale.com/net/packet from tailscale.com/wgengine/filter
|
||||||
tailscale.com/net/stun from tailscale.com/net/netcheck
|
tailscale.com/net/stun from tailscale.com/net/netcheck
|
||||||
tailscale.com/net/tlsdial from tailscale.com/control/controlclient+
|
tailscale.com/net/tlsdial from tailscale.com/control/controlclient+
|
||||||
tailscale.com/net/tsaddr from tailscale.com/net/interfaces+
|
tailscale.com/net/tsaddr from tailscale.com/net/interfaces
|
||||||
💣 tailscale.com/net/tshttpproxy from tailscale.com/control/controlclient+
|
💣 tailscale.com/net/tshttpproxy from tailscale.com/control/controlclient+
|
||||||
tailscale.com/paths from tailscale.com/cmd/tailscale/cli
|
tailscale.com/paths from tailscale.com/cmd/tailscale/cli
|
||||||
tailscale.com/safesocket from tailscale.com/cmd/tailscale/cli
|
tailscale.com/safesocket from tailscale.com/cmd/tailscale/cli
|
||||||
@ -67,9 +57,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
tailscale.com/version from tailscale.com/cmd/tailscale/cli+
|
tailscale.com/version from tailscale.com/cmd/tailscale/cli+
|
||||||
tailscale.com/version/distro from tailscale.com/cmd/tailscale/cli+
|
tailscale.com/version/distro from tailscale.com/cmd/tailscale/cli+
|
||||||
tailscale.com/wgengine/filter from tailscale.com/control/controlclient
|
tailscale.com/wgengine/filter from tailscale.com/control/controlclient
|
||||||
tailscale.com/wgengine/wgcfg from tailscale.com/control/controlclient
|
|
||||||
golang.org/x/crypto/blake2b from golang.org/x/crypto/nacl/box
|
golang.org/x/crypto/blake2b from golang.org/x/crypto/nacl/box
|
||||||
golang.org/x/crypto/blake2s from github.com/tailscale/wireguard-go/device
|
|
||||||
golang.org/x/crypto/chacha20 from golang.org/x/crypto/chacha20poly1305
|
golang.org/x/crypto/chacha20 from golang.org/x/crypto/chacha20poly1305
|
||||||
golang.org/x/crypto/chacha20poly1305 from crypto/tls+
|
golang.org/x/crypto/chacha20poly1305 from crypto/tls+
|
||||||
golang.org/x/crypto/cryptobyte from crypto/ecdsa+
|
golang.org/x/crypto/cryptobyte from crypto/ecdsa+
|
||||||
@ -78,17 +66,14 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
golang.org/x/crypto/hkdf from crypto/tls
|
golang.org/x/crypto/hkdf from crypto/tls
|
||||||
golang.org/x/crypto/nacl/box from tailscale.com/control/controlclient+
|
golang.org/x/crypto/nacl/box from tailscale.com/control/controlclient+
|
||||||
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
|
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
|
||||||
golang.org/x/crypto/poly1305 from github.com/tailscale/wireguard-go/device+
|
golang.org/x/crypto/poly1305 from golang.org/x/crypto/chacha20poly1305+
|
||||||
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
|
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
|
||||||
golang.org/x/net/bpf from golang.org/x/net/ipv4+
|
|
||||||
golang.org/x/net/context/ctxhttp from golang.org/x/oauth2/internal
|
golang.org/x/net/context/ctxhttp from golang.org/x/oauth2/internal
|
||||||
golang.org/x/net/dns/dnsmessage from net
|
golang.org/x/net/dns/dnsmessage from net
|
||||||
golang.org/x/net/http/httpguts from net/http
|
golang.org/x/net/http/httpguts from net/http
|
||||||
golang.org/x/net/http/httpproxy from net/http
|
golang.org/x/net/http/httpproxy from net/http
|
||||||
golang.org/x/net/http2/hpack from net/http
|
golang.org/x/net/http2/hpack from net/http
|
||||||
golang.org/x/net/idna from golang.org/x/net/http/httpguts+
|
golang.org/x/net/idna from golang.org/x/net/http/httpguts+
|
||||||
golang.org/x/net/ipv4 from github.com/tailscale/wireguard-go/device
|
|
||||||
golang.org/x/net/ipv6 from github.com/tailscale/wireguard-go/device+
|
|
||||||
golang.org/x/net/proxy from tailscale.com/net/netns
|
golang.org/x/net/proxy from tailscale.com/net/netns
|
||||||
D golang.org/x/net/route from net
|
D golang.org/x/net/route from net
|
||||||
golang.org/x/oauth2 from tailscale.com/control/controlclient+
|
golang.org/x/oauth2 from tailscale.com/control/controlclient+
|
||||||
@ -96,7 +81,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
golang.org/x/sync/errgroup from tailscale.com/derp
|
golang.org/x/sync/errgroup from tailscale.com/derp
|
||||||
golang.org/x/sync/singleflight from tailscale.com/net/dnscache
|
golang.org/x/sync/singleflight from tailscale.com/net/dnscache
|
||||||
golang.org/x/sys/cpu from golang.org/x/crypto/blake2b+
|
golang.org/x/sys/cpu from golang.org/x/crypto/blake2b+
|
||||||
LD golang.org/x/sys/unix from github.com/tailscale/wireguard-go/conn+
|
LD golang.org/x/sys/unix from tailscale.com/net/netns+
|
||||||
W golang.org/x/sys/windows from github.com/apenwarr/fixconsole+
|
W golang.org/x/sys/windows from github.com/apenwarr/fixconsole+
|
||||||
W golang.org/x/sys/windows/registry from golang.zx2c4.com/wireguard/windows/tunnel/winipcfg
|
W golang.org/x/sys/windows/registry from golang.zx2c4.com/wireguard/windows/tunnel/winipcfg
|
||||||
golang.org/x/text/secure/bidirule from golang.org/x/net/idna
|
golang.org/x/text/secure/bidirule from golang.org/x/net/idna
|
||||||
@ -157,7 +142,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
math from compress/flate+
|
math from compress/flate+
|
||||||
math/big from crypto/dsa+
|
math/big from crypto/dsa+
|
||||||
math/bits from compress/flate+
|
math/bits from compress/flate+
|
||||||
math/rand from github.com/tailscale/wireguard-go/device+
|
math/rand from math/big+
|
||||||
mime from golang.org/x/oauth2/internal+
|
mime from golang.org/x/oauth2/internal+
|
||||||
mime/multipart from net/http
|
mime/multipart from net/http
|
||||||
mime/quotedprintable from mime/multipart
|
mime/quotedprintable from mime/multipart
|
||||||
|
@ -129,7 +129,8 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/wgengine/router/dns from tailscale.com/ipn/ipnlocal+
|
tailscale.com/wgengine/router/dns from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/wgengine/tsdns from tailscale.com/ipn/ipnlocal+
|
tailscale.com/wgengine/tsdns from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/wgengine/tstun from tailscale.com/wgengine+
|
tailscale.com/wgengine/tstun from tailscale.com/wgengine+
|
||||||
tailscale.com/wgengine/wgcfg from tailscale.com/control/controlclient+
|
tailscale.com/wgengine/wgcfg from tailscale.com/ipn/ipnlocal+
|
||||||
|
tailscale.com/wgengine/wgcfg/nmcfg from tailscale.com/ipn/ipnlocal
|
||||||
tailscale.com/wgengine/wglog from tailscale.com/wgengine
|
tailscale.com/wgengine/wglog from tailscale.com/wgengine
|
||||||
W 💣 tailscale.com/wgengine/winnet from tailscale.com/wgengine/router
|
W 💣 tailscale.com/wgengine/winnet from tailscale.com/wgengine/router
|
||||||
golang.org/x/crypto/blake2b from golang.org/x/crypto/nacl/box
|
golang.org/x/crypto/blake2b from golang.org/x/crypto/nacl/box
|
||||||
|
@ -7,19 +7,14 @@ package controlclient
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/net/tsaddr"
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/logger"
|
|
||||||
"tailscale.com/types/wgkey"
|
"tailscale.com/types/wgkey"
|
||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
"tailscale.com/wgengine/wgcfg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type NetworkMap struct {
|
type NetworkMap struct {
|
||||||
@ -252,118 +247,6 @@ const (
|
|||||||
AllowSubnetRoutes
|
AllowSubnetRoutes
|
||||||
)
|
)
|
||||||
|
|
||||||
// EndpointDiscoSuffix is appended to the hex representation of a peer's discovery key
|
|
||||||
// and is then the sole wireguard endpoint for peers with a non-zero discovery key.
|
|
||||||
// This form is then recognize by magicsock's CreateEndpoint.
|
|
||||||
const EndpointDiscoSuffix = ".disco.tailscale:12345"
|
|
||||||
|
|
||||||
// WGCfg returns the NetworkMaps's Wireguard configuration.
|
|
||||||
func (nm *NetworkMap) WGCfg(logf logger.Logf, flags WGConfigFlags) (*wgcfg.Config, error) {
|
|
||||||
cfg := &wgcfg.Config{
|
|
||||||
Name: "tailscale",
|
|
||||||
PrivateKey: wgcfg.PrivateKey(nm.PrivateKey),
|
|
||||||
Addresses: nm.Addresses,
|
|
||||||
ListenPort: nm.LocalPort,
|
|
||||||
Peers: make([]wgcfg.Peer, 0, len(nm.Peers)),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, peer := range nm.Peers {
|
|
||||||
if Debug.OnlyDisco && peer.DiscoKey.IsZero() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
cfg.Peers = append(cfg.Peers, wgcfg.Peer{
|
|
||||||
PublicKey: wgcfg.Key(peer.Key),
|
|
||||||
})
|
|
||||||
cpeer := &cfg.Peers[len(cfg.Peers)-1]
|
|
||||||
if peer.KeepAlive {
|
|
||||||
cpeer.PersistentKeepalive = 25 // seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
if !peer.DiscoKey.IsZero() {
|
|
||||||
if err := appendEndpoint(cpeer, fmt.Sprintf("%x%s", peer.DiscoKey[:], EndpointDiscoSuffix)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cpeer.Endpoints = fmt.Sprintf("%x.disco.tailscale:12345", peer.DiscoKey[:])
|
|
||||||
} else {
|
|
||||||
if err := appendEndpoint(cpeer, peer.DERP); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, ep := range peer.Endpoints {
|
|
||||||
if err := appendEndpoint(cpeer, ep); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, allowedIP := range peer.AllowedIPs {
|
|
||||||
if allowedIP.IsSingleIP() && tsaddr.IsTailscaleIP(allowedIP.IP) && (flags&AllowSingleHosts) == 0 {
|
|
||||||
logf("[v1] wgcfg: skipping node IP %v from %q (%v)",
|
|
||||||
allowedIP.IP, nodeDebugName(peer), peer.Key.ShortString())
|
|
||||||
continue
|
|
||||||
} else if cidrIsSubnet(peer, allowedIP) {
|
|
||||||
if (flags & AllowSubnetRoutes) == 0 {
|
|
||||||
logf("[v1] wgcfg: not accepting subnet route %v from %q (%v)",
|
|
||||||
allowedIP, nodeDebugName(peer), peer.Key.ShortString())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cpeer.AllowedIPs = append(cpeer.AllowedIPs, allowedIP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeDebugName(n *tailcfg.Node) string {
|
|
||||||
name := n.Name
|
|
||||||
if name == "" {
|
|
||||||
name = n.Hostinfo.Hostname
|
|
||||||
}
|
|
||||||
if i := strings.Index(name, "."); i != -1 {
|
|
||||||
name = name[:i]
|
|
||||||
}
|
|
||||||
if name == "" && len(n.Addresses) != 0 {
|
|
||||||
return n.Addresses[0].String()
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
// cidrIsSubnet reports whether cidr is a non-default-route subnet
|
|
||||||
// exported by node that is not one of its own self addresses.
|
|
||||||
func cidrIsSubnet(node *tailcfg.Node, cidr netaddr.IPPrefix) bool {
|
|
||||||
if cidr.Bits == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !cidr.IsSingleIP() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, selfCIDR := range node.Addresses {
|
|
||||||
if cidr == selfCIDR {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendEndpoint(peer *wgcfg.Peer, epStr string) error {
|
|
||||||
if epStr == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
_, port, err := net.SplitHostPort(epStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("malformed endpoint %q for peer %v", epStr, peer.PublicKey.ShortString())
|
|
||||||
}
|
|
||||||
_, err = strconv.ParseUint(port, 10, 16)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("invalid port in endpoint %q for peer %v", epStr, peer.PublicKey.ShortString())
|
|
||||||
}
|
|
||||||
if peer.Endpoints != "" {
|
|
||||||
peer.Endpoints += ","
|
|
||||||
}
|
|
||||||
peer.Endpoints += epStr
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// eqStringsIgnoreNil reports whether a and b have the same length and
|
// eqStringsIgnoreNil reports whether a and b have the same length and
|
||||||
// contents, but ignore whether a or b are nil.
|
// contents, but ignore whether a or b are nil.
|
||||||
func eqStringsIgnoreNil(a, b []string) bool {
|
func eqStringsIgnoreNil(a, b []string) bool {
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
"tailscale.com/wgengine/router/dns"
|
"tailscale.com/wgengine/router/dns"
|
||||||
"tailscale.com/wgengine/tsdns"
|
"tailscale.com/wgengine/tsdns"
|
||||||
"tailscale.com/wgengine/wgcfg"
|
"tailscale.com/wgengine/wgcfg"
|
||||||
|
"tailscale.com/wgengine/wgcfg/nmcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var controlDebugFlags = getControlDebugFlags()
|
var controlDebugFlags = getControlDebugFlags()
|
||||||
@ -1268,7 +1269,7 @@ func (b *LocalBackend) authReconfig() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := nm.WGCfg(b.logf, flags)
|
cfg, err := nmcfg.WGCfg(nm, b.logf, flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.logf("wgcfg: %v", err)
|
b.logf("wgcfg: %v", err)
|
||||||
return
|
return
|
||||||
|
@ -51,6 +51,7 @@ import (
|
|||||||
"tailscale.com/types/nettype"
|
"tailscale.com/types/nettype"
|
||||||
"tailscale.com/types/wgkey"
|
"tailscale.com/types/wgkey"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
|
"tailscale.com/wgengine/wgcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Various debugging and experimental tweakables, set by environment
|
// Various debugging and experimental tweakables, set by environment
|
||||||
@ -2643,11 +2644,11 @@ func (c *Conn) CreateEndpoint(pubKey [32]byte, addrs string) (conn.Endpoint, err
|
|||||||
pk := key.Public(pubKey)
|
pk := key.Public(pubKey)
|
||||||
c.logf("magicsock: CreateEndpoint: key=%s: %s", pk.ShortString(), derpStr(addrs))
|
c.logf("magicsock: CreateEndpoint: key=%s: %s", pk.ShortString(), derpStr(addrs))
|
||||||
|
|
||||||
if !strings.HasSuffix(addrs, controlclient.EndpointDiscoSuffix) {
|
if !strings.HasSuffix(addrs, wgcfg.EndpointDiscoSuffix) {
|
||||||
return c.createLegacyEndpointLocked(pk, addrs)
|
return c.createLegacyEndpointLocked(pk, addrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
discoHex := strings.TrimSuffix(addrs, controlclient.EndpointDiscoSuffix)
|
discoHex := strings.TrimSuffix(addrs, wgcfg.EndpointDiscoSuffix)
|
||||||
discoKey, err := key.NewPublicFromHexMem(mem.S(discoHex))
|
discoKey, err := key.NewPublicFromHexMem(mem.S(discoHex))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("magicsock: invalid discokey endpoint %q for %v: %w", addrs, pk.ShortString(), err)
|
return nil, fmt.Errorf("magicsock: invalid discokey endpoint %q for %v: %w", addrs, pk.ShortString(), err)
|
||||||
|
@ -46,6 +46,7 @@ import (
|
|||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
"tailscale.com/wgengine/tstun"
|
"tailscale.com/wgengine/tstun"
|
||||||
"tailscale.com/wgengine/wgcfg"
|
"tailscale.com/wgengine/wgcfg"
|
||||||
|
"tailscale.com/wgengine/wgcfg/nmcfg"
|
||||||
"tailscale.com/wgengine/wglog"
|
"tailscale.com/wgengine/wglog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -293,7 +294,7 @@ func meshStacks(logf logger.Logf, ms []*magicStack) (cleanup func()) {
|
|||||||
peerSet[key.Public(peer.Key)] = struct{}{}
|
peerSet[key.Public(peer.Key)] = struct{}{}
|
||||||
}
|
}
|
||||||
m.conn.UpdatePeers(peerSet)
|
m.conn.UpdatePeers(peerSet)
|
||||||
wg, err := netmap.WGCfg(logf, controlclient.AllowSingleHosts)
|
wg, err := nmcfg.WGCfg(netmap, logf, controlclient.AllowSingleHosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// We're too far from the *testing.T to be graceful,
|
// We're too far from the *testing.T to be graceful,
|
||||||
// blow up. Shouldn't happen anyway.
|
// blow up. Shouldn't happen anyway.
|
||||||
|
@ -9,6 +9,11 @@ import (
|
|||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// EndpointDiscoSuffix is appended to the hex representation of a peer's discovery key
|
||||||
|
// and is then the sole wireguard endpoint for peers with a non-zero discovery key.
|
||||||
|
// This form is then recognize by magicsock's CreateEndpoint.
|
||||||
|
const EndpointDiscoSuffix = ".disco.tailscale:12345"
|
||||||
|
|
||||||
// Config is a WireGuard configuration.
|
// Config is a WireGuard configuration.
|
||||||
// It only supports the set of things Tailscale uses.
|
// It only supports the set of things Tailscale uses.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
126
wgengine/wgcfg/nmcfg/nmcfg.go
Normal file
126
wgengine/wgcfg/nmcfg/nmcfg.go
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
// 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 nmcfg converts a controlclient.NetMap into a wgcfg config.
|
||||||
|
package nmcfg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/control/controlclient"
|
||||||
|
"tailscale.com/net/tsaddr"
|
||||||
|
"tailscale.com/tailcfg"
|
||||||
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/wgengine/wgcfg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func nodeDebugName(n *tailcfg.Node) string {
|
||||||
|
name := n.Name
|
||||||
|
if name == "" {
|
||||||
|
name = n.Hostinfo.Hostname
|
||||||
|
}
|
||||||
|
if i := strings.Index(name, "."); i != -1 {
|
||||||
|
name = name[:i]
|
||||||
|
}
|
||||||
|
if name == "" && len(n.Addresses) != 0 {
|
||||||
|
return n.Addresses[0].String()
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
// cidrIsSubnet reports whether cidr is a non-default-route subnet
|
||||||
|
// exported by node that is not one of its own self addresses.
|
||||||
|
func cidrIsSubnet(node *tailcfg.Node, cidr netaddr.IPPrefix) bool {
|
||||||
|
if cidr.Bits == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !cidr.IsSingleIP() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, selfCIDR := range node.Addresses {
|
||||||
|
if cidr == selfCIDR {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// WGCfg returns the NetworkMaps's Wireguard configuration.
|
||||||
|
func WGCfg(nm *controlclient.NetworkMap, logf logger.Logf, flags controlclient.WGConfigFlags) (*wgcfg.Config, error) {
|
||||||
|
cfg := &wgcfg.Config{
|
||||||
|
Name: "tailscale",
|
||||||
|
PrivateKey: wgcfg.PrivateKey(nm.PrivateKey),
|
||||||
|
Addresses: nm.Addresses,
|
||||||
|
ListenPort: nm.LocalPort,
|
||||||
|
Peers: make([]wgcfg.Peer, 0, len(nm.Peers)),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, peer := range nm.Peers {
|
||||||
|
if controlclient.Debug.OnlyDisco && peer.DiscoKey.IsZero() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cfg.Peers = append(cfg.Peers, wgcfg.Peer{
|
||||||
|
PublicKey: wgcfg.Key(peer.Key),
|
||||||
|
})
|
||||||
|
cpeer := &cfg.Peers[len(cfg.Peers)-1]
|
||||||
|
if peer.KeepAlive {
|
||||||
|
cpeer.PersistentKeepalive = 25 // seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
if !peer.DiscoKey.IsZero() {
|
||||||
|
if err := appendEndpoint(cpeer, fmt.Sprintf("%x%s", peer.DiscoKey[:], wgcfg.EndpointDiscoSuffix)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cpeer.Endpoints = fmt.Sprintf("%x.disco.tailscale:12345", peer.DiscoKey[:])
|
||||||
|
} else {
|
||||||
|
if err := appendEndpoint(cpeer, peer.DERP); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, ep := range peer.Endpoints {
|
||||||
|
if err := appendEndpoint(cpeer, ep); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, allowedIP := range peer.AllowedIPs {
|
||||||
|
if allowedIP.IsSingleIP() && tsaddr.IsTailscaleIP(allowedIP.IP) && (flags&controlclient.AllowSingleHosts) == 0 {
|
||||||
|
logf("[v1] wgcfg: skipping node IP %v from %q (%v)",
|
||||||
|
allowedIP.IP, nodeDebugName(peer), peer.Key.ShortString())
|
||||||
|
continue
|
||||||
|
} else if cidrIsSubnet(peer, allowedIP) {
|
||||||
|
if (flags & controlclient.AllowSubnetRoutes) == 0 {
|
||||||
|
logf("[v1] wgcfg: not accepting subnet route %v from %q (%v)",
|
||||||
|
allowedIP, nodeDebugName(peer), peer.Key.ShortString())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cpeer.AllowedIPs = append(cpeer.AllowedIPs, allowedIP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendEndpoint(peer *wgcfg.Peer, epStr string) error {
|
||||||
|
if epStr == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
_, port, err := net.SplitHostPort(epStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("malformed endpoint %q for peer %v", epStr, peer.PublicKey.ShortString())
|
||||||
|
}
|
||||||
|
_, err = strconv.ParseUint(port, 10, 16)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid port in endpoint %q for peer %v", epStr, peer.PublicKey.ShortString())
|
||||||
|
}
|
||||||
|
if peer.Endpoints != "" {
|
||||||
|
peer.Endpoints += ","
|
||||||
|
}
|
||||||
|
peer.Endpoints += epStr
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user