5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-09-20 03:42:32 +00:00

Add AlwaysAllowOutbound to session firewall

This commit is contained in:
Neil Alexander 2018-10-08 19:51:51 +01:00
parent 3f237372c9
commit 3ed63ede1e
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
4 changed files with 31 additions and 9 deletions

View File

@ -30,6 +30,7 @@ type SessionFirewall struct {
Enable bool `comment:"Enable or disable the session firewall. If disabled, network traffic\nfrom any node will be allowed. If enabled, the below rules apply."` Enable bool `comment:"Enable or disable the session firewall. If disabled, network traffic\nfrom any node will be allowed. If enabled, the below rules apply."`
AllowFromDirect bool `comment:"Allow network traffic from directly connected peers."` AllowFromDirect bool `comment:"Allow network traffic from directly connected peers."`
AllowFromRemote bool `comment:"Allow network traffic from remote nodes on the network that you are\nnot directly peered with."` AllowFromRemote bool `comment:"Allow network traffic from remote nodes on the network that you are\nnot directly peered with."`
AlwaysAllowOutbound bool `comment:"Allow outbound network traffic regardless of AllowFromDirect or\nAllowFromRemote. This does allow a remote node to send unsolicited\ntraffic back to you for the length of the session."`
WhitelistEncryptionPublicKeys []string `comment:"List of public keys from which network traffic is always accepted,\nregardless of AllowFromDirect or AllowFromRemote."` WhitelistEncryptionPublicKeys []string `comment:"List of public keys from which network traffic is always accepted,\nregardless of AllowFromDirect or AllowFromRemote."`
BlacklistEncryptionPublicKeys []string `comment:"List of public keys from which network traffic is always rejected,\nregardless of the whitelist, AllowFromDirect or AllowFromRemote."` BlacklistEncryptionPublicKeys []string `comment:"List of public keys from which network traffic is always rejected,\nregardless of the whitelist, AllowFromDirect or AllowFromRemote."`
} }

View File

@ -108,7 +108,11 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
} }
c.sessions.setSessionFirewallState(nc.SessionFirewall.Enable) c.sessions.setSessionFirewallState(nc.SessionFirewall.Enable)
c.sessions.setSessionFirewallDefaults(nc.SessionFirewall.AllowFromDirect, nc.SessionFirewall.AllowFromRemote) c.sessions.setSessionFirewallDefaults(
nc.SessionFirewall.AllowFromDirect,
nc.SessionFirewall.AllowFromRemote,
nc.SessionFirewall.AlwaysAllowOutbound,
)
c.sessions.setSessionFirewallWhitelist(nc.SessionFirewall.WhitelistEncryptionPublicKeys) c.sessions.setSessionFirewallWhitelist(nc.SessionFirewall.WhitelistEncryptionPublicKeys)
c.sessions.setSessionFirewallBlacklist(nc.SessionFirewall.BlacklistEncryptionPublicKeys) c.sessions.setSessionFirewallBlacklist(nc.SessionFirewall.BlacklistEncryptionPublicKeys)

View File

@ -184,6 +184,10 @@ func (s *searches) checkDHTRes(info *searchInfo, res *dhtRes) bool {
sinfo, isIn := s.core.sessions.getByTheirPerm(&res.Key) sinfo, isIn := s.core.sessions.getByTheirPerm(&res.Key)
if !isIn { if !isIn {
sinfo = s.core.sessions.createSession(&res.Key) sinfo = s.core.sessions.createSession(&res.Key)
if sinfo == nil {
// nil if the DHT search finished but the session wasn't allowed
return true
}
_, isIn := s.core.sessions.getByTheirPerm(&res.Key) _, isIn := s.core.sessions.getByTheirPerm(&res.Key)
if !isIn { if !isIn {
panic("This should never happen") panic("This should never happen")

View File

@ -109,11 +109,12 @@ type sessions struct {
addrToPerm map[address]*boxPubKey addrToPerm map[address]*boxPubKey
subnetToPerm map[subnet]*boxPubKey subnetToPerm map[subnet]*boxPubKey
// Options from the session firewall // Options from the session firewall
sessionFirewallEnabled bool sessionFirewallEnabled bool
sessionFirewallAllowsDirect bool sessionFirewallAllowsDirect bool
sessionFirewallAllowsRemote bool sessionFirewallAllowsRemote bool
sessionFirewallWhitelist []string sessionFirewallAlwaysAllowsOutbound bool
sessionFirewallBlacklist []string sessionFirewallWhitelist []string
sessionFirewallBlacklist []string
} }
// Initializes the session struct. // Initializes the session struct.
@ -135,9 +136,10 @@ func (ss *sessions) setSessionFirewallState(enabled bool) {
// Set the session firewall defaults (first parameter is whether to allow // Set the session firewall defaults (first parameter is whether to allow
// sessions from direct peers, second is whether to allow from remote nodes). // sessions from direct peers, second is whether to allow from remote nodes).
func (ss *sessions) setSessionFirewallDefaults(allowsDirect bool, allowsRemote bool) { func (ss *sessions) setSessionFirewallDefaults(allowsDirect bool, allowsRemote bool, alwaysAllowsOutbound bool) {
ss.sessionFirewallAllowsDirect = allowsDirect ss.sessionFirewallAllowsDirect = allowsDirect
ss.sessionFirewallAllowsRemote = allowsRemote ss.sessionFirewallAllowsRemote = allowsRemote
ss.sessionFirewallAlwaysAllowsOutbound = alwaysAllowsOutbound
} }
// Set the session firewall whitelist - nodes always allowed to open sessions. // Set the session firewall whitelist - nodes always allowed to open sessions.
@ -152,7 +154,7 @@ func (ss *sessions) setSessionFirewallBlacklist(blacklist []string) {
// 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 *boxPubKey) bool { func (ss *sessions) isSessionAllowed(pubkey *boxPubKey, initiator bool) bool {
// Allow by default if the session firewall is disabled // Allow by default if the session firewall is disabled
if !ss.sessionFirewallEnabled { if !ss.sessionFirewallEnabled {
return true return true
@ -179,6 +181,12 @@ func (ss *sessions) isSessionAllowed(pubkey *boxPubKey) bool {
} }
} }
} }
// Allow outbound sessions if appropriate
if ss.sessionFirewallAlwaysAllowsOutbound {
if initiator {
return true
}
}
// 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
for _, peer := range ss.core.peers.ports.Load().(map[switchPort]*peer) { for _, peer := range ss.core.peers.ports.Load().(map[switchPort]*peer) {
@ -252,6 +260,11 @@ func (ss *sessions) getByTheirSubnet(snet *subnet) (*sessionInfo, bool) {
// Creates a new session and lazily cleans up old/timedout existing sessions. // Creates a new session and lazily cleans up old/timedout existing sessions.
// This includse initializing session info to sane defaults (e.g. lowest supported MTU). // This includse initializing session info to sane defaults (e.g. lowest supported MTU).
func (ss *sessions) createSession(theirPermKey *boxPubKey) *sessionInfo { func (ss *sessions) createSession(theirPermKey *boxPubKey) *sessionInfo {
if ss.sessionFirewallEnabled {
if !ss.isSessionAllowed(theirPermKey, true) {
return nil
}
}
sinfo := sessionInfo{} sinfo := sessionInfo{}
sinfo.core = ss.core sinfo.core = ss.core
sinfo.theirPermPub = *theirPermKey sinfo.theirPermPub = *theirPermKey
@ -391,7 +404,7 @@ func (ss *sessions) handlePing(ping *sessionPing) {
sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub) sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub)
// Check the session firewall // Check the session firewall
if !isIn && ss.sessionFirewallEnabled { if !isIn && ss.sessionFirewallEnabled {
if !ss.isSessionAllowed(&ping.SendPermPub) { if !ss.isSessionAllowed(&ping.SendPermPub, false) {
return return
} }
} }