@@ -29,11 +29,6 @@ type Manager interface {
2929 ApplyFiltering (networkMap * mgmProto.NetworkMap , dnsRouteFeatureFlag bool )
3030}
3131
32- type protoMatch struct {
33- ips map [string ]int
34- policyID []byte
35- }
36-
3732// DefaultManager uses firewall manager to handle
3833type DefaultManager struct {
3934 firewall firewall.Manager
@@ -86,21 +81,14 @@ func (d *DefaultManager) ApplyFiltering(networkMap *mgmProto.NetworkMap, dnsRout
8681}
8782
8883func (d * DefaultManager ) applyPeerACLs (networkMap * mgmProto.NetworkMap ) {
89- rules , squashedProtocols := d . squashAcceptRules ( networkMap )
84+ rules := networkMap . FirewallRules
9085
9186 enableSSH := networkMap .PeerConfig != nil &&
9287 networkMap .PeerConfig .SshConfig != nil &&
9388 networkMap .PeerConfig .SshConfig .SshEnabled
94- if _ , ok := squashedProtocols [mgmProto .RuleProtocol_ALL ]; ok {
95- enableSSH = enableSSH && ! ok
96- }
97- if _ , ok := squashedProtocols [mgmProto .RuleProtocol_TCP ]; ok {
98- enableSSH = enableSSH && ! ok
99- }
10089
101- // if TCP protocol rules not squashed and SSH enabled
102- // we add default firewall rule which accepts connection to any peer
103- // in the network by SSH (TCP 22 port).
90+ // If SSH enabled, add default firewall rule which accepts connection to any peer
91+ // in the network by SSH (TCP port defined by ssh.DefaultSSHPort).
10492 if enableSSH {
10593 rules = append (rules , & mgmProto.FirewallRule {
10694 PeerIP : "0.0.0.0" ,
@@ -368,145 +356,6 @@ func (d *DefaultManager) getPeerRuleID(
368356 return id .RuleID (hex .EncodeToString (md5 .New ().Sum ([]byte (idStr ))))
369357}
370358
371- // squashAcceptRules does complex logic to convert many rules which allows connection by traffic type
372- // to all peers in the network map to one rule which just accepts that type of the traffic.
373- //
374- // NOTE: It will not squash two rules for same protocol if one covers all peers in the network,
375- // but other has port definitions or has drop policy.
376- func (d * DefaultManager ) squashAcceptRules (
377- networkMap * mgmProto.NetworkMap ,
378- ) ([]* mgmProto.FirewallRule , map [mgmProto.RuleProtocol ]struct {}) {
379- totalIPs := 0
380- for _ , p := range append (networkMap .RemotePeers , networkMap .OfflinePeers ... ) {
381- for range p .AllowedIps {
382- totalIPs ++
383- }
384- }
385-
386- in := map [mgmProto.RuleProtocol ]* protoMatch {}
387- out := map [mgmProto.RuleProtocol ]* protoMatch {}
388-
389- // trace which type of protocols was squashed
390- squashedRules := []* mgmProto.FirewallRule {}
391- squashedProtocols := map [mgmProto.RuleProtocol ]struct {}{}
392-
393- // this function we use to do calculation, can we squash the rules by protocol or not.
394- // We summ amount of Peers IP for given protocol we found in original rules list.
395- // But we zeroed the IP's for protocol if:
396- // 1. Any of the rule has DROP action type.
397- // 2. Any of rule contains Port.
398- //
399- // We zeroed this to notify squash function that this protocol can't be squashed.
400- addRuleToCalculationMap := func (i int , r * mgmProto.FirewallRule , protocols map [mgmProto.RuleProtocol ]* protoMatch ) {
401- hasPortRestrictions := r .Action == mgmProto .RuleAction_DROP ||
402- r .Port != "" || ! portInfoEmpty (r .PortInfo )
403-
404- if hasPortRestrictions {
405- // Don't squash rules with port restrictions
406- protocols [r .Protocol ] = & protoMatch {ips : map [string ]int {}}
407- return
408- }
409-
410- if _ , ok := protocols [r .Protocol ]; ! ok {
411- protocols [r .Protocol ] = & protoMatch {
412- ips : map [string ]int {},
413- // store the first encountered PolicyID for this protocol
414- policyID : r .PolicyID ,
415- }
416- }
417-
418- // special case, when we receive this all network IP address
419- // it means that rules for that protocol was already optimized on the
420- // management side
421- if r .PeerIP == "0.0.0.0" {
422- squashedRules = append (squashedRules , r )
423- squashedProtocols [r .Protocol ] = struct {}{}
424- return
425- }
426-
427- ipset := protocols [r .Protocol ].ips
428-
429- if _ , ok := ipset [r .PeerIP ]; ok {
430- return
431- }
432- ipset [r .PeerIP ] = i
433- }
434-
435- for i , r := range networkMap .FirewallRules {
436- // calculate squash for different directions
437- if r .Direction == mgmProto .RuleDirection_IN {
438- addRuleToCalculationMap (i , r , in )
439- } else {
440- addRuleToCalculationMap (i , r , out )
441- }
442- }
443-
444- // order of squashing by protocol is important
445- // only for their first element ALL, it must be done first
446- protocolOrders := []mgmProto.RuleProtocol {
447- mgmProto .RuleProtocol_ALL ,
448- mgmProto .RuleProtocol_ICMP ,
449- mgmProto .RuleProtocol_TCP ,
450- mgmProto .RuleProtocol_UDP ,
451- }
452-
453- squash := func (matches map [mgmProto.RuleProtocol ]* protoMatch , direction mgmProto.RuleDirection ) {
454- for _ , protocol := range protocolOrders {
455- match , ok := matches [protocol ]
456- if ! ok || len (match .ips ) != totalIPs || len (match .ips ) < 2 {
457- // don't squash if :
458- // 1. Rules not cover all peers in the network
459- // 2. Rules cover only one peer in the network.
460- continue
461- }
462-
463- // add special rule 0.0.0.0 which allows all IP's in our firewall implementations
464- squashedRules = append (squashedRules , & mgmProto.FirewallRule {
465- PeerIP : "0.0.0.0" ,
466- Direction : direction ,
467- Action : mgmProto .RuleAction_ACCEPT ,
468- Protocol : protocol ,
469- PolicyID : match .policyID ,
470- })
471- squashedProtocols [protocol ] = struct {}{}
472-
473- if protocol == mgmProto .RuleProtocol_ALL {
474- // if we have ALL traffic type squashed rule
475- // it allows all other type of traffic, so we can stop processing
476- break
477- }
478- }
479- }
480-
481- squash (in , mgmProto .RuleDirection_IN )
482- squash (out , mgmProto .RuleDirection_OUT )
483-
484- // if all protocol was squashed everything is allow and we can ignore all other rules
485- if _ , ok := squashedProtocols [mgmProto .RuleProtocol_ALL ]; ok {
486- return squashedRules , squashedProtocols
487- }
488-
489- if len (squashedRules ) == 0 {
490- return networkMap .FirewallRules , squashedProtocols
491- }
492-
493- var rules []* mgmProto.FirewallRule
494- // filter out rules which was squashed from final list
495- // if we also have other not squashed rules.
496- for i , r := range networkMap .FirewallRules {
497- if _ , ok := squashedProtocols [r .Protocol ]; ok {
498- if m , ok := in [r .Protocol ]; ok && m .ips [r .PeerIP ] == i {
499- continue
500- } else if m , ok := out [r .Protocol ]; ok && m .ips [r .PeerIP ] == i {
501- continue
502- }
503- }
504- rules = append (rules , r )
505- }
506-
507- return append (rules , squashedRules ... ), squashedProtocols
508- }
509-
510359// getRuleGroupingSelector takes all rule properties except IP address to build selector
511360func (d * DefaultManager ) getRuleGroupingSelector (rule * mgmProto.FirewallRule ) string {
512361 return fmt .Sprintf ("%v:%v:%v:%s:%v" , strconv .Itoa (int (rule .Direction )), rule .Action , rule .Protocol , rule .Port , rule .PortInfo )
0 commit comments