@@ -479,14 +479,19 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
479479 }
480480
481481 chainExists := iptables .ExistChain (ingressChain , iptables .Nat )
482+ filterChainExists := iptables .ExistChain (ingressChain , iptables .Filter )
482483
483484 ingressOnce .Do (func () {
485+ // Flush nat table and filter table ingress chain rules during init if it
486+ // exists. It might contain stale rules from previous life.
484487 if chainExists {
485- // Flush ingress chain rules during init if it
486- // exists. It might contain stale rules from
487- // previous life.
488488 if err := iptables .RawCombinedOutput ("-t" , "nat" , "-F" , ingressChain ); err != nil {
489- logrus .Errorf ("Could not flush ingress chain rules during init: %v" , err )
489+ logrus .Errorf ("Could not flush nat table ingress chain rules during init: %v" , err )
490+ }
491+ }
492+ if filterChainExists {
493+ if err := iptables .RawCombinedOutput ("-F" , ingressChain ); err != nil {
494+ logrus .Errorf ("Could not flush filter table ingress chain rules during init: %v" , err )
490495 }
491496 }
492497 })
@@ -497,10 +502,21 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
497502 return fmt .Errorf ("failed to create ingress chain: %v" , err )
498503 }
499504 }
505+ if ! filterChainExists {
506+ if err := iptables .RawCombinedOutput ("-N" , ingressChain ); err != nil {
507+ return fmt .Errorf ("failed to create filter table ingress chain: %v" , err )
508+ }
509+ }
500510
501511 if ! iptables .Exists (iptables .Nat , ingressChain , "-j" , "RETURN" ) {
502512 if err := iptables .RawCombinedOutput ("-t" , "nat" , "-A" , ingressChain , "-j" , "RETURN" ); err != nil {
503- return fmt .Errorf ("failed to add return rule in ingress chain: %v" , err )
513+ return fmt .Errorf ("failed to add return rule in nat table ingress chain: %v" , err )
514+ }
515+ }
516+
517+ if ! iptables .Exists (iptables .Filter , ingressChain , "-j" , "RETURN" ) {
518+ if err := iptables .RawCombinedOutput ("-A" , ingressChain , "-j" , "RETURN" ); err != nil {
519+ return fmt .Errorf ("failed to add return rule to filter table ingress chain: %v" , err )
504520 }
505521 }
506522
@@ -512,6 +528,12 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
512528 }
513529 }
514530
531+ if ! iptables .Exists (iptables .Filter , "FORWARD" , "-j" , ingressChain ) {
532+ if err := iptables .RawCombinedOutput ("-I" , "FORWARD" , "-j" , ingressChain ); err != nil {
533+ return fmt .Errorf ("failed to add jump rule to %s in filter table forward chain: %v" , ingressChain , err )
534+ }
535+ }
536+
515537 oifName , err := findOIFName (gwIP )
516538 if err != nil {
517539 return fmt .Errorf ("failed to find gateway bridge interface name for %s: %v" , gwIP , err )
@@ -544,6 +566,30 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
544566 }
545567 }
546568
569+ // Filter table rules to allow a published service to be accessible in the local node from..
570+ // 1) service tasks attached to other networks
571+ // 2) unmanaged containers on bridge networks
572+ rule := strings .Fields (fmt .Sprintf ("%s %s -m state -p %s --sport %d --state ESTABLISHED,RELATED -j ACCEPT" ,
573+ addDelOpt , ingressChain , strings .ToLower (PortConfig_Protocol_name [int32 (iPort .Protocol )]), iPort .PublishedPort ))
574+ if err := iptables .RawCombinedOutput (rule ... ); err != nil {
575+ errStr := fmt .Sprintf ("setting up rule failed, %v: %v" , rule , err )
576+ if ! isDelete {
577+ return fmt .Errorf ("%s" , errStr )
578+ }
579+ logrus .Warnf ("%s" , errStr )
580+ }
581+
582+ rule = strings .Fields (fmt .Sprintf ("%s %s -p %s --dport %d -j ACCEPT" ,
583+ addDelOpt , ingressChain , strings .ToLower (PortConfig_Protocol_name [int32 (iPort .Protocol )]), iPort .PublishedPort ))
584+ if err := iptables .RawCombinedOutput (rule ... ); err != nil {
585+ errStr := fmt .Sprintf ("setting up rule failed, %v: %v" , rule , err )
586+ if ! isDelete {
587+ return fmt .Errorf ("%s" , errStr )
588+ }
589+
590+ logrus .Warnf ("%s" , errStr )
591+ }
592+
547593 if err := plumbProxy (iPort , isDelete ); err != nil {
548594 logrus .Warnf ("failed to create proxy for port %d: %v" , iPort .PublishedPort , err )
549595 }
@@ -552,6 +598,22 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
552598 return nil
553599}
554600
601+ // In the filter table FORWARD chain first rule should be to jump to INGRESS-CHAIN
602+ // This chain has the rules to allow access to the published ports for swarm tasks
603+ // from local bridge networks and docker_gwbridge (ie:taks on other swarm netwroks)
604+ func arrangeIngressFilterRule () {
605+ if iptables .ExistChain (ingressChain , iptables .Filter ) {
606+ if iptables .Exists (iptables .Filter , "FORWARD" , "-j" , ingressChain ) {
607+ if err := iptables .RawCombinedOutput ("-D" , "FORWARD" , "-j" , ingressChain ); err != nil {
608+ logrus .Warnf ("failed to delete jump rule to ingressChain in filter table: %v" , err )
609+ }
610+ }
611+ if err := iptables .RawCombinedOutput ("-I" , "FORWARD" , "-j" , ingressChain ); err != nil {
612+ logrus .Warnf ("failed to add jump rule to ingressChain in filter table: %v" , err )
613+ }
614+ }
615+ }
616+
555617func findOIFName (ip net.IP ) (string , error ) {
556618 nlh := ns .NlHandle ()
557619
0 commit comments