mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Implement session firewall as gatekeeper func in cmd/yggdrasil
This commit is contained in:
		
							parent
							
								
									720a078a35
								
							
						
					
					
						commit
						907986f200
					
				
					 1 changed files with 75 additions and 10 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue