From 81a9338d343c89351c903b7da4c2d083e8e40dc8 Mon Sep 17 00:00:00 2001 From: endymx <345793738@qq.com> Date: Thu, 4 Dec 2025 16:40:22 +0800 Subject: [PATCH] feat(iptables): range forward --- .../utils/firewall/client/iptables/forward.go | 2 ++ frontend/src/lang/modules/en.ts | 1 + frontend/src/lang/modules/zh.ts | 1 + .../host/firewall/forward/operate/index.vue | 19 +++++++++++++++++-- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/agent/utils/firewall/client/iptables/forward.go b/agent/utils/firewall/client/iptables/forward.go index c13ac0a54..1b369d933 100644 --- a/agent/utils/firewall/client/iptables/forward.go +++ b/agent/utils/firewall/client/iptables/forward.go @@ -6,6 +6,8 @@ import ( ) func AddForward(protocol, srcPort, dest, destPort, iface string, save bool) error { + // iptabels destPort 范围端口规则为:%d-%d + destPort = strings.ReplaceAll(destPort, ":", "-") if dest != "" && dest != "127.0.0.1" && dest != "localhost" { iptablesArg := fmt.Sprintf("-A %s", Chain1PanelPreRouting) if iface != "" { diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 7f5f663e6..07726b519 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2915,6 +2915,7 @@ const message = { targetPort: 'Destination port', forwardHelper1: 'If you want to forward to the local port, the destination IP should be set to "127.0.0.1".', forwardHelper2: 'Leave the destination IP blank to forward to the local port.', + forwardPortHelper: 'Support port range, e.g. 80:90', forwardInboundInterface: 'Forward Inbound Network Interface', exportHelper: 'About to export {0} firewall rules. Continue?', importSuccess: 'Successfully imported {0} rules', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index eff185c14..dbb0dc583 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -2703,6 +2703,7 @@ const message = { targetPort: '目标端口', forwardHelper1: '如果是本机端口转发,目标IP为:127.0.0.1', forwardHelper2: '如果目标IP不填写,则默认为本机端口转发', + forwardPortHelper: '支持端口范围,如:80:90', forwardInboundInterface: '转发入站网卡', exportHelper: '即将导出 {0} 条防火墙规则,是否继续?', importSuccess: '成功导入 {0} 条规则', diff --git a/frontend/src/views/host/firewall/forward/operate/index.vue b/frontend/src/views/host/firewall/forward/operate/index.vue index 7514c6379..af8046b9c 100644 --- a/frontend/src/views/host/firewall/forward/operate/index.vue +++ b/frontend/src/views/host/firewall/forward/operate/index.vue @@ -14,6 +14,7 @@ + {{ $t('firewall.forwardPortHelper') }} @@ -24,6 +25,7 @@ + {{ $t('firewall.forwardPortHelper') }} @@ -103,8 +105,21 @@ function checkPortRule(rule: any, value: string, callback: any) { if (!value) { return callback(new Error(i18n.global.t('firewall.portFormatError'))); } - if (checkPort(value)) { - return callback(new Error(i18n.global.t('firewall.portFormatError'))); + if (value.indexOf(':') !== -1) { + const ports = value.split(':'); + if (ports.length !== 2) { + return callback(new Error(i18n.global.t('firewall.portFormatError'))); + } + if (checkPort(ports[0]) || checkPort(ports[1])) { + return callback(new Error(i18n.global.t('firewall.portFormatError'))); + } + if (Number(ports[0]) > Number(ports[1])) { + return callback(new Error(i18n.global.t('firewall.portFormatError'))); + } + } else { + if (checkPort(value)) { + return callback(new Error(i18n.global.t('firewall.portFormatError'))); + } } callback(); }