From d2fe9fe6cfa0ba32a234bfbafda0b28ff0ef098e Mon Sep 17 00:00:00 2001 From: "Joseph.Rawlings" Date: Thu, 4 Dec 2025 22:49:06 -0500 Subject: [PATCH] feat: refine matching logic in firewall to ensure source IP consistency and enhance flexibility in destination port checks --- .../Servers/Proxmox/Livewire/Firewall.php | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/extensions/Servers/Proxmox/Livewire/Firewall.php b/extensions/Servers/Proxmox/Livewire/Firewall.php index ea650dc62..35c424131 100644 --- a/extensions/Servers/Proxmox/Livewire/Firewall.php +++ b/extensions/Servers/Proxmox/Livewire/Firewall.php @@ -1677,11 +1677,21 @@ class Firewall extends Component $normalizedStateDestIP = strtolower(trim($stateDestIP)); $normalizedProtocol = strtoupper(trim($protocol)); - // Flexible matching logic - multiple levels of matching + // Matching logic - Source IP from log MUST always match + // The source IP can appear as either source or destination in the state (for return traffic) $ipMatch = false; $matchType = ''; - // Level 1: Exact bidirectional match (both IPs match in either direction) + // Check if the log's source IP appears in the state + $sourceInState = ($normalizedStateSourceIP === $normalizedSourceIP || $normalizedStateDestIP === $normalizedSourceIP); + + if (!$sourceInState) { + // Source IP not found in this state - skip it + continue; + } + + // Source IP matches, now check destination + // Level 1: Exact match - both IPs match (in either direction) if ($normalizedStateSourceIP === $normalizedSourceIP && $normalizedStateDestIP === $normalizedDestIP) { $ipMatch = true; $matchType = 'exact'; @@ -1690,22 +1700,16 @@ class Firewall extends Component $ipMatch = true; $matchType = 'exact-reversed'; } - // Level 2: Destination IP match (log dest matches either state IP) - catches related traffic - elseif ($normalizedStateSourceIP === $normalizedDestIP || $normalizedStateDestIP === $normalizedDestIP) { + // Level 2: Source IP matches, destination is flexible (shows all traffic from this source) + elseif ($sourceInState) { $ipMatch = true; - $matchType = 'dest-partial'; - } - // Level 3: Source IP match (log source matches either state IP) - catches related traffic - elseif ($normalizedStateSourceIP === $normalizedSourceIP || $normalizedStateDestIP === $normalizedSourceIP) { - $ipMatch = true; - $matchType = 'source-partial'; + $matchType = 'source-match'; } // Protocol match - be flexible $protocolMatch = (empty($protocol) || $protocol === '-' || $normalizedProtocol === $stateProtocol); // Port match - check if destination port from log matches any port in state - // Also allow match if no port specified or if it's a partial IP match $portMatch = false; if (empty($destPort) || $destPort === '-') { $portMatch = true; // No port specified, match all @@ -1714,8 +1718,8 @@ class Firewall extends Component if ($stateDestPort === $destPortNum || $stateSourcePort === $destPortNum) { $portMatch = true; } - // For partial matches, also accept if protocol matches even if port doesn't - if (!$portMatch && str_contains($matchType, 'partial') && $protocolMatch) { + // For source-match type, be more flexible on ports if protocol matches + if (!$portMatch && $matchType === 'source-match' && $protocolMatch) { $portMatch = true; } }