mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-10 02:50:27 +00:00
Implement session firewall as gatekeeper func in cmd/yggdrasil
This commit is contained in:
parent
720a078a35
commit
907986f200
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -20,22 +21,21 @@ import (
|
|||||||
|
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
|
"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/tuntap"
|
"github.com/yggdrasil-network/yggdrasil-go/src/tuntap"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nodeConfig = config.NodeConfig
|
|
||||||
type Core = yggdrasil.Core
|
|
||||||
|
|
||||||
type node struct {
|
type node struct {
|
||||||
core Core
|
core yggdrasil.Core
|
||||||
|
state *config.NodeState
|
||||||
tuntap tuntap.TunAdapter
|
tuntap tuntap.TunAdapter
|
||||||
multicast multicast.Multicast
|
multicast multicast.Multicast
|
||||||
admin admin.AdminSocket
|
admin admin.AdminSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *nodeConfig {
|
func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *config.NodeConfig {
|
||||||
// Use a configuration file. If -useconf, the configuration will be read
|
// Use a configuration file. If -useconf, the configuration will be read
|
||||||
// from stdin. If -useconffile, the configuration will be read from the
|
// from stdin. If -useconffile, the configuration will be read from the
|
||||||
// filesystem.
|
// filesystem.
|
||||||
@ -116,7 +116,7 @@ func main() {
|
|||||||
logging := flag.String("logging", "info,warn,error", "comma-separated list of logging levels to enable")
|
logging := flag.String("logging", "info,warn,error", "comma-separated list of logging levels to enable")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var cfg *nodeConfig
|
var cfg *config.NodeConfig
|
||||||
var err error
|
var err error
|
||||||
switch {
|
switch {
|
||||||
case *version:
|
case *version:
|
||||||
@ -181,18 +181,20 @@ func main() {
|
|||||||
n := node{}
|
n := node{}
|
||||||
// Now start Yggdrasil - this starts the DHT, router, switch and other core
|
// Now start Yggdrasil - this starts the DHT, router, switch and other core
|
||||||
// components needed for Yggdrasil to operate
|
// components needed for Yggdrasil to operate
|
||||||
state, err := n.core.Start(cfg, logger)
|
n.state, err = n.core.Start(cfg, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorln("An error occurred during startup")
|
logger.Errorln("An error occurred during startup")
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
// Register the session firewall gatekeeper function
|
||||||
|
n.core.SetSessionGatekeeper(n.sessionFirewall)
|
||||||
// Start the admin socket
|
// Start the admin socket
|
||||||
n.admin.Init(&n.core, 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 {
|
||||||
logger.Errorln("An error occurred starting admin socket:", err)
|
logger.Errorln("An error occurred starting admin socket:", err)
|
||||||
}
|
}
|
||||||
// Start the multicast interface
|
// Start the multicast interface
|
||||||
n.multicast.Init(&n.core, state, logger, nil)
|
n.multicast.Init(&n.core, n.state, logger, nil)
|
||||||
if err := n.multicast.Start(); err != nil {
|
if err := n.multicast.Start(); err != nil {
|
||||||
logger.Errorln("An error occurred starting multicast:", err)
|
logger.Errorln("An error occurred starting multicast:", err)
|
||||||
}
|
}
|
||||||
@ -200,7 +202,7 @@ func main() {
|
|||||||
// Start the TUN/TAP interface
|
// Start the TUN/TAP interface
|
||||||
if listener, err := n.core.ConnListen(); err == nil {
|
if listener, err := n.core.ConnListen(); err == nil {
|
||||||
if dialer, err := n.core.ConnDialer(); err == nil {
|
if dialer, err := n.core.ConnDialer(); err == nil {
|
||||||
n.tuntap.Init(state, logger, listener, dialer)
|
n.tuntap.Init(n.state, logger, listener, dialer)
|
||||||
if err := n.tuntap.Start(); err != nil {
|
if err := n.tuntap.Start(); err != nil {
|
||||||
logger.Errorln("An error occurred starting TUN/TAP:", err)
|
logger.Errorln("An error occurred starting TUN/TAP:", err)
|
||||||
}
|
}
|
||||||
@ -251,3 +253,66 @@ func main() {
|
|||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
|
||||||
|
n.state.Mutex.RLock()
|
||||||
|
defer n.state.Mutex.RUnlock()
|
||||||
|
|
||||||
|
// Allow by default if the session firewall is disabled
|
||||||
|
if !n.state.Current.SessionFirewall.Enable {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare for checking whitelist/blacklist
|
||||||
|
var box crypto.BoxPubKey
|
||||||
|
// Reject blacklisted nodes
|
||||||
|
for _, b := range n.state.Current.SessionFirewall.BlacklistEncryptionPublicKeys {
|
||||||
|
key, err := hex.DecodeString(b)
|
||||||
|
if err == nil {
|
||||||
|
copy(box[:crypto.BoxPubKeyLen], key)
|
||||||
|
if box == *pubkey {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow whitelisted nodes
|
||||||
|
for _, b := range n.state.Current.SessionFirewall.WhitelistEncryptionPublicKeys {
|
||||||
|
key, err := hex.DecodeString(b)
|
||||||
|
if err == nil {
|
||||||
|
copy(box[:crypto.BoxPubKeyLen], key)
|
||||||
|
if box == *pubkey {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow outbound sessions if appropriate
|
||||||
|
if n.state.Current.SessionFirewall.AlwaysAllowOutbound {
|
||||||
|
if initiator {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look and see if the pubkey is that of a direct peer
|
||||||
|
var isDirectPeer bool
|
||||||
|
for _, peer := range n.core.GetPeers() {
|
||||||
|
if peer.PublicKey == *pubkey {
|
||||||
|
isDirectPeer = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow direct peers if appropriate
|
||||||
|
if n.state.Current.SessionFirewall.AllowFromDirect && isDirectPeer {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow remote nodes if appropriate
|
||||||
|
if n.state.Current.SessionFirewall.AllowFromRemote && !isDirectPeer {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, default-deny if not matching any of the above rules
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user