mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Add source addresses option and more intelligent source checking
This commit is contained in:
		
							parent
							
								
									cfdbc481a5
								
							
						
					
					
						commit
						8c2327a2bf
					
				
					 3 changed files with 64 additions and 12 deletions
				
			
		| 
						 | 
					@ -12,12 +12,14 @@ import (
 | 
				
			||||||
// allow traffic for non-Yggdrasil ranges to be routed over Yggdrasil.
 | 
					// allow traffic for non-Yggdrasil ranges to be routed over Yggdrasil.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type cryptokey struct {
 | 
					type cryptokey struct {
 | 
				
			||||||
	core       *Core
 | 
						core        *Core
 | 
				
			||||||
	enabled    bool
 | 
						enabled     bool
 | 
				
			||||||
	ipv4routes []cryptokey_route
 | 
						ipv4routes  []cryptokey_route
 | 
				
			||||||
	ipv6routes []cryptokey_route
 | 
						ipv6routes  []cryptokey_route
 | 
				
			||||||
	ipv4cache  map[address]cryptokey_route
 | 
						ipv4cache   map[address]cryptokey_route
 | 
				
			||||||
	ipv6cache  map[address]cryptokey_route
 | 
						ipv6cache   map[address]cryptokey_route
 | 
				
			||||||
 | 
						ipv4sources []net.IPNet
 | 
				
			||||||
 | 
						ipv6sources []net.IPNet
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type cryptokey_route struct {
 | 
					type cryptokey_route struct {
 | 
				
			||||||
| 
						 | 
					@ -31,12 +33,60 @@ func (c *cryptokey) init(core *Core) {
 | 
				
			||||||
	c.ipv6routes = make([]cryptokey_route, 0)
 | 
						c.ipv6routes = make([]cryptokey_route, 0)
 | 
				
			||||||
	c.ipv4cache = make(map[address]cryptokey_route, 0)
 | 
						c.ipv4cache = make(map[address]cryptokey_route, 0)
 | 
				
			||||||
	c.ipv6cache = make(map[address]cryptokey_route, 0)
 | 
						c.ipv6cache = make(map[address]cryptokey_route, 0)
 | 
				
			||||||
 | 
						c.ipv4sources = make([]net.IPNet, 0)
 | 
				
			||||||
 | 
						c.ipv6sources = make([]net.IPNet, 0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *cryptokey) isEnabled() bool {
 | 
					func (c *cryptokey) isEnabled() bool {
 | 
				
			||||||
	return c.enabled
 | 
						return c.enabled
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *cryptokey) isValidSource(addr address) bool {
 | 
				
			||||||
 | 
						ip := net.IP(addr[:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Does this match our node's address?
 | 
				
			||||||
 | 
						if addr == c.core.router.addr {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Does this match our node's subnet?
 | 
				
			||||||
 | 
						var subnet net.IPNet
 | 
				
			||||||
 | 
						copy(subnet.IP, c.core.router.subnet[:])
 | 
				
			||||||
 | 
						copy(subnet.Mask, net.CIDRMask(64, 128))
 | 
				
			||||||
 | 
						if subnet.Contains(ip) {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Does it match a configured CKR source?
 | 
				
			||||||
 | 
						for _, subnet := range c.ipv6sources {
 | 
				
			||||||
 | 
							if subnet.Contains(ip) {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Doesn't match any of the above
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *cryptokey) addSourceSubnet(cidr string) error {
 | 
				
			||||||
 | 
						// Is the CIDR we've been given valid?
 | 
				
			||||||
 | 
						_, ipnet, err := net.ParseCIDR(cidr)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if we already have this CIDR
 | 
				
			||||||
 | 
						for _, subnet := range c.ipv6sources {
 | 
				
			||||||
 | 
							if subnet.String() == ipnet.String() {
 | 
				
			||||||
 | 
								return errors.New("Source subnet already configured")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Add the source subnet
 | 
				
			||||||
 | 
						c.ipv6sources = append(c.ipv6sources, *ipnet)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *cryptokey) addRoute(cidr string, dest string) error {
 | 
					func (c *cryptokey) addRoute(cidr string, dest string) error {
 | 
				
			||||||
	// Is the CIDR we've been given valid?
 | 
						// Is the CIDR we've been given valid?
 | 
				
			||||||
	ipaddr, ipnet, err := net.ParseCIDR(cidr)
 | 
						ipaddr, ipnet, err := net.ParseCIDR(cidr)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,7 @@ type SessionFirewall struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TunnelRouting contains the crypto-key routing tables for tunneling
 | 
					// TunnelRouting contains the crypto-key routing tables for tunneling
 | 
				
			||||||
type TunnelRouting struct {
 | 
					type TunnelRouting struct {
 | 
				
			||||||
	Enable     bool              `comment:"Enable or disable tunneling."`
 | 
						Enable      bool              `comment:"Enable or disable tunneling."`
 | 
				
			||||||
	IPv6Routes map[string]string `comment:"IPv6 subnets, mapped to the public keys to which they should be routed."`
 | 
						IPv6Routes  map[string]string `comment:"IPv6 subnets, mapped to the public keys to which they should be routed."`
 | 
				
			||||||
 | 
						IPv6Sources []string          `comment:"Allow source addresses in these subnets."`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@ import (
 | 
				
			||||||
type router struct {
 | 
					type router struct {
 | 
				
			||||||
	core      *Core
 | 
						core      *Core
 | 
				
			||||||
	addr      address
 | 
						addr      address
 | 
				
			||||||
 | 
						subnet    subnet
 | 
				
			||||||
	in        <-chan []byte // packets we received from the network, link to peer's "out"
 | 
						in        <-chan []byte // packets we received from the network, link to peer's "out"
 | 
				
			||||||
	out       func([]byte)  // packets we're sending to the network, link to peer's "in"
 | 
						out       func([]byte)  // packets we're sending to the network, link to peer's "in"
 | 
				
			||||||
	recv      chan<- []byte // place where the tun pulls received packets from
 | 
						recv      chan<- []byte // place where the tun pulls received packets from
 | 
				
			||||||
| 
						 | 
					@ -47,6 +48,7 @@ type router struct {
 | 
				
			||||||
func (r *router) init(core *Core) {
 | 
					func (r *router) init(core *Core) {
 | 
				
			||||||
	r.core = core
 | 
						r.core = core
 | 
				
			||||||
	r.addr = *address_addrForNodeID(&r.core.dht.nodeID)
 | 
						r.addr = *address_addrForNodeID(&r.core.dht.nodeID)
 | 
				
			||||||
 | 
						r.subnet = *address_subnetForNodeID(&r.core.dht.nodeID)
 | 
				
			||||||
	in := make(chan []byte, 32) // TODO something better than this...
 | 
						in := make(chan []byte, 32) // TODO something better than this...
 | 
				
			||||||
	p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)")
 | 
						p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)")
 | 
				
			||||||
	p.out = func(packet []byte) {
 | 
						p.out = func(packet []byte) {
 | 
				
			||||||
| 
						 | 
					@ -128,6 +130,9 @@ func (r *router) sendPacket(bs []byte) {
 | 
				
			||||||
	var snet subnet
 | 
						var snet subnet
 | 
				
			||||||
	copy(sourceAddr[:], bs[8:])
 | 
						copy(sourceAddr[:], bs[8:])
 | 
				
			||||||
	copy(sourceSubnet[:], bs[8:])
 | 
						copy(sourceSubnet[:], bs[8:])
 | 
				
			||||||
 | 
						if !r.cryptokey.isValidSource(sourceAddr) {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	copy(dest[:], bs[24:])
 | 
						copy(dest[:], bs[24:])
 | 
				
			||||||
	copy(snet[:], bs[24:])
 | 
						copy(snet[:], bs[24:])
 | 
				
			||||||
	if !dest.isValid() && !snet.isValid() {
 | 
						if !dest.isValid() && !snet.isValid() {
 | 
				
			||||||
| 
						 | 
					@ -141,10 +146,6 @@ func (r *router) sendPacket(bs []byte) {
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if !sourceAddr.isValid() && !sourceSubnet.isValid() {
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	doSearch := func(packet []byte) {
 | 
						doSearch := func(packet []byte) {
 | 
				
			||||||
		var nodeID, mask *NodeID
 | 
							var nodeID, mask *NodeID
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue