Пример #1
0
func (c *Context) validateNoTunnel() {
	policies, err := netlink.XfrmPolicyList(netlink.FAMILY_ALL)
	if err != nil {
		c.Fatalf("Failed to get policies: %v", err)
	}
	if len(policies) != 0 {
		c.Fatalf("Policies not removed")
	}
	states, err := netlink.XfrmStateList(netlink.FAMILY_ALL)
	if err != nil {
		c.Fatalf("Failed to get states: %v", err)
	}
	if len(states) != 0 {
		c.Fatalf("States not removed")
	}
}
Пример #2
0
func (c *Context) validateTunnel(udp bool) {
	policies, err := netlink.XfrmPolicyList(netlink.FAMILY_ALL)
	if err != nil {
		c.Fatalf("Failed to get policies: %v", err)
	}
	if len(policies) != 4 {
		c.Fatalf("Wrong number of policies found: %v", policies)
	}
	c.validatePolicy(policies[0], "127.0.0.2", "127.0.0.1")
	c.validatePolicy(policies[1], "127.0.0.1", "127.0.0.2")
	c.validatePolicy(policies[2], "127.0.0.1", "127.0.0.2")
	c.validatePolicy(policies[3], "127.0.0.2", "127.0.0.1")
	states, err := netlink.XfrmStateList(netlink.FAMILY_ALL)
	if err != nil {
		c.Fatalf("Failed to get states: %v", err)
	}
	if len(states) != 2 {
		c.Fatalf("Wrong number of states found: %v", states)
	}
	c.validateState(states[0], "127.0.0.1", "127.0.0.2", udp)
	c.validateState(states[1], "127.0.0.2", "127.0.0.1", udp)
}
Пример #3
0
func discoverTunnels() {
	glog.Infof("Discovering existing tunnels")
	lo, err := netlink.LinkByName("lo")
	if err != nil {
		glog.Errorf("Failed to get loopback device: %v", err)
		return
	}
	addrs, err := netlink.AddrList(lo, netlink.FAMILY_ALL)
	if err != nil {
		glog.Errorf("Failed to get addrs: %v", err)
		return
	}
	routes, err := netlink.RouteList(nil, netlink.FAMILY_ALL)
	if err != nil {
		glog.Errorf("Failed to get routes: %v", err)
		return
	}
	policies, err := netlink.XfrmPolicyList(netlink.FAMILY_ALL)
	if err != nil {
		glog.Errorf("Failed to get xfrm policies: %v", err)
		return
	}
	states, err := netlink.XfrmStateList(netlink.FAMILY_ALL)
	if err != nil {
		glog.Errorf("Failed to get xfrm states: %v", err)
		return
	}
	for _, addr := range addrs {
		if opts.cidr.Contains(addr.IP) {
			tunnel := client.Tunnel{}
			tunnel.Src = addr.IP
			err := reserveIP(tunnel.Src)
			if err != nil {
				glog.Warningf("Duplicate tunnel ip detected: %v", tunnel.Src)
			}
			tunnel.Dst = nil
			glog.Infof("Potential tunnel found from %s", tunnel.Src)
			for _, route := range routes {
				if route.Src == nil || !route.Src.Equal(tunnel.Src) {
					continue
				}
				tunnel.Dst = route.Dst.IP
				break
			}
			if tunnel.Dst == nil {
				glog.Warningf("could not find dst for tunnel src %s", tunnel.Src)
				continue
			}
			err = reserveIP(tunnel.Dst)
			if err != nil {
				glog.Warningf("Duplicate tunnel ip detected: %v", tunnel.Dst)
			}
			var dst net.IP
			for _, policy := range policies {
				if !policy.Dst.IP.Equal(tunnel.Dst) {
					continue
				}
				if len(policy.Tmpls) == 0 {
					glog.Warningf("Tunnel policy has no associated template")
					continue
				}
				dst = policy.Tmpls[0].Dst
				break
			}
			if dst == nil {
				glog.Warningf("could not find ip for tunnel between %s and %s", tunnel.Src, tunnel.Dst)
				continue
			}
			for _, state := range states {
				if !state.Dst.Equal(dst) {
					continue
				}
				tunnel.Reqid = state.Reqid
				if state.Auth == nil {
					glog.Warningf("Tunnel state has no associated authentication entry")
					continue
				}
				tunnel.AuthKey = state.Auth.Key
				if state.Crypt == nil {
					glog.Warningf("Tunnel state has no associated encryption entry")
					continue
				}
				tunnel.EncKey = state.Crypt.Key
				if state.Encap != nil {
					tunnel.SrcPort = state.Encap.SrcPort
					tunnel.SrcPort = state.Encap.DstPort
				}
				glog.Infof("Discovered tunnel between %v and %v over %v", tunnel.Src, tunnel.Dst, dst)
				var socket int
				if tunnel.SrcPort != 0 {
					socket, err = createEncapListener(tunnel.Src, tunnel.SrcPort)
					if err != nil {
						glog.Warningf("Failed to create udp listener: %v", err)
					}
				}
				addTunnel(dst.String(), &tunnel, socket)
				break
			}
		}
	}
	glog.Infof("Finished discovering existing tunnels")
}
Пример #4
0
func (o *Overlay) cleanup() error {
	changed := false
	defer func() {
		if !changed {
			return
		}

		time.Sleep(2 * time.Second)

		if err := o.loadConns(); err != nil {
			logrus.Errorf("Failed to reload connections: %v", err)
		}
		if err := o.configure(); err != nil {
			logrus.Errorf("Failed to reconfigure: %v", err)
		}
	}()

	o.Lock()
	defer o.Unlock()

	previouslyUnknown := o.unknownSpis
	o.unknownSpis = map[string]int{}

	client, err := getClient()
	if err != nil {
		return err
	}
	defer client.Close()

	conns, err := client.ListAllVpnConnInfo()
	if err != nil {
		return err
	}

	knownSpis := map[string]bool{}
	badConns := map[string]bool{}
	for _, conn := range conns {
		if conn.Local_host != "127.0.0.1" && conn.Local_host != o.db.LocalIpAddress() {
			badConns[conn.IkeSaName] = true
			if conn.ChildSaName != "" {
				logrus.Infof("Terminating connection: %s %s != %s", conn.IkeSaName, conn.Local_host, o.db.LocalIpAddress())
				err := client.Terminate(&goStrongswanVici.TerminateRequest{
					Ike: conn.IkeSaName,
				})
				if err != nil {
					logrus.Infof("Failed to termination connection %s: %v", conn.ChildSaName, err)
				}
			}
		}

		children := []goStrongswanVici.Child_sas{conn.Child_sas}
		for _, child := range conn.IkeSa.Child_sas {
			children = append(children, child)
		}

		for _, child := range children {
			for _, i := range []string{child.Spi_in, child.Spi_out} {
				if i != "" {
					if badConns[conn.IkeSaName] {
						previouslyUnknown[i] = 4
					} else {
						knownSpis[i] = true
					}
				}
			}
		}
	}

	if len(badConns) > 0 {
		changed = true

		logrus.Infof("Bad connections %v", badConns)
		for badConn, _ := range badConns {
			logrus.Infof("Deleting %s", badConn)
			err := client.UnloadConn(&goStrongswanVici.UnloadConnRequest{
				Name: badConn,
			})
			if err != nil {
				logrus.Infof("Failed to delete %s: %v", badConn, err)
			}
		}
	}

	stateList, err := netlink.XfrmStateList(netlink.FAMILY_V4)
	if err != nil {
		return err
	}
	for _, state := range stateList {
		spi := fmt.Sprintf("%x", state.Spi)
		if !knownSpis[spi] {
			if previouslyUnknown[spi] > 3 {
				logrus.Infof("Deleting unknown SPI %s: %#v", spi, state)
				netlink.XfrmStateDel(&state)
			} else {
				o.unknownSpis[spi] = previouslyUnknown[spi] + 1
			}
		}
	}

	if len(o.unknownSpis) > 0 {
		logrus.Infof("Unknown SPIs: %#v, Conns: %#v", o.unknownSpis, conns)
	}

	return nil
}