Skip to content

Commit

Permalink
Add OUTPUT firewall rule to handle local traffic
Browse files Browse the repository at this point in the history
A PREROUTING rule does not apply to traffic originating from the
same host, and as a result our redirect doesn't apply when the node
holding the API VIP attempts to contact it. This adds an OUTPUT rule
to handle that case. The only difference is that it goes to the
OUTPUT chain instead of PREROUTING, and a "-o lo" param needs to be
added to the rule spec.
  • Loading branch information
cybertron committed Jul 2, 2020
1 parent c5cfa4a commit 15f8f27
Showing 1 changed file with 46 additions and 7 deletions.
53 changes: 46 additions & 7 deletions pkg/monitor/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import (

const (
table = "nat"
chain = "PREROUTING"
)

func getHAProxyRuleSpec(apiVip string, apiPort, lbPort uint16) (ruleSpec []string, err error) {
func getHAProxyRuleSpec(apiVip string, apiPort, lbPort uint16, loopback bool) (ruleSpec []string, err error) {
apiPortStr := strconv.Itoa(int(apiPort))
lbPortStr := strconv.Itoa(int(lbPort))
ruleSpec = []string{"--dst", apiVip, "-p", "tcp", "--dport", apiPortStr, "-j", "REDIRECT", "--to-ports", lbPortStr, "-m", "comment", "--comment", "OCP_API_LB_REDIRECT"}
if loopback {
ruleSpec = append(ruleSpec, "-o", "lo")
}
return ruleSpec, err
}

Expand All @@ -35,15 +37,30 @@ func cleanHAProxyPreRoutingRule(apiVip string, apiPort, lbPort uint16) error {
return err
}

ruleSpec, err := getHAProxyRuleSpec(apiVip, apiPort, lbPort)
ruleSpec, err := getHAProxyRuleSpec(apiVip, apiPort, lbPort, false)
if err != nil {
return err
}

chain := "PREROUTING"
if exists, _ := ipt.Exists(table, chain, ruleSpec...); exists {
log.WithFields(logrus.Fields{
"spec": strings.Join(ruleSpec, " "),
}).Info("Removing existing nat PREROUTING rule")
err = ipt.Delete(table, chain, ruleSpec...)
if err != nil {
return err
}
}
ruleSpec, err = getHAProxyRuleSpec(apiVip, apiPort, lbPort, true)
if err != nil {
return err
}
chain = "OUTPUT"
if exists, _ := ipt.Exists(table, chain, ruleSpec...); exists {
log.WithFields(logrus.Fields{
"spec": strings.Join(ruleSpec, " "),
}).Info("Removing existing nat OUTPUT rule")
return ipt.Delete(table, chain, ruleSpec...)
}
return nil
Expand All @@ -55,16 +72,33 @@ func ensureHAProxyPreRoutingRule(apiVip string, apiPort, lbPort uint16) error {
return err
}

ruleSpec, err := getHAProxyRuleSpec(apiVip, apiPort, lbPort)
ruleSpec, err := getHAProxyRuleSpec(apiVip, apiPort, lbPort, false)
if err != nil {
return err
}
chain := "PREROUTING"
if exists, _ := ipt.Exists(table, chain, ruleSpec...); exists {
return nil
} else {
log.WithFields(logrus.Fields{
"spec": strings.Join(ruleSpec, " "),
}).Info("Inserting nat PREROUTING rule")
err = ipt.Insert(table, chain, 1, ruleSpec...)
if err != nil {
return err
}
}
ruleSpec, err = getHAProxyRuleSpec(apiVip, apiPort, lbPort, true)
if err != nil {
return err
}
chain = "OUTPUT"
if exists, _ := ipt.Exists(table, chain, ruleSpec...); exists {
return nil
} else {
log.WithFields(logrus.Fields{
"spec": strings.Join(ruleSpec, " "),
}).Info("Inserting nat OUTPUT rule")
return ipt.Insert(table, chain, 1, ruleSpec...)
}
}
Expand All @@ -75,11 +109,16 @@ func checkHAProxyPreRoutingRule(apiVip string, apiPort, lbPort uint16) (bool, er
return false, err
}

ruleSpec, err := getHAProxyRuleSpec(apiVip, apiPort, lbPort)
ruleSpec, err := getHAProxyRuleSpec(apiVip, apiPort, lbPort, false)
if err != nil {
return false, err
}
preroutingExists, _ := ipt.Exists(table, "PREROUTING", ruleSpec...)

exists, _ := ipt.Exists(table, chain, ruleSpec...)
return exists, nil
ruleSpec, err = getHAProxyRuleSpec(apiVip, apiPort, lbPort, true)
if err != nil {
return false, err
}
outputExists, _ := ipt.Exists(table, "OUTPUT", ruleSpec...)
return (preroutingExists && outputExists), nil
}

0 comments on commit 15f8f27

Please sign in to comment.