mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-01-06 15:14:29 +08:00
* 修复https防窜站关闭时修改默认站点报错的问题 * feat: Add inbound interface restriction option for ufw forward rules (#10345) --------- Co-authored-by: live <Anxys@outlook.com>
This commit is contained in:
parent
72a0e0200e
commit
d0bb9165bf
23 changed files with 109 additions and 40 deletions
|
|
@ -37,6 +37,7 @@ type ForwardRuleOperate struct {
|
|||
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
||||
Num string `json:"num"`
|
||||
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
|
||||
Interface string `json:"interface"`
|
||||
Port string `json:"port" validate:"required"`
|
||||
TargetIP string `json:"targetIP"`
|
||||
TargetPort string `json:"targetPort" validate:"required"`
|
||||
|
|
|
|||
|
|
@ -18,4 +18,5 @@ type Forward struct {
|
|||
Port string `gorm:"not null" json:"port"`
|
||||
TargetIP string `gorm:"not null" json:"targetIP"`
|
||||
TargetPort string `gorm:"not null" json:"targetPort"`
|
||||
Interface string `json:"interface"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,7 +329,8 @@ func (u *FirewallService) OperateForwardRule(req dto.ForwardRuleOperate) error {
|
|||
if reqRule.Port == rule.Port &&
|
||||
reqRule.TargetPort == rule.TargetPort &&
|
||||
reqRule.TargetIP == rule.TargetIP &&
|
||||
proto == rule.Protocol {
|
||||
proto == rule.Protocol &&
|
||||
reqRule.Interface == rule.Interface {
|
||||
shouldKeep = false
|
||||
break
|
||||
}
|
||||
|
|
@ -353,7 +354,8 @@ func (u *FirewallService) OperateForwardRule(req dto.ForwardRuleOperate) error {
|
|||
if reqRule.Port == rule.Port &&
|
||||
reqRule.TargetPort == rule.TargetPort &&
|
||||
reqRule.TargetIP == rule.TargetIP &&
|
||||
proto == rule.Protocol {
|
||||
proto == rule.Protocol &&
|
||||
reqRule.Interface == rule.Interface {
|
||||
return buserr.New("ErrRecordExist")
|
||||
}
|
||||
}
|
||||
|
|
@ -383,6 +385,7 @@ func (u *FirewallService) OperateForwardRule(req dto.ForwardRuleOperate) error {
|
|||
Port: r.Port,
|
||||
TargetIP: r.TargetIP,
|
||||
TargetPort: r.TargetPort,
|
||||
Interface: r.Interface,
|
||||
}, r.Operation); err != nil {
|
||||
if req.ForceDelete {
|
||||
global.LOG.Error(err)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import (
|
|||
)
|
||||
|
||||
var AddTable = &gormigrate.Migration{
|
||||
ID: "20250902-add-table",
|
||||
ID: "20250930-add-table",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.AutoMigrate(
|
||||
&model.AppDetail{},
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ type FireInfo struct {
|
|||
Num string `json:"num"`
|
||||
TargetIP string `json:"targetIP"`
|
||||
TargetPort string `json:"targetPort"`
|
||||
Interface string `json:"interface"`
|
||||
|
||||
UsedStatus string `json:"usedStatus"`
|
||||
Description string `json:"description"`
|
||||
|
|
@ -21,12 +22,15 @@ type Forward struct {
|
|||
Port string `json:"port"`
|
||||
TargetIP string `json:"targetIP"`
|
||||
TargetPort string `json:"targetPort"`
|
||||
Interface string `json:"interface"`
|
||||
}
|
||||
|
||||
type IptablesNatInfo struct {
|
||||
Num string `json:"num"`
|
||||
Target string `json:"target"`
|
||||
Protocol string `json:"protocol"`
|
||||
InIface string `json:"inIface"`
|
||||
OutIface string `json:"outIface"`
|
||||
Opt string `json:"opt"`
|
||||
Source string `json:"source"`
|
||||
Destination string `json:"destination"`
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const (
|
|||
const NatChain = "1PANEL"
|
||||
|
||||
var (
|
||||
natListRegex = regexp.MustCompile(`^(\d+)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)(?:\s+(.+?) .+?:(\d{1,5}(?::\d+)?).+?[ :](.+-.+|(?:.+:)?\d{1,5}(?:-\d{1,5})?))?$`)
|
||||
natListRegex = regexp.MustCompile(`^(\d+)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)(?:\s+(.+?) .+?:(\d{1,5}(?::\d+)?).+?[ :](.+-.+|(?:.+:)?\d{1,5}(?:-\d{1,5})?))?$`)
|
||||
)
|
||||
|
||||
type Iptables struct {
|
||||
|
|
@ -92,7 +92,7 @@ func (iptables *Iptables) NatList(chain ...string) ([]IptablesNatInfo, error) {
|
|||
if len(chain) == 0 {
|
||||
chain = append(chain, PreRoutingChain)
|
||||
}
|
||||
stdout, err := iptables.outf(NatTab, "-nL %s --line", chain[0])
|
||||
stdout, err := iptables.outf(NatTab, "-nvL %s --line-numbers", chain[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -104,18 +104,20 @@ func (iptables *Iptables) NatList(chain ...string) ([]IptablesNatInfo, error) {
|
|||
})
|
||||
if natListRegex.MatchString(line) {
|
||||
match := natListRegex.FindStringSubmatch(line)
|
||||
if !strings.Contains(match[9], ":") {
|
||||
match[9] = fmt.Sprintf(":%s", match[9])
|
||||
if !strings.Contains(match[13], ":") {
|
||||
match[13] = fmt.Sprintf(":%s", match[13])
|
||||
}
|
||||
forwardList = append(forwardList, IptablesNatInfo{
|
||||
Num: match[1],
|
||||
Target: match[2],
|
||||
Protocol: match[7],
|
||||
Opt: match[4],
|
||||
Source: match[5],
|
||||
Destination: match[6],
|
||||
SrcPort: match[8],
|
||||
DestPort: match[9],
|
||||
Target: match[4],
|
||||
Protocol: match[11],
|
||||
InIface: match[7],
|
||||
OutIface: match[8],
|
||||
Opt: match[6],
|
||||
Source: match[9],
|
||||
Destination: match[10],
|
||||
SrcPort: match[12],
|
||||
DestPort: match[13],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -123,16 +125,14 @@ func (iptables *Iptables) NatList(chain ...string) ([]IptablesNatInfo, error) {
|
|||
return forwardList, nil
|
||||
}
|
||||
|
||||
func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort string, save bool) error {
|
||||
func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort, iface string, save bool) error {
|
||||
if dest != "" && dest != "127.0.0.1" && dest != "localhost" {
|
||||
if err := iptables.runf(NatTab, fmt.Sprintf(
|
||||
"-A %s -p %s --dport %s -j DNAT --to-destination %s:%s",
|
||||
PreRoutingChain,
|
||||
protocol,
|
||||
srcPort,
|
||||
dest,
|
||||
destPort,
|
||||
)); err != nil {
|
||||
iptablesArg := fmt.Sprintf("-A %s", PreRoutingChain)
|
||||
if iface != "" {
|
||||
iptablesArg += fmt.Sprintf(" -i %s", iface)
|
||||
}
|
||||
iptablesArg += fmt.Sprintf(" -p %s --dport %s -j DNAT --to-destination %s:%s", protocol, srcPort, dest, destPort)
|
||||
if err := iptables.runf(NatTab, iptablesArg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -166,13 +166,12 @@ func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort string, save
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
if err := iptables.runf(NatTab, fmt.Sprintf(
|
||||
"-A %s -p %s --dport %s -j REDIRECT --to-port %s",
|
||||
PreRoutingChain,
|
||||
protocol,
|
||||
srcPort,
|
||||
destPort,
|
||||
)); err != nil {
|
||||
iptablesArg := fmt.Sprintf("-A %s", PreRoutingChain)
|
||||
if iface != "" {
|
||||
iptablesArg += fmt.Sprintf(" -i %s", iface)
|
||||
}
|
||||
iptablesArg += fmt.Sprintf(" -p %s --dport %s -j REDIRECT --to-port %s", protocol, srcPort, destPort)
|
||||
if err := iptables.runf(NatTab, iptablesArg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -183,12 +182,13 @@ func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort string, save
|
|||
Port: srcPort,
|
||||
TargetIP: dest,
|
||||
TargetPort: destPort,
|
||||
Interface: iface,
|
||||
}).Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iptables *Iptables) NatRemove(num string, protocol, srcPort, dest, destPort string) error {
|
||||
func (iptables *Iptables) NatRemove(num string, protocol, srcPort, dest, destPort, iface string) error {
|
||||
if err := iptables.runf(NatTab, "-D %s %s", PreRoutingChain, num); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -226,11 +226,13 @@ func (iptables *Iptables) NatRemove(num string, protocol, srcPort, dest, destPor
|
|||
}
|
||||
|
||||
global.DB.Where(
|
||||
"protocol = ? AND port = ? AND target_ip = ? AND target_port = ?",
|
||||
"protocol = ? AND port = ? AND target_ip = ? AND target_port = ? AND (interface = ? OR (interface IS NULL AND ? = ''))",
|
||||
protocol,
|
||||
srcPort,
|
||||
dest,
|
||||
destPort,
|
||||
iface,
|
||||
iface,
|
||||
).Delete(&model.Forward{})
|
||||
return nil
|
||||
}
|
||||
|
|
@ -249,7 +251,7 @@ func (iptables *Iptables) Reload() error {
|
|||
var rules []model.Forward
|
||||
global.DB.Find(&rules)
|
||||
for _, forward := range rules {
|
||||
if err := iptables.NatAdd(forward.Protocol, forward.Port, forward.TargetIP, forward.TargetPort, false); err != nil {
|
||||
if err := iptables.NatAdd(forward.Protocol, forward.Port, forward.TargetIP, forward.TargetPort, forward.Interface, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ func (f *Ufw) ListForward() ([]FireInfo, error) {
|
|||
list = append(list, FireInfo{
|
||||
Num: rule.Num,
|
||||
Protocol: rule.Protocol,
|
||||
Interface: rule.InIface,
|
||||
Port: rule.SrcPort,
|
||||
TargetIP: dest[0],
|
||||
TargetPort: dest[1],
|
||||
|
|
@ -241,9 +242,9 @@ func (f *Ufw) PortForward(info Forward, operation string) error {
|
|||
}
|
||||
|
||||
if operation == "add" {
|
||||
err = iptables.NatAdd(info.Protocol, info.Port, info.TargetIP, info.TargetPort, true)
|
||||
err = iptables.NatAdd(info.Protocol, info.Port, info.TargetIP, info.TargetPort, info.Interface, true)
|
||||
} else {
|
||||
err = iptables.NatRemove(info.Num, info.Protocol, info.Port, info.TargetIP, info.TargetPort)
|
||||
err = iptables.NatRemove(info.Num, info.Protocol, info.Port, info.TargetIP, info.TargetPort, info.Interface)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s port forward failed, err: %s", operation, err)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export namespace Dashboard {
|
|||
title: string;
|
||||
detail: string;
|
||||
recommend: number;
|
||||
isShow: boolean ;
|
||||
isShow: boolean;
|
||||
router: string;
|
||||
}
|
||||
export interface AppLauncher {
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ export namespace Host {
|
|||
port: string;
|
||||
targetIP: string;
|
||||
targetPort: string;
|
||||
interface: string;
|
||||
}
|
||||
export interface RuleIP {
|
||||
operation: string;
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ export namespace Setting {
|
|||
id: number;
|
||||
name: string;
|
||||
addr: string;
|
||||
description: string;
|
||||
description: string;
|
||||
systemVersion: string;
|
||||
securityEntrance: string;
|
||||
cpuUsedPercent: number;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export const operateFire = (operation: string, withDockerRestart: boolean) => {
|
|||
export const operatePortRule = (params: Host.RulePort) => {
|
||||
return http.post<Host.RulePort>(`/hosts/firewall/port`, params, TimeoutEnum.T_40S);
|
||||
};
|
||||
export const operateForwardRule = (params: { rules: Host.RuleForward[]; forceDelete: boolean }) => {
|
||||
export const operateForwardRule = (params: { rules: Host.RuleForward[]; forceDelete?: boolean }) => {
|
||||
return http.post<Host.RulePort>(`/hosts/firewall/forward`, params, TimeoutEnum.T_40S);
|
||||
};
|
||||
export const operateIPRule = (params: Host.RuleIP) => {
|
||||
|
|
|
|||
|
|
@ -2857,6 +2857,7 @@ const message = {
|
|||
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.',
|
||||
forwardHelper3: 'Only support IPv4 port forwarding.',
|
||||
forwardInboundInterface: 'Forward Inbound Network Interface',
|
||||
},
|
||||
runtime: {
|
||||
runtime: 'Runtime',
|
||||
|
|
|
|||
|
|
@ -2824,6 +2824,7 @@ const message = {
|
|||
forwardHelper1: 'Si quieres reenviar al puerto local, la IP de destino debe ser "127.0.0.1".',
|
||||
forwardHelper2: 'Deja en blanco la IP de destino para reenviar al puerto local.',
|
||||
forwardHelper3: 'Solo se admite redirección de puertos IPv4.',
|
||||
forwardInboundInterface: 'Interfaz de Red de Entrada para Reenvío',
|
||||
},
|
||||
runtime: {
|
||||
runtime: 'Runtime',
|
||||
|
|
|
|||
|
|
@ -2771,6 +2771,7 @@ const message = {
|
|||
forwardHelper1: 'ローカルポートに転送する場合は、宛先IPを「127.0.0.1」に設定する必要があります。',
|
||||
forwardHelper2: '宛先IPを空白のままにして、ローカルポートに転送します。',
|
||||
forwardHelper3: 'IPv4ポート転送のみをサポートします。',
|
||||
forwardInboundInterface: '転送入站ネットワークインターフェース',
|
||||
},
|
||||
runtime: {
|
||||
runtime: 'ランタイム',
|
||||
|
|
|
|||
|
|
@ -2722,6 +2722,7 @@ const message = {
|
|||
forwardHelper1: "로컬 포트로 전달하려면, 대상 IP 를 '127.0.0.1'로 설정해야 합니다.",
|
||||
forwardHelper2: '대상 IP 를 비워두면 로컬 포트로 전달됩니다.',
|
||||
forwardHelper3: 'IPv4 포트 전달만 지원됩니다.',
|
||||
forwardInboundInterface: '포워딩 인바운드 네트워크 인터페이스',
|
||||
},
|
||||
runtime: {
|
||||
runtime: '실행 환경',
|
||||
|
|
|
|||
|
|
@ -2833,6 +2833,7 @@ const message = {
|
|||
forwardHelper1: 'Jika anda ingin memajukan ke port tempatan, IP sasaran harus ditetapkan kepada "127.0.0.1".',
|
||||
forwardHelper2: 'Biarkan IP sasaran kosong untuk memajukan ke port tempatan.',
|
||||
forwardHelper3: 'Hanya menyokong pemajuan port IPv4.',
|
||||
forwardInboundInterface: 'Antara Muka Rangkaian Masukan Penerusan',
|
||||
},
|
||||
runtime: {
|
||||
runtime: 'Runtime',
|
||||
|
|
|
|||
|
|
@ -2838,6 +2838,7 @@ const message = {
|
|||
'Se você deseja redirecionar para a porta local, o IP de destino deve ser definido como "127.0.0.1".',
|
||||
forwardHelper2: 'Deixe o IP de destino em branco para redirecionar para a porta local.',
|
||||
forwardHelper3: 'Somente suporta redirecionamento de porta IPv4.',
|
||||
forwardInboundInterface: 'Interface de Rede de Entrada para Encaminhamento',
|
||||
},
|
||||
runtime: {
|
||||
runtime: 'Runtime',
|
||||
|
|
|
|||
|
|
@ -2834,6 +2834,7 @@ const message = {
|
|||
'Если вы хотите перенаправить на локальный порт, целевой IP должен быть установлен как "127.0.0.1".',
|
||||
forwardHelper2: 'Оставьте целевой IP пустым для перенаправления на локальный порт.',
|
||||
forwardHelper3: 'Поддерживается только переадресация портов IPv4.',
|
||||
forwardInboundInterface: '转发入站Сетевой интерфейс для пересылки входящего трафика网卡',
|
||||
},
|
||||
runtime: {
|
||||
runtime: 'Среда выполнения',
|
||||
|
|
|
|||
|
|
@ -2895,6 +2895,7 @@ const message = {
|
|||
forwardHelper1: 'Yerel porta yönlendirmek istiyorsanız, hedef IP "127.0.0.1" olarak ayarlanmalıdır.',
|
||||
forwardHelper2: 'Yerel porta yönlendirmek için hedef IP’yi boş bırakın.',
|
||||
forwardHelper3: 'Yalnızca IPv4 port yönlendirmesini destekler.',
|
||||
forwardInboundInterface: 'İletme Gelen Ağ Arayüzü',
|
||||
},
|
||||
runtime: {
|
||||
runtime: 'Çalışma Zamanı',
|
||||
|
|
|
|||
|
|
@ -2659,6 +2659,7 @@ const message = {
|
|||
forwardHelper1: '如果是本機埠轉發,目標 IP 為:127.0.0.1',
|
||||
forwardHelper2: '如果目標 IP 不填寫,預設為本機埠轉發',
|
||||
forwardHelper3: '目前僅支援 IPv4 的埠轉發',
|
||||
forwardInboundInterface: '轉發入站網路介面',
|
||||
},
|
||||
runtime: {
|
||||
runtime: '執行環境',
|
||||
|
|
|
|||
|
|
@ -2651,6 +2651,7 @@ const message = {
|
|||
forwardHelper1: '如果是本机端口转发,目标IP为:127.0.0.1',
|
||||
forwardHelper2: '如果目标IP不填写,则默认为本机端口转发',
|
||||
forwardHelper3: '当前仅支持 IPv4 的端口转发',
|
||||
forwardInboundInterface: '转发入站网卡',
|
||||
},
|
||||
runtime: {
|
||||
runtime: '运行环境',
|
||||
|
|
|
|||
|
|
@ -43,6 +43,19 @@
|
|||
<el-table-column :label="$t('firewall.sourcePort')" :min-width="70" prop="port" />
|
||||
<el-table-column :min-width="80" :label="$t('firewall.targetIP')" prop="targetIP" />
|
||||
<el-table-column :label="$t('firewall.targetPort')" :min-width="70" prop="targetPort" />
|
||||
<template v-if="fireName === 'ufw'">
|
||||
<el-table-column
|
||||
:label="$t('firewall.forwardInboundInterface')"
|
||||
:min-width="70"
|
||||
prop="interface"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.interface === '' ? $t('commons.table.all') : row.interface }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<fu-table-operations
|
||||
width="200px"
|
||||
:buttons="buttons"
|
||||
|
|
@ -125,7 +138,13 @@ const search = async () => {
|
|||
await searchFireRule(params)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
data.value = res.data.items || [];
|
||||
data.value =
|
||||
res.data.items?.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
interface: item.interface === '*' ? '' : item.interface,
|
||||
};
|
||||
}) || [];
|
||||
paginationConfig.total = res.data.total;
|
||||
})
|
||||
.catch(() => {
|
||||
|
|
@ -141,11 +160,13 @@ const onOpenDialog = async (
|
|||
port: '8080',
|
||||
targetIP: '',
|
||||
targetPort: '',
|
||||
interface: '',
|
||||
},
|
||||
) => {
|
||||
let params = {
|
||||
title,
|
||||
rowData: { ...rowData },
|
||||
fireName: fireName.value,
|
||||
};
|
||||
dialogRef.value!.acceptParams(params);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,6 +23,19 @@
|
|||
<el-form-item :label="$t('firewall.targetPort')" prop="targetPort">
|
||||
<el-input clearable v-model.trim="dialogData.rowData!.targetPort" />
|
||||
</el-form-item>
|
||||
|
||||
<template v-if="dialogData.fireName === 'ufw'">
|
||||
<el-form-item :label="$t('firewall.forwardInboundInterface')" prop="interface">
|
||||
<el-select class="w-full" v-model="dialogData.rowData!.interface">
|
||||
<el-option
|
||||
v-for="item in interfaceOptions"
|
||||
:key="item.value"
|
||||
:label="item.label === 'all' ? $t('commons.table.all') : item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
|
|
@ -42,15 +55,18 @@ import i18n from '@/lang';
|
|||
import { ElForm } from 'element-plus';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import { operateForwardRule } from '@/api/modules/host';
|
||||
import { operateForwardRule, getNetworkOptions } from '@/api/modules/host';
|
||||
import { checkCidr, checkCidrV6, checkIp, checkPort, deepCopy } from '@/utils/util';
|
||||
|
||||
const loading = ref();
|
||||
const oldRule = ref<Host.RuleForward>();
|
||||
|
||||
const interfaceOptions = ref<Array<{ label: string; value: string }>>([]);
|
||||
|
||||
interface DialogProps {
|
||||
title: string;
|
||||
rowData?: Host.RuleForward;
|
||||
fireName?: string;
|
||||
getTableList?: () => Promise<any>;
|
||||
}
|
||||
const title = ref<string>('');
|
||||
|
|
@ -63,6 +79,12 @@ const acceptParams = (params: DialogProps): void => {
|
|||
if (dialogData.value.title === 'edit') {
|
||||
oldRule.value = deepCopy(params.rowData);
|
||||
}
|
||||
if (dialogData.value.fireName === 'ufw') {
|
||||
getNetworkOptions().then((res) => {
|
||||
interfaceOptions.value = res.data.map((item) => ({ label: item, value: item }));
|
||||
dialogData.value.rowData!.interface = dialogData.value.rowData!.interface || 'all';
|
||||
});
|
||||
}
|
||||
title.value = i18n.global.t('firewall.' + dialogData.value.title);
|
||||
drawerVisible.value = true;
|
||||
};
|
||||
|
|
@ -127,6 +149,9 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
|||
if (rowData.targetIP === '') {
|
||||
rowData.targetIP = '127.0.0.1';
|
||||
}
|
||||
if (rowData.interface === 'all') {
|
||||
rowData.interface = '';
|
||||
}
|
||||
rules.push(rowData);
|
||||
loading.value = true;
|
||||
if (dialogData.value.title === 'create') {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue