Check CKR remotes when receiving traffic

This commit is contained in:
Neil Alexander 2019-08-20 09:38:46 +01:00
parent 2b6462c8a9
commit b6e67bc0ba
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
2 changed files with 36 additions and 23 deletions

View File

@ -27,9 +27,9 @@ type cryptokey struct {
ipv6cache map[address.Address]cryptokey_route ipv6cache map[address.Address]cryptokey_route
ipv4locals []net.IPNet ipv4locals []net.IPNet
ipv6locals []net.IPNet ipv6locals []net.IPNet
mutexroutes sync.RWMutex mutexremotes sync.RWMutex
mutexcaches sync.RWMutex mutexcaches sync.RWMutex
mutexsources sync.RWMutex mutexlocals sync.RWMutex
} }
type cryptokey_route struct { type cryptokey_route struct {
@ -65,10 +65,10 @@ func (c *cryptokey) configure() error {
c.setEnabled(current.TunnelRouting.Enable) c.setEnabled(current.TunnelRouting.Enable)
// Clear out existing routes // Clear out existing routes
c.mutexroutes.Lock() c.mutexremotes.Lock()
c.ipv6remotes = make([]cryptokey_route, 0) c.ipv6remotes = make([]cryptokey_route, 0)
c.ipv4remotes = make([]cryptokey_route, 0) c.ipv4remotes = make([]cryptokey_route, 0)
c.mutexroutes.Unlock() c.mutexremotes.Unlock()
// Add IPv6 routes // Add IPv6 routes
for ipv6, pubkey := range current.TunnelRouting.IPv6RemoteSubnets { for ipv6, pubkey := range current.TunnelRouting.IPv6RemoteSubnets {
@ -85,10 +85,10 @@ func (c *cryptokey) configure() error {
} }
// Clear out existing sources // Clear out existing sources
c.mutexsources.Lock() c.mutexlocals.Lock()
c.ipv6locals = make([]net.IPNet, 0) c.ipv6locals = make([]net.IPNet, 0)
c.ipv4locals = make([]net.IPNet, 0) c.ipv4locals = make([]net.IPNet, 0)
c.mutexsources.Unlock() c.mutexlocals.Unlock()
// Add IPv6 sources // Add IPv6 sources
c.ipv6locals = make([]net.IPNet, 0) c.ipv6locals = make([]net.IPNet, 0)
@ -130,8 +130,8 @@ func (c *cryptokey) isEnabled() bool {
// matches either the current node's address, the node's routed subnet or the // matches either the current node's address, the node's routed subnet or the
// list of subnets specified in ipv4locals/ipv6locals. // list of subnets specified in ipv4locals/ipv6locals.
func (c *cryptokey) isValidLocalAddress(addr address.Address, addrlen int) bool { func (c *cryptokey) isValidLocalAddress(addr address.Address, addrlen int) bool {
c.mutexsources.RLock() c.mutexlocals.RLock()
defer c.mutexsources.RUnlock() defer c.mutexlocals.RUnlock()
ip := net.IP(addr[:addrlen]) ip := net.IP(addr[:addrlen])
@ -175,8 +175,8 @@ func (c *cryptokey) isValidLocalAddress(addr address.Address, addrlen int) bool
// Adds a source subnet, which allows traffic with these source addresses to // Adds a source subnet, which allows traffic with these source addresses to
// be tunnelled using crypto-key routing. // be tunnelled using crypto-key routing.
func (c *cryptokey) addLocalSubnet(cidr string) error { func (c *cryptokey) addLocalSubnet(cidr string) error {
c.mutexsources.Lock() c.mutexlocals.Lock()
defer c.mutexsources.Unlock() defer c.mutexlocals.Unlock()
// Is the CIDR we've been given valid? // Is the CIDR we've been given valid?
_, ipnet, err := net.ParseCIDR(cidr) _, ipnet, err := net.ParseCIDR(cidr)
@ -215,9 +215,9 @@ func (c *cryptokey) addLocalSubnet(cidr string) error {
// Adds a destination route for the given CIDR to be tunnelled to the node // Adds a destination route for the given CIDR to be tunnelled to the node
// with the given BoxPubKey. // with the given BoxPubKey.
func (c *cryptokey) addRemoteSubnet(cidr string, dest string) error { func (c *cryptokey) addRemoteSubnet(cidr string, dest string) error {
c.mutexroutes.Lock() c.mutexremotes.Lock()
c.mutexcaches.Lock() c.mutexcaches.Lock()
defer c.mutexroutes.Unlock() defer c.mutexremotes.Unlock()
defer c.mutexcaches.Unlock() defer c.mutexcaches.Unlock()
// Is the CIDR we've been given valid? // Is the CIDR we've been given valid?
@ -323,8 +323,8 @@ func (c *cryptokey) getPublicKeyForAddress(addr address.Address, addrlen int) (c
c.mutexcaches.RUnlock() c.mutexcaches.RUnlock()
c.mutexroutes.RLock() c.mutexremotes.RLock()
defer c.mutexroutes.RUnlock() defer c.mutexremotes.RUnlock()
// Check if the prefix is IPv4 or IPv6 // Check if the prefix is IPv4 or IPv6
if addrlen == net.IPv6len { if addrlen == net.IPv6len {
@ -366,14 +366,14 @@ func (c *cryptokey) getPublicKeyForAddress(addr address.Address, addrlen int) (c
} }
// No route was found if we got to this point // No route was found if we got to this point
return crypto.BoxPubKey{}, errors.New(fmt.Sprintf("No route to %s", ip.String())) return crypto.BoxPubKey{}, fmt.Errorf("no route to %s", ip.String())
} }
// Removes a source subnet, which allows traffic with these source addresses to // Removes a source subnet, which allows traffic with these source addresses to
// be tunnelled using crypto-key routing. // be tunnelled using crypto-key routing.
func (c *cryptokey) removeLocalSubnet(cidr string) error { func (c *cryptokey) removeLocalSubnet(cidr string) error {
c.mutexsources.Lock() c.mutexlocals.Lock()
defer c.mutexsources.Unlock() defer c.mutexlocals.Unlock()
// Is the CIDR we've been given valid? // Is the CIDR we've been given valid?
_, ipnet, err := net.ParseCIDR(cidr) _, ipnet, err := net.ParseCIDR(cidr)
@ -410,9 +410,9 @@ func (c *cryptokey) removeLocalSubnet(cidr string) error {
// Removes a destination route for the given CIDR to be tunnelled to the node // Removes a destination route for the given CIDR to be tunnelled to the node
// with the given BoxPubKey. // with the given BoxPubKey.
func (c *cryptokey) removeRemoteSubnet(cidr string, dest string) error { func (c *cryptokey) removeRemoteSubnet(cidr string, dest string) error {
c.mutexroutes.Lock() c.mutexremotes.Lock()
c.mutexcaches.Lock() c.mutexcaches.Lock()
defer c.mutexroutes.Unlock() defer c.mutexremotes.Unlock()
defer c.mutexcaches.Unlock() defer c.mutexcaches.Unlock()
// Is the CIDR we've been given valid? // Is the CIDR we've been given valid?

View File

@ -21,6 +21,7 @@ func (tun *TunAdapter) writer() error {
if n == 0 { if n == 0 {
continue continue
} }
var srcAddr address.Address
var dstAddr address.Address var dstAddr address.Address
var addrlen int var addrlen int
// Check whether the packet is IPv4, IPv6 or neither // Check whether the packet is IPv4, IPv6 or neither
@ -31,8 +32,9 @@ func (tun *TunAdapter) writer() error {
util.PutBytes(b) util.PutBytes(b)
continue continue
} }
// Extract the destination IPv6 address // Extract the IPv6 addresses
copy(dstAddr[:16], b[24:]) copy(srcAddr[:16], b[8:24])
copy(dstAddr[:16], b[24:40])
addrlen = 16 addrlen = 16
} else if b[0]&0xf0 == 0x40 { } else if b[0]&0xf0 == 0x40 {
// IPv4 packet found // IPv4 packet found
@ -41,8 +43,9 @@ func (tun *TunAdapter) writer() error {
util.PutBytes(b) util.PutBytes(b)
continue continue
} }
// Extract the destination IPv4 address // Extract the IPv4 addresses
copy(dstAddr[:4], b[16:]) copy(srcAddr[:4], b[12:16])
copy(dstAddr[:4], b[16:20])
addrlen = 4 addrlen = 4
} else { } else {
// Neither IPv4 nor IPv6 // Neither IPv4 nor IPv6
@ -54,6 +57,16 @@ func (tun *TunAdapter) writer() error {
util.PutBytes(b) util.PutBytes(b)
continue continue
} }
if srcAddr[0] != 0x02 && srcAddr[0] != 0x03 {
// TODO: is this check useful? this doesn't actually guarantee that the
// packet came from the configured public key for that remote, just that
// it came from *a* configured remote. at this stage we have no ability
// to know which Conn or public key was involved
if _, err := tun.ckr.getPublicKeyForAddress(srcAddr, addrlen); err != nil {
util.PutBytes(b)
continue
}
}
} else { } else {
if addrlen != 16 { if addrlen != 16 {
util.PutBytes(b) util.PutBytes(b)