diff --git a/network-go/iptables/iptables.go b/network-go/iptables/iptables.go index 5289b50..ea52680 100644 --- a/network-go/iptables/iptables.go +++ b/network-go/iptables/iptables.go @@ -279,6 +279,13 @@ func (m *Manager) InsertPreroutingRule(sourceIP, proto, sourcePort, targetIP, ta logger.Info("IPTABLES: checking PREROUTING DNAT rule: src=%s proto=%s sport=%s -> dst=%s dport=%s comment=%q", sourceIP, proto, sourcePort, targetIP, targetPort, comment) + // Validate source and destination networks are defined + if sourceIP == "" || targetIP == "" { + logger.Warn("IPTABLES: PREROUTING DNAT rule skipped — source=%q or destination=%q network not defined (comment=%q)", + sourceIP, targetIP, comment) + return nil + } + // Idempotent: check if rule already exists existing := m.getLineNumbers("PREROUTING", "nat", comment, "DNAT", targetIP, targetPort) if len(existing) > 0 { @@ -304,6 +311,12 @@ func (m *Manager) InsertPreroutingRuleOnInterface(iface, proto, sourcePort, targ logger.Info("IPTABLES: checking PREROUTING DNAT rule on interface %s: proto=%s dport=%s -> %s:%s comment=%q", iface, proto, sourcePort, targetIP, targetPort, comment) + // Validate destination network is defined + if targetIP == "" { + logger.Warn("IPTABLES: PREROUTING DNAT rule on %s skipped — destination network not defined (comment=%q)", iface, comment) + return nil + } + // Check if rule already exists (idempotent: don't re-apply) // Must include port in check to distinguish port 80 from port 443 rules with same comment existing := m.getLineNumbers("PREROUTING", "nat", comment, "DNAT", targetIP, targetPort) @@ -330,6 +343,12 @@ func (m *Manager) InsertPostroutingMasquerade(destCIDR, proto, destPort, comment logger.Info("IPTABLES: checking POSTROUTING MASQUERADE rule: dst=%s proto=%s dport=%s comment=%q", destCIDR, proto, destPort, comment) + // Validate destination network is defined + if destCIDR == "" { + logger.Warn("IPTABLES: POSTROUTING MASQUERADE rule skipped — destination network not defined (comment=%q)", comment) + return nil + } + // Check if rule already exists (idempotent: don't re-apply) // Must include port in check to distinguish port 80 from port 443 rules with same comment existing := m.getLineNumbers("POSTROUTING", "nat", comment, "MASQUERADE", destCIDR, destPort) @@ -356,6 +375,12 @@ func (m *Manager) InsertPostroutingMasqueradeForTarget(targetCIDR, proto, target logger.Info("IPTABLES: checking POSTROUTING MASQUERADE rule for target: dst=%s proto=%s dport=%s comment=%q", targetCIDR, proto, targetPort, comment) + // Validate destination network is defined + if targetCIDR == "" { + logger.Warn("IPTABLES: POSTROUTING MASQUERADE for target skipped — destination network not defined (comment=%q)", comment) + return nil + } + // Idempotent: check if rule already exists // Must include port in check to distinguish port 80 from port 443 rules with same comment existing := m.getLineNumbers("POSTROUTING", "nat", comment, "MASQUERADE", targetCIDR, targetPort) @@ -382,6 +407,13 @@ func (m *Manager) InsertForwardAccept(chain, sourceIP, targetIP, proto, sourcePo logger.Info("IPTABLES: checking FORWARD ACCEPT rule: chain=%s src=%s dst=%s proto=%s sport=%s dport=%s comment=%q", chain, sourceIP, targetIP, proto, sourcePort, targetPort, comment) + // Validate source and destination networks are defined + if sourceIP == "" || targetIP == "" { + logger.Warn("IPTABLES: FORWARD ACCEPT rule skipped in %s — source=%q or destination=%q network not defined (comment=%q)", + chain, sourceIP, targetIP, comment) + return nil + } + // Idempotent: check if rule already exists var grepPatterns []string grepPatterns = append(grepPatterns, comment, proto)