mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Handle session firewall using central config
This commit is contained in:
		
							parent
							
								
									fdf300a1ff
								
							
						
					
					
						commit
						9d5085492e
					
				
					 2 changed files with 14 additions and 58 deletions
				
			
		| 
						 | 
					@ -212,15 +212,6 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.sessions.setSessionFirewallState(nc.SessionFirewall.Enable)
 | 
					 | 
				
			||||||
	c.sessions.setSessionFirewallDefaults(
 | 
					 | 
				
			||||||
		nc.SessionFirewall.AllowFromDirect,
 | 
					 | 
				
			||||||
		nc.SessionFirewall.AllowFromRemote,
 | 
					 | 
				
			||||||
		nc.SessionFirewall.AlwaysAllowOutbound,
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	c.sessions.setSessionFirewallWhitelist(nc.SessionFirewall.WhitelistEncryptionPublicKeys)
 | 
					 | 
				
			||||||
	c.sessions.setSessionFirewallBlacklist(nc.SessionFirewall.BlacklistEncryptionPublicKeys)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := c.router.start(); err != nil {
 | 
						if err := c.router.start(); err != nil {
 | 
				
			||||||
		c.log.Println("Failed to start router")
 | 
							c.log.Println("Failed to start router")
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,6 @@ package yggdrasil
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
				
			||||||
| 
						 | 
					@ -115,14 +114,6 @@ type sessions struct {
 | 
				
			||||||
	byTheirPerm  map[crypto.BoxPubKey]*crypto.Handle
 | 
						byTheirPerm  map[crypto.BoxPubKey]*crypto.Handle
 | 
				
			||||||
	addrToPerm   map[address.Address]*crypto.BoxPubKey
 | 
						addrToPerm   map[address.Address]*crypto.BoxPubKey
 | 
				
			||||||
	subnetToPerm map[address.Subnet]*crypto.BoxPubKey
 | 
						subnetToPerm map[address.Subnet]*crypto.BoxPubKey
 | 
				
			||||||
	// Options from the session firewall
 | 
					 | 
				
			||||||
	sessionFirewallMutex                sync.RWMutex
 | 
					 | 
				
			||||||
	sessionFirewallEnabled              bool
 | 
					 | 
				
			||||||
	sessionFirewallAllowsDirect         bool
 | 
					 | 
				
			||||||
	sessionFirewallAllowsRemote         bool
 | 
					 | 
				
			||||||
	sessionFirewallAlwaysAllowsOutbound bool
 | 
					 | 
				
			||||||
	sessionFirewallWhitelist            []string
 | 
					 | 
				
			||||||
	sessionFirewallBlacklist            []string
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Initializes the session struct.
 | 
					// Initializes the session struct.
 | 
				
			||||||
| 
						 | 
					@ -155,51 +146,28 @@ func (ss *sessions) init(core *Core) {
 | 
				
			||||||
	ss.lastCleanup = time.Now()
 | 
						ss.lastCleanup = time.Now()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Enable or disable the session firewall
 | 
					// Determines whether the session firewall is enabled.
 | 
				
			||||||
func (ss *sessions) setSessionFirewallState(enabled bool) {
 | 
					func (ss *sessions) isSessionFirewallEnabled() bool {
 | 
				
			||||||
	ss.sessionFirewallMutex.Lock()
 | 
						ss.core.configMutex.RLock()
 | 
				
			||||||
	defer ss.sessionFirewallMutex.Unlock()
 | 
						defer ss.core.configMutex.RUnlock()
 | 
				
			||||||
	ss.sessionFirewallEnabled = enabled
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set the session firewall defaults (first parameter is whether to allow
 | 
						return ss.core.config.SessionFirewall.Enable
 | 
				
			||||||
// sessions from direct peers, second is whether to allow from remote nodes).
 | 
					 | 
				
			||||||
func (ss *sessions) setSessionFirewallDefaults(allowsDirect bool, allowsRemote bool, alwaysAllowsOutbound bool) {
 | 
					 | 
				
			||||||
	ss.sessionFirewallMutex.Lock()
 | 
					 | 
				
			||||||
	defer ss.sessionFirewallMutex.Unlock()
 | 
					 | 
				
			||||||
	ss.sessionFirewallAllowsDirect = allowsDirect
 | 
					 | 
				
			||||||
	ss.sessionFirewallAllowsRemote = allowsRemote
 | 
					 | 
				
			||||||
	ss.sessionFirewallAlwaysAllowsOutbound = alwaysAllowsOutbound
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set the session firewall whitelist - nodes always allowed to open sessions.
 | 
					 | 
				
			||||||
func (ss *sessions) setSessionFirewallWhitelist(whitelist []string) {
 | 
					 | 
				
			||||||
	ss.sessionFirewallMutex.Lock()
 | 
					 | 
				
			||||||
	defer ss.sessionFirewallMutex.Unlock()
 | 
					 | 
				
			||||||
	ss.sessionFirewallWhitelist = whitelist
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set the session firewall blacklist - nodes never allowed to open sessions.
 | 
					 | 
				
			||||||
func (ss *sessions) setSessionFirewallBlacklist(blacklist []string) {
 | 
					 | 
				
			||||||
	ss.sessionFirewallMutex.Lock()
 | 
					 | 
				
			||||||
	defer ss.sessionFirewallMutex.Unlock()
 | 
					 | 
				
			||||||
	ss.sessionFirewallBlacklist = blacklist
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Determines whether the session with a given publickey is allowed based on
 | 
					// Determines whether the session with a given publickey is allowed based on
 | 
				
			||||||
// session firewall rules.
 | 
					// session firewall rules.
 | 
				
			||||||
func (ss *sessions) isSessionAllowed(pubkey *crypto.BoxPubKey, initiator bool) bool {
 | 
					func (ss *sessions) isSessionAllowed(pubkey *crypto.BoxPubKey, initiator bool) bool {
 | 
				
			||||||
	ss.sessionFirewallMutex.RLock()
 | 
						ss.core.configMutex.RLock()
 | 
				
			||||||
	defer ss.sessionFirewallMutex.RUnlock()
 | 
						defer ss.core.configMutex.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allow by default if the session firewall is disabled
 | 
						// Allow by default if the session firewall is disabled
 | 
				
			||||||
	if !ss.sessionFirewallEnabled {
 | 
						if !ss.isSessionFirewallEnabled() {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Prepare for checking whitelist/blacklist
 | 
						// Prepare for checking whitelist/blacklist
 | 
				
			||||||
	var box crypto.BoxPubKey
 | 
						var box crypto.BoxPubKey
 | 
				
			||||||
	// Reject blacklisted nodes
 | 
						// Reject blacklisted nodes
 | 
				
			||||||
	for _, b := range ss.sessionFirewallBlacklist {
 | 
						for _, b := range ss.core.config.SessionFirewall.BlacklistEncryptionPublicKeys {
 | 
				
			||||||
		key, err := hex.DecodeString(b)
 | 
							key, err := hex.DecodeString(b)
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			copy(box[:crypto.BoxPubKeyLen], key)
 | 
								copy(box[:crypto.BoxPubKeyLen], key)
 | 
				
			||||||
| 
						 | 
					@ -209,7 +177,7 @@ func (ss *sessions) isSessionAllowed(pubkey *crypto.BoxPubKey, initiator bool) b
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Allow whitelisted nodes
 | 
						// Allow whitelisted nodes
 | 
				
			||||||
	for _, b := range ss.sessionFirewallWhitelist {
 | 
						for _, b := range ss.core.config.SessionFirewall.WhitelistEncryptionPublicKeys {
 | 
				
			||||||
		key, err := hex.DecodeString(b)
 | 
							key, err := hex.DecodeString(b)
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			copy(box[:crypto.BoxPubKeyLen], key)
 | 
								copy(box[:crypto.BoxPubKeyLen], key)
 | 
				
			||||||
| 
						 | 
					@ -219,7 +187,7 @@ func (ss *sessions) isSessionAllowed(pubkey *crypto.BoxPubKey, initiator bool) b
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Allow outbound sessions if appropriate
 | 
						// Allow outbound sessions if appropriate
 | 
				
			||||||
	if ss.sessionFirewallAlwaysAllowsOutbound {
 | 
						if ss.core.config.SessionFirewall.AlwaysAllowOutbound {
 | 
				
			||||||
		if initiator {
 | 
							if initiator {
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -233,11 +201,11 @@ func (ss *sessions) isSessionAllowed(pubkey *crypto.BoxPubKey, initiator bool) b
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Allow direct peers if appropriate
 | 
						// Allow direct peers if appropriate
 | 
				
			||||||
	if ss.sessionFirewallAllowsDirect && isDirectPeer {
 | 
						if ss.core.config.SessionFirewall.AllowFromDirect && isDirectPeer {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Allow remote nodes if appropriate
 | 
						// Allow remote nodes if appropriate
 | 
				
			||||||
	if ss.sessionFirewallAllowsRemote && !isDirectPeer {
 | 
						if ss.core.config.SessionFirewall.AllowFromRemote && !isDirectPeer {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Finally, default-deny if not matching any of the above rules
 | 
						// Finally, default-deny if not matching any of the above rules
 | 
				
			||||||
| 
						 | 
					@ -474,14 +442,11 @@ func (ss *sessions) handlePing(ping *sessionPing) {
 | 
				
			||||||
	// Get the corresponding session (or create a new session)
 | 
						// Get the corresponding session (or create a new session)
 | 
				
			||||||
	sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub)
 | 
						sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub)
 | 
				
			||||||
	// Check the session firewall
 | 
						// Check the session firewall
 | 
				
			||||||
	ss.sessionFirewallMutex.RLock()
 | 
						if !isIn && ss.isSessionFirewallEnabled() {
 | 
				
			||||||
	if !isIn && ss.sessionFirewallEnabled {
 | 
					 | 
				
			||||||
		if !ss.isSessionAllowed(&ping.SendPermPub, false) {
 | 
							if !ss.isSessionAllowed(&ping.SendPermPub, false) {
 | 
				
			||||||
			ss.sessionFirewallMutex.RUnlock()
 | 
					 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ss.sessionFirewallMutex.RUnlock()
 | 
					 | 
				
			||||||
	if !isIn || sinfo.timedout() {
 | 
						if !isIn || sinfo.timedout() {
 | 
				
			||||||
		if isIn {
 | 
							if isIn {
 | 
				
			||||||
			sinfo.close()
 | 
								sinfo.close()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue