fix: correct POSTROUTING MASQUERADE to use destination CIDR and port
continuous-integration/drone/push Build is passing

Modify InsertPostroutingMasquerade and InsertPostroutingMasqueradeInContainer functions to use destCIDR, proto, and destPort instead of sourceCIDR, proto, and sourcePort. This ensures the masquerade rule correctly targets destination traffic for proper NAT configuration.
This commit is contained in:
gyurix
2026-06-16 08:51:25 +02:00
parent d1c8eaef3e
commit 903bc1a7da
+16 -16
View File
@@ -302,24 +302,24 @@ func (m *Manager) InsertPreroutingRuleOnInterface(iface, proto, sourcePort, targ
} }
// InsertPostroutingMasquerade inserts a MASQUERADE POSTROUTING rule on the host // InsertPostroutingMasquerade inserts a MASQUERADE POSTROUTING rule on the host
func (m *Manager) InsertPostroutingMasquerade(sourceCIDR, proto, sourcePort, comment string) error { func (m *Manager) InsertPostroutingMasquerade(destCIDR, proto, destPort, comment string) error {
logger.Info("IPTABLES: checking POSTROUTING MASQUERADE rule: src=%s proto=%s sport=%s comment=%q", logger.Info("IPTABLES: checking POSTROUTING MASQUERADE rule: dst=%s proto=%s dport=%s comment=%q",
sourceCIDR, proto, sourcePort, comment) destCIDR, proto, destPort, comment)
// Check if rule already exists (idempotent: don't re-apply) // Check if rule already exists (idempotent: don't re-apply)
existing := m.getLineNumbers("POSTROUTING", "nat", comment, "MASQUERADE", sourceCIDR) existing := m.getLineNumbers("POSTROUTING", "nat", comment, "MASQUERADE", destCIDR)
if len(existing) > 0 { if len(existing) > 0 {
logger.Debug("IPTABLES: POSTROUTING MASQUERADE rule already exists (lines=%v), skipping", existing) logger.Debug("IPTABLES: POSTROUTING MASQUERADE rule already exists (lines=%v), skipping", existing)
return nil return nil
} }
logger.Info("IPTABLES: inserting POSTROUTING MASQUERADE rule: src=%s proto=%s sport=%s comment=%q", logger.Info("IPTABLES: inserting POSTROUTING MASQUERADE rule: dst=%s proto=%s dport=%s comment=%q",
sourceCIDR, proto, sourcePort, comment) destCIDR, proto, destPort, comment)
args := []string{ args := []string{
"-w", "-t", "nat", "-I", "POSTROUTING", "-w", "-t", "nat", "-I", "POSTROUTING",
"-s", sourceCIDR, "-d", destCIDR,
"-p", proto, "-p", proto,
"--sport", sourcePort, "--dport", destPort,
"-m", "comment", "--comment", comment, "-m", "comment", "--comment", comment,
"-j", "MASQUERADE", "-j", "MASQUERADE",
} }
@@ -472,9 +472,9 @@ func (m *Manager) InsertPreroutingRuleInContainer(pid int, sourceIP, proto, sour
} }
// InsertPostroutingMasqueradeInContainer inserts a MASQUERADE POSTROUTING rule inside a container namespace // InsertPostroutingMasqueradeInContainer inserts a MASQUERADE POSTROUTING rule inside a container namespace
func (m *Manager) InsertPostroutingMasqueradeInContainer(pid int, sourceCIDR, proto, sourcePort, comment string) error { func (m *Manager) InsertPostroutingMasqueradeInContainer(pid int, destCIDR, proto, destPort, comment string) error {
logger.Info("IPTABLES: inserting POSTROUTING MASQUERADE rule in container PID %d: src=%s proto=%s sport=%s comment=%q", logger.Info("IPTABLES: inserting POSTROUTING MASQUERADE rule in container PID %d: dst=%s proto=%s dport=%s comment=%q",
pid, sourceCIDR, proto, sourcePort, comment) pid, destCIDR, proto, destPort, comment)
// First, try to list the chain inside the container to check state // First, try to list the chain inside the container to check state
output, err := m.checkContainerChainExists(pid, "nat", "POSTROUTING") output, err := m.checkContainerChainExists(pid, "nat", "POSTROUTING")
@@ -488,27 +488,27 @@ func (m *Manager) InsertPostroutingMasqueradeInContainer(pid int, sourceCIDR, pr
for _, line := range strings.Split(output, "\n") { for _, line := range strings.Split(output, "\n") {
if strings.Contains(line, "MASQUERADE") && if strings.Contains(line, "MASQUERADE") &&
strings.Contains(line, comment) && strings.Contains(line, comment) &&
strings.Contains(line, sourceCIDR) { strings.Contains(line, destCIDR) {
ruleExists = true ruleExists = true
break break
} }
} }
if ruleExists { if ruleExists {
logger.Info("IPTABLES: POSTROUTING MASQUERADE rule already exists in container PID %d (src=%s), skipping", pid, sourceCIDR) logger.Info("IPTABLES: POSTROUTING MASQUERADE rule already exists in container PID %d (dst=%s), skipping", pid, destCIDR)
return nil return nil
} }
// Rule doesn't exist — clean up stale/duplicate rules then insert // Rule doesn't exist — clean up stale/duplicate rules then insert
patterns := []string{"MASQUERADE", comment, sourceCIDR, sourcePort} patterns := []string{"MASQUERADE", comment, destCIDR, destPort}
if delErr := m.deleteMatchingLinesInContainer(pid, "nat", "POSTROUTING", patterns...); delErr != nil { if delErr := m.deleteMatchingLinesInContainer(pid, "nat", "POSTROUTING", patterns...); delErr != nil {
logger.Debug("IPTABLES: stale POSTROUTING cleanup in container PID %d: %v", pid, delErr) logger.Debug("IPTABLES: stale POSTROUTING cleanup in container PID %d: %v", pid, delErr)
} }
args := []string{ args := []string{
"-I", "POSTROUTING", "-I", "POSTROUTING",
"-s", sourceCIDR, "-d", destCIDR,
"-p", proto, "-p", proto,
"--sport", sourcePort, "--dport", destPort,
"-m", "comment", "--comment", comment, "-m", "comment", "--comment", comment,
"-j", "MASQUERADE", "-j", "MASQUERADE",
} }