diff --git a/mesh/connection.go b/mesh/connection.go index b2c09139..ae03017d 100644 --- a/mesh/connection.go +++ b/mesh/connection.go @@ -96,7 +96,7 @@ func StartLocalConnection(connRemote *RemoteConnection, tcpConn *net.TCPConn, ro RemoteConnection: *connRemote, // NB, we're taking a copy of connRemote here. Router: router, TCPConn: tcpConn, - TrustRemote: false, + TrustRemote: router.Trusts(connRemote), uid: randUint64(), actionChan: actionChan, errorChan: errorChan, diff --git a/mesh/router.go b/mesh/router.go index 5f51cc87..598e485d 100644 --- a/mesh/router.go +++ b/mesh/router.go @@ -37,6 +37,7 @@ type Config struct { Password []byte ConnLimit int PeerDiscovery bool + TrustedSubnets []*net.IPNet } type Router struct { @@ -181,3 +182,17 @@ func (router *Router) applyTopologyUpdate(update []byte) (PeerNameSet, PeerNameS } return origUpdate, newUpdate, nil } + +func (router *Router) Trusts(remote *RemoteConnection) bool { + if tcpAddr, err := net.ResolveTCPAddr("tcp4", remote.remoteTCPAddr); err == nil { + for _, trustedSubnet := range router.TrustedSubnets { + if trustedSubnet.Contains(tcpAddr.IP) { + return true + } + } + } else { + // Should not happen as remoteTCPAddr was obtained from TCPConn + log.Errorf("Unable to parse remote TCP addr: %s", err) + } + return false +} diff --git a/prog/weaver/main.go b/prog/weaver/main.go index d5fb2553..51acd0c3 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -69,6 +69,7 @@ func main() { dnsEffectiveListenAddress string iface *net.Interface datapathName string + trustedSubnetStr string ) mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit") @@ -101,6 +102,8 @@ func main() { mflag.StringVar(&dnsEffectiveListenAddress, []string{"-dns-effective-listen-address"}, "", "address DNS will actually be listening, after Docker port mapping") mflag.StringVar(&datapathName, []string{"-datapath"}, "", "ODP datapath name") + mflag.StringVar(&trustedSubnetStr, []string{"-trusted-subnets"}, "", "Command separated list of trusted subnets in CIDR notation") + // crude way of detecting that we probably have been started in a // container, with `weave launch` --> suppress misleading paths in // mflags error messages. @@ -193,10 +196,7 @@ func main() { Log.Println("Communication between peers is unencrypted.") } else { config.Password = []byte(password) - Log.Println("Communication between peers is encrypted.") - - // fastdp doesn't support encryption - fastDPOverlay = nil + Log.Println("Communication between peers via untrusted networks is encrypted.") } overlays := weave.NewOverlaySwitch() @@ -237,6 +237,10 @@ func main() { networkConfig.PacketLogging = nopPacketLogging{} } + if config.TrustedSubnets, err = parseTrustedSubnets(trustedSubnetStr); err != nil { + Log.Fatal("Unable to parse trusted subnets: ", err) + } + router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlays) Log.Println("Our name is", router.Ourself) @@ -405,6 +409,24 @@ func determineQuorum(initPeerCountFlag int, peers []string) uint { return quorum } +func parseTrustedSubnets(trustedSubnetStr string) ([]*net.IPNet, error) { + trustedSubnets := []*net.IPNet{} + + if trustedSubnetStr == "" { + return trustedSubnets, nil + } + + for _, subnetStr := range strings.Split(trustedSubnetStr, ",") { + _, subnet, err := net.ParseCIDR(subnetStr) + if err != nil { + return nil, err + } + trustedSubnets = append(trustedSubnets, subnet) + } + + return trustedSubnets, nil +} + func listenAndServeHTTP(httpAddr string, muxRouter *mux.Router) { protocol := "tcp" if strings.HasPrefix(httpAddr, "/") { diff --git a/router/fastdp.go b/router/fastdp.go index 571fb10c..0fee5205 100644 --- a/router/fastdp.go +++ b/router/fastdp.go @@ -515,9 +515,8 @@ type fastDatapathForwarder struct { func (fastdp fastDatapathOverlay) PrepareConnection(params mesh.OverlayConnectionParams) (mesh.OverlayConnection, error) { if params.SessionKey != nil { - // No encryption suport in fastdp. The weaver main.go - // is responsible for ensuring this doesn't happen. - log.Fatal("Attempt to use FastDatapath with encryption") + // No encryption support in fastdp + return nil, fmt.Errorf("encryption not supported") } vxlanVportID := fastdp.mainVxlanVportID diff --git a/router/overlay_switch.go b/router/overlay_switch.go index 9e6efd00..da4bab78 100644 --- a/router/overlay_switch.go +++ b/router/overlay_switch.go @@ -204,8 +204,16 @@ func (osw *OverlaySwitch) PrepareConnection(params mesh.OverlayConnectionParams) subConn, err := overlay.PrepareConnection(params) if err != nil { - fwd.stopFrom(0) - return nil, err + log.Infof("Unable to use %s for connection to %s(%s): %s", + overlay.name, + params.RemotePeer.Name, + params.RemotePeer.NickName, + err) + // failed to start subforwarder - record overlay name and continue + fwd.forwarders[i] = subForwarder{ + overlayName: overlay.name, + } + continue } subFwd := subConn.(OverlayForwarder) diff --git a/weave b/weave index bd3c49dc..feca703d 100755 --- a/weave +++ b/weave @@ -42,7 +42,8 @@ weave setup weave version weave launch [--password ] [--nickname ] [--ipalloc-range [--ipalloc-default-subnet ]] - [--no-discovery] [--init-peer-count ] ... + [--no-discovery] [--init-peer-count ] + [--trusted-subnets ,...] ... weave launch-router [--password ] [--nickname ] [--ipalloc-range [--ipalloc-default-subnet ]] [--no-discovery] [--init-peer-count ] ...