mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 08:03:55 +08:00
fix(firewall): validate whitelist ports and sources in form (#13835)
This commit is contained in:
@@ -4318,7 +4318,6 @@ const message = {
|
||||
'Set one port allowed by the firewall. Manage the listening port in the service settings.',
|
||||
whitelistSourcesHelper:
|
||||
'Enter IP addresses or CIDR ranges, separated by commas or new lines. Leave blank to allow all IPv4 and IPv6 sources.',
|
||||
systemAccessSourceError: 'Enter at least one valid {0} address or CIDR range.',
|
||||
destinationPortPlaceholder: 'e.g. 80, 80,443, or 8080-8089',
|
||||
deleteRuleConfirm: 'Will delete {0} rules. Continue?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4371,7 +4371,6 @@ const message = {
|
||||
'Configure un único puerto permitido por el cortafuegos. El puerto de escucha se gestiona en la configuración del servicio.',
|
||||
whitelistSourcesHelper:
|
||||
'Introduzca direcciones IP o rangos CIDR separados por comas o saltos de línea. Déjelo en blanco para permitir todos los orígenes IPv4 e IPv6.',
|
||||
systemAccessSourceError: 'Introduzca al menos una dirección o red CIDR {0} válida.',
|
||||
destinationPortPlaceholder: 'p. ej. 80, 80,443 o 8080-8089',
|
||||
deleteRuleConfirm: 'Se eliminarán {0} reglas. ¿Continuar?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4275,7 +4275,6 @@ const message = {
|
||||
'یک درگاه مجاز برای دیواره آتش تنظیم کنید. درگاه شنود را در تنظیمات سرویس تغییر دهید.',
|
||||
whitelistSourcesHelper:
|
||||
'آدرسهای IP یا محدودههای CIDR را با ویرگول یا خط جدید جدا کنید. برای مجاز کردن همه مبدأهای IPv4 و IPv6، این قسمت را خالی بگذارید.',
|
||||
systemAccessSourceError: 'حداقل یک نشانی {0} یا بازه CIDR معتبر وارد کنید.',
|
||||
destinationPortPlaceholder: 'مثلاً: 80، 80,443 یا 8080-8089',
|
||||
deleteRuleConfirm: '{0} قانون حذف خواهند شد. ادامه میدهید؟',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4301,7 +4301,6 @@ const message = {
|
||||
'ファイアウォールで許可するポートを1つ設定します。待ち受けポートは各サービスの設定で変更してください。',
|
||||
whitelistSourcesHelper:
|
||||
'IP アドレスまたは CIDR をカンマか改行で区切って入力してください。 空欄の場合、すべての IPv4 および IPv6 の接続元を許可します。',
|
||||
systemAccessSourceError: '有効な {0} アドレスまたは CIDR を1つ以上入力してください。',
|
||||
destinationPortPlaceholder: '例: 80、80,443、8080-8089',
|
||||
deleteRuleConfirm: '{0} 個のルールを削除します。続行しますか?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4222,7 +4222,6 @@ const message = {
|
||||
'방화벽에서 허용할 포트 하나를 설정합니다. 수신 포트는 해당 서비스 설정에서 변경하세요.',
|
||||
whitelistSourcesHelper:
|
||||
'IP 주소 또는 CIDR 대역을 쉼표나 줄바꿈으로 구분하세요. 비워 두면 모든 IPv4 및 IPv6 출발지를 허용합니다.',
|
||||
systemAccessSourceError: '유효한 {0} 주소 또는 CIDR 대역을 하나 이상 입력하세요.',
|
||||
destinationPortPlaceholder: '예: 80, 80,443 또는 8080-8089',
|
||||
deleteRuleConfirm: '{0}개의 규칙을 삭제합니다. 계속하시겠습니까?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4185,7 +4185,6 @@ const message = {
|
||||
whitelistServicePortsHelper: 'ຕັ້ງຄ່າໜຶ່ງພອດທີ່ໄຟວໍອະນຸຍາດ. ປ່ຽນພອດຮັບຟັງໃນການຕັ້ງຄ່າບໍລິການ.',
|
||||
whitelistSourcesHelper:
|
||||
'ປ້ອນທີ່ຢູ່ IP ຫຼື CIDR ໂດຍແຍກດ້ວຍຈຸດຈ້ຳ ຫຼື ຂຶ້ນແຖວໃໝ່. ຖ້າປະໄວ້ຫວ່າງ ຈະອະນຸຍາດທຸກແຫຼ່ງທີ່ມາ IPv4 ແລະ IPv6.',
|
||||
systemAccessSourceError: 'ປ້ອນທີ່ຢູ່ {0} ຫຼື CIDR ທີ່ຖືກຕ້ອງຢ່າງໜ້ອຍໜຶ່ງລາຍການ.',
|
||||
destinationPortPlaceholder: 'ຕົວຢ່າງ: 80, 80,443 ຫຼື 8080-8089',
|
||||
deleteRuleConfirm: 'ຈະລຶບ {0} ກົດລະບຽບ. ຕ້ອງການຕໍ່ຫຼືບໍ່?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4385,7 +4385,6 @@ const message = {
|
||||
'Tetapkan satu port yang dibenarkan oleh tembok api. Urus port pendengar dalam tetapan perkhidmatan.',
|
||||
whitelistSourcesHelper:
|
||||
'Masukkan alamat IP atau julat CIDR, dipisahkan dengan koma atau baris baharu. Biarkan kosong untuk membenarkan semua sumber IPv4 dan IPv6.',
|
||||
systemAccessSourceError: 'Masukkan sekurang-kurangnya satu alamat {0} atau julat CIDR yang sah.',
|
||||
destinationPortPlaceholder: 'contoh: 80, 80,443 atau 8080-8089',
|
||||
deleteRuleConfirm: 'Akan memadam {0} peraturan. Teruskan?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4407,7 +4407,6 @@ const message = {
|
||||
'Defina uma única porta permitida pelo firewall. Gerencie a porta de escuta nas configurações do serviço.',
|
||||
whitelistSourcesHelper:
|
||||
'Insira endereços IP ou intervalos CIDR separados por vírgulas ou quebras de linha. Deixe em branco para permitir todas as origens IPv4 e IPv6.',
|
||||
systemAccessSourceError: 'Informe pelo menos um endereço {0} ou intervalo CIDR válido.',
|
||||
destinationPortPlaceholder: 'por exemplo: 80, 80,443 ou 8080-8089',
|
||||
deleteRuleConfirm: 'Excluirá {0} regras. Continuar?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4373,7 +4373,6 @@ const message = {
|
||||
'Укажите один порт, разрешённый брандмауэром. Порт прослушивания меняется в настройках службы.',
|
||||
whitelistSourcesHelper:
|
||||
'Введите IP-адреса или подсети CIDR через запятую или с новой строки. Оставьте поле пустым, чтобы разрешить все источники IPv4 и IPv6.',
|
||||
systemAccessSourceError: 'Укажите хотя бы один допустимый адрес {0} или диапазон CIDR.',
|
||||
destinationPortPlaceholder: 'например: 80, 80,443 или 8080-8089',
|
||||
deleteRuleConfirm: 'Удалит {0} правил. Продолжить?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4389,7 +4389,6 @@ const message = {
|
||||
'Güvenlik duvarının izin verdiği tek bir port ayarlayın. Dinleme portunu hizmet ayarlarından yönetin.',
|
||||
whitelistSourcesHelper:
|
||||
'IP adreslerini veya CIDR aralıklarını virgül ya da yeni satırla ayırın. Tüm IPv4 ve IPv6 kaynaklarına izin vermek için boş bırakın.',
|
||||
systemAccessSourceError: 'En az bir geçerli {0} adresi veya CIDR aralığı girin.',
|
||||
destinationPortPlaceholder: 'örn. 80, 80,443 veya 8080-8089',
|
||||
deleteRuleConfirm: '{0} kural silinecek. Devam etmek istiyor musunuz?',
|
||||
deleteUsedRuleConfirm:
|
||||
|
||||
@@ -4022,7 +4022,6 @@ const message = {
|
||||
systemAccessChangeConfirm: '對 {0} 白名單規則執行此操作後,可能無法透過該服務遠端存取。是否繼續?',
|
||||
whitelistServicePortsHelper: '設定一個防火牆放行連接埠,服務監聽連接埠請在對應服務設定中修改。',
|
||||
whitelistSourcesHelper: '支援 IP 或 CIDR,多個以逗號或換行分隔。留空預設允許所有 IPv4 和 IPv6 來源。',
|
||||
systemAccessSourceError: '請至少填寫一個有效的 {0} 位址或 CIDR 網段。',
|
||||
destinationPortPlaceholder: '例如:80、80,443 或 8080-8089',
|
||||
deleteRuleConfirm: '將刪除 {0} 條規則,是否繼續?',
|
||||
deleteUsedRuleConfirm: '該規則涵蓋由 {0} 提供的監聽服務。刪除後可能導致相關服務無法存取,是否繼續?',
|
||||
|
||||
@@ -4070,7 +4070,6 @@ const message = {
|
||||
systemAccessChangeConfirm: '对 {0} 白名单规则执行此操作后,可能无法通过该服务远程访问。是否继续?',
|
||||
whitelistServicePortsHelper: '设置一个防火墙放行端口,服务监听端口请在对应服务设置中修改。',
|
||||
whitelistSourcesHelper: '支持 IP 或 CIDR,多个以逗号或换行分隔。留空默认允许所有 IPv4 和 IPv6 来源。',
|
||||
systemAccessSourceError: '请至少填写一个有效的 {0} 地址或 CIDR 网段。',
|
||||
destinationPortPlaceholder: '例如:80、80,443 或 8080-8089',
|
||||
deleteRuleConfirm: '将删除 {0} 条规则,是否继续?',
|
||||
deleteUsedRuleConfirm: '该规则覆盖了由 {0} 提供的监听服务。删除后可能导致相关服务无法访问,是否继续?',
|
||||
|
||||
@@ -46,7 +46,14 @@
|
||||
:title="$t(editingRule ? 'commons.button.edit' : 'commons.button.create')"
|
||||
:show-close="!saving"
|
||||
>
|
||||
<el-form label-position="top" :disabled="saving" @submit.prevent="saveRule">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="top"
|
||||
:disabled="saving"
|
||||
@submit.prevent="saveRule"
|
||||
>
|
||||
<el-form-item :label="$t('commons.table.type')">
|
||||
<el-select v-model="form.type" :disabled="!!editingRule">
|
||||
<el-option value="custom" :label="$t('website.other')" />
|
||||
@@ -65,16 +72,16 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<template v-if="form.type === 'custom'">
|
||||
<el-form-item :label="$t('firewall.portOrRange')" required>
|
||||
<el-form-item :label="$t('firewall.portOrRange')" prop="port">
|
||||
<el-input v-model.trim="form.port" placeholder="80 / 8000-8100" clearable />
|
||||
<span class="input-help">{{ $t('firewall.portWhiteListHelper') }}</span>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item v-else-if="editingRule" :label="$t('commons.table.port')" required>
|
||||
<el-form-item v-else-if="editingRule" :label="$t('commons.table.port')" prop="port">
|
||||
<el-input v-model.trim="form.port" :placeholder="form.type === 'ssh' ? '2222' : '18443'" clearable />
|
||||
<span class="input-help">{{ $t('firewall.whitelistServicePortsHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('firewall.allowedSources')">
|
||||
<el-form-item :label="$t('firewall.allowedSources')" prop="sourceInput">
|
||||
<el-input
|
||||
v-model.trim="form.sourceInput"
|
||||
type="textarea"
|
||||
@@ -102,8 +109,13 @@ import {
|
||||
} from '@/api/modules/firewall';
|
||||
import i18n from '@/lang';
|
||||
import { MsgError } from '@/utils/message';
|
||||
import { formatHostAddressList, isValidIPOrCIDR, splitTagValues } from '@/views/host/firewall/utils/validation';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import {
|
||||
formatHostAddressList,
|
||||
isValidIPOrCIDR,
|
||||
isValidPortRange,
|
||||
splitTagValues,
|
||||
} from '@/views/host/firewall/utils/validation';
|
||||
import { ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
|
||||
import { normalizeWhiteListRule, WhiteListProtocol, WhiteListRule, WhiteListType, whiteListRuleKey } from './model';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -120,12 +132,45 @@ const busy = computed(() => props.loading || saving.value);
|
||||
const disabled = computed(() => busy.value || !props.rules);
|
||||
const data = computed(() => props.rules || []);
|
||||
const editingRule = ref<WhiteListRule>();
|
||||
const formRef = ref<FormInstance>();
|
||||
const form = ref({
|
||||
type: 'custom' as WhiteListType | 'custom',
|
||||
protocol: 'tcp' as WhiteListProtocol,
|
||||
port: '',
|
||||
sourceInput: '',
|
||||
});
|
||||
const rules: FormRules = {
|
||||
port: [
|
||||
{
|
||||
required: true,
|
||||
validator: (_rule, value: string, callback) => {
|
||||
if (!value) {
|
||||
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
|
||||
return;
|
||||
}
|
||||
if (!isValidPortRange(value) || (form.value.type !== 'custom' && !/^\d+$/.test(value))) {
|
||||
const message = form.value.type === 'custom' ? 'firewall.portFormatError' : 'commons.rule.port';
|
||||
callback(new Error(i18n.global.t(message)));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
sourceInput: [
|
||||
{
|
||||
validator: (_rule, value: string, callback) => {
|
||||
if (splitTagValues([value]).some((source) => !isValidIPOrCIDR(source))) {
|
||||
callback(new Error(i18n.global.t('commons.rule.ip')));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
};
|
||||
const serviceTypes: WhiteListType[] = ['ssh', 'panel'];
|
||||
const serviceLabel = (type: WhiteListType) => (type === 'panel' ? '1Panel' : 'SSH');
|
||||
const servicePortLabel = (type: WhiteListType) =>
|
||||
@@ -145,19 +190,18 @@ const openEditor = (rule?: WhiteListRule) => {
|
||||
port: rule?.port || '',
|
||||
sourceInput: formatHostAddressList(rule ? rule.sources || [] : ['0.0.0.0/0', '::/0']),
|
||||
};
|
||||
formRef.value?.clearValidate();
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const saveRule = async () => {
|
||||
if (disabled.value) return;
|
||||
if (disabled.value || !formRef.value) return;
|
||||
const valid = await formRef.value.validate().catch(() => false);
|
||||
if (!valid) return;
|
||||
const sources = splitTagValues([form.value.sourceInput]);
|
||||
if (!sources.length) {
|
||||
sources.push('0.0.0.0/0', '::/0');
|
||||
}
|
||||
if (sources.some((source) => !isValidIPOrCIDR(source))) {
|
||||
MsgError(i18n.global.t('firewall.systemAccessSourceError', ['IPv4 / IPv6']));
|
||||
return;
|
||||
}
|
||||
let rule: WhiteListRule;
|
||||
try {
|
||||
rule = normalizeWhiteListRule({
|
||||
|
||||
Reference in New Issue
Block a user