fix(firewall): improve batch operations and task log completion

This commit is contained in:
ssongliu
2026-09-21 19:00:10 +08:00
parent 3a5371652e
commit 964f2ae407
18 changed files with 45 additions and 24 deletions
@@ -1060,7 +1060,7 @@ func (systemBackend) Run(ctx context.Context, command filter.NativeCommand) erro
}
timeout := 60 * time.Second
if options > 1 {
timeout = 5 * time.Minute
timeout = 15 * time.Minute
}
var stderr strings.Builder
err := cmd.NewCommandMgr(
+1 -1
View File
@@ -18,7 +18,7 @@ var (
var ErrVerificationFailed = errors.New("firewall rule verification failed")
func ProtectRuleSet(snapshot RuleSet, ports []PortWhitelist) (RuleSet, error) {
rules := append([]ObservedRule(nil), snapshot.Rules...)
rules := slices.Clone(snapshot.Rules)
whitelist := NewPortWhitelistIndex(ports)
for index := range rules {
if rules[index].ParseStatus == ParseStatusSupported && whitelist.Matches(rules[index].Rule) {
+9 -1
View File
@@ -267,6 +267,7 @@ const getContent = async (pre: boolean) => {
}
isLoading.value = true;
emit('update:isReading', true);
const requestedPage = readReq.page;
let res;
try {
@@ -290,7 +291,6 @@ const getContent = async (pre: boolean) => {
if (res.data.taskStatus && res.data.taskStatus !== 'Executing') {
isTailDisabled.value = true;
tailLog.value = false;
}
logPath.value = res.data.path;
@@ -396,6 +396,14 @@ const getContent = async (pre: boolean) => {
}
}
isLoading.value = false;
if (readReq.type === 'task' && res.data.taskStatus && res.data.taskStatus !== 'Executing') {
if (!pre && !res.data.end && res.data.scope !== 'tail' && requestedPage < res.data.total) {
readReq.page = requestedPage + 1;
await getContent(false);
} else {
onCloseLog();
}
}
};
const onCloseLog = async () => {
+1 -1
View File
@@ -4179,7 +4179,7 @@ const message = {
'The runtime and permanent firewall configurations differ. Synchronize them first.',
plan_protected_rule: 'This rule is protected and cannot be taken over, changed, or deleted.',
plan_blocked: 'This rule cannot be applied safely. Refresh the rules and try again.',
largeRuleSet: 'There are more than {0} firewall rules. We recommend using iptables or nftables.',
largeRuleSet: 'Too many firewall rules may slow down operations. We recommend using iptables or nftables.',
scopeDefaultMismatch: 'The system default zone is {0}; this page manages only the public zone.',
scopeMissing: 'Managed scope {0} is missing and will be created safely when the first rule is applied.',
scopeUnmanagedActive: 'Other active scopes were detected: {0}. 1Panel will not modify their rules.',
+2 -1
View File
@@ -4225,7 +4225,8 @@ const message = {
plan_runtime_permanent_mismatch: 'Las configuraciones activa y permanente difieren. Sincronízalas primero.',
plan_protected_rule: 'Esta regla está protegida y no se puede asumir, modificar ni eliminar.',
plan_blocked: 'La regla no puede aplicarse de forma segura. Actualiza la lista e inténtalo de nuevo.',
largeRuleSet: 'Hay más de {0} reglas de cortafuegos. Se recomienda usar iptables o nftables.',
largeRuleSet:
'Demasiadas reglas de cortafuegos pueden ralentizar las operaciones. Se recomienda usar iptables o nftables.',
scopeDefaultMismatch: 'La zona predeterminada es {0}; esta página solo gestiona la zona public.',
scopeMissing: 'Falta el ámbito gestionado {0}; se creará de forma segura al aplicar la primera regla.',
scopeUnmanagedActive: 'Se detectaron otros ámbitos activos: {0}. 1Panel no modificará sus reglas.',
+2 -1
View File
@@ -4134,7 +4134,8 @@ const message = {
plan_runtime_permanent_mismatch: 'پیکربندی فعال و دائمی دیوارهٔ آتش متفاوت است. ابتدا آن‌ها را همگام کنید.',
plan_protected_rule: 'این قانون محافظت‌شده است و نمی‌توان آن را مدیریت، تغییر یا حذف کرد.',
plan_blocked: 'این قانون با ایمنی قابل اعمال نیست. فهرست را تازه‌سازی و دوباره تلاش کنید.',
largeRuleSet: 'تعداد قوانین دیوارهٔ آتش بیش از {0} است. استفاده از iptables یا nftables توصیه می‌شود.',
largeRuleSet:
'تعداد زیاد قوانین دیوارهٔ آتش ممکن است عملیات را کند کند. استفاده از iptables یا nftables توصیه می‌شود.',
scopeDefaultMismatch: 'ناحیهٔ پیش‌فرض سامانه {0} است؛ این صفحه فقط ناحیهٔ public را مدیریت می‌کند.',
scopeMissing: 'محدودهٔ مدیریت‌شدهٔ {0} وجود ندارد و هنگام اعمال نخستین قانون به‌صورت امن ایجاد می‌شود.',
scopeUnmanagedActive: 'محدوده‌های فعال دیگری یافت شد: {0}. 1Panel قوانین آن‌ها را تغییر نمی‌دهد.',
+2 -1
View File
@@ -4160,7 +4160,8 @@ const message = {
plan_runtime_permanent_mismatch: '実行中と永続設定のファイアウォール構成が異なります先に同期してください',
plan_protected_rule: 'このルールは保護されており管理対象化変更削除はできません',
plan_blocked: 'このルールは安全に適用できませんルールを更新して再試行してください',
largeRuleSet: 'ファイアウォールルールが {0} 件を超えていますiptables または nftables の使用を推奨します',
largeRuleSet:
'ファイアウォールルールが多すぎると操作が遅くなる可能性がありますiptables または nftables の使用を推奨します',
scopeDefaultMismatch: 'システムの既定 zone {0} ですこのページでは public zone のみ管理します',
scopeMissing: '管理対象スコープ {0} がありません最初のルール適用時に安全に作成されます',
scopeUnmanagedActive: '他の有効な範囲が見つかりました{0}1Panel はそのルールを変更しません',
+1 -1
View File
@@ -4084,7 +4084,7 @@ const message = {
plan_runtime_permanent_mismatch: '실행 구성과 영구 방화벽 구성이 다릅니다. 먼저 동기화하세요.',
plan_protected_rule: ' 규칙은 보호되어 관리 전환, 변경 또는 삭제할 없습니다.',
plan_blocked: ' 규칙을 안전하게 적용할 없습니다. 목록을 새로 고친 다시 시도하세요.',
largeRuleSet: '방화벽 규칙이 {0}개를 초과했습니다. iptables 또는 nftables 사용을 권장합니다.',
largeRuleSet: '방화벽 규칙이 너무 많으면 작업이 느려질 습니다. iptables 또는 nftables 사용을 권장합니다.',
scopeDefaultMismatch: '시스템 기본 zone은 {0}이며 페이지는 public zone만 관리합니다.',
scopeMissing: '관리 범위 {0}() 없으며 규칙을 적용할 안전하게 생성됩니다.',
scopeUnmanagedActive: '다른 활성 범위가 감지되었습니다: {0}. 1Panel은 해당 규칙을 변경하지 않습니다.',
+1 -1
View File
@@ -4051,7 +4051,7 @@ const message = {
plan_runtime_permanent_mismatch: 'ຄ່າໄຟວໍທີ່ໃຊ້ງານແລະຄ່າຖາວອນບໍ່ກົງກັນ. ກະລຸນາຊິງກ່ອນ.',
plan_protected_rule: 'ກົດນີ້ຖືກປົກປ້ອງ ແລະບໍ່ສາມາດຮັບເຂົ້າ, ແກ້ໄຂ ຫຼືລຶບໄດ້.',
plan_blocked: 'ບໍ່ສາມາດນຳໃຊ້ກົດນີ້ໄດ້ຢ່າງປອດໄພ. ກະລຸນາໂຫຼດໃໝ່ແລ້ວລອງອີກຄັ້ງ.',
largeRuleSet: 'ມີກົດໄຟວໍຫຼາຍກວ່າ {0} ລາຍການ. ແນະນຳໃຫ້ໃຊ້ iptables ຫຼື nftables.',
largeRuleSet: 'ກົດໄຟວໍທີ່ຫຼາຍເກີນໄປອາດເຮັດໃຫ້ການດຳເນີນງານຊ້າລົງ. ແນະນຳໃຫ້ໃຊ້ iptables ຫຼື nftables.',
scopeDefaultMismatch: 'zone ຄ່າເລີ່ມຕົ້ນແມ່ນ {0}; ໜ້ານີ້ຈັດການສະເພາະ public zone.',
scopeMissing: 'ບໍ່ພົບຂອບເຂດຈັດການ {0}; ລະບົບຈະສ້າງຢ່າງປອດໄພເມື່ອນຳໃຊ້ກົດທຳອິດ.',
scopeUnmanagedActive: 'ພົບຂອບເຂດອື່ນທີ່ໃຊ້ງານ: {0}. 1Panel ຈະບໍ່ແກ້ໄຂກົດເຫຼົ່ານັ້ນ.',
+2 -1
View File
@@ -4246,7 +4246,8 @@ const message = {
plan_runtime_permanent_mismatch: 'Konfigurasi tembok api aktif dan kekal berbeza. Segerakkan dahulu.',
plan_protected_rule: 'Peraturan ini dilindungi dan tidak boleh diambil alih, diubah atau dipadam.',
plan_blocked: 'Peraturan ini tidak dapat digunakan dengan selamat. Muat semula senarai dan cuba lagi.',
largeRuleSet: 'Terdapat lebih daripada {0} peraturan tembok api. Penggunaan iptables atau nftables disyorkan.',
largeRuleSet:
'Terlalu banyak peraturan tembok api boleh melambatkan operasi. Penggunaan iptables atau nftables disyorkan.',
scopeDefaultMismatch: 'Zon lalai sistem ialah {0}; halaman ini hanya mengurus zon public.',
scopeMissing: 'Skop terurus {0} tiada dan akan dicipta dengan selamat apabila peraturan pertama digunakan.',
scopeUnmanagedActive: 'Skop aktif lain dikesan: {0}. 1Panel tidak akan mengubah peraturannya.',
+2 -1
View File
@@ -4263,7 +4263,8 @@ const message = {
plan_runtime_permanent_mismatch: 'As configurações ativa e permanente são diferentes. Sincronize-as primeiro.',
plan_protected_rule: 'Esta regra está protegida e não pode ser assumida, alterada ou excluída.',
plan_blocked: 'A regra não pode ser aplicada com segurança. Atualize a lista e tente novamente.',
largeRuleSet: ' mais de {0} regras de firewall. Recomendamos usar iptables ou nftables.',
largeRuleSet:
'Regras de firewall em excesso podem tornar as operações lentas. Recomendamos usar iptables ou nftables.',
scopeDefaultMismatch: 'A zona padrão do sistema é {0}; esta página gerencia apenas a zona public.',
scopeMissing: 'O escopo gerenciado {0} não existe e será criado com segurança ao aplicar a primeira regra.',
scopeUnmanagedActive: 'Outros escopos ativos foram detectados: {0}. O 1Panel não modificará suas regras.',
+2 -1
View File
@@ -4231,7 +4231,8 @@ const message = {
plan_runtime_permanent_mismatch: 'Активная и постоянная конфигурации различаются. Сначала синхронизируйте их.',
plan_protected_rule: 'Правило защищено: его нельзя взять под управление, изменить или удалить.',
plan_blocked: 'Правило нельзя безопасно применить. Обновите список и повторите попытку.',
largeRuleSet: 'Количество правил брандмауэра превышает {0}. Рекомендуется использовать iptables или nftables.',
largeRuleSet:
'Слишком большое количество правил брандмауэра может замедлить операции. Рекомендуется использовать iptables или nftables.',
scopeDefaultMismatch: 'Системная зона по умолчанию {0}; на этой странице управляется только зона public.',
scopeMissing: 'Управляемая область {0} отсутствует и будет безопасно создана при применении первого правила.',
scopeUnmanagedActive: 'Обнаружены другие активные области: {0}. 1Panel не будет изменять их правила.',
+2 -1
View File
@@ -4248,7 +4248,8 @@ const message = {
plan_runtime_permanent_mismatch: 'Etkin ve kalıcı güvenlik duvarı yapılandırmaları farklı. Önce eşitleyin.',
plan_protected_rule: 'Bu kural korumalıdır; yönetimi devralınamaz, değiştirilemez veya silinemez.',
plan_blocked: 'Bu kural güvenle uygulanamıyor. Listeyi yenileyip tekrar deneyin.',
largeRuleSet: 'Güvenlik duvarı kural sayısı {0} değerini aşıyor. iptables veya nftables kullanılması önerilir.',
largeRuleSet:
'Çok fazla güvenlik duvarı kuralı işlemleri yavaşlatabilir. iptables veya nftables kullanılması önerilir.',
scopeDefaultMismatch: 'Sistemin varsayılan zone değeri {0}; bu sayfa yalnızca public zone alanını yönetir.',
scopeMissing: 'Yönetilen {0} kapsamı eksik ve ilk kural uygulanırken güvenli şekilde oluşturulacak.',
scopeUnmanagedActive: 'Başka etkin kapsamlar algılandı: {0}. 1Panel bunların kurallarını değiştirmez.',
+1 -1
View File
@@ -3896,7 +3896,7 @@ const message = {
plan_runtime_permanent_mismatch: '防火牆執行設定與永久設定不一致請先完成同步',
plan_protected_rule: '此規則受到保護不能認領修改或刪除',
plan_blocked: '目前規則無法安全套用請重新整理規則後再試',
largeRuleSet: '目前防火牆規則超過 {0} 建議使用 iptables nftables',
largeRuleSet: '防火牆規則過多可能導致操作卡頓建議使用 iptables nftables',
scopeDefaultMismatch: '系統預設 zone {0}目前頁面僅管理 public zone',
scopeMissing: '託管範圍 {0} 尚未建立套用第一條規則時將以安全方式建立',
scopeUnmanagedActive: '偵測到其他使用中範圍{0}1Panel 不會修改其中的規則',
+1 -1
View File
@@ -3944,7 +3944,7 @@ const message = {
plan_runtime_permanent_mismatch: '当前生效的防火墙规则与重启后保留的规则不一致请先同步后重试',
plan_protected_rule: '该规则受到保护不能认领修改或删除',
plan_blocked: '暂时无法处理这条规则本次操作未生效请刷新后重试如仍失败请检查规则状态',
largeRuleSet: '当前防火墙规则超过 {0} 建议使用 iptables nftables',
largeRuleSet: '防火墙规则过多可能导致操作卡顿建议使用 iptables nftables',
scopeDefaultMismatch: '系统默认 zone {0}当前页面仅管理 public zone',
scopeMissing: '托管范围 {0} 尚未创建应用首条规则时将以安全方式创建',
scopeUnmanagedActive: '检测到其他活动范围{0}1Panel 不会修改其中的规则',
@@ -56,13 +56,13 @@
<template #default="{ row }">{{ displayAddress(row, row.sourceAddress) }}</template>
</el-table-column>
<el-table-column :label="$t('firewall.sourcePort')" min-width="110">
<template #default="{ row }">{{ row.sourcePort || $t('firewall.allPorts') }}</template>
<template #default="{ row }">{{ row.sourcePort || '*' }}</template>
</el-table-column>
<el-table-column :label="$t('firewall.destIP')" min-width="150">
<template #default="{ row }">{{ displayAddress(row, row.destinationAddress) }}</template>
</el-table-column>
<el-table-column :label="$t('firewall.destPort')" min-width="110">
<template #default="{ row }">{{ row.destinationPort || $t('firewall.allPorts') }}</template>
<template #default="{ row }">{{ row.destinationPort || '*' }}</template>
</el-table-column>
<el-table-column :label="$t('firewall.action')" prop="action" min-width="90">
<template #default="{ row }">{{ actionLabel(row.action) }}</template>
@@ -898,10 +898,10 @@ const changeRuleFilter = () => {
const notices = computed<DisplayNotice[]>(() => {
const unique = new Map<string, DisplayNotice>();
if (inventoryTotal.value > 200 && isServiceBackend.value) {
if (inventoryTotal.value > 1000 && isServiceBackend.value) {
unique.set('largeRuleSet', {
key: 'largeRuleSet',
text: i18n.global.t('firewall.largeRuleSet', [200]),
text: i18n.global.t('firewall.largeRuleSet'),
});
}
scopeNotices.value.forEach((notice) => {
@@ -108,7 +108,7 @@
</el-table-column>
<el-table-column :label="$t('commons.table.port')" min-width="120">
<template #default="{ row }">
{{ row.rule?.destinationPort || $t('firewall.allPorts') }}
{{ row.rule ? row.rule.destinationPort || '*' : '-' }}
</template>
</el-table-column>
<el-table-column :label="$t('firewall.action')" width="90">
@@ -347,10 +347,16 @@ const reasonText = (reasonCode?: string, reason?: string) => {
const actionText = (action?: Firewall.Action) => (action ? i18n.global.t(`firewall.${action}`) : '-');
const displayAddress = (rule: Firewall.Rule) => {
const values = [rule.sourceAddress, rule.destinationAddress]
.filter((value): value is string => Boolean(value))
.map((value) => formatHostAddress(value, rule.scope.family));
return values.length > 0 ? values.join(' → ') : i18n.global.t('firewall.anyWhere');
const wildcard =
rule.scope.family === 'ipv6' ? '::/0' : rule.scope.family === 'inet' ? '0.0.0.0/0, ::/0' : '0.0.0.0/0';
const addresses = rule.destinationAddress ? [rule.sourceAddress, rule.destinationAddress] : [rule.sourceAddress];
return addresses
.map((address) =>
address && address !== wildcard
? formatHostAddress(address, rule.scope.family)
: `${wildcard}${i18n.global.t('firewall.anyWhere')}`,
)
.join(' → ');
};
const dockerAddress = (rule?: Firewall.DockerGuardEndpoint) => {