mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-09 16:20:26 +00:00
move sessionfirewall into the tuntap. this needs testing. the name is also slightly wrong, since a crypto session can still be set up, packets are just accepted/rejected at the tun/tap level instead
This commit is contained in:
parent
7e10025ef0
commit
5b00273dfc
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/ed25519"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
@ -277,11 +278,11 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
// Register the session firewall gatekeeper function
|
// Register the session firewall gatekeeper function
|
||||||
// TODO n.core.SetSessionGatekeeper(n.sessionFirewall)
|
|
||||||
// Allocate our modules
|
// Allocate our modules
|
||||||
n.admin = &admin.AdminSocket{}
|
n.admin = &admin.AdminSocket{}
|
||||||
n.multicast = &multicast.Multicast{}
|
n.multicast = &multicast.Multicast{}
|
||||||
n.tuntap = &tuntap.TunAdapter{}
|
n.tuntap = &tuntap.TunAdapter{}
|
||||||
|
n.tuntap.(*tuntap.TunAdapter).SetSessionGatekeeper(n.sessionFirewall)
|
||||||
// Start the admin socket
|
// Start the admin socket
|
||||||
n.admin.Init(&n.core, n.state, logger, nil)
|
n.admin.Init(&n.core, n.state, logger, nil)
|
||||||
if err := n.admin.Start(); err != nil {
|
if err := n.admin.Start(); err != nil {
|
||||||
@ -300,21 +301,6 @@ func main() {
|
|||||||
logger.Errorln("An error occurred starting TUN/TAP:", err)
|
logger.Errorln("An error occurred starting TUN/TAP:", err)
|
||||||
}
|
}
|
||||||
n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
|
n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
|
||||||
/*
|
|
||||||
if listener, err := n.core.ConnListen(); err == nil {
|
|
||||||
if dialer, err := n.core.ConnDialer(); err == nil {
|
|
||||||
n.tuntap.Init(&n.core, n.state, logger, tuntap.TunOptions{Listener: listener, Dialer: dialer})
|
|
||||||
if err := n.tuntap.Start(); err != nil {
|
|
||||||
logger.Errorln("An error occurred starting TUN/TAP:", err)
|
|
||||||
}
|
|
||||||
n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
|
|
||||||
} else {
|
|
||||||
logger.Errorln("Unable to get Dialer:", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.Errorln("Unable to get Listener:", err)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// Make some nice output that tells us what our IPv6 address and subnet are.
|
// Make some nice output that tells us what our IPv6 address and subnet are.
|
||||||
// This is just logged to stdout for the user.
|
// This is just logged to stdout for the user.
|
||||||
address := n.core.Address()
|
address := n.core.Address()
|
||||||
@ -337,7 +323,7 @@ func (n *node) shutdown() {
|
|||||||
n.core.Stop()
|
n.core.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
|
func (n *node) sessionFirewall(pubkey ed25519.PublicKey, initiator bool) bool {
|
||||||
n.state.Mutex.RLock()
|
n.state.Mutex.RLock()
|
||||||
defer n.state.Mutex.RUnlock()
|
defer n.state.Mutex.RUnlock()
|
||||||
|
|
||||||
@ -346,14 +332,11 @@ func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for checking whitelist/blacklist
|
|
||||||
var box crypto.BoxPubKey
|
|
||||||
// Reject blacklisted nodes
|
// Reject blacklisted nodes
|
||||||
for _, b := range n.state.Current.SessionFirewall.BlacklistPublicKeys {
|
for _, b := range n.state.Current.SessionFirewall.BlacklistPublicKeys {
|
||||||
key, err := hex.DecodeString(b)
|
key, err := hex.DecodeString(b)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
copy(box[:crypto.BoxPubKeyLen], key)
|
if bytes.Equal(key, pubkey) {
|
||||||
if box == *pubkey {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,8 +346,7 @@ func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
|
|||||||
for _, b := range n.state.Current.SessionFirewall.WhitelistPublicKeys {
|
for _, b := range n.state.Current.SessionFirewall.WhitelistPublicKeys {
|
||||||
key, err := hex.DecodeString(b)
|
key, err := hex.DecodeString(b)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
copy(box[:crypto.BoxPubKeyLen], key)
|
if bytes.Equal(key, pubkey) {
|
||||||
if box == *pubkey {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -379,14 +361,12 @@ func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
|
|||||||
|
|
||||||
// Look and see if the pubkey is that of a direct peer
|
// Look and see if the pubkey is that of a direct peer
|
||||||
var isDirectPeer bool
|
var isDirectPeer bool
|
||||||
/* TODO
|
|
||||||
for _, peer := range n.core.GetPeers() {
|
for _, peer := range n.core.GetPeers() {
|
||||||
if peer.PublicKey == *pubkey {
|
if bytes.Equal(peer.Key[:], pubkey[:]) {
|
||||||
isDirectPeer = true
|
isDirectPeer = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Allow direct peers if appropriate
|
// Allow direct peers if appropriate
|
||||||
if n.state.Current.SessionFirewall.AllowFromDirect && isDirectPeer {
|
if n.state.Current.SessionFirewall.AllowFromDirect && isDirectPeer {
|
||||||
|
@ -93,6 +93,9 @@ func (tun *TunAdapter) write() {
|
|||||||
continue // bad local address/subnet
|
continue // bad local address/subnet
|
||||||
}
|
}
|
||||||
info := tun.store.update(ed25519.PublicKey(from.(iwt.Addr)))
|
info := tun.store.update(ed25519.PublicKey(from.(iwt.Addr)))
|
||||||
|
if info == nil {
|
||||||
|
continue // Blocked by the gatekeeper
|
||||||
|
}
|
||||||
if srcAddr != info.address && srcSubnet != info.subnet {
|
if srcAddr != info.address && srcSubnet != info.subnet {
|
||||||
continue // bad remote address/subnet
|
continue // bad remote address/subnet
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,18 @@ func (k *keyStore) update(key ed25519.PublicKey) *keyInfo {
|
|||||||
info.address = *address.AddrForKey(ed25519.PublicKey(info.key[:]))
|
info.address = *address.AddrForKey(ed25519.PublicKey(info.key[:]))
|
||||||
info.subnet = *address.SubnetForKey(ed25519.PublicKey(info.key[:]))
|
info.subnet = *address.SubnetForKey(ed25519.PublicKey(info.key[:]))
|
||||||
info.mtu = MTU(^uint16(0)) // TODO
|
info.mtu = MTU(^uint16(0)) // TODO
|
||||||
|
var isOutgoing bool
|
||||||
|
if k.addrBuffer[info.address] != nil {
|
||||||
|
isOutgoing = true
|
||||||
|
}
|
||||||
|
if k.subnetBuffer[info.subnet] != nil {
|
||||||
|
isOutgoing = true
|
||||||
|
}
|
||||||
|
if !k.tun.gatekeeper(key, isOutgoing) {
|
||||||
|
// Blocked by the gatekeeper, so don't create an entry for this
|
||||||
|
k.mutex.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
k.keyToInfo[info.key] = info
|
k.keyToInfo[info.key] = info
|
||||||
k.addrToInfo[info.address] = info
|
k.addrToInfo[info.address] = info
|
||||||
k.subnetToInfo[info.subnet] = info
|
k.subnetToInfo[info.subnet] = info
|
||||||
|
@ -44,7 +44,14 @@ type TunAdapter struct {
|
|||||||
iface tun.Device
|
iface tun.Device
|
||||||
phony.Inbox // Currently only used for _handlePacket from the reader, TODO: all the stuff that currently needs a mutex below
|
phony.Inbox // Currently only used for _handlePacket from the reader, TODO: all the stuff that currently needs a mutex below
|
||||||
//mutex sync.RWMutex // Protects the below
|
//mutex sync.RWMutex // Protects the below
|
||||||
isOpen bool
|
isOpen bool
|
||||||
|
gatekeeper func(pubkey ed25519.PublicKey, initiator bool) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tun *TunAdapter) SetSessionGatekeeper(gatekeeper func(pubkey ed25519.PublicKey, initiator bool) bool) {
|
||||||
|
phony.Block(tun, func() {
|
||||||
|
tun.gatekeeper = gatekeeper
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the maximum supported MTU for the platform based on the defaults in
|
// Gets the maximum supported MTU for the platform based on the defaults in
|
||||||
|
Loading…
Reference in New Issue
Block a user