From deddd392bae747a602a9ea64a895bc8218ae2c29 Mon Sep 17 00:00:00 2001 From: ssongliu Date: Tue, 1 Sep 2026 09:33:29 +0800 Subject: [PATCH] fix(firewall): handle Docker host input ports (#13675) --- agent/app/dto/firewall.go | 1 + agent/app/service/firewall_docker.go | 300 +++++++++++++++++- frontend/src/api/interface/firewall.ts | 1 + frontend/src/lang/modules/en.ts | 23 +- frontend/src/lang/modules/es-es.ts | 53 ++-- frontend/src/lang/modules/fa.ts | 54 ++-- frontend/src/lang/modules/ja.ts | 51 ++- frontend/src/lang/modules/ko.ts | 54 ++-- frontend/src/lang/modules/lo.ts | 48 ++- frontend/src/lang/modules/ms.ts | 51 ++- frontend/src/lang/modules/pt-br.ts | 54 ++-- frontend/src/lang/modules/ru.ts | 51 ++- frontend/src/lang/modules/tr.ts | 53 ++-- frontend/src/lang/modules/zh-Hant.ts | 44 ++- frontend/src/lang/modules/zh.ts | 61 ++-- .../host/firewall/docker/detail/index.vue | 28 +- .../src/views/host/firewall/docker/index.vue | 40 ++- .../src/views/host/firewall/docker/model.ts | 2 + .../src/views/host/firewall/rule/index.vue | 9 +- 19 files changed, 609 insertions(+), 369 deletions(-) diff --git a/agent/app/dto/firewall.go b/agent/app/dto/firewall.go index 747d7f87a..98b35611b 100644 --- a/agent/app/dto/firewall.go +++ b/agent/app/dto/firewall.go @@ -173,6 +173,7 @@ type DockerPortGuardEndpoint struct { Sources []string `json:"sources"` Effective bool `json:"effective"` Description string `json:"description,omitempty"` + TrafficPath string `json:"trafficPath"` } type DockerPortGuardPortGroup struct { diff --git a/agent/app/service/firewall_docker.go b/agent/app/service/firewall_docker.go index 0bdf1dc90..2aa6b3b93 100644 --- a/agent/app/service/firewall_docker.go +++ b/agent/app/service/firewall_docker.go @@ -6,9 +6,12 @@ import ( "errors" "fmt" "net/netip" + "path/filepath" "sort" + "strconv" "strings" "sync" + "time" "github.com/1Panel-dev/1Panel/agent/app/dto" "github.com/1Panel-dev/1Panel/agent/app/model" @@ -17,6 +20,7 @@ import ( "github.com/1Panel-dev/1Panel/agent/constant" "github.com/1Panel-dev/1Panel/agent/global" agenti18n "github.com/1Panel-dev/1Panel/agent/i18n" + "github.com/1Panel-dev/1Panel/agent/utils/cmd" "github.com/1Panel-dev/1Panel/agent/utils/docker" "github.com/1Panel-dev/1Panel/agent/utils/firewall/docker_guard" "github.com/1Panel-dev/1Panel/agent/utils/firewall/filter" @@ -31,8 +35,22 @@ import ( const ( dockerGuardComposeProjectLabel = "com.docker.compose.project" dockerGuardComposeCreatedBy = "createdBy" + dockerTrafficPathForward = "forward" + dockerTrafficPathInput = "input" + dockerTrafficPathUnknown = "unknown" ) +type dockerProxyEndpoint struct { + protocol string + hostIP string + hostPort uint16 +} + +type dockerForwardRules struct { + output string + inspected bool +} + type dockerGuardRuntime = docker_guard.Runtime type DockerPortGuardService struct { @@ -99,6 +117,11 @@ func (s *DockerPortGuardService) LoadPublishedPorts(ctx context.Context) ([]dto. if err != nil { return nil, err } + backend := selectedDockerFirewallBackend("") + if info, infoErr := cli.Info(ctx); infoErr == nil { + backend = dockerFirewallBackend(info) + } + annotateDockerEndpointTrafficPaths(endpoints, backend) return groupDockerGuardContainers(endpoints), nil } @@ -121,7 +144,8 @@ func (s *DockerPortGuardService) LoadOverview(ctx context.Context) (dto.DockerPo base.Message = agenti18n.Get("ErrDockerFailed") return dto.DockerPortGuardList{Base: base, Containers: []dto.DockerPortGuardContainer{}, OrphanPolicies: dockerGuardPolicyEndpoints(policies)}, nil } - base.Backend = selectedDockerFirewallBackend(dockerFirewallBackend(info)) + detectedBackend := dockerFirewallBackend(info) + base.Backend = selectedDockerFirewallBackend(detectedBackend) base = s.runtimeStatus(s.guardRuntime(base.Backend), base.Backend) base.Version = s.loadFirewallVersion(base.Backend) if reconcileErr := lastDockerPortGuardReconcileError(); reconcileErr != nil { @@ -131,6 +155,7 @@ func (s *DockerPortGuardService) LoadOverview(ctx context.Context) (dto.DockerPo if err != nil { return dto.DockerPortGuardList{}, err } + annotateDockerEndpointTrafficPaths(endpoints, detectedBackend) endpoints, orphanPolicies := matchDockerGuardPolicies(base, policies, endpoints) sort.Slice(endpoints, func(i, j int) bool { return guardEndpointKey(endpoints[i].Family, endpoints[i].HostIP, endpoints[i].HostPort, endpoints[i].Protocol) < guardEndpointKey(endpoints[j].Family, endpoints[j].HostIP, endpoints[j].HostPort, endpoints[j].Protocol) @@ -158,7 +183,8 @@ func matchDockerGuardPolicies( } endpoints[i].PolicyUUID, endpoints[i].Mode, endpoints[i].Sources = policy.UUID, policy.Mode, docker_guard.DecodeSources(policy.Sources) endpoints[i].Description = policy.Description - endpoints[i].Effective = (policy.Family == docker_guard.FamilyIPv4 && base.IPv4.Effective) || (policy.Family == docker_guard.FamilyIPv6 && base.IPv6.Effective) + endpoints[i].Effective = endpoints[i].TrafficPath == dockerTrafficPathForward && + ((policy.Family == docker_guard.FamilyIPv4 && base.IPv4.Effective) || (policy.Family == docker_guard.FamilyIPv6 && base.IPv6.Effective)) delete(byEndpoint, key) } orphanPolicies := make([]dto.DockerPortGuardEndpoint, 0, len(byEndpoint)) @@ -166,6 +192,7 @@ func matchDockerGuardPolicies( orphanPolicies = append(orphanPolicies, dto.DockerPortGuardEndpoint{ Family: policy.Family, HostIP: policy.HostIP, HostPort: policy.HostPort, Protocol: policy.Protocol, PolicyUUID: policy.UUID, Mode: policy.Mode, Sources: docker_guard.DecodeSources(policy.Sources), Description: policy.Description, + TrafficPath: dockerTrafficPathUnknown, }) } return endpoints, orphanPolicies @@ -291,6 +318,9 @@ func (s *DockerPortGuardService) DeletePolicies(ctx context.Context, request dto func (s *DockerPortGuardService) UpsertPolicies(ctx context.Context, request dto.DockerPortGuardPolicyBatch) error { dockerPortGuardServiceMu.Lock() defer dockerPortGuardServiceMu.Unlock() + if err := s.rejectHostInputDockerGuardEndpoints(ctx, request.Endpoints); err != nil { + return err + } policies := make([]model.DockerPortGuardPolicy, 0, len(request.Endpoints)) seen := make(map[string]struct{}, len(request.Endpoints)) for _, endpoint := range request.Endpoints { @@ -319,6 +349,39 @@ func (s *DockerPortGuardService) UpsertPolicies(ctx context.Context, request dto return s.reconcileLocked(ctx) } +func (s *DockerPortGuardService) rejectHostInputDockerGuardEndpoints( + ctx context.Context, + requested []dto.DockerPortGuardEndpointIdentity, +) error { + if s.client == nil || len(requested) == 0 { + return nil + } + cli, err := s.client() + if err != nil { + return nil + } + defer cli.Close() + info, err := cli.Info(ctx) + if err != nil { + return nil + } + endpoints, err := discoverDockerEndpoints(ctx, cli) + if err != nil { + return nil + } + annotateDockerEndpointTrafficPaths(endpoints, dockerFirewallBackend(info)) + paths := make(map[string]string, len(endpoints)) + for _, endpoint := range endpoints { + paths[guardEndpointKey(endpoint.Family, endpoint.HostIP, endpoint.HostPort, endpoint.Protocol)] = endpoint.TrafficPath + } + for _, endpoint := range requested { + if paths[guardEndpointKey(endpoint.Family, endpoint.HostIP, endpoint.HostPort, endpoint.Protocol)] == dockerTrafficPathInput { + return fmt.Errorf("%w: endpoint traffic is handled by the host input firewall", ErrDockerGuardInvalid) + } + } + return nil +} + func (s *DockerPortGuardService) Reconcile(ctx context.Context) error { dockerPortGuardServiceMu.Lock() defer dockerPortGuardServiceMu.Unlock() @@ -393,6 +456,7 @@ func dockerGuardRuleSyncDTO(policy model.DockerPortGuardPolicy) *dto.DockerPortG return &dto.DockerPortGuardEndpoint{ Family: policy.Family, HostIP: policy.HostIP, HostPort: policy.HostPort, Protocol: policy.Protocol, PolicyUUID: policy.UUID, Mode: policy.Mode, Sources: docker_guard.DecodeSources(policy.Sources), Description: policy.Description, + TrafficPath: dockerTrafficPathUnknown, } } @@ -400,6 +464,7 @@ func dockerGuardRuntimeRuleSyncDTO(policy docker_guard.Policy) *dto.DockerPortGu return &dto.DockerPortGuardEndpoint{ Family: policy.Family, HostIP: policy.HostIP, HostPort: policy.HostPort, Protocol: policy.Protocol, PolicyUUID: policy.UUID, Mode: policy.Mode, Sources: append([]string(nil), policy.Sources...), + TrafficPath: dockerTrafficPathUnknown, } } @@ -630,7 +695,7 @@ func dockerGuardPolicyEndpoints(policies []model.DockerPortGuardPolicy) []dto.Do endpoints = append(endpoints, dto.DockerPortGuardEndpoint{ Family: policy.Family, HostIP: policy.HostIP, HostPort: policy.HostPort, Protocol: policy.Protocol, PolicyUUID: policy.UUID, Mode: policy.Mode, Sources: docker_guard.DecodeSources(policy.Sources), - Description: policy.Description, + Description: policy.Description, TrafficPath: dockerTrafficPathUnknown, }) } return endpoints @@ -666,7 +731,7 @@ func groupDockerGuardContainers(endpoints []dto.DockerPortGuardEndpoint) []dto.D for i, endpoint := range container.Endpoints { sources := append([]string(nil), endpoint.Sources...) sort.Strings(sources) - policyKey := fmt.Sprintf("%t|%s|%s|%t|%s", endpoint.PolicyUUID != "", endpoint.Mode, strings.Join(sources, ","), endpoint.Effective, endpoint.Description) + policyKey := fmt.Sprintf("%t|%s|%s|%t|%s|%s", endpoint.PolicyUUID != "", endpoint.Mode, strings.Join(sources, ","), endpoint.Effective, endpoint.Description, endpoint.TrafficPath) items = append(items, docker.PortRangeItem{ Key: endpoint.Family + "|" + endpoint.HostIP + "|" + endpoint.Protocol + "|" + policyKey, PublicPort: endpoint.HostPort, PrivatePort: endpoint.ContainerPort, @@ -711,3 +776,230 @@ func firstGuardString(values []string) string { } return values[0] } + +func annotateDockerEndpointTrafficPaths(endpoints []dto.DockerPortGuardEndpoint, backend string) { + rules := map[string]dockerForwardRules{ + constant.FirewallFamilyIPv4: loadDockerDNATRules(backend, constant.FirewallFamilyIPv4), + constant.FirewallFamilyIPv6: loadDockerDNATRules(backend, constant.FirewallFamilyIPv6), + } + proxies := loadDockerProxyEndpoints() + for i := range endpoints { + familyRules := rules[endpoints[i].Family] + endpoints[i].TrafficPath = dockerEndpointTrafficPath(backend, familyRules.output, familyRules.inspected, proxies, endpoints[i]) + } +} + +func dockerEndpointTrafficPath(backend, rules string, inspected bool, proxies []dockerProxyEndpoint, endpoint dto.DockerPortGuardEndpoint) string { + if !inspected { + return dockerTrafficPathUnknown + } + if dockerDNATRuleMatches(backend, rules, endpoint) { + return dockerTrafficPathForward + } + if dockerProxyEndpointMatches(proxies, endpoint) { + return dockerTrafficPathInput + } + return dockerTrafficPathUnknown +} + +func loadDockerDNATRules(backend, family string) dockerForwardRules { + manager := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Second), cmd.WithEnv("LC_ALL=C")) + if backend == constant.FirewallProviderNftables { + tableFamily := "ip" + if family == constant.FirewallFamilyIPv6 { + tableFamily = "ip6" + } + tables, err := manager.RunWithOptionalSudoAndStdout("nft", "list", "tables") + if err != nil { + return dockerForwardRules{} + } + if !strings.Contains(tables, "table "+tableFamily+" docker-bridges") { + return dockerForwardRules{inspected: true} + } + output, err := manager.RunWithOptionalSudoAndStdout("nft", "list", "table", tableFamily, "docker-bridges") + return dockerForwardRules{output: output, inspected: err == nil} + } + commands, err := lifecycle.ResolveIptablesCommands() + if err != nil { + return dockerForwardRules{} + } + executable := commands.IPv4 + if family == constant.FirewallFamilyIPv6 { + executable = commands.IPv6 + } + if executable == "" { + return dockerForwardRules{} + } + output, err := manager.RunWithOptionalSudoAndStdout(executable, "-w", "-t", "nat", "-S") + return dockerForwardRules{output: output, inspected: err == nil} +} + +func loadDockerProxyEndpoints() []dockerProxyEndpoint { + manager := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Second), cmd.WithEnv("LC_ALL=C")) + output, err := manager.RunWithStdout("ps", "-ww", "-eo", "args=") + if err != nil { + return nil + } + return parseDockerProxyEndpoints(output) +} + +func parseDockerProxyEndpoints(output string) []dockerProxyEndpoint { + result := make([]dockerProxyEndpoint, 0) + for _, line := range strings.Split(output, "\n") { + fields := strings.Fields(line) + if len(fields) == 0 || !dockerProxyCommand(fields) { + continue + } + protocol := commandFlagValue(fields, "-proto") + hostIP := commandFlagValue(fields, "-host-ip") + hostPortValue := commandFlagValue(fields, "-host-port") + hostPort, err := strconv.ParseUint(hostPortValue, 10, 16) + if err != nil || (protocol != "tcp" && protocol != "udp") || hostIP == "" { + continue + } + result = append(result, dockerProxyEndpoint{protocol: protocol, hostIP: canonicalAddress(hostIP), hostPort: uint16(hostPort)}) + } + return result +} + +func dockerProxyCommand(fields []string) bool { + for _, field := range fields { + if filepath.Base(field) == "docker-proxy" { + return true + } + } + return false +} + +func commandFlagValue(fields []string, name string) string { + for i := 0; i < len(fields); i++ { + if fields[i] == name && i+1 < len(fields) { + return fields[i+1] + } + if strings.HasPrefix(fields[i], name+"=") { + return strings.TrimPrefix(fields[i], name+"=") + } + } + return "" +} + +func dockerProxyEndpointMatches(proxies []dockerProxyEndpoint, endpoint dto.DockerPortGuardEndpoint) bool { + for _, proxy := range proxies { + if proxy.protocol == endpoint.Protocol && proxy.hostPort == endpoint.HostPort && hostAddressMatches(proxy.hostIP, endpoint.HostIP, endpoint.Family) { + return true + } + } + return false +} + +func dockerDNATRuleMatches(backend, output string, endpoint dto.DockerPortGuardEndpoint) bool { + if strings.TrimSpace(output) == "" { + return false + } + if backend == constant.FirewallProviderNftables { + return nftDNATRuleMatches(output, endpoint) + } + return iptablesDNATRuleMatches(output, endpoint) +} + +func iptablesDNATRuleMatches(output string, endpoint dto.DockerPortGuardEndpoint) bool { + port := strconv.Itoa(int(endpoint.HostPort)) + for _, line := range strings.Split(output, "\n") { + fields := strings.Fields(line) + if commandFlagValue(fields, "-p") != endpoint.Protocol || commandFlagValue(fields, "--dport") != port || commandFlagValue(fields, "-j") != "DNAT" { + continue + } + if destinationAddressMatches(commandFlagValue(fields, "-d"), endpoint) { + return true + } + } + return false +} + +func nftDNATRuleMatches(output string, endpoint dto.DockerPortGuardEndpoint) bool { + port := strconv.Itoa(int(endpoint.HostPort)) + for _, line := range strings.Split(output, "\n") { + fields := strings.Fields(strings.NewReplacer("{", " ", "}", " ", ",", " ", ";", " ").Replace(line)) + if !containsToken(fields, "dnat") || !nftProtocolPortMatches(fields, endpoint.Protocol, port) { + continue + } + destination := nftDestinationAddress(fields, endpoint.Family) + if destinationAddressMatches(destination, endpoint) { + return true + } + } + return false +} + +func nftProtocolPortMatches(fields []string, protocol, port string) bool { + for i := 0; i+2 < len(fields); i++ { + if fields[i] == protocol && fields[i+1] == "dport" && fields[i+2] == port { + return true + } + if fields[i] == "th" && fields[i+1] == "dport" && fields[i+2] == port && nftMetaProtocolMatches(fields, protocol) { + return true + } + } + return false +} + +func nftMetaProtocolMatches(fields []string, protocol string) bool { + for i := 0; i+2 < len(fields); i++ { + if fields[i] == "meta" && fields[i+1] == "l4proto" && fields[i+2] == protocol { + return true + } + } + return false +} + +func nftDestinationAddress(fields []string, family string) string { + token := "ip" + if family == constant.FirewallFamilyIPv6 { + token = "ip6" + } + for i := 0; i+2 < len(fields); i++ { + if fields[i] == token && fields[i+1] == "daddr" { + return fields[i+2] + } + } + return "" +} + +func destinationAddressMatches(ruleAddress string, endpoint dto.DockerPortGuardEndpoint) bool { + ruleAddress = strings.TrimSpace(strings.Split(ruleAddress, "/")[0]) + if isWildcardHostAddress(endpoint.HostIP, endpoint.Family) { + return ruleAddress == "" + } + return ruleAddress == "" || canonicalAddress(ruleAddress) == canonicalAddress(endpoint.HostIP) +} + +func hostAddressMatches(left, right, family string) bool { + if isWildcardHostAddress(left, family) && isWildcardHostAddress(right, family) { + return true + } + return canonicalAddress(left) == canonicalAddress(right) +} + +func isWildcardHostAddress(value, family string) bool { + value = strings.TrimSpace(value) + if family == constant.FirewallFamilyIPv6 { + return value == "" || value == "::" + } + return value == "" || value == "0.0.0.0" +} + +func canonicalAddress(value string) string { + if address, err := netip.ParseAddr(strings.TrimSpace(value)); err == nil { + return address.String() + } + return strings.TrimSpace(value) +} + +func containsToken(fields []string, value string) bool { + for _, field := range fields { + if field == value { + return true + } + } + return false +} diff --git a/frontend/src/api/interface/firewall.ts b/frontend/src/api/interface/firewall.ts index 040434f00..ddd302a10 100644 --- a/frontend/src/api/interface/firewall.ts +++ b/frontend/src/api/interface/firewall.ts @@ -403,6 +403,7 @@ export namespace Firewall { sources: string[]; effective: boolean; description?: string; + trafficPath: 'forward' | 'input' | 'unknown'; } export interface DockerGuardPortGroup { key: string; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index a2f57767d..d13d1770c 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -4123,12 +4123,9 @@ const message = { configuredRules: '{0} rules configured', addressFamily: 'IP version', portOrRange: 'Port / range', - exportAllRules: 'Export all rules', importBackendHelper: 'Imported rules are converted for the current {0} backend. Source rules are not changed.', ruleSyncTitle: 'Synchronize rules', ruleSyncAction: 'Sync rules', - ruleSyncHelper: - 'Sync 1Panel-managed rules from the selected firewall to the current firewall. Source rules stay unchanged, and external rules are not included.', ruleSyncDatabase: '1Panel database', ruleSyncDatabaseHelper: 'Synchronize and reconcile the managed rules in the current firewall based on the 1Panel database rules. Missing rules will be added and extra rules will be removed.', @@ -4137,7 +4134,6 @@ const message = { 'Synchronize {1} to exactly match the {0} database rules? {2} target rule(s) will be removed and missing rules will be added.', ruleSyncSource: 'Configuration source', ruleSyncTarget: 'Current backend', - ruleSyncTotal: 'Converted rules', ruleSyncReady: 'Ready', ruleSyncExisting: 'Existing', ruleSyncRemove: 'To remove', @@ -4159,14 +4155,6 @@ const message = { protectedRule: 'This protected firewall rule cannot be modified.', cannotReconcile: 'The target rule cannot be reconciled: {0}', }, - ruleSyncConfirm: 'Synchronize {0} rules from {1} to {2}? The source backend will not be modified.', - ruleSyncResetSource: 'Reset and disable source firewall {0} after synchronization succeeds', - ruleSyncResetSourceHelper: - 'The source firewall is reset only after every rule is synchronized successfully. This operation cannot be undone.', - ruleSyncResetSourceBlocked: - 'Some rules cannot be synchronized. Resolve them before automatically resetting the source firewall.', - ruleSyncResetSourceConfirm: - 'Synchronize {0} rules from {1} to {2}, then reset and disable {1}? This deletes all {1} firewall configuration and cannot be undone.', ruleSyncPartial: 'Synchronization completed: {0} succeeded, {1} already existed, and {2} failed.', ruleSyncSuccess: 'Synchronization completed: {0} succeeded, {1} already existed, and {2} were removed.', ruleSyncStatus: { @@ -4197,6 +4185,13 @@ const message = { partiallyInitialized: 'Partially initialized', dockerGuardHelper: 'Set access restrictions for ports published from Docker containers to the host. Unprotected ports retain Docker default access behavior.', + dockerTrafficPathMixed: 'The selected ports use different access paths. Configure them separately.', + dockerTrafficPathUnknown: + 'The access path for this port could not be determined. Check the Docker network configuration and try again.', + dockerTrafficPathPending: 'Access path pending', + dockerInputPolicyNotEffective: + 'The host receives this port directly, so the existing container port protection rule does not apply. Configure it in the host firewall instead.', + dockerInputUseHostFirewall: 'Configure access for this port in the host firewall.', dockerInputNotProtected: 'Host INPUT rules do not directly protect this Docker published port. Click to open Container Port Guard.', notInitialized: 'Not initialized', @@ -4228,9 +4223,7 @@ const message = { 'The selected rules have different configurations. Configure them again to overwrite all selected rules; an empty description clears all descriptions.', effective: 'Effective', forwardUnsynced: 'Unsynced', - notEnabled: 'Not enabled', notEffective: 'Not effective', - dockerGuardStatusEffective: '{0} container port protection is working normally', dockerGuardStatusReason: { command_missing: 'The {0} firewall component is unavailable, so the corresponding container port protection cannot be enabled. Check the system firewall environment', @@ -4256,8 +4249,6 @@ const message = { importSuccess: 'Successfully imported {0} rules', importPartialSuccess: 'Import completed: {0} succeeded, {1} failed', basicStatus: 'The current firewall is unbound. Bind it first.', - baseIptables: 'iptables Service', - forwardIptables: 'iptables Port Forwarding Service', initMsg: 'About to initialize {0}, continue?', initDirectBackendConflictMsg: '{1} is still bound. If {0} is initialized, both firewall rule sets will be active and may unexpectedly block access. Continue?', diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index bbc9bce06..1c65d7728 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -4167,28 +4167,10 @@ const message = { configuredRules: '{0} reglas configuradas', addressFamily: 'Versión de IP', portOrRange: 'Puerto / rango', - exportAllRules: 'Exportar todas las reglas', importBackendHelper: 'Las reglas importadas se convierten para el backend actual {0}. Las reglas de origen no se modifican.', - resetDirectRulesHelper: - 'Elimina de {0} las cadenas, reglas activas y archivos persistentes del firewall de 1Panel; se conservan las políticas de la base de datos', - resetWhitelistRulesHelper: - 'Restablece la configuración personalizada activa en {0}, restaura los valores iniciales y desactiva {0}; las políticas de la base de datos se conservan y pueden volver a sincronizarse.', - cleanupForwardingBackendHelper: - 'Restablece las reglas de ejecución del reenvío de puertos de 1Panel en {0}: elimina todas las reglas y cadenas relacionadas y conserva los datos de la base de datos', - cleanupDockerBackendHelper: - 'Restablece las reglas de ejecución de protección de puertos Docker de 1Panel en {0}: elimina todas las reglas y cadenas relacionadas y conserva los datos de la base de datos', - cleanupBeforeBackendSwitch: - 'El backend actual {0} todavía contiene reglas de ejecución de 1Panel. Restablézcalo antes de cambiar a {1}.', - cleanupAction: 'Restablecer', - backendSwitchNotice: - 'Restablece el backend actual antes de cambiar el firewall del sistema, el reenvío de puertos o la protección Docker. Las políticas de la base de datos se conservan y pueden inicializarse o sincronizarse después.', - switchBackendHelper: '¿Cambiar a {0}?', - switchDockerBackendHelper: '¿Cambiar a {0}? Esto actualizará la configuración y reiniciará Docker.', ruleSyncTitle: 'Sincronizar reglas', ruleSyncAction: 'Sincronizar reglas', - ruleSyncHelper: - 'Sincroniza las reglas gestionadas por 1Panel del firewall seleccionado al firewall actual. Las reglas de origen no se eliminan y las reglas externas no se incluyen.', ruleSyncDatabase: 'Base de datos de 1Panel', ruleSyncDatabaseHelper: 'Sincroniza y concilia las reglas administradas del firewall actual con las reglas de la base de datos de 1Panel. Se añadirán las reglas que falten y se eliminarán las sobrantes.', @@ -4197,7 +4179,6 @@ const message = { '¿Sincronizar {1} para que coincida exactamente con las {0} reglas de la base de datos? Se eliminarán {2} reglas del destino y se añadirán las que falten.', ruleSyncSource: 'Origen de configuración', ruleSyncTarget: 'Backend actual', - ruleSyncTotal: 'Reglas convertidas', ruleSyncReady: 'Preparadas', ruleSyncExisting: 'Existentes', ruleSyncRemove: 'Para eliminar', @@ -4220,14 +4201,6 @@ const message = { protectedRule: 'Esta regla protegida del firewall no se puede modificar.', cannotReconcile: 'No se puede sincronizar la regla de destino: {0}', }, - ruleSyncConfirm: '¿Sincronizar {0} reglas de {1} a {2}? El backend de origen no se modificará.', - ruleSyncResetSource: 'Restablecer y desactivar el firewall de origen {0} tras sincronizar', - ruleSyncResetSourceHelper: - 'El firewall de origen solo se restablece si todas las reglas se sincronizan correctamente.', - ruleSyncResetSourceBlocked: - 'Hay reglas que no se pueden sincronizar. Resuélvalas antes de restablecer el origen.', - ruleSyncResetSourceConfirm: - '¿Sincronizar {0} reglas de {1} a {2} y después restablecer y desactivar {1}? Se eliminará toda su configuración y no se puede deshacer.', ruleSyncPartial: 'Sincronización completada: {0} correctas, {1} ya existían y {2} fallaron.', ruleSyncSuccess: 'Sincronización completada: {0} correctas, {1} ya existían y {2} eliminadas.', ruleSyncStatus: { @@ -4236,6 +4209,21 @@ const message = { remove: 'Para eliminar', blocked: 'No disponible', }, + resetDirectRulesHelper: + 'Elimina de {0} las cadenas, reglas activas y archivos persistentes del firewall de 1Panel; se conservan las políticas de la base de datos', + resetWhitelistRulesHelper: + 'Restablece la configuración personalizada activa en {0}, restaura los valores iniciales y desactiva {0}; las políticas de la base de datos se conservan y pueden volver a sincronizarse.', + cleanupForwardingBackendHelper: + 'Restablece las reglas de ejecución del reenvío de puertos de 1Panel en {0}: elimina todas las reglas y cadenas relacionadas y conserva los datos de la base de datos', + cleanupDockerBackendHelper: + 'Restablece las reglas de ejecución de protección de puertos Docker de 1Panel en {0}: elimina todas las reglas y cadenas relacionadas y conserva los datos de la base de datos', + cleanupBeforeBackendSwitch: + 'El backend actual {0} todavía contiene reglas de ejecución de 1Panel. Restablézcalo antes de cambiar a {1}.', + cleanupAction: 'Restablecer', + backendSwitchNotice: + 'Restablece el backend actual antes de cambiar el firewall del sistema, el reenvío de puertos o la protección Docker. Las políticas de la base de datos se conservan y pueden inicializarse o sincronizarse después.', + switchBackendHelper: '¿Cambiar a {0}?', + switchDockerBackendHelper: '¿Cambiar a {0}? Esto actualizará la configuración y reiniciará Docker.', uninstalledStatus: 'No instalado', selectedBackendNotInstalled: 'No se detectó el servicio {backend}. Instálelo manualmente desde {library} o cambie el backend del firewall en {settings}.', @@ -4243,6 +4231,13 @@ const message = { partiallyInitialized: 'Parcialmente inicializado', dockerGuardHelper: 'Configura restricciones de acceso para los puertos que los contenedores Docker publican en el host. Los puertos sin protección mantienen el comportamiento de acceso predeterminado de Docker.', + dockerTrafficPathMixed: 'Los puertos seleccionados usan rutas de acceso diferentes. Configúralos por separado.', + dockerTrafficPathUnknown: + 'No se pudo determinar la ruta de acceso de este puerto. Comprueba la red de Docker e inténtalo de nuevo.', + dockerTrafficPathPending: 'Ruta de acceso pendiente', + dockerInputPolicyNotEffective: + 'El host recibe este puerto directamente, por lo que la regla de protección del puerto del contenedor no se aplica. Configúralo en el firewall del host.', + dockerInputUseHostFirewall: 'Configure el acceso a este puerto en el firewall del host.', dockerInputNotProtected: 'Las reglas INPUT del host no protegen directamente este puerto publicado por Docker. Haz clic para abrir la protección de puertos de contenedores.', notInitialized: 'No inicializado', @@ -4275,9 +4270,7 @@ const message = { 'Las reglas seleccionadas tienen configuraciones diferentes. Configúralas de nuevo para sobrescribirlas todas; una descripción vacía borrará todas las descripciones.', effective: 'En vigor', forwardUnsynced: 'Sin sincronizar', - notEnabled: 'No habilitado', notEffective: 'Sin efecto', - dockerGuardStatusEffective: 'La protección de puertos de contenedores {0} funciona correctamente', dockerGuardStatusReason: { command_missing: 'El componente de firewall {0} no está disponible y no se puede habilitar la protección correspondiente. Comprueba el firewall del sistema', @@ -4305,8 +4298,6 @@ const message = { importSuccess: 'Se importaron correctamente {0} reglas', importPartialSuccess: 'Importación completada: {0} correctas, {1} fallidas', basicStatus: 'El firewall actual no está vinculado. Vincúlelo primero.', - baseIptables: 'Servicio iptables', - forwardIptables: 'Servicio de Reenvío de Puertos iptables', initMsg: 'A punto de inicializar {0}, ¿continuar?', initDirectBackendConflictMsg: '{1} sigue vinculado. Si se inicializa {0}, ambos conjuntos de reglas estarán activos y podrían bloquear el acceso de forma inesperada. ¿Desea continuar?', diff --git a/frontend/src/lang/modules/fa.ts b/frontend/src/lang/modules/fa.ts index 018c06b6e..5178dc98b 100644 --- a/frontend/src/lang/modules/fa.ts +++ b/frontend/src/lang/modules/fa.ts @@ -4078,28 +4078,9 @@ const message = { configuredRules: '{0} قانون پیکربندی شده', addressFamily: 'نسخه IP', portOrRange: 'پورت / بازه', - exportAllRules: 'خروجی همه قوانین', importBackendHelper: 'قوانین واردشده برای بک‌اند فعلی {0} تبدیل می‌شوند. قوانین مبدأ تغییر نمی‌کنند.', - resetDirectRulesHelper: - 'زنجیره‌ها، قوانین اجرایی و فایل‌های پایدار فایروال سیستمی 1Panel از {0} حذف می‌شوند؛ سیاست‌های ذخیره‌شده پایگاه داده حفظ می‌شوند', - resetWhitelistRulesHelper: - 'تنظیمات سفارشی فعال در {0} بازنشانی، پیش‌فرض‌های نصب بازیابی و {0} غیرفعال می‌شود؛ سیاست‌های پایگاه داده حفظ شده و دوباره قابل همگام‌سازی هستند.', - cleanupForwardingBackendHelper: - 'قوانین زمان اجرای انتقال پورت 1Panel در {0} بازنشانی می‌شوند: همه قوانین و زنجیره‌های مرتبط حذف و داده‌های پایگاه داده حفظ می‌شوند', - cleanupDockerBackendHelper: - 'قوانین زمان اجرای محافظت پورت Docker مربوط به 1Panel در {0} بازنشانی می‌شوند: همه قوانین و زنجیره‌های مرتبط حذف و داده‌های پایگاه داده حفظ می‌شوند', - cleanupBeforeBackendSwitch: - 'بک‌اند فعلی {0} هنوز شامل قوانین زمان اجرای 1Panel است. پیش از تغییر به {1} آن را بازنشانی کنید.', - cleanupAction: 'بازنشانی', - backendSwitchNotice: - 'پیش از تغییر فایروال سیستم، انتقال پورت یا محافظت Docker، بک‌اند فعلی را بازنشانی کنید. سیاست‌های پایگاه داده حفظ می‌شوند و پس از تغییر قابل راه‌اندازی یا همگام‌سازی هستند.', - switchBackendHelper: 'به {0} تغییر داده شود؟', - switchDockerBackendHelper: - 'به {0} تغییر داده شود؟ پیکربندی Docker به‌روزرسانی و Docker راه‌اندازی مجدد می‌شود.', ruleSyncTitle: 'همگام‌سازی قوانین', ruleSyncAction: 'همگام‌سازی قوانین', - ruleSyncHelper: - 'قوانین مدیریت‌شده توسط 1Panel را از فایروال انتخاب‌شده با فایروال فعلی همگام می‌کند. قوانین مبدأ حذف نمی‌شوند و قوانین خارجی همگام نخواهند شد.', ruleSyncDatabase: 'پایگاه داده 1Panel', ruleSyncDatabaseHelper: 'قوانین مدیریت‌شده در فایروال فعلی را بر اساس قوانین پایگاه داده 1Panel همگام‌سازی و هماهنگ می‌کند. قوانین مفقود اضافه و قوانین اضافی حذف می‌شوند.', @@ -4108,7 +4089,6 @@ const message = { 'آیا {1} دقیقاً با {0} قانون پایگاه داده همگام شود؟ {2} قانون مقصد حذف و قوانین مفقود اضافه خواهند شد.', ruleSyncSource: 'منبع پیکربندی', ruleSyncTarget: 'بک‌اند فعلی', - ruleSyncTotal: 'قوانین تبدیل‌شده', ruleSyncReady: 'آماده', ruleSyncExisting: 'موجود', ruleSyncRemove: 'در انتظار حذف', @@ -4131,12 +4111,6 @@ const message = { protectedRule: 'این قانون محافظت‌شدهٔ فایروال قابل تغییر نیست.', cannotReconcile: 'قانون مقصد قابل همگام‌سازی نیست: {0}', }, - ruleSyncConfirm: '{0} قانون از {1} به {2} همگام شود؟ بک‌اند مبدأ تغییر نخواهد کرد.', - ruleSyncResetSource: 'پس از همگام‌سازی موفق، فایروال مبدأ {0} بازنشانی و غیرفعال شود', - ruleSyncResetSourceHelper: 'فایروال مبدأ فقط پس از همگام‌سازی موفق همه قوانین بازنشانی می‌شود.', - ruleSyncResetSourceBlocked: 'برخی قوانین قابل همگام‌سازی نیستند؛ ابتدا آن‌ها را برطرف کنید.', - ruleSyncResetSourceConfirm: - '{0} قانون از {1} به {2} همگام و سپس {1} بازنشانی و غیرفعال شود؟ همه تنظیمات آن حذف خواهد شد و قابل بازگشت نیست.', ruleSyncPartial: 'همگام‌سازی پایان یافت: {0} موفق، {1} از قبل موجود و {2} ناموفق.', ruleSyncSuccess: 'همگام‌سازی پایان یافت: {0} موفق، {1} از قبل موجود و {2} حذف شد.', ruleSyncStatus: { @@ -4145,6 +4119,22 @@ const message = { remove: 'در انتظار حذف', blocked: 'غیرقابل همگام‌سازی', }, + resetDirectRulesHelper: + 'زنجیره‌ها، قوانین اجرایی و فایل‌های پایدار فایروال سیستمی 1Panel از {0} حذف می‌شوند؛ سیاست‌های ذخیره‌شده پایگاه داده حفظ می‌شوند', + resetWhitelistRulesHelper: + 'تنظیمات سفارشی فعال در {0} بازنشانی، پیش‌فرض‌های نصب بازیابی و {0} غیرفعال می‌شود؛ سیاست‌های پایگاه داده حفظ شده و دوباره قابل همگام‌سازی هستند.', + cleanupForwardingBackendHelper: + 'قوانین زمان اجرای انتقال پورت 1Panel در {0} بازنشانی می‌شوند: همه قوانین و زنجیره‌های مرتبط حذف و داده‌های پایگاه داده حفظ می‌شوند', + cleanupDockerBackendHelper: + 'قوانین زمان اجرای محافظت پورت Docker مربوط به 1Panel در {0} بازنشانی می‌شوند: همه قوانین و زنجیره‌های مرتبط حذف و داده‌های پایگاه داده حفظ می‌شوند', + cleanupBeforeBackendSwitch: + 'بک‌اند فعلی {0} هنوز شامل قوانین زمان اجرای 1Panel است. پیش از تغییر به {1} آن را بازنشانی کنید.', + cleanupAction: 'بازنشانی', + backendSwitchNotice: + 'پیش از تغییر فایروال سیستم، انتقال پورت یا محافظت Docker، بک‌اند فعلی را بازنشانی کنید. سیاست‌های پایگاه داده حفظ می‌شوند و پس از تغییر قابل راه‌اندازی یا همگام‌سازی هستند.', + switchBackendHelper: 'به {0} تغییر داده شود؟', + switchDockerBackendHelper: + 'به {0} تغییر داده شود؟ پیکربندی Docker به‌روزرسانی و Docker راه‌اندازی مجدد می‌شود.', uninstalledStatus: 'نصب‌نشده', selectedBackendNotInstalled: 'سرویس {backend} شناسایی نشد. آن را به‌صورت دستی از {library} نصب کنید یا بک‌اند فایروال را در {settings} تغییر دهید.', @@ -4152,6 +4142,14 @@ const message = { partiallyInitialized: 'تا حدی راه‌اندازی شده', dockerGuardHelper: 'محدودیت دسترسی برای پورت‌هایی که کانتینرهای Docker روی میزبان منتشر می‌کنند تنظیم کنید. پورت‌های محافظت‌نشده رفتار دسترسی پیش‌فرض Docker را حفظ می‌کنند.', + dockerTrafficPathMixed: + 'پورت‌های انتخاب‌شده از مسیرهای دسترسی متفاوت استفاده می‌کنند. آن‌ها را جداگانه تنظیم کنید.', + dockerTrafficPathUnknown: + 'مسیر دسترسی این پورت قابل تشخیص نیست. تنظیمات شبکه Docker را بررسی کرده و دوباره تلاش کنید.', + dockerTrafficPathPending: 'مسیر دسترسی نامشخص', + dockerInputPolicyNotEffective: + 'این پورت مستقیماً توسط میزبان دریافت می‌شود، بنابراین قانون فعلی محافظت پورت کانتینر اعمال نمی‌شود. آن را در فایروال میزبان تنظیم کنید.', + dockerInputUseHostFirewall: 'دسترسی این پورت را در فایروال میزبان پیکربندی کنید.', dockerInputNotProtected: 'قوانین INPUT میزبان مستقیماً از این پورت منتشرشده Docker محافظت نمی‌کنند. برای باز کردن محافظت از پورت کانتینر کلیک کنید.', notInitialized: 'راه‌اندازی نشده', @@ -4183,9 +4181,7 @@ const message = { 'پیکربندی قوانین انتخاب‌شده متفاوت است. برای بازنویسی همه، دوباره تنظیم کنید؛ توضیح خالی، توضیحات همه قوانین را پاک می‌کند.', effective: 'فعال', forwardUnsynced: 'همگام‌نشده', - notEnabled: 'فعال نشده', notEffective: 'بی‌اثر', - dockerGuardStatusEffective: 'محافظت از پورت کانتینر {0} به‌درستی کار می‌کند', dockerGuardStatusReason: { command_missing: 'مؤلفه فایروال {0} در دسترس نیست، بنابراین محافظت مربوطه فعال نمی‌شود. فایروال سیستم را بررسی کنید', @@ -4210,8 +4206,6 @@ const message = { importSuccess: 'واردات {0} قانون با موفقیت انجام شد', importPartialSuccess: 'واردات انجام شد: {0} موفق، {1} ناموفق', basicStatus: 'دیواره آتش فعلی متصل نیست. ابتدا آن را متصل کنید!', - baseIptables: 'سرویس iptables', - forwardIptables: 'سرویس انتقال پورت iptables', initMsg: 'در حال راه‌اندازی {0}، ادامه می‌دهید؟', initDirectBackendConflictMsg: '{1} همچنان متصل است. با راه‌اندازی {0}، هر دو مجموعه قانون فایروال فعال می‌شوند و ممکن است دسترسی را ناخواسته مسدود کنند. ادامه می‌دهید؟', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index 72faf48e3..980dd8248 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -4105,28 +4105,10 @@ const message = { configuredRules: '{0} 件設定済み', addressFamily: 'IP バージョン', portOrRange: 'ポート / 範囲', - exportAllRules: 'すべてのルールをエクスポート', importBackendHelper: 'インポートしたルールは現在の {0} バックエンド向けに変換されます。移行元のルールは変更されません。', - resetDirectRulesHelper: - '{0} から 1Panel システムファイアウォールのチェーン、実行ルール、永続化ファイルを削除し、データベースポリシーは保持します', - resetWhitelistRulesHelper: - '{0} の有効なカスタム設定をリセットし、インストール時の既定値に戻して無効化します。データベースポリシーは保持され、後で再同期できます。', - cleanupForwardingBackendHelper: - '{0} の 1Panel ポート転送ランタイムルールをリセットします。関連するルールとチェーンをすべて削除し、データベースデータを保持します', - cleanupDockerBackendHelper: - '{0} の 1Panel Docker ポート保護ランタイムルールをリセットします。関連するルールとチェーンをすべて削除し、データベースデータを保持します', - cleanupBeforeBackendSwitch: - '現在の {0} バックエンドには 1Panel の実行時ルールが残っています。{1} に切り替える前にリセットしてください。', - cleanupAction: 'リセット', - backendSwitchNotice: - 'システムファイアウォール、ポート転送、Docker 保護を切り替える前に現在のバックエンドをリセットしてください。データベースポリシーは保持され、切り替え後に再初期化または同期できます。', - switchBackendHelper: '{0} に切り替えますか?', - switchDockerBackendHelper: '{0} に切り替えますか?Docker の設定を更新し、Docker を再起動します。', ruleSyncTitle: 'ルールを同期', ruleSyncAction: 'ルールを同期', - ruleSyncHelper: - '選択したファイアウォールの 1Panel 管理ルールを現在のファイアウォールへ同期します。元のルールは削除されず、外部ルールは同期されません。', ruleSyncDatabase: '1Panel データベース', ruleSyncDatabaseHelper: '1Panel データベースのルールを基準に、現在のファイアウォールの管理対象ルールを同期・調整します。不足しているルールは追加され、余分なルールは削除されます。', @@ -4135,7 +4117,6 @@ const message = { 'データベースの {0} 件のルールに完全一致するよう {1} を同期しますか?対象側の {2} 件のルールを削除し、不足ルールを追加します。', ruleSyncSource: '設定ソース', ruleSyncTarget: '現在のバックエンド', - ruleSyncTotal: '変換後のルール', ruleSyncReady: '同期可能', ruleSyncExisting: '存在済み', ruleSyncRemove: '削除予定', @@ -4158,12 +4139,6 @@ const message = { protectedRule: '保護されたファイアウォールルールは変更できません。', cannotReconcile: '対象ルールを同期できません:{0}', }, - ruleSyncConfirm: '{0} 件のルールを {1} から {2} へ同期しますか?元バックエンドは変更されません。', - ruleSyncResetSource: '同期成功後に移行元ファイアウォール {0} をリセットして無効化する', - ruleSyncResetSourceHelper: 'すべてのルールが正常に同期された場合にのみ移行元をリセットします。', - ruleSyncResetSourceBlocked: '同期できないルールがあります。解決してから移行元を自動リセットしてください。', - ruleSyncResetSourceConfirm: - '{0} 件のルールを {1} から {2} へ同期し、その後 {1} をリセットして無効化しますか?すべての設定が削除され、元に戻せません。', ruleSyncPartial: '同期完了:成功 {0} 件、存在済み {1} 件、失敗 {2} 件。', ruleSyncSuccess: '同期完了:成功 {0} 件、存在済み {1} 件、削除 {2} 件。', ruleSyncStatus: { @@ -4172,6 +4147,21 @@ const message = { remove: '削除予定', blocked: '同期不可', }, + resetDirectRulesHelper: + '{0} から 1Panel システムファイアウォールのチェーン、実行ルール、永続化ファイルを削除し、データベースポリシーは保持します', + resetWhitelistRulesHelper: + '{0} の有効なカスタム設定をリセットし、インストール時の既定値に戻して無効化します。データベースポリシーは保持され、後で再同期できます。', + cleanupForwardingBackendHelper: + '{0} の 1Panel ポート転送ランタイムルールをリセットします。関連するルールとチェーンをすべて削除し、データベースデータを保持します', + cleanupDockerBackendHelper: + '{0} の 1Panel Docker ポート保護ランタイムルールをリセットします。関連するルールとチェーンをすべて削除し、データベースデータを保持します', + cleanupBeforeBackendSwitch: + '現在の {0} バックエンドには 1Panel の実行時ルールが残っています。{1} に切り替える前にリセットしてください。', + cleanupAction: 'リセット', + backendSwitchNotice: + 'システムファイアウォール、ポート転送、Docker 保護を切り替える前に現在のバックエンドをリセットしてください。データベースポリシーは保持され、切り替え後に再初期化または同期できます。', + switchBackendHelper: '{0} に切り替えますか?', + switchDockerBackendHelper: '{0} に切り替えますか?Docker の設定を更新し、Docker を再起動します。', uninstalledStatus: '未インストール', selectedBackendNotInstalled: '{backend} サービスが検出されませんでした。{library} から手動でインストールするか、{settings} でファイアウォールバックエンドを切り替えてください。', @@ -4179,6 +4169,13 @@ const message = { partiallyInitialized: '一部初期化済み', dockerGuardHelper: 'Docker コンテナがホストに公開するポートのアクセス制限を設定します。未保護のポートは Docker のデフォルトのアクセス動作を維持します。', + dockerTrafficPathMixed: '選択したポートは異なるアクセス経路を使用しています。個別に設定してください。', + dockerTrafficPathUnknown: + 'このポートのアクセス経路を確認できません。Docker ネットワーク設定を確認して再試行してください。', + dockerTrafficPathPending: 'アクセス経路を確認中', + dockerInputPolicyNotEffective: + 'このポートはホストが直接受信するため、既存のコンテナポート保護ルールは適用されません。ホストファイアウォールで設定してください。', + dockerInputUseHostFirewall: 'このポートのアクセスはホストファイアウォールで設定してください。', dockerInputNotProtected: 'ホストの INPUT ルールでは、この Docker 公開ポートを直接保護できません。クリックしてコンテナポート保護を開きます。', notInitialized: '未初期化', @@ -4209,9 +4206,7 @@ const message = { '選択したルールの設定が異なります。再設定するとすべて統一して上書きされ、説明が空の場合はすべてクリアされます。', effective: '有効', forwardUnsynced: '未同期', - notEnabled: '未有効化', notEffective: '未反映', - dockerGuardStatusEffective: '{0} コンテナポート保護は正常に動作しています', dockerGuardStatusReason: { command_missing: '{0} ファイアウォールコンポーネントが利用できないため、対応する保護を有効にできません。システムファイアウォールを確認してください', @@ -4237,8 +4232,6 @@ const message = { importSuccess: '{0} 件のルールを正常にインポートしました', importPartialSuccess: 'インポート完了: {0} 件成功、{1} 件失敗', basicStatus: '現在のファイアウォールはバインドされていません。先にバインドしてください。', - baseIptables: 'iptables サービス', - forwardIptables: 'iptables ポート転送サービス', initMsg: '{0} を初期化します。続行しますか?', initDirectBackendConflictMsg: '{1} はまだバインドされています。{0} を初期化すると両方のファイアウォールルールが有効になり、予期せずアクセスが遮断される可能性があります。続行しますか?', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 285d1f698..e336e45db 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -3961,6 +3961,8 @@ const message = { firewall: { create: '규칙 만들기', edit: '규칙 수정', + quickJump: '빠른 이동', + used: '사용됨', unUsed: '사용 안 함', managed: '패널 생성', @@ -4029,27 +4031,9 @@ const message = { configuredRules: '{0}개 규칙 설정됨', addressFamily: 'IP 버전', portOrRange: '포트 / 범위', - exportAllRules: '모든 규칙 내보내기', importBackendHelper: '가져온 규칙은 현재 {0} 백엔드에 맞게 변환됩니다. 원본 백엔드의 규칙은 변경되지 않습니다.', - resetDirectRulesHelper: - '{0}에서 1Panel 시스템 방화벽 체인, 실행 규칙 및 영구 파일을 삭제하고 데이터베이스 정책은 유지합니다', - resetWhitelistRulesHelper: - '{0}의 활성 사용자 설정을 재설정하고 설치 기본값으로 복원한 후 비활성화합니다. 데이터베이스 정책은 유지되며 나중에 다시 동기화할 수 있습니다.', - cleanupForwardingBackendHelper: - '{0}의 1Panel 포트 전달 런타임 규칙을 재설정합니다. 관련 규칙과 체인을 모두 삭제하고 데이터베이스 데이터는 유지합니다', - cleanupDockerBackendHelper: - '{0}의 1Panel Docker 포트 보호 런타임 규칙을 재설정합니다. 관련 규칙과 체인을 모두 삭제하고 데이터베이스 데이터는 유지합니다', - cleanupBeforeBackendSwitch: - '현재 {0} 백엔드에 1Panel 런타임 규칙이 남아 있습니다. {1}(으)로 전환하기 전에 먼저 재설정하세요.', - cleanupAction: '재설정', - backendSwitchNotice: - '시스템 방화벽, 포트 전달 또는 Docker 보호를 전환하기 전에 현재 백엔드를 재설정하세요. 데이터베이스 정책은 유지되며 전환 후 다시 초기화하거나 동기화할 수 있습니다.', - switchBackendHelper: '{0}(으)로 전환하시겠습니까?', - switchDockerBackendHelper: '{0}(으)로 전환하시겠습니까? Docker 설정을 업데이트하고 Docker를 재시작합니다.', ruleSyncTitle: '규칙 동기화', ruleSyncAction: '규칙 동기화', - ruleSyncHelper: - '선택한 방화벽의 1Panel 관리 규칙을 현재 방화벽에 동기화합니다. 원본 규칙은 삭제되지 않으며 외부 규칙은 동기화되지 않습니다.', ruleSyncDatabase: '1Panel 데이터베이스', ruleSyncDatabaseHelper: '1Panel 데이터베이스 규칙을 기준으로 현재 방화벽의 관리 규칙을 동기화하고 조정합니다. 누락된 규칙은 추가되고 불필요한 규칙은 삭제됩니다.', @@ -4058,7 +4042,6 @@ const message = { '데이터베이스 규칙 {0}개와 정확히 일치하도록 {1}을 동기화하시겠습니까? 대상 규칙 {2}개가 삭제되고 누락된 규칙이 추가됩니다.', ruleSyncSource: '구성 소스', ruleSyncTarget: '현재 백엔드', - ruleSyncTotal: '변환된 규칙', ruleSyncReady: '동기화 가능', ruleSyncExisting: '이미 존재', ruleSyncRemove: '삭제 예정', @@ -4080,12 +4063,6 @@ const message = { protectedRule: '보호된 방화벽 규칙은 수정할 수 없습니다.', cannotReconcile: '대상 규칙을 동기화할 수 없습니다: {0}', }, - ruleSyncConfirm: '{0}개 규칙을 {1}에서 {2}(으)로 동기화하시겠습니까? 원본 백엔드는 변경되지 않습니다.', - ruleSyncResetSource: '동기화 성공 후 원본 방화벽 {0} 재설정 및 비활성화', - ruleSyncResetSourceHelper: '모든 규칙이 성공적으로 동기화된 경우에만 원본 방화벽을 재설정합니다.', - ruleSyncResetSourceBlocked: '동기화할 수 없는 규칙이 있습니다. 먼저 해결한 후 원본을 재설정하십시오.', - ruleSyncResetSourceConfirm: - '{0}개 규칙을 {1}에서 {2}(으)로 동기화한 후 {1}을(를) 재설정하고 비활성화하시겠습니까? 모든 설정이 삭제되며 되돌릴 수 없습니다.', ruleSyncPartial: '동기화 완료: 성공 {0}개, 이미 존재 {1}개, 실패 {2}개.', ruleSyncSuccess: '동기화 완료: 성공 {0}개, 이미 존재 {1}개, 삭제 {2}개.', ruleSyncStatus: { @@ -4094,6 +4071,21 @@ const message = { remove: '삭제 예정', blocked: '동기화 불가', }, + resetDirectRulesHelper: + '{0}에서 1Panel 시스템 방화벽 체인, 실행 규칙 및 영구 파일을 삭제하고 데이터베이스 정책은 유지합니다', + resetWhitelistRulesHelper: + '{0}의 활성 사용자 설정을 재설정하고 설치 기본값으로 복원한 후 비활성화합니다. 데이터베이스 정책은 유지되며 나중에 다시 동기화할 수 있습니다.', + cleanupForwardingBackendHelper: + '{0}의 1Panel 포트 전달 런타임 규칙을 재설정합니다. 관련 규칙과 체인을 모두 삭제하고 데이터베이스 데이터는 유지합니다', + cleanupDockerBackendHelper: + '{0}의 1Panel Docker 포트 보호 런타임 규칙을 재설정합니다. 관련 규칙과 체인을 모두 삭제하고 데이터베이스 데이터는 유지합니다', + cleanupBeforeBackendSwitch: + '현재 {0} 백엔드에 1Panel 런타임 규칙이 남아 있습니다. {1}(으)로 전환하기 전에 먼저 재설정하세요.', + cleanupAction: '재설정', + backendSwitchNotice: + '시스템 방화벽, 포트 전달 또는 Docker 보호를 전환하기 전에 현재 백엔드를 재설정하세요. 데이터베이스 정책은 유지되며 전환 후 다시 초기화하거나 동기화할 수 있습니다.', + switchBackendHelper: '{0}(으)로 전환하시겠습니까?', + switchDockerBackendHelper: '{0}(으)로 전환하시겠습니까? Docker 설정을 업데이트하고 Docker를 재시작합니다.', uninstalledStatus: '설치되지 않음', selectedBackendNotInstalled: '{backend} 서비스를 감지하지 못했습니다. {library}에서 수동으로 설치하거나 {settings}에서 방화벽 백엔드를 전환하세요.', @@ -4101,6 +4093,13 @@ const message = { partiallyInitialized: '일부 초기화됨', dockerGuardHelper: 'Docker 컨테이너가 호스트에 게시한 포트의 접근 제한을 설정합니다. 보호되지 않은 포트는 Docker 기본 접근 방식을 유지합니다.', + dockerTrafficPathMixed: '선택한 포트가 서로 다른 접근 경로를 사용합니다. 각각 설정하세요.', + dockerTrafficPathUnknown: + '이 포트의 접근 경로를 확인할 수 없습니다. Docker 네트워크 설정을 확인한 후 다시 시도하세요.', + dockerTrafficPathPending: '접근 경로 확인 대기', + dockerInputPolicyNotEffective: + '이 포트는 호스트가 직접 수신하므로 기존 컨테이너 포트 보호 규칙이 적용되지 않습니다. 호스트 방화벽에서 설정하세요.', + dockerInputUseHostFirewall: '이 포트의 접근 규칙은 호스트 방화벽에서 설정하세요.', dockerInputNotProtected: '호스트 INPUT 규칙은 이 Docker 게시 포트를 직접 보호하지 않습니다. 클릭하여 컨테이너 포트 보호를 여세요.', notInitialized: '초기화되지 않음', @@ -4131,9 +4130,7 @@ const message = { '선택한 규칙의 설정이 서로 다릅니다. 다시 설정하면 모두 동일하게 덮어쓰며, 설명이 비어 있으면 모든 설명을 지웁니다.', effective: '적용됨', forwardUnsynced: '미동기화', - notEnabled: '활성화되지 않음', notEffective: '적용되지 않음', - dockerGuardStatusEffective: '{0} 컨테이너 포트 보호가 정상적으로 작동 중입니다', dockerGuardStatusReason: { command_missing: '{0} 방화벽 구성 요소를 사용할 수 없어 해당 보호를 활성화할 수 없습니다. 시스템 방화벽 환경을 확인하세요', @@ -4158,8 +4155,6 @@ const message = { importSuccess: '{0}개의 규칙을 성공적으로 가져왔습니다', importPartialSuccess: '가져오기 완료: 성공 {0}건, 실패 {1}건', basicStatus: '현재 방화벽이 바인딩되지 않았습니다. 먼저 바인딩하세요!', - baseIptables: 'iptables 서비스', - forwardIptables: 'iptables 포트 포워딩 서비스', initMsg: '{0}을(를) 초기화하려고 합니다. 계속하시겠습니까?', initDirectBackendConflictMsg: '{1}이(가) 아직 바인딩되어 있습니다. {0}을(를) 초기화하면 두 방화벽 규칙 세트가 모두 적용되어 예기치 않게 접근이 차단될 수 있습니다. 계속하시겠습니까?', @@ -4192,7 +4187,6 @@ const message = { deleteRiskRulesConfirm: '{0}개의 규칙을 삭제합니다. 그중 {1}개의 허용 규칙이 서비스 접근에 영향을 줄 수 있습니다. 계속하시겠습니까?', editRuleConfirm: '다음 필드가 변경됩니다: {0}. 규칙이 즉시 적용되고 다시 검증됩니다. 계속하시겠습니까?', - quickJump: '빠른 이동', }, runtime: { runtime: '실행 환경', diff --git a/frontend/src/lang/modules/lo.ts b/frontend/src/lang/modules/lo.ts index 088486172..37ebf5671 100644 --- a/frontend/src/lang/modules/lo.ts +++ b/frontend/src/lang/modules/lo.ts @@ -4000,26 +4000,9 @@ const message = { configuredRules: 'ຕັ້ງຄ່າແລ້ວ {0} ກົດ', addressFamily: 'ລຸ້ນ IP', portOrRange: 'ພອດ / ຊ່ວງ', - exportAllRules: 'ສົ່ງອອກກົດທັງໝົດ', importBackendHelper: 'ກົດທີ່ນຳເຂົ້າຈະຖືກປ່ຽນໃຫ້ເໝາະກັບແບັກເອນ {0} ປັດຈຸບັນ. ກົດຕົ້ນທາງຈະບໍ່ຖືກປ່ຽນ.', - resetDirectRulesHelper: - 'ລຶບ chain, ກົດທີ່ກຳລັງໃຊ້ ແລະ ໄຟລ໌ຖາວອນຂອງໄຟວໍລະບົບ 1Panel ຈາກ {0}; ນະໂຍບາຍໃນຖານຂໍ້ມູນຈະຖືກເກັບໄວ້', - resetWhitelistRulesHelper: - 'ຣີເຊັດການຕັ້ງຄ່າກຳນົດເອງທີ່ກຳລັງໃຊ້ໃນ {0}, ຄືນຄ່າເລີ່ມຕົ້ນ ແລະປິດ {0}; ນະໂຍບາຍໃນຖານຂໍ້ມູນຈະຖືກເກັບໄວ້ ແລະຊິງຄືນໄດ້.', - cleanupForwardingBackendHelper: - 'ຣີເຊັດກົດ runtime ສຳລັບການສົ່ງຕໍ່ພອດ 1Panel ໃນ {0}: ລຶບກົດ ແລະ chain ທີ່ກ່ຽວຂ້ອງທັງໝົດ ແລະເກັບຂໍ້ມູນໃນຖານຂໍ້ມູນ', - cleanupDockerBackendHelper: - 'ຣີເຊັດກົດ runtime ປ້ອງກັນພອດ Docker ຂອງ 1Panel ໃນ {0}: ລຶບກົດ ແລະ chain ທີ່ກ່ຽວຂ້ອງທັງໝົດ ແລະເກັບຂໍ້ມູນໃນຖານຂໍ້ມູນ', - cleanupBeforeBackendSwitch: 'ແບັກເອັນປັດຈຸບັນ {0} ຍັງມີກົດ runtime ຂອງ 1Panel. ກະລຸນາຣີເຊັດກ່ອນສະຫຼັບໄປ {1}.', - cleanupAction: 'ຣີເຊັດ', - backendSwitchNotice: - 'ຣີເຊັດແບັກເອັນປັດຈຸບັນກ່ອນສະຫຼັບໄຟວໍລະບົບ, ການສົ່ງຕໍ່ພອດ ຫຼື ການປ້ອງກັນ Docker. ນະໂຍບາຍໃນຖານຂໍ້ມູນຈະຖືກເກັບໄວ້ ແລະສາມາດເລີ່ມ ຫຼືຊິງຫຼັງສະຫຼັບ.', - switchBackendHelper: 'ຢືນຢັນການສະຫຼັບເປັນ {0} ບໍ?', - switchDockerBackendHelper: 'ປ່ຽນເປັນ {0} ບໍ? ການຕັ້ງຄ່າ Docker ຈະຖືກອັບເດດ ແລະ Docker ຈະເລີ່ມໃໝ່.', ruleSyncTitle: 'ຊິງກົດ', ruleSyncAction: 'ຊິງກົດ', - ruleSyncHelper: - 'ຊິງກົດທີ່ 1Panel ຈັດການຈາກໄຟຣ໌ວໍທີ່ເລືອກໄປຫາໄຟຣ໌ວໍປັດຈຸບັນ. ກົດຕົ້ນທາງຈະບໍ່ຖືກລຶບ ແລະ ກົດພາຍນອກຈະບໍ່ຖືກຊິງ.', ruleSyncDatabase: 'ຖານຂໍ້ມູນ 1Panel', ruleSyncDatabaseHelper: 'ໃຊ້ກົດໃນຖານຂໍ້ມູນ 1Panel ເປັນຫຼັກເພື່ອຊິງຄ໌ ແລະປັບກົດທີ່ຈັດການໂດຍ 1Panel ໃນໄຟຣ໌ວໍປັດຈຸບັນ. ກົດທີ່ຂາດຈະຖືກເພີ່ມ ແລະກົດທີ່ເກີນຈະຖືກລຶບ.', @@ -4027,7 +4010,6 @@ const message = { ruleSyncDatabaseConfirm: 'ຊິງ {1} ໃຫ້ກົງກັບ {0} ກົດໃນຖານຂໍ້ມູນບໍ? ຈະລຶບ {2} ກົດຂອງເປົ້າໝາຍ ແລະເພີ່ມກົດທີ່ຂາດ.', ruleSyncSource: 'ແຫຼ່ງການຕັ້ງຄ່າ', ruleSyncTarget: 'ແບັກເອນປັດຈຸບັນ', - ruleSyncTotal: 'ກົດທີ່ແປງແລ້ວ', ruleSyncReady: 'ພ້ອມຊິງ', ruleSyncExisting: 'ມີແລ້ວ', ruleSyncRemove: 'ຈະລຶບ', @@ -4049,12 +4031,6 @@ const message = { protectedRule: 'ກົດໄຟວໍທີ່ຖືກປົກປ້ອງນີ້ບໍ່ສາມາດແກ້ໄຂໄດ້.', cannotReconcile: 'ບໍ່ສາມາດຊິງກົດເປົ້າໝາຍ: {0}', }, - ruleSyncConfirm: 'ຊິງ {0} ກົດຈາກ {1} ໄປ {2} ບໍ? ແບັກເອນຕົ້ນທາງຈະບໍ່ຖືກປ່ຽນ.', - ruleSyncResetSource: 'ຫຼັງຈາກຊິງສຳເລັດ ໃຫ້ຣີເຊັດ ແລະ ປິດໄຟວໍຕົ້ນທາງ {0}', - ruleSyncResetSourceHelper: 'ໄຟວໍຕົ້ນທາງຈະຖືກຣີເຊັດສະເພາະເມື່ອກົດທັງໝົດຊິງສຳເລັດ.', - ruleSyncResetSourceBlocked: 'ມີກົດທີ່ຊິງບໍ່ໄດ້; ກະລຸນາແກ້ໄຂກ່ອນຣີເຊັດຕົ້ນທາງ.', - ruleSyncResetSourceConfirm: - 'ຊິງ {0} ກົດຈາກ {1} ໄປ {2} ແລ້ວຣີເຊັດແລະປິດ {1} ບໍ? ການຕັ້ງຄ່າທັງໝົດຈະຖືກລຶບ ແລະ ຍ້ອນກັບບໍ່ໄດ້.', ruleSyncPartial: 'ຊິງສຳເລັດ: ສຳເລັດ {0}, ມີແລ້ວ {1}, ລົ້ມເຫຼວ {2}.', ruleSyncSuccess: 'ຊິງສຳເລັດ: ສຳເລັດ {0}, ມີແລ້ວ {1}, ລຶບ {2}.', ruleSyncStatus: { @@ -4063,6 +4039,20 @@ const message = { remove: 'ຈະລຶບ', blocked: 'ຊິງບໍ່ໄດ້', }, + resetDirectRulesHelper: + 'ລຶບ chain, ກົດທີ່ກຳລັງໃຊ້ ແລະ ໄຟລ໌ຖາວອນຂອງໄຟວໍລະບົບ 1Panel ຈາກ {0}; ນະໂຍບາຍໃນຖານຂໍ້ມູນຈະຖືກເກັບໄວ້', + resetWhitelistRulesHelper: + 'ຣີເຊັດການຕັ້ງຄ່າກຳນົດເອງທີ່ກຳລັງໃຊ້ໃນ {0}, ຄືນຄ່າເລີ່ມຕົ້ນ ແລະປິດ {0}; ນະໂຍບາຍໃນຖານຂໍ້ມູນຈະຖືກເກັບໄວ້ ແລະຊິງຄືນໄດ້.', + cleanupForwardingBackendHelper: + 'ຣີເຊັດກົດ runtime ສຳລັບການສົ່ງຕໍ່ພອດ 1Panel ໃນ {0}: ລຶບກົດ ແລະ chain ທີ່ກ່ຽວຂ້ອງທັງໝົດ ແລະເກັບຂໍ້ມູນໃນຖານຂໍ້ມູນ', + cleanupDockerBackendHelper: + 'ຣີເຊັດກົດ runtime ປ້ອງກັນພອດ Docker ຂອງ 1Panel ໃນ {0}: ລຶບກົດ ແລະ chain ທີ່ກ່ຽວຂ້ອງທັງໝົດ ແລະເກັບຂໍ້ມູນໃນຖານຂໍ້ມູນ', + cleanupBeforeBackendSwitch: 'ແບັກເອັນປັດຈຸບັນ {0} ຍັງມີກົດ runtime ຂອງ 1Panel. ກະລຸນາຣີເຊັດກ່ອນສະຫຼັບໄປ {1}.', + cleanupAction: 'ຣີເຊັດ', + backendSwitchNotice: + 'ຣີເຊັດແບັກເອັນປັດຈຸບັນກ່ອນສະຫຼັບໄຟວໍລະບົບ, ການສົ່ງຕໍ່ພອດ ຫຼື ການປ້ອງກັນ Docker. ນະໂຍບາຍໃນຖານຂໍ້ມູນຈະຖືກເກັບໄວ້ ແລະສາມາດເລີ່ມ ຫຼືຊິງຫຼັງສະຫຼັບ.', + switchBackendHelper: 'ຢືນຢັນການສະຫຼັບເປັນ {0} ບໍ?', + switchDockerBackendHelper: 'ປ່ຽນເປັນ {0} ບໍ? ການຕັ້ງຄ່າ Docker ຈະຖືກອັບເດດ ແລະ Docker ຈະເລີ່ມໃໝ່.', uninstalledStatus: 'ຍັງບໍ່ໄດ້ຕິດຕັ້ງ', selectedBackendNotInstalled: 'ບໍ່ພົບບໍລິການ {backend}. ກະລຸນາຕິດຕັ້ງແບບກຳນົດເອງຈາກ {library} ຫຼືປ່ຽນແບັກເອັນໄຟວໍໃນ {settings}.', @@ -4070,6 +4060,12 @@ const message = { partiallyInitialized: 'ເລີ່ມຕົ້ນບາງສ່ວນ', dockerGuardHelper: 'ຕັ້ງຄ່າຂໍ້ຈຳກັດການເຂົ້າເຖິງສຳລັບພອດທີ່ Docker ເຜີຍແຜ່ໃນໂຮສ. ພອດທີ່ບໍ່ໄດ້ປ້ອງກັນຈະໃຊ້ຮູບແບບເຂົ້າເຖິງເລີ່ມຕົ້ນຂອງ Docker.', + dockerTrafficPathMixed: 'ພອດທີ່ເລືອກໃຊ້ເສັ້ນທາງເຂົ້າເຖິງຕ່າງກັນ. ກະລຸນາຕັ້ງຄ່າແຍກກັນ.', + dockerTrafficPathUnknown: 'ບໍ່ສາມາດກຳນົດເສັ້ນທາງເຂົ້າເຖິງຂອງພອດນີ້ໄດ້. ກວດສອບເຄືອຂ່າຍ Docker ແລ້ວລອງໃໝ່.', + dockerTrafficPathPending: 'ລໍຖ້າກວດສອບເສັ້ນທາງ', + dockerInputPolicyNotEffective: + 'ພອດນີ້ຖືກຮັບໂດຍໂຮສໂດຍກົງ ດັ່ງນັ້ນກົດປ້ອງກັນພອດຄອນເທນເນີຈຶ່ງບໍ່ມີຜົນ. ກະລຸນາຕັ້ງຄ່າໃນໄຟວໍຂອງໂຮສ.', + dockerInputUseHostFirewall: 'ກະລຸນາຕັ້ງຄ່າການເຂົ້າເຖິງພອດນີ້ໃນໄຟວໍຂອງໂຮສ.', dockerInputNotProtected: 'ກົດ INPUT ຂອງໂຮສບໍ່ໄດ້ປ້ອງກັນພອດ Docker ນີ້ໂດຍກົງ. ຄລິກເພື່ອເປີດການປ້ອງກັນພອດຄອນເທນເນີ.', notInitialized: 'ຍັງບໍ່ໄດ້ເລີ່ມຕົ້ນ', @@ -4100,9 +4096,7 @@ const message = { 'ກົດທີ່ເລືອກມີການຕັ້ງຄ່າແຕກຕ່າງກັນ. ກຳນົດໃໝ່ເພື່ອຂຽນທັບທັງໝົດ; ຄຳອະທິບາຍຫວ່າງຈະລຶບຄຳອະທິບາຍທັງໝົດ.', effective: 'ມີຜົນແລ້ວ', forwardUnsynced: 'ຍັງບໍ່ຊິງຄ໌', - notEnabled: 'ບໍ່ໄດ້ເປີດໃຊ້', notEffective: 'ບໍ່ມີຜົນ', - dockerGuardStatusEffective: 'ການປ້ອງກັນພອດຄອນເທນເນີ {0} ເຮັດວຽກປົກກະຕິ', dockerGuardStatusReason: { command_missing: 'ບໍ່ມີອົງປະກອບໄຟວໍ {0}, ຈຶ່ງບໍ່ສາມາດເປີດການປ້ອງກັນທີ່ກ່ຽວຂ້ອງໄດ້. ກວດສອບໄຟວໍລະບົບ', docker_chain_missing: @@ -4125,8 +4119,6 @@ const message = { importSuccess: 'ນຳເຂົ້າ {0} ກົດລະບຽບສຳເລັດແລ້ວ', importPartialSuccess: 'ນຳເຂົ້າສຳເລັດ: ສຳເລັດ {0}, ລົ້ມເຫຼວ {1}', basicStatus: 'ໄຟວໍປັດຈຸບັນຍັງບໍ່ໄດ້ຜູກມັດ. ກະລຸນາຜູກມັດກ່ອນ!', - baseIptables: 'ບໍລິການ iptables', - forwardIptables: 'ບໍລິການສົ່ງຕໍ່ພອດ iptables', initMsg: 'ກຳລັງຈະເລີ່ມຕົ້ນ {0}, ຕ້ອງການຕໍ່ຫຼືບໍ່?', initDirectBackendConflictMsg: '{1} ຍັງຖືກຜູກຢູ່. ຖ້າເລີ່ມຕົ້ນ {0}, ກົດໄຟວອລທັງສອງຊຸດຈະເຮັດວຽກ ແລະອາດປິດກັ້ນການເຂົ້າເຖິງໂດຍບໍ່ຄາດຄິດ. ສືບຕໍ່ບໍ?', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index 832822960..420ad98d0 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -4189,28 +4189,10 @@ const message = { configuredRules: '{0} peraturan dikonfigurasi', addressFamily: 'Versi IP', portOrRange: 'Port / julat', - exportAllRules: 'Eksport semua peraturan', importBackendHelper: 'Peraturan yang diimport ditukar untuk bahagian belakang semasa {0}. Peraturan sumber tidak diubah.', - resetDirectRulesHelper: - 'Padam rantaian, peraturan masa jalan dan fail berterusan tembok api sistem 1Panel daripada {0}; dasar pangkalan data yang disimpan dikekalkan', - resetWhitelistRulesHelper: - 'Tetapkan semula konfigurasi tersuai aktif dalam {0}, pulihkan tetapan pemasangan asal dan nyahdayakan {0}; dasar pangkalan data dikekalkan dan boleh disegerakkan semula.', - cleanupForwardingBackendHelper: - 'Tetapkan semula peraturan masa jalan pemajuan port 1Panel dalam {0}: padam semua peraturan dan rantaian berkaitan sambil mengekalkan data pangkalan data', - cleanupDockerBackendHelper: - 'Tetapkan semula peraturan masa jalan perlindungan port Docker 1Panel dalam {0}: padam semua peraturan dan rantaian berkaitan sambil mengekalkan data pangkalan data', - cleanupBeforeBackendSwitch: - 'Bahagian belakang semasa {0} masih mengandungi peraturan masa jalan 1Panel. Tetapkan semula sebelum bertukar kepada {1}.', - cleanupAction: 'Tetapkan semula', - backendSwitchNotice: - 'Tetapkan semula bahagian belakang semasa sebelum menukar tembok api sistem, pemajuan port atau perlindungan Docker. Dasar pangkalan data dikekalkan dan boleh dimulakan atau disegerakkan selepas penukaran.', - switchBackendHelper: 'Tukar kepada {0}?', - switchDockerBackendHelper: 'Tukar kepada {0}? Ini akan mengemas kini konfigurasi dan memulakan semula Docker.', ruleSyncTitle: 'Segerakkan peraturan', ruleSyncAction: 'Segerakkan peraturan', - ruleSyncHelper: - 'Segerakkan peraturan yang diurus oleh 1Panel daripada tembok api terpilih ke tembok api semasa. Peraturan sumber tidak dipadam dan peraturan luaran tidak disertakan.', ruleSyncDatabase: 'Pangkalan data 1Panel', ruleSyncDatabaseHelper: 'Segerakkan dan selaraskan peraturan terurus dalam tembok api semasa berdasarkan peraturan pangkalan data 1Panel. Peraturan yang tiada akan ditambah dan peraturan berlebihan akan dipadam.', @@ -4219,7 +4201,6 @@ const message = { 'Segerakkan {1} supaya sepadan tepat dengan {0} peraturan pangkalan data? {2} peraturan sasaran akan dipadam dan peraturan yang tiada akan ditambah.', ruleSyncSource: 'Sumber konfigurasi', ruleSyncTarget: 'Bahagian belakang semasa', - ruleSyncTotal: 'Peraturan ditukar', ruleSyncReady: 'Sedia', ruleSyncExisting: 'Sedia ada', ruleSyncRemove: 'Untuk dipadam', @@ -4242,13 +4223,6 @@ const message = { protectedRule: 'Peraturan tembok api yang dilindungi ini tidak boleh diubah.', cannotReconcile: 'Peraturan sasaran tidak dapat disegerakkan: {0}', }, - ruleSyncConfirm: 'Segerakkan {0} peraturan daripada {1} ke {2}? Bahagian belakang sumber tidak akan diubah.', - ruleSyncResetSource: 'Tetapkan semula dan nyahdayakan tembok api sumber {0} selepas penyegerakan berjaya', - ruleSyncResetSourceHelper: 'Sumber hanya ditetapkan semula selepas semua peraturan berjaya disegerakkan.', - ruleSyncResetSourceBlocked: - 'Ada peraturan yang tidak dapat disegerakkan. Selesaikan dahulu sebelum menetapkan semula sumber.', - ruleSyncResetSourceConfirm: - 'Segerakkan {0} peraturan daripada {1} ke {2}, kemudian tetapkan semula dan nyahdayakan {1}? Semua konfigurasinya akan dipadam dan tidak boleh dibuat asal.', ruleSyncPartial: 'Penyegerakan selesai: {0} berjaya, {1} sudah wujud dan {2} gagal.', ruleSyncSuccess: 'Penyegerakan selesai: {0} berjaya, {1} sudah wujud dan {2} dipadam.', ruleSyncStatus: { @@ -4257,6 +4231,21 @@ const message = { remove: 'Untuk dipadam', blocked: 'Tidak tersedia', }, + resetDirectRulesHelper: + 'Padam rantaian, peraturan masa jalan dan fail berterusan tembok api sistem 1Panel daripada {0}; dasar pangkalan data yang disimpan dikekalkan', + resetWhitelistRulesHelper: + 'Tetapkan semula konfigurasi tersuai aktif dalam {0}, pulihkan tetapan pemasangan asal dan nyahdayakan {0}; dasar pangkalan data dikekalkan dan boleh disegerakkan semula.', + cleanupForwardingBackendHelper: + 'Tetapkan semula peraturan masa jalan pemajuan port 1Panel dalam {0}: padam semua peraturan dan rantaian berkaitan sambil mengekalkan data pangkalan data', + cleanupDockerBackendHelper: + 'Tetapkan semula peraturan masa jalan perlindungan port Docker 1Panel dalam {0}: padam semua peraturan dan rantaian berkaitan sambil mengekalkan data pangkalan data', + cleanupBeforeBackendSwitch: + 'Bahagian belakang semasa {0} masih mengandungi peraturan masa jalan 1Panel. Tetapkan semula sebelum bertukar kepada {1}.', + cleanupAction: 'Tetapkan semula', + backendSwitchNotice: + 'Tetapkan semula bahagian belakang semasa sebelum menukar tembok api sistem, pemajuan port atau perlindungan Docker. Dasar pangkalan data dikekalkan dan boleh dimulakan atau disegerakkan selepas penukaran.', + switchBackendHelper: 'Tukar kepada {0}?', + switchDockerBackendHelper: 'Tukar kepada {0}? Ini akan mengemas kini konfigurasi dan memulakan semula Docker.', uninstalledStatus: 'Belum dipasang', selectedBackendNotInstalled: 'Perkhidmatan {backend} tidak dikesan. Pasang secara manual daripada {library}, atau tukar backend firewall dalam {settings}.', @@ -4264,6 +4253,12 @@ const message = { partiallyInitialized: 'Dimulakan sebahagian', dockerGuardHelper: 'Tetapkan sekatan akses untuk port yang diterbitkan oleh bekas Docker pada hos. Port tanpa perlindungan mengekalkan tingkah laku akses lalai Docker.', + dockerTrafficPathMixed: 'Port yang dipilih menggunakan laluan akses berbeza. Tetapkannya secara berasingan.', + dockerTrafficPathUnknown: 'Laluan akses port ini tidak dapat ditentukan. Semak rangkaian Docker dan cuba lagi.', + dockerTrafficPathPending: 'Laluan akses belum ditentukan', + dockerInputPolicyNotEffective: + 'Port ini diterima terus oleh hos, jadi peraturan perlindungan port bekas sedia ada tidak digunakan. Tetapkannya dalam firewall hos.', + dockerInputUseHostFirewall: 'Konfigurasikan akses port ini dalam tembok api hos.', dockerInputNotProtected: 'Peraturan INPUT hos tidak melindungi port terbitan Docker ini secara langsung. Klik untuk membuka perlindungan port bekas.', notInitialized: 'Belum dimulakan', @@ -4294,9 +4289,7 @@ const message = { 'Peraturan yang dipilih mempunyai konfigurasi berbeza. Tetapkan semula untuk menulis ganti semuanya; keterangan kosong akan mengosongkan semua keterangan.', effective: 'Berkuat kuasa', forwardUnsynced: 'Belum disegerak', - notEnabled: 'Tidak didayakan', notEffective: 'Tidak berkuat kuasa', - dockerGuardStatusEffective: 'Perlindungan port bekas {0} berfungsi seperti biasa', dockerGuardStatusReason: { command_missing: 'Komponen firewall {0} tidak tersedia, jadi perlindungan berkaitan tidak boleh didayakan. Semak firewall sistem', @@ -4322,8 +4315,6 @@ const message = { importSuccess: '{0} peraturan berjaya diimport', importPartialSuccess: 'Import selesai: {0} berjaya, {1} gagal', basicStatus: 'Firewall semasa tidak terikat. Sila ikat dahulu.', - baseIptables: 'Perkhidmatan iptables', - forwardIptables: 'Perkhidmatan Penerusan Port iptables', initMsg: 'Akan memulakan {0}, teruskan?', initDirectBackendConflictMsg: '{1} masih terikat. Jika {0} dimulakan, kedua-dua set peraturan firewall akan aktif dan mungkin menyekat akses tanpa dijangka. Teruskan?', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index f656dd7e8..e231b4969 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -4208,28 +4208,10 @@ const message = { configuredRules: '{0} regras configuradas', addressFamily: 'Versão do IP', portOrRange: 'Porta / intervalo', - exportAllRules: 'Exportar todas as regras', importBackendHelper: 'As regras importadas são convertidas para o backend atual {0}. As regras de origem não são alteradas.', - resetDirectRulesHelper: - 'Exclua de {0} as cadeias, regras em execução e arquivos persistentes do firewall do 1Panel; as políticas salvas no banco são mantidas', - resetWhitelistRulesHelper: - 'Redefina a configuração personalizada ativa em {0}, restaure os padrões de instalação e desative {0}; as políticas do banco são mantidas e podem ser sincronizadas novamente.', - cleanupForwardingBackendHelper: - 'Redefina as regras de execução de encaminhamento de portas do 1Panel em {0}: exclua todas as regras e cadeias relacionadas e mantenha os dados do banco de dados', - cleanupDockerBackendHelper: - 'Redefina as regras de execução de proteção de portas Docker do 1Panel em {0}: exclua todas as regras e cadeias relacionadas e mantenha os dados do banco de dados', - cleanupBeforeBackendSwitch: - 'O backend atual {0} ainda contém regras de execução do 1Panel. Redefina-o antes de mudar para {1}.', - cleanupAction: 'Redefinir', - backendSwitchNotice: - 'Redefina o backend atual antes de trocar o firewall do sistema, o encaminhamento de portas ou a proteção Docker. As políticas do banco são mantidas e podem ser inicializadas ou sincronizadas após a troca.', - switchBackendHelper: 'Mudar para {0}?', - switchDockerBackendHelper: 'Mudar para {0}? Isso atualizará a configuração e reiniciará o Docker.', ruleSyncTitle: 'Sincronizar regras', ruleSyncAction: 'Sincronizar regras', - ruleSyncHelper: - 'Sincroniza as regras gerenciadas pelo 1Panel do firewall selecionado para o firewall atual. As regras de origem não são excluídas e regras externas não são incluídas.', ruleSyncDatabase: 'Banco de dados do 1Panel', ruleSyncDatabaseHelper: 'Sincroniza e ajusta as regras gerenciadas no firewall atual com base nas regras do banco de dados do 1Panel. As regras ausentes serão adicionadas e as excedentes serão removidas.', @@ -4238,7 +4220,6 @@ const message = { 'Sincronizar {1} para corresponder exatamente às {0} regras do banco de dados? {2} regras do destino serão removidas e as ausentes serão adicionadas.', ruleSyncSource: 'Fonte da configuração', ruleSyncTarget: 'Backend atual', - ruleSyncTotal: 'Regras convertidas', ruleSyncReady: 'Prontas', ruleSyncExisting: 'Existentes', ruleSyncRemove: 'A remover', @@ -4261,14 +4242,6 @@ const message = { protectedRule: 'Esta regra protegida do firewall não pode ser modificada.', cannotReconcile: 'Não foi possível sincronizar a regra de destino: {0}', }, - ruleSyncConfirm: 'Sincronizar {0} regras de {1} para {2}? O backend de origem não será alterado.', - ruleSyncResetSource: 'Redefinir e desativar o firewall de origem {0} após a sincronização', - ruleSyncResetSourceHelper: - 'A origem só será redefinida depois que todas as regras forem sincronizadas com sucesso.', - ruleSyncResetSourceBlocked: - 'Algumas regras não podem ser sincronizadas. Resolva-as antes de redefinir a origem.', - ruleSyncResetSourceConfirm: - 'Sincronizar {0} regras de {1} para {2} e depois redefinir e desativar {1}? Toda a configuração será removida e não poderá ser recuperada.', ruleSyncPartial: 'Sincronização concluída: {0} com sucesso, {1} já existiam e {2} falharam.', ruleSyncSuccess: 'Sincronização concluída: {0} com sucesso, {1} já existiam e {2} removidas.', ruleSyncStatus: { @@ -4277,6 +4250,21 @@ const message = { remove: 'A remover', blocked: 'Indisponível', }, + resetDirectRulesHelper: + 'Exclua de {0} as cadeias, regras em execução e arquivos persistentes do firewall do 1Panel; as políticas salvas no banco são mantidas', + resetWhitelistRulesHelper: + 'Redefina a configuração personalizada ativa em {0}, restaure os padrões de instalação e desative {0}; as políticas do banco são mantidas e podem ser sincronizadas novamente.', + cleanupForwardingBackendHelper: + 'Redefina as regras de execução de encaminhamento de portas do 1Panel em {0}: exclua todas as regras e cadeias relacionadas e mantenha os dados do banco de dados', + cleanupDockerBackendHelper: + 'Redefina as regras de execução de proteção de portas Docker do 1Panel em {0}: exclua todas as regras e cadeias relacionadas e mantenha os dados do banco de dados', + cleanupBeforeBackendSwitch: + 'O backend atual {0} ainda contém regras de execução do 1Panel. Redefina-o antes de mudar para {1}.', + cleanupAction: 'Redefinir', + backendSwitchNotice: + 'Redefina o backend atual antes de trocar o firewall do sistema, o encaminhamento de portas ou a proteção Docker. As políticas do banco são mantidas e podem ser inicializadas ou sincronizadas após a troca.', + switchBackendHelper: 'Mudar para {0}?', + switchDockerBackendHelper: 'Mudar para {0}? Isso atualizará a configuração e reiniciará o Docker.', uninstalledStatus: 'Não instalado', selectedBackendNotInstalled: 'O serviço {backend} não foi detectado. Instale-o manualmente pela {library} ou altere o backend do firewall em {settings}.', @@ -4284,6 +4272,14 @@ const message = { partiallyInitialized: 'Parcialmente inicializado', dockerGuardHelper: 'Configure restrições de acesso para as portas publicadas pelos contêineres Docker no host. Portas sem proteção mantêm o acesso padrão do Docker.', + dockerTrafficPathMixed: + 'As portas selecionadas usam caminhos de acesso diferentes. Configure-as separadamente.', + dockerTrafficPathUnknown: + 'Não foi possível determinar o caminho de acesso desta porta. Verifique a rede do Docker e tente novamente.', + dockerTrafficPathPending: 'Caminho de acesso pendente', + dockerInputPolicyNotEffective: + 'O host recebe esta porta diretamente, portanto a regra de proteção da porta do contêiner não se aplica. Configure-a no firewall do host.', + dockerInputUseHostFirewall: 'Configure o acesso a esta porta no firewall do host.', dockerInputNotProtected: 'As regras INPUT do host não protegem diretamente esta porta publicada pelo Docker. Clique para abrir a proteção de portas de contêineres.', notInitialized: 'Não inicializado', @@ -4314,9 +4310,7 @@ const message = { 'As regras selecionadas têm configurações diferentes. Configure-as novamente para substituir todas; uma descrição vazia limpará todas as descrições.', effective: 'Em vigor', forwardUnsynced: 'Não sincronizado', - notEnabled: 'Não habilitado', notEffective: 'Sem efeito', - dockerGuardStatusEffective: 'A proteção de portas de contêineres {0} está funcionando normalmente', dockerGuardStatusReason: { command_missing: 'O componente de firewall {0} não está disponível e a proteção correspondente não pode ser habilitada. Verifique o firewall do sistema', @@ -4343,8 +4337,6 @@ const message = { importSuccess: '{0} regras importadas com sucesso', importPartialSuccess: 'Importação concluída: {0} sucesso, {1} falha', basicStatus: 'O firewall atual não está vinculado. Vincule-o primeiro.', - baseIptables: 'Serviço iptables', - forwardIptables: 'Serviço de Encaminhamento de Porta iptables', initMsg: 'Prestes a inicializar {0}, continuar?', initDirectBackendConflictMsg: '{1} ainda está vinculado. Se {0} for inicializado, os dois conjuntos de regras ficarão ativos e poderão bloquear o acesso inesperadamente. Continuar?', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index d5197536e..d4ecd281a 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -4175,28 +4175,10 @@ const message = { configuredRules: 'Настроено правил: {0}', addressFamily: 'Версия IP', portOrRange: 'Порт / диапазон', - exportAllRules: 'Экспортировать все правила', importBackendHelper: 'Импортируемые правила преобразуются для текущего бэкенда {0}. Исходные правила не изменяются.', - resetDirectRulesHelper: - 'Удалить из {0} системные цепочки, действующие правила и постоянные файлы 1Panel; политики в базе данных сохраняются', - resetWhitelistRulesHelper: - 'Сбросить активную пользовательскую конфигурацию {0}, восстановить исходные настройки и отключить {0}; политики базы данных сохраняются и могут быть синхронизированы повторно.', - cleanupForwardingBackendHelper: - 'Сбросить правила времени выполнения переадресации портов 1Panel в {0}: удалить все связанные правила и цепочки, сохранив данные в базе данных', - cleanupDockerBackendHelper: - 'Сбросить правила времени выполнения защиты портов Docker 1Panel в {0}: удалить все связанные правила и цепочки, сохранив данные в базе данных', - cleanupBeforeBackendSwitch: - 'Текущий бэкенд {0} всё ещё содержит правила времени выполнения 1Panel. Сбросьте его перед переключением на {1}.', - cleanupAction: 'Сбросить', - backendSwitchNotice: - 'Перед переключением системного брандмауэра, переадресации портов или защиты Docker сбросьте текущий бэкенд. Политики базы данных сохраняются и могут быть инициализированы или синхронизированы после переключения.', - switchBackendHelper: 'Переключиться на {0}?', - switchDockerBackendHelper: 'Переключиться на {0}? Конфигурация Docker будет обновлена, а Docker перезапущен.', ruleSyncTitle: 'Синхронизация правил', ruleSyncAction: 'Синхронизировать правила', - ruleSyncHelper: - 'Синхронизирует правила 1Panel из выбранного брандмауэра с текущим. Исходные правила не удаляются, а внешние правила не синхронизируются.', ruleSyncDatabase: 'База данных 1Panel', ruleSyncDatabaseHelper: 'Синхронизирует и приводит управляемые правила текущего межсетевого экрана в соответствие с правилами из базы данных 1Panel. Недостающие правила будут добавлены, а лишние — удалены.', @@ -4205,7 +4187,6 @@ const message = { 'Синхронизировать {1} в точном соответствии с {0} правилами базы данных? Будет удалено {2} правил на целевой стороне, а недостающие будут добавлены.', ruleSyncSource: 'Источник конфигурации', ruleSyncTarget: 'Текущий бэкенд', - ruleSyncTotal: 'Преобразованные правила', ruleSyncReady: 'Готово', ruleSyncExisting: 'Уже существует', ruleSyncRemove: 'К удалению', @@ -4228,12 +4209,6 @@ const message = { protectedRule: 'Это защищённое правило брандмауэра нельзя изменить.', cannotReconcile: 'Не удалось синхронизировать целевое правило: {0}', }, - ruleSyncConfirm: 'Синхронизировать {0} правил из {1} в {2}? Исходный бэкенд не будет изменён.', - ruleSyncResetSource: 'После синхронизации сбросить и отключить исходный брандмауэр {0}', - ruleSyncResetSourceHelper: 'Источник сбрасывается только после успешной синхронизации всех правил.', - ruleSyncResetSourceBlocked: 'Некоторые правила нельзя синхронизировать. Сначала устраните проблемы.', - ruleSyncResetSourceConfirm: - 'Синхронизировать {0} правил из {1} в {2}, затем сбросить и отключить {1}? Вся его конфигурация будет удалена без возможности восстановления.', ruleSyncPartial: 'Синхронизация завершена: успешно — {0}, уже существовало — {1}, ошибок — {2}.', ruleSyncSuccess: 'Синхронизация завершена: успешно — {0}, уже существовало — {1}, удалено — {2}.', ruleSyncStatus: { @@ -4242,6 +4217,21 @@ const message = { remove: 'К удалению', blocked: 'Недоступно', }, + resetDirectRulesHelper: + 'Удалить из {0} системные цепочки, действующие правила и постоянные файлы 1Panel; политики в базе данных сохраняются', + resetWhitelistRulesHelper: + 'Сбросить активную пользовательскую конфигурацию {0}, восстановить исходные настройки и отключить {0}; политики базы данных сохраняются и могут быть синхронизированы повторно.', + cleanupForwardingBackendHelper: + 'Сбросить правила времени выполнения переадресации портов 1Panel в {0}: удалить все связанные правила и цепочки, сохранив данные в базе данных', + cleanupDockerBackendHelper: + 'Сбросить правила времени выполнения защиты портов Docker 1Panel в {0}: удалить все связанные правила и цепочки, сохранив данные в базе данных', + cleanupBeforeBackendSwitch: + 'Текущий бэкенд {0} всё ещё содержит правила времени выполнения 1Panel. Сбросьте его перед переключением на {1}.', + cleanupAction: 'Сбросить', + backendSwitchNotice: + 'Перед переключением системного брандмауэра, переадресации портов или защиты Docker сбросьте текущий бэкенд. Политики базы данных сохраняются и могут быть инициализированы или синхронизированы после переключения.', + switchBackendHelper: 'Переключиться на {0}?', + switchDockerBackendHelper: 'Переключиться на {0}? Конфигурация Docker будет обновлена, а Docker перезапущен.', uninstalledStatus: 'Не установлено', selectedBackendNotInstalled: 'Служба {backend} не обнаружена. Установите её вручную из {library} или переключите бэкенд межсетевого экрана в разделе {settings}.', @@ -4249,6 +4239,13 @@ const message = { partiallyInitialized: 'Частично инициализировано', dockerGuardHelper: 'Настройте ограничения доступа к портам, опубликованным контейнерами Docker на хосте. Незащищенные порты сохраняют стандартный режим доступа Docker.', + dockerTrafficPathMixed: 'Выбранные порты используют разные пути доступа. Настройте их отдельно.', + dockerTrafficPathUnknown: + 'Не удалось определить путь доступа к этому порту. Проверьте сеть Docker и повторите попытку.', + dockerTrafficPathPending: 'Путь доступа не определён', + dockerInputPolicyNotEffective: + 'Хост принимает этот порт напрямую, поэтому существующее правило защиты порта контейнера не применяется. Настройте его в межсетевом экране хоста.', + dockerInputUseHostFirewall: 'Настройте доступ к этому порту в межсетевом экране хоста.', dockerInputNotProtected: 'Правила INPUT хоста не защищают этот опубликованный Docker-порт напрямую. Нажмите, чтобы открыть защиту портов контейнеров.', notInitialized: 'Не инициализировано', @@ -4280,9 +4277,7 @@ const message = { 'Выбранные правила имеют разные настройки. Задайте их заново, чтобы перезаписать все; пустое описание очистит описания у всех правил.', effective: 'Действует', forwardUnsynced: 'Не синхронизировано', - notEnabled: 'Не включено', notEffective: 'Не действует', - dockerGuardStatusEffective: 'Защита портов контейнеров {0} работает нормально', dockerGuardStatusReason: { command_missing: 'Компонент межсетевого экрана {0} недоступен, поэтому соответствующую защиту нельзя включить. Проверьте системный межсетевой экран', @@ -4309,8 +4304,6 @@ const message = { importSuccess: 'Успешно импортировано {0} правил', importPartialSuccess: 'Импорт завершён: {0} успешно, {1} с ошибкой', basicStatus: 'Текущий межсетевой экран не привязан. Сначала привяжите его.', - baseIptables: 'Сервис iptables', - forwardIptables: 'Сервис Переадресации Порта iptables', initMsg: 'Собираюсь инициализировать {0}, продолжить?', initDirectBackendConflictMsg: '{1} всё ещё привязан. После инициализации {0} оба набора правил будут активны и могут неожиданно заблокировать доступ. Продолжить?', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index 0815350e0..537a4eb5b 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -4188,29 +4188,10 @@ const message = { configuredRules: '{0} kural yapılandırıldı', addressFamily: 'IP sürümü', portOrRange: 'Port / aralık', - exportAllRules: 'Tüm kuralları dışa aktar', importBackendHelper: 'İçe aktarılan kurallar geçerli {0} arka ucu için dönüştürülür. Kaynak kurallar değiştirilmez.', - resetDirectRulesHelper: - '{0} içindeki 1Panel sistem güvenlik duvarı zincirlerini, çalışma zamanı kurallarını ve kalıcı dosyaları silin; veritabanı ilkelerini koruyun', - resetWhitelistRulesHelper: - '{0} içindeki etkin özel yapılandırmayı sıfırlayın, kurulum varsayılanlarını geri yükleyin ve {0} öğesini devre dışı bırakın; veritabanı ilkeleri korunur ve yeniden eşitlenebilir.', - cleanupForwardingBackendHelper: - '{0} içindeki 1Panel bağlantı noktası yönlendirme çalışma zamanı kurallarını sıfırlayın: ilgili tüm kuralları ve zincirleri silip veritabanı verilerini koruyun', - cleanupDockerBackendHelper: - '{0} içindeki 1Panel Docker bağlantı noktası koruma çalışma zamanı kurallarını sıfırlayın: ilgili tüm kuralları ve zincirleri silip veritabanı verilerini koruyun', - cleanupBeforeBackendSwitch: - 'Mevcut {0} arka ucu hâlâ 1Panel çalışma zamanı kuralları içeriyor. {1} arka ucuna geçmeden önce sıfırlayın.', - cleanupAction: 'Sıfırla', - backendSwitchNotice: - 'Sistem güvenlik duvarı, bağlantı noktası yönlendirme veya Docker korumasını değiştirmeden önce mevcut arka ucu sıfırlayın. Veritabanı ilkeleri korunur ve geçişten sonra yeniden başlatılabilir veya eşitlenebilir.', - switchBackendHelper: '{0} arka ucuna geçilsin mi?', - switchDockerBackendHelper: - '{0} arka ucuna geçilsin mi? Docker yapılandırması güncellenecek ve Docker yeniden başlatılacak.', ruleSyncTitle: 'Kuralları eşitle', ruleSyncAction: 'Kuralları eşitle', - ruleSyncHelper: - 'Seçilen güvenlik duvarındaki 1Panel yönetimli kuralları mevcut güvenlik duvarıyla eşitler. Kaynak kurallar silinmez ve harici kurallar eşitlenmez.', ruleSyncDatabase: '1Panel veritabanı', ruleSyncDatabaseHelper: 'Mevcut güvenlik duvarındaki yönetilen kuralları 1Panel veritabanı kurallarına göre eşitler ve uyumlu hale getirir. Eksik kurallar eklenir, fazla kurallar silinir.', @@ -4219,7 +4200,6 @@ const message = { '{1}, {0} veritabanı kuralıyla tam olarak eşleşecek şekilde eşitlensin mi? Hedefteki {2} kural silinecek ve eksik kurallar eklenecektir.', ruleSyncSource: 'Yapılandırma kaynağı', ruleSyncTarget: 'Mevcut arka uç', - ruleSyncTotal: 'Dönüştürülen kurallar', ruleSyncReady: 'Hazır', ruleSyncExisting: 'Mevcut', ruleSyncRemove: 'Silinecek', @@ -4242,12 +4222,6 @@ const message = { protectedRule: 'Bu korumalı güvenlik duvarı kuralı değiştirilemez.', cannotReconcile: 'Hedef kural eşitlenemiyor: {0}', }, - ruleSyncConfirm: '{0} kural {1} arka ucundan {2} arka ucuna eşitlensin mi? Kaynak arka uç değiştirilmez.', - ruleSyncResetSource: 'Eşitleme başarılı olunca kaynak güvenlik duvarı {0} sıfırlansın ve devre dışı bırakılsın', - ruleSyncResetSourceHelper: 'Kaynak yalnızca tüm kurallar başarıyla eşitlendikten sonra sıfırlanır.', - ruleSyncResetSourceBlocked: 'Bazı kurallar eşitlenemiyor. Kaynağı sıfırlamadan önce bunları çözün.', - ruleSyncResetSourceConfirm: - '{0} kural {1} üzerinden {2} üzerine eşitlenip ardından {1} sıfırlansın ve devre dışı bırakılsın mı? Tüm yapılandırma silinir ve geri alınamaz.', ruleSyncPartial: 'Eşitleme tamamlandı: {0} başarılı, {1} zaten mevcut, {2} başarısız.', ruleSyncSuccess: 'Eşitleme tamamlandı: {0} başarılı, {1} zaten mevcut, {2} silindi.', ruleSyncStatus: { @@ -4256,6 +4230,22 @@ const message = { remove: 'Silinecek', blocked: 'Kullanılamaz', }, + resetDirectRulesHelper: + '{0} içindeki 1Panel sistem güvenlik duvarı zincirlerini, çalışma zamanı kurallarını ve kalıcı dosyaları silin; veritabanı ilkelerini koruyun', + resetWhitelistRulesHelper: + '{0} içindeki etkin özel yapılandırmayı sıfırlayın, kurulum varsayılanlarını geri yükleyin ve {0} öğesini devre dışı bırakın; veritabanı ilkeleri korunur ve yeniden eşitlenebilir.', + cleanupForwardingBackendHelper: + '{0} içindeki 1Panel bağlantı noktası yönlendirme çalışma zamanı kurallarını sıfırlayın: ilgili tüm kuralları ve zincirleri silip veritabanı verilerini koruyun', + cleanupDockerBackendHelper: + '{0} içindeki 1Panel Docker bağlantı noktası koruma çalışma zamanı kurallarını sıfırlayın: ilgili tüm kuralları ve zincirleri silip veritabanı verilerini koruyun', + cleanupBeforeBackendSwitch: + 'Mevcut {0} arka ucu hâlâ 1Panel çalışma zamanı kuralları içeriyor. {1} arka ucuna geçmeden önce sıfırlayın.', + cleanupAction: 'Sıfırla', + backendSwitchNotice: + 'Sistem güvenlik duvarı, bağlantı noktası yönlendirme veya Docker korumasını değiştirmeden önce mevcut arka ucu sıfırlayın. Veritabanı ilkeleri korunur ve geçişten sonra yeniden başlatılabilir veya eşitlenebilir.', + switchBackendHelper: '{0} arka ucuna geçilsin mi?', + switchDockerBackendHelper: + '{0} arka ucuna geçilsin mi? Docker yapılandırması güncellenecek ve Docker yeniden başlatılacak.', uninstalledStatus: 'Yüklü değil', selectedBackendNotInstalled: '{backend} hizmeti algılanmadı. {library} üzerinden manuel olarak yükleyin veya {settings} bölümünden güvenlik duvarı arka ucunu değiştirin.', @@ -4263,6 +4253,13 @@ const message = { partiallyInitialized: 'Kısmen başlatıldı', dockerGuardHelper: 'Docker konteynerlerinin ana makinede yayımladığı portlar için erişim kısıtlamaları ayarlayın. Korunmayan portlar Docker varsayılan erişim davranışını korur.', + dockerTrafficPathMixed: 'Seçilen portlar farklı erişim yolları kullanıyor. Bunları ayrı ayrı yapılandırın.', + dockerTrafficPathUnknown: + 'Bu portun erişim yolu belirlenemedi. Docker ağ yapılandırmasını kontrol edip tekrar deneyin.', + dockerTrafficPathPending: 'Erişim yolu bekleniyor', + dockerInputPolicyNotEffective: + 'Bu port doğrudan ana makine tarafından alındığından mevcut konteyner port koruma kuralı uygulanmaz. Ana makine güvenlik duvarında yapılandırın.', + dockerInputUseHostFirewall: 'Bu bağlantı noktasına erişimi ana makine güvenlik duvarında yapılandırın.', dockerInputNotProtected: 'Ana makine INPUT kuralları bu Docker yayımlanmış portunu doğrudan korumaz. Konteyner portu korumasını açmak için tıklayın.', notInitialized: 'Başlatılmadı', @@ -4294,9 +4291,7 @@ const message = { 'Seçili kuralların yapılandırmaları farklı. Tümünün üzerine yazmak için yeniden ayarlayın; açıklamanın boş bırakılması tüm açıklamaları temizler.', effective: 'Etkin', forwardUnsynced: 'Senkronize değil', - notEnabled: 'Etkin değil', notEffective: 'Uygulanmıyor', - dockerGuardStatusEffective: '{0} konteyner portu koruması normal çalışıyor', dockerGuardStatusReason: { command_missing: '{0} güvenlik duvarı bileşeni kullanılamıyor, bu nedenle ilgili koruma etkinleştirilemiyor. Sistem güvenlik duvarını kontrol edin', @@ -4321,8 +4316,6 @@ const message = { importSuccess: '{0} kural başarıyla içe aktarıldı', importPartialSuccess: 'İçe aktarma tamamlandı: {0} başarılı, {1} başarısız', basicStatus: 'Mevcut güvenlik duvarı bağlı değil. Önce bağlayın.', - baseIptables: 'iptables Servisi', - forwardIptables: 'iptables Port Yönlendirme Servisi', initMsg: '{0} başlatılmak üzere, devam etmek istiyor musunuz?', initDirectBackendConflictMsg: '{1} hâlâ bağlı. {0} başlatılırsa iki güvenlik duvarı kural kümesi de etkin olur ve erişimi beklenmedik şekilde engelleyebilir. Devam edilsin mi?', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index a6d8295f0..6c6876e4e 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -3850,24 +3850,9 @@ const message = { configuredRules: '已設定 {0} 條規則', addressFamily: 'IP 版本', portOrRange: '連接埠 / 範圍', - exportAllRules: '匯出全部規則', importBackendHelper: '匯入規則會轉換並寫入目前後端 {0},來源後端規則不會被修改。', - resetDirectRulesHelper: '刪除 {0} 中全部 1Panel 系統防火牆鏈、執行規則及持久化檔案,保留資料庫策略', - resetWhitelistRulesHelper: - '重設 {0} 中目前生效的自訂防火牆設定,恢復安裝預設狀態並停用 {0};資料庫策略會保留,之後可重新同步。', - cleanupForwardingBackendHelper: - '重設 {0} 中的 1Panel 連接埠轉送執行時規則:刪除全部相關規則及規則鏈,僅保留資料庫資料', - cleanupDockerBackendHelper: - '重設 {0} 中的 1Panel Docker 連接埠防護執行時規則:刪除全部相關規則及規則鏈,僅保留資料庫資料', - cleanupBeforeBackendSwitch: '目前後端 {0} 仍存在 1Panel 執行時規則,請先重設該後端,再切換到 {1}。', - cleanupAction: '重設', - backendSwitchNotice: - '主機防火牆、連接埠轉送和 Docker 防護切換前都必須先重設目前後端;資料庫策略會保留,切換後可重新初始化或同步。', - switchBackendHelper: '確認切換為 {0}?', - switchDockerBackendHelper: '確認切換為 {0}?此操作會更新 Docker 設定並重新啟動 Docker 服務。', ruleSyncTitle: '同步規則', ruleSyncAction: '同步規則', - ruleSyncHelper: '將所選防火牆中由 1Panel 管理的規則同步至目前防火牆。原規則不會刪除,外部規則不會同步。', ruleSyncDatabase: '1Panel 資料庫', ruleSyncDatabaseHelper: '以 1Panel 資料庫規則為準,同步並校準目前防火牆中的管理規則。缺少的規則會被新增,多餘的規則會被刪除。', @@ -3876,7 +3861,6 @@ const message = { '即將以資料庫中的 {0} 條規則覆蓋同步 {1};將刪除 {2} 條目標規則,並補上缺少的規則。是否繼續?', ruleSyncSource: '設定來源', ruleSyncTarget: '目前後端', - ruleSyncTotal: '轉換後規則', ruleSyncReady: '可同步', ruleSyncExisting: '已存在', ruleSyncRemove: '待刪除', @@ -3898,12 +3882,6 @@ const message = { protectedRule: '此防火牆規則受保護,無法修改。', cannotReconcile: '無法同步目標規則:{0}', }, - ruleSyncConfirm: '即將把 {0} 條規則從 {1} 同步至 {2},來源後端不會被修改。是否繼續?', - ruleSyncResetSource: '同步成功後重設並停用來源防火牆 {0}', - ruleSyncResetSourceHelper: '僅在全部規則同步成功後重設來源防火牆,此操作無法復原。', - ruleSyncResetSourceBlocked: '存在無法同步的規則,請先處理後再自動重設來源防火牆。', - ruleSyncResetSourceConfirm: - '即將把 {0} 條規則從 {1} 同步至 {2},成功後重設並停用 {1}。這會刪除 {1} 的全部防火牆設定且無法復原,是否繼續?', ruleSyncPartial: '同步完成:成功 {0} 條,已存在 {1} 條,失敗 {2} 條。', ruleSyncSuccess: '同步完成:成功 {0} 條,已存在 {1} 條,刪除 {2} 條。', ruleSyncStatus: { @@ -3912,12 +3890,30 @@ const message = { remove: '待刪除', blocked: '不可同步', }, + resetDirectRulesHelper: '刪除 {0} 中全部 1Panel 系統防火牆鏈、執行規則及持久化檔案,保留資料庫策略', + resetWhitelistRulesHelper: + '重設 {0} 中目前生效的自訂防火牆設定,恢復安裝預設狀態並停用 {0};資料庫策略會保留,之後可重新同步。', + cleanupForwardingBackendHelper: + '重設 {0} 中的 1Panel 連接埠轉送執行時規則:刪除全部相關規則及規則鏈,僅保留資料庫資料', + cleanupDockerBackendHelper: + '重設 {0} 中的 1Panel Docker 連接埠防護執行時規則:刪除全部相關規則及規則鏈,僅保留資料庫資料', + cleanupBeforeBackendSwitch: '目前後端 {0} 仍存在 1Panel 執行時規則,請先重設該後端,再切換到 {1}。', + cleanupAction: '重設', + backendSwitchNotice: + '主機防火牆、連接埠轉送和 Docker 防護切換前都必須先重設目前後端;資料庫策略會保留,切換後可重新初始化或同步。', + switchBackendHelper: '確認切換為 {0}?', + switchDockerBackendHelper: '確認切換為 {0}?此操作會更新 Docker 設定並重新啟動 Docker 服務。', uninstalledStatus: '未安裝', selectedBackendNotInstalled: '未偵測到 {backend} 服務,請前往{library}頁面手動安裝,或在{settings}中切換防火牆後端。', initializedStatus: '已初始化', partiallyInitialized: '部分初始化', dockerGuardHelper: '為 Docker 容器發佈到主機的連接埠設定存取限制;未設定防護的連接埠維持 Docker 預設存取方式。', + dockerTrafficPathMixed: '所選連接埠使用不同的存取方式,請分別設定。', + dockerTrafficPathUnknown: '暫時無法確認此連接埠的存取方式,請檢查 Docker 網路設定後重試。', + dockerTrafficPathPending: '存取方式待確認', + dockerInputPolicyNotEffective: '此連接埠由主機直接接收,現有容器連接埠防護規則不會生效,請改用主機防火牆設定。', + dockerInputUseHostFirewall: '此連接埠需要透過主機防火牆設定存取規則,請前往主機防火牆進行設定。', dockerInputNotProtected: '主機 INPUT 規則無法直接保護此 Docker 發佈連接埠,點擊前往容器連接埠防護。', notInitialized: '未初始化', familyUnsupported: '系統不支援 {0}', @@ -3944,9 +3940,7 @@ const message = { dockerGuardInconsistentConfigHelper: '所選規則設定不一致,請重新設定;提交後將統一覆寫,空白描述將統一清除。', effective: '已生效', forwardUnsynced: '未同步', - notEnabled: '未啟用', notEffective: '未生效', - dockerGuardStatusEffective: '{0} 容器連接埠防護運作正常', dockerGuardStatusReason: { command_missing: '系統缺少 {0} 防火牆元件,對應的容器連接埠防護暫時無法使用,請檢查系統防火牆環境', docker_chain_missing: @@ -3969,8 +3963,6 @@ const message = { importSuccess: '成功匯入 {0} 條規則', importPartialSuccess: '匯入完成:成功 {0} 條,失敗 {1} 條', basicStatus: '目前防火牆尚未綁定,請先綁定', - baseIptables: 'iptables 服務', - forwardIptables: 'iptables 埠轉發服務', initMsg: '即將初始化 {0}, 是否繼續?', initDirectBackendConflictMsg: '偵測到 {1} 仍處於綁定狀態。繼續初始化 {0} 後,兩套防火牆規則將同時生效,可能導致存取被意外阻擋。是否繼續?', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 21a45b8c1..0de0f5432 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -3858,11 +3858,13 @@ const message = { ruleCheckReadyHelper: '检查通过,可以创建该规则。', ruleCheckExternalExists: '系统中已有相同的外部规则,本次将自动跳过。', ruleCheckBlockedHelper: '存在错误规则,不能提交。请返回修改后重新检查。', - plan_managed_rule_drifted: '1Panel 管理记录与系统实际规则不一致,请检查系统规则。', - plan_opaque_rule_in_target_scope: '目标范围内存在无法安全解析的规则,本次操作已停止。', - plan_runtime_permanent_mismatch: '防火墙运行配置与永久配置不一致,请先完成同步。', + plan_managed_rule_drifted: + '这条规则在 1Panel 中的记录与防火墙实际状态不一致,请先刷新规则;如仍异常,请重新同步。', + plan_opaque_rule_in_target_scope: + '当前防火墙中存在 1Panel 暂不支持的规则。为避免影响现有访问,本次未创建。请返回规则列表,查看内容无法完整显示的“外部规则”,并在系统防火墙中处理后重试。', + plan_runtime_permanent_mismatch: '当前生效的防火墙规则与重启后保留的规则不一致,请先同步后重试。', plan_protected_rule: '该规则受到保护,不能认领、修改或删除。', - plan_blocked: '当前规则无法安全应用,请刷新规则后重试。', + plan_blocked: '暂时无法处理这条规则,本次操作未生效。请刷新后重试;如仍失败,请检查规则状态。', scopeDefaultMismatch: '系统默认 zone 为 {0},当前页面仅管理 public zone。', scopeInactive: '当前托管范围未激活,新增规则可能不会作用于现有流量。', scopeMissing: '托管范围 {0} 尚未创建,应用首条规则时将以安全方式创建。', @@ -3878,13 +3880,13 @@ const message = { enableBanPing: '禁 ping', disableBanPing: '解除禁 ping', stop: '禁止', - portFormatError: '请输入正确的端口信息!', + portFormatError: '请输入有效的端口或端口范围', accept: '允许', drop: '拒绝', anyWhere: '任何位置', allow: '放行', deny: '屏蔽', - addressFormatError: '请输入合法的 ip 地址!', + addressFormatError: '请输入有效的 IP 地址', forwardRule: '端口转发', dockerGuard: '容器端口防护', systemFirewall: '主机防火墙', @@ -3896,11 +3898,9 @@ const message = { configuredRules: '已配置 {0} 条规则', addressFamily: 'IP 版本', portOrRange: '端口 / 范围', - exportAllRules: '导出全部规则', importBackendHelper: '导入规则会转换并写入当前后端 {0},源后端规则不会被修改。', ruleSyncTitle: '同步规则', ruleSyncAction: '同步规则', - ruleSyncHelper: '将所选防火墙中由 1Panel 管理的规则同步到当前防火墙。原规则不会删除,外部规则不会同步。', ruleSyncDatabase: '1Panel 数据库', ruleSyncDatabaseHelper: '以 1Panel 数据库规则为准,同步并校准当前防火墙中的管理规则。缺失规则会被添加,多余规则会被删除。', @@ -3909,34 +3909,28 @@ const message = { '即将以数据库中的 {0} 条规则覆盖同步 {1};将删除 {2} 条目标规则,并补充缺失规则。是否继续?', ruleSyncSource: '配置来源', ruleSyncTarget: '当前后端', - ruleSyncTotal: '转换后规则', ruleSyncReady: '可同步', ruleSyncExisting: '已存在', ruleSyncRemove: '待删除', ruleSyncBlocked: '不可同步', ruleSyncReason: '检查结果', ruleSyncReasonDetail: { - matchesDatabasePolicy: '该规则已与数据库策略一致。', - managedOrderDiffers: '受管规则顺序与数据库顺序不一致。', - managedOnlyInTarget: '该受管规则仅存在于目标防火墙中。', - managedRuntimeCannotRemove: '无法安全删除该受管运行时规则。', - managedOrderBlocked: '受管规则的排序不能跨越外部、无法识别或受保护的规则。', - mayBlockManagement: '该规则可能会阻断当前管理连接。', - missingFromTarget: '目标防火墙中缺少该规则。', - targetDiffers: '目标规则与数据库策略不一致。', - alreadyExistsInTarget: '目标防火墙中已存在该规则。', - onlyInTarget: '该规则仅存在于目标防火墙中。', - stale: '防火墙规则状态已过期,请刷新后重试。', - lockoutRisk: '此次防火墙变更可能会阻断管理访问。', - protectedRule: '该防火墙规则受保护,无法修改。', - cannotReconcile: '无法同步目标规则:{0}', + matchesDatabasePolicy: '该规则已与 1Panel 保存的设置一致。', + managedOrderDiffers: '防火墙中的规则顺序与 1Panel 保存的顺序不一致,本次将调整。', + managedOnlyInTarget: '该规则仍存在于防火墙中,但 1Panel 已不再保存,本次将删除。', + managedRuntimeCannotRemove: '该规则仅在当前运行中生效,1Panel 无法确认删除后的影响,因此本次不会删除。', + managedOrderBlocked: + '调整规则顺序时会跨过外部规则、无法识别的规则或系统保护规则,为避免改变现有访问,本次不会调整。', + mayBlockManagement: '该规则可能导致当前 1Panel 管理页面无法访问。', + missingFromTarget: '防火墙中缺少该规则,本次将补充。', + targetDiffers: '防火墙中的规则与 1Panel 保存的设置不一致,本次将修复。', + alreadyExistsInTarget: '防火墙中已存在相同规则,无需重复添加。', + onlyInTarget: '该规则只存在于当前防火墙中。', + stale: '检查后防火墙状态已发生变化,请刷新后重试。', + lockoutRisk: '执行后可能导致当前 1Panel 管理页面无法访问,本次操作已停止。', + protectedRule: '这是保证系统正常运行的必要规则,不能修改。', + cannotReconcile: '该规则无法自动同步:{0}', }, - ruleSyncConfirm: '即将把 {0} 条规则从 {1} 同步到 {2},源后端不会被修改。是否继续?', - ruleSyncResetSource: '同步成功后重置并停用源防火墙 {0}', - ruleSyncResetSourceHelper: '仅在全部规则同步成功后重置源防火墙,此操作不可恢复。', - ruleSyncResetSourceBlocked: '存在不可同步规则,请先处理后再自动重置源防火墙。', - ruleSyncResetSourceConfirm: - '即将把 {0} 条规则从 {1} 同步到 {2},成功后重置并停用 {1}。这会删除 {1} 的全部防火墙配置且不可恢复,是否继续?', ruleSyncPartial: '同步完成:成功 {0} 条,已存在 {1} 条,失败 {2} 条。', ruleSyncSuccess: '同步完成:成功 {0} 条,已存在 {1} 条,删除 {2} 条。', ruleSyncStatus: { @@ -3964,6 +3958,11 @@ const message = { initializedStatus: '已初始化', partiallyInitialized: '部分初始化', dockerGuardHelper: '为 Docker 容器发布到宿主机的端口配置访问限制;未设置防护的端口保持 Docker 默认访问方式。', + dockerTrafficPathMixed: '所选端口使用不同的访问方式,请分别设置。', + dockerTrafficPathUnknown: '暂时无法确认该端口的访问方式,请检查 Docker 网络配置后重试。', + dockerTrafficPathPending: '访问方式待确认', + dockerInputPolicyNotEffective: '该端口由主机直接接收,现有容器端口防护规则不会生效,请改用主机防火墙设置。', + dockerInputUseHostFirewall: '该端口需要通过主机防火墙设置访问规则,请前往主机防火墙进行配置。', dockerInputNotProtected: '宿主机 INPUT 规则不能直接保护此 Docker 发布端口,点击前往容器端口防护。', notInitialized: '未初始化', familyUnsupported: '系统不支持 {0}', @@ -3989,9 +3988,7 @@ const message = { dockerGuardInconsistentConfigHelper: '所选规则配置不一致,请重新设置;提交后将统一覆盖,空描述将统一清空。', effective: '已生效', forwardUnsynced: '未同步', - notEnabled: '未启用', notEffective: '未生效', - dockerGuardStatusEffective: '{0} 容器端口防护运行正常', dockerGuardStatusReason: { command_missing: '系统缺少 {0} 防火墙组件,对应的容器端口防护暂不可用,请检查系统防火墙环境', docker_chain_missing: @@ -4015,8 +4012,6 @@ const message = { importPartialSuccess: '导入完成:成功 {0} 条,失败 {1} 条', basicStatus: '当前防火墙未绑定,请先绑定!', - baseIptables: 'iptables 服务', - forwardIptables: 'iptables 端口转发服务', initMsg: '即将初始化 {0}, 是否继续?', initDirectBackendConflictMsg: '检测到 {1} 仍处于绑定状态。继续初始化 {0} 后,两套防火墙规则将同时生效,可能导致访问被意外阻断。是否继续?', diff --git a/frontend/src/views/host/firewall/docker/detail/index.vue b/frontend/src/views/host/firewall/docker/detail/index.vue index 138f1b2b3..9c36d08a9 100644 --- a/frontend/src/views/host/firewall/docker/detail/index.vue +++ b/frontend/src/views/host/firewall/docker/detail/index.vue @@ -79,13 +79,15 @@
{{ $t('firewall.protection') }} - {{ protectionSummary(group.endpoint) }} + + {{ protectionSummary(group.endpoint) }} +
-
+
{{ $t('commons.table.description') }} - - {{ group.endpoint.description || '-' }} + + {{ group.endpoint.description }}
@@ -163,7 +165,7 @@ import { computed, nextTick, reactive, ref } from 'vue'; import { Firewall } from '@/api/interface/firewall'; import { deleteDockerPortGuardPolicies, upsertDockerPortGuardPolicies } from '@/api/modules/firewall'; import i18n from '@/lang'; -import { MsgSuccess } from '@/utils/message'; +import { MsgSuccess, MsgWarning } from '@/utils/message'; import { ElMessageBox, type FormInstance, type FormRules } from 'element-plus'; import { dockerGuardEndpointStatusMessage, isValidDockerGuardSource } from '@/views/host/firewall/docker/model'; import { formatHostAddress, formatHostAddressList, splitTagValues } from '@/views/host/firewall/utils/validation'; @@ -277,6 +279,20 @@ const toggleSelection = (key: string) => { }; const openPolicy = (endpoints: Firewall.DockerGuardEndpoint[]) => { if (!endpoints.length) return; + const paths = new Set(endpoints.map((endpoint) => endpoint.trafficPath || 'unknown')); + if (paths.size !== 1) { + MsgWarning(i18n.global.t('firewall.dockerTrafficPathMixed')); + return; + } + const path = [...paths][0]; + if (path === 'input') { + MsgWarning(i18n.global.t('firewall.dockerInputUseHostFirewall')); + return; + } + if (path !== 'forward') { + MsgWarning(i18n.global.t('firewall.dockerTrafficPathUnknown')); + return; + } policyEndpoints.value = endpoints; const first = endpoints[0]; form.mode = hasMixedFamilies.value ? 'deny_all' : policyConfigConsistent.value ? first.mode || 'deny_sources' : ''; @@ -363,6 +379,8 @@ const portMappingLabel = (row: Firewall.DockerGuardPortGroup) => { return `${publishedEndpoint} → ${value}/${row.endpoint.protocol}`; }; const protectionSummary = (row: Firewall.DockerGuardEndpoint) => { + if (row.trafficPath === 'input') return i18n.global.t('firewall.dockerInputUseHostFirewall'); + if (row.trafficPath === 'unknown') return i18n.global.t('firewall.dockerTrafficPathPending'); if (!row.policyUUID) return i18n.global.t('firewall.dockerGuardUnprotected'); let summary = i18n.global.t('firewall.denyAll'); if (row.mode === 'deny_sources') { diff --git a/frontend/src/views/host/firewall/docker/index.vue b/frontend/src/views/host/firewall/docker/index.vue index bda0567c8..1d0af4640 100644 --- a/frontend/src/views/host/firewall/docker/index.vue +++ b/frontend/src/views/host/firewall/docker/index.vue @@ -76,35 +76,36 @@ > - + + {{ endpointPrompt(group.endpoint) }} + + - {{ - group.endpoint.policyUUID - ? protectionModeLabel(group.endpoint) - : $t('firewall.dockerGuardUnprotected') - }} + {{ protectionModeLabel(group.endpoint) }} {{ displaySources(group.endpoint) }} - +
{{ $t( @@ -401,6 +402,13 @@ const displaySources = (endpoint: Firewall.DockerGuardEndpoint) => formatHostAddressList(endpoint.sources, endpoint.family); const endpointStatusMessage = (endpoint: Firewall.DockerGuardEndpoint) => dockerGuardEndpointStatusMessage(data.base, endpoint); +const isDockerPolicyEndpoint = (endpoint: Firewall.DockerGuardEndpoint) => + endpoint.trafficPath === 'forward' && Boolean(endpoint.policyUUID); +const endpointPrompt = (endpoint: Firewall.DockerGuardEndpoint) => { + if (endpoint.trafficPath === 'input') return i18n.global.t('firewall.dockerInputUseHostFirewall'); + if (endpoint.trafficPath === 'unknown') return i18n.global.t('firewall.dockerTrafficPathPending'); + return i18n.global.t('firewall.dockerGuardUnprotected'); +}; const search = async () => { loading.value = true; diff --git a/frontend/src/views/host/firewall/docker/model.ts b/frontend/src/views/host/firewall/docker/model.ts index 3885e0e37..89f66d1ee 100644 --- a/frontend/src/views/host/firewall/docker/model.ts +++ b/frontend/src/views/host/firewall/docker/model.ts @@ -34,6 +34,8 @@ export const dockerGuardEndpointStatusMessage = ( endpoint: Firewall.DockerGuardEndpoint, ): string => { if (!endpoint.policyUUID || endpoint.effective) return ''; + if (endpoint.trafficPath === 'input') return i18n.global.t('firewall.dockerInputPolicyNotEffective'); + if (endpoint.trafficPath === 'unknown') return i18n.global.t('firewall.dockerTrafficPathUnknown'); const ipv6 = endpoint.family === 'ipv6'; return dockerGuardFamilyStatusMessage(base, ipv6 ? 'IPv6' : 'IPv4', ipv6 ? base.ipv6 : base.ipv4); }; diff --git a/frontend/src/views/host/firewall/rule/index.vue b/frontend/src/views/host/firewall/rule/index.vue index ee2c2b131..39d46c4c5 100644 --- a/frontend/src/views/host/firewall/rule/index.vue +++ b/frontend/src/views/host/firewall/rule/index.vue @@ -419,6 +419,7 @@ interface UsageEntry { owner: string; pid?: number; docker?: boolean; + dockerTrafficPath?: Firewall.DockerGuardEndpoint['trafficPath']; } interface DisplayNotice { @@ -763,6 +764,7 @@ const ruleUsageEntries = (row: RuleRow): UsageEntry[] => { ]; }); const docker = dockerEndpoints.value + .filter((endpoint) => row.rule.scope.family === 'inet' || endpoint.family === row.rule.scope.family) .filter((endpoint) => protocols.includes(endpoint.protocol === 'tcp' ? 1 : 2)) .filter((endpoint) => isPortInRule(row.rule.destinationPort, endpoint.hostPort)) .map((endpoint) => ({ @@ -770,13 +772,18 @@ const ruleUsageEntries = (row: RuleRow): UsageEntry[] => { ports: [endpoint.hostPort], owner: `Docker: ${endpoint.containerName || endpoint.containerID?.slice(0, 12) || '-'}`, docker: true, + dockerTrafficPath: endpoint.trafficPath, })); return [...processes, ...docker]; }; const usageEntryPortText = (entry: UsageEntry) => entry.ports.join(', ') || '-'; const usageEntryLabel = (entry: UsageEntry) => entry.docker - ? `${entry.owner} (${usageEntryPortText(entry)}) — ${i18n.global.t('firewall.dockerInputNotProtected')}` + ? `${entry.owner} (${usageEntryPortText(entry)}) — ${i18n.global.t( + entry.dockerTrafficPath === 'input' + ? 'firewall.dockerInputUseHostFirewall' + : 'firewall.dockerInputNotProtected', + )}` : `${entry.owner} (${usageEntryPortText(entry)})`; const openUsageDetail = (entry: UsageEntry) => { if (entry.docker) {