ソースを参照

fix(firewall): adapt bridge and mac options and guard against output src_mac

Proxmox Router 3 日 前
親
コミット
582bc8dad1
2 ファイル変更、47 行追加、11 行削除
  1. 2 2
      internal/firewall/validation.go
  2. 45 9
      internal/web/static/app.js

+ 2 - 2
internal/firewall/validation.go

@@ -451,8 +451,8 @@ func validateChainPlacement(kind string, rule any) error {
 	if kind == "filter" && (chain == "prerouting" || chain == "postrouting") || kind == "nat" && chain == "forward" {
 		return fmt.Errorf("chain %s is not available in the %s table", chain, kind)
 	}
-	if (chain == "output" || chain == "postrouting") && (text(v, "in_interface") != "" || text(v, "in_interface_list") != "" || text(v, "in_bridge_port") != "") {
-		return fmt.Errorf("chain %s cannot match an incoming interface", chain)
+	if (chain == "output" || chain == "postrouting") && (text(v, "in_interface") != "" || text(v, "in_interface_list") != "" || text(v, "in_bridge_port") != "" || text(v, "src_mac_address") != "") {
+		return fmt.Errorf("chain %s cannot match an incoming interface or source MAC", chain)
 	}
 	if (chain == "input" || chain == "prerouting") && (text(v, "out_interface") != "" || text(v, "out_interface_list") != "" || text(v, "out_bridge_port") != "") {
 		return fmt.Errorf("chain %s cannot match an outgoing interface", chain)

+ 45 - 9
internal/web/static/app.js

@@ -4315,22 +4315,34 @@ function handleFilterChainChange() {
   const rowInList = document.getElementById('fw-row-inifacelist');
   const rowOut = document.getElementById('fw-row-outiface');
   const rowOutList = document.getElementById('fw-row-outifacelist');
+  const rowInBridge = document.getElementById('fw-row-inbridgeport');
+  const rowOutBridge = document.getElementById('fw-row-outbridgeport');
+  const rowSrcMac = document.getElementById('fw-row-srcmac');
 
   if (chain === 'input') {
     if (rowIn) rowIn.classList.remove('hidden');
     if (rowInList) rowInList.classList.remove('hidden');
     if (rowOut) rowOut.classList.add('hidden');
     if (rowOutList) rowOutList.classList.add('hidden');
+    if (rowInBridge) rowInBridge.classList.remove('hidden');
+    if (rowOutBridge) rowOutBridge.classList.add('hidden');
+    if (rowSrcMac) rowSrcMac.classList.remove('hidden');
   } else if (chain === 'output') {
     if (rowIn) rowIn.classList.add('hidden');
     if (rowInList) rowInList.classList.add('hidden');
     if (rowOut) rowOut.classList.remove('hidden');
     if (rowOutList) rowOutList.classList.remove('hidden');
+    if (rowInBridge) rowInBridge.classList.add('hidden');
+    if (rowOutBridge) rowOutBridge.classList.remove('hidden');
+    if (rowSrcMac) rowSrcMac.classList.add('hidden');
   } else {
     if (rowIn) rowIn.classList.remove('hidden');
     if (rowInList) rowInList.classList.remove('hidden');
     if (rowOut) rowOut.classList.remove('hidden');
     if (rowOutList) rowOutList.classList.remove('hidden');
+    if (rowInBridge) rowInBridge.classList.remove('hidden');
+    if (rowOutBridge) rowOutBridge.classList.remove('hidden');
+    if (rowSrcMac) rowSrcMac.classList.remove('hidden');
   }
 
   checkFilterActionChainCompatibility();
@@ -4710,9 +4722,9 @@ async function applyFilterRule(closeAfter = false) {
 
     // Advanced tab
     content: getFwFieldVal('content', false),
-    src_mac_address: getFwFieldVal('srcmac', true),
-    out_bridge_port: getFwFieldVal('outbridgeport', false),
-    in_bridge_port: getFwFieldVal('inbridgeport', false),
+    src_mac_address: chainLower === 'output' ? '' : getFwFieldVal('srcmac', true),
+    out_bridge_port: chainLower === 'input' ? '' : getFwFieldVal('outbridgeport', false),
+    in_bridge_port: chainLower === 'output' ? '' : getFwFieldVal('inbridgeport', false),
     ipsec_policy: getFwFieldVal('ipsec', false),
     dscp: getFwFieldVal('dscp', false),
     tcp_mss: getFwFieldVal('tcpmss', false),
@@ -5180,22 +5192,34 @@ function handleNATChainChange() {
   const rowInList = document.getElementById('nat-row-inifacelist');
   const rowOut = document.getElementById('nat-row-outiface');
   const rowOutList = document.getElementById('nat-row-outifacelist');
+  const rowInBridge = document.getElementById('nat-row-inbridgeport');
+  const rowOutBridge = document.getElementById('nat-row-outbridgeport');
+  const rowSrcMac = document.getElementById('nat-row-srcmac');
 
   if (chain === 'prerouting' || chain === 'input') {
     if (rowIn) rowIn.classList.remove('hidden');
     if (rowInList) rowInList.classList.remove('hidden');
     if (rowOut) rowOut.classList.add('hidden');
     if (rowOutList) rowOutList.classList.add('hidden');
+    if (rowInBridge) rowInBridge.classList.remove('hidden');
+    if (rowOutBridge) rowOutBridge.classList.add('hidden');
+    if (rowSrcMac) rowSrcMac.classList.remove('hidden');
   } else if (chain === 'postrouting' || chain === 'output') {
     if (rowIn) rowIn.classList.add('hidden');
     if (rowInList) rowInList.classList.add('hidden');
     if (rowOut) rowOut.classList.remove('hidden');
     if (rowOutList) rowOutList.classList.remove('hidden');
+    if (rowInBridge) rowInBridge.classList.add('hidden');
+    if (rowOutBridge) rowOutBridge.classList.remove('hidden');
+    if (rowSrcMac) rowSrcMac.classList.add('hidden');
   } else {
     if (rowIn) rowIn.classList.remove('hidden');
     if (rowInList) rowInList.classList.remove('hidden');
     if (rowOut) rowOut.classList.remove('hidden');
     if (rowOutList) rowOutList.classList.remove('hidden');
+    if (rowInBridge) rowInBridge.classList.remove('hidden');
+    if (rowOutBridge) rowOutBridge.classList.remove('hidden');
+    if (rowSrcMac) rowSrcMac.classList.remove('hidden');
   }
 
   checkNATActionChainCompatibility();
@@ -5565,9 +5589,9 @@ async function applyNATRule(closeAfter = false) {
 
     // Advanced tab
     content: getNATFieldVal('content', false),
-    src_mac_address: getNATFieldVal('srcmac', true),
-    out_bridge_port: getNATFieldVal('outbridgeport', false),
-    in_bridge_port: getNATFieldVal('inbridgeport', false),
+    src_mac_address: (chainLower === 'output' || chainLower === 'postrouting') ? '' : getNATFieldVal('srcmac', true),
+    out_bridge_port: (chainLower === 'input' || chainLower === 'prerouting') ? '' : getNATFieldVal('outbridgeport', false),
+    in_bridge_port: (chainLower === 'output' || chainLower === 'postrouting') ? '' : getNATFieldVal('inbridgeport', false),
     ipsec_policy: getNATFieldVal('ipsec', false),
     dscp: getNATFieldVal('dscp', false),
     tcp_mss: getNATFieldVal('tcpmss', false),
@@ -5972,22 +5996,34 @@ function handleMangleChainChange() {
   const rowInList = document.getElementById('mangle-row-inifacelist');
   const rowOut = document.getElementById('mangle-row-outiface');
   const rowOutList = document.getElementById('mangle-row-outifacelist');
+  const rowInBridge = document.getElementById('mangle-row-inbridgeport');
+  const rowOutBridge = document.getElementById('mangle-row-outbridgeport');
+  const rowSrcMac = document.getElementById('mangle-row-srcmac');
 
   if (chain === 'prerouting' || chain === 'input') {
     if (rowIn) rowIn.classList.remove('hidden');
     if (rowInList) rowInList.classList.remove('hidden');
     if (rowOut) rowOut.classList.add('hidden');
     if (rowOutList) rowOutList.classList.add('hidden');
+    if (rowInBridge) rowInBridge.classList.remove('hidden');
+    if (rowOutBridge) rowOutBridge.classList.add('hidden');
+    if (rowSrcMac) rowSrcMac.classList.remove('hidden');
   } else if (chain === 'output' || chain === 'postrouting') {
     if (rowIn) rowIn.classList.add('hidden');
     if (rowInList) rowInList.classList.add('hidden');
     if (rowOut) rowOut.classList.remove('hidden');
     if (rowOutList) rowOutList.classList.remove('hidden');
+    if (rowInBridge) rowInBridge.classList.add('hidden');
+    if (rowOutBridge) rowOutBridge.classList.remove('hidden');
+    if (rowSrcMac) rowSrcMac.classList.add('hidden');
   } else {
     if (rowIn) rowIn.classList.remove('hidden');
     if (rowInList) rowInList.classList.remove('hidden');
     if (rowOut) rowOut.classList.remove('hidden');
     if (rowOutList) rowOutList.classList.remove('hidden');
+    if (rowInBridge) rowInBridge.classList.remove('hidden');
+    if (rowOutBridge) rowOutBridge.classList.remove('hidden');
+    if (rowSrcMac) rowSrcMac.classList.remove('hidden');
   }
 
   checkMangleActionChainCompatibility();
@@ -6414,9 +6450,9 @@ async function applyMangleRule(closeAfter = false) {
 
     // Advanced tab
     content: getMangleFieldVal('content', false),
-    src_mac_address: getMangleFieldVal('srcmac', true),
-    out_bridge_port: getMangleFieldVal('outbridgeport', false),
-    in_bridge_port: getMangleFieldVal('inbridgeport', false),
+    src_mac_address: (chainLower === 'output' || chainLower === 'postrouting') ? '' : getMangleFieldVal('srcmac', true),
+    out_bridge_port: (chainLower === 'input' || chainLower === 'prerouting') ? '' : getMangleFieldVal('outbridgeport', false),
+    in_bridge_port: (chainLower === 'output' || chainLower === 'postrouting') ? '' : getMangleFieldVal('inbridgeport', false),
     ipsec_policy: getMangleFieldVal('ipsec', false),
     dscp: getMangleFieldVal('dscp', false),
     tcp_mss: getMangleFieldVal('tcpmss', false),