mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-23 00:51:35 +00:00
Add source addresses option and more intelligent source checking
This commit is contained in:
parent
cfdbc481a5
commit
8c2327a2bf
@ -18,6 +18,8 @@ type cryptokey struct {
|
|||||||
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)
|
||||||
|
@ -41,4 +41,5 @@ type SessionFirewall struct {
|
|||||||
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…
Reference in New Issue
Block a user