diff --git a/agent/app/service/firewall.go b/agent/app/service/firewall.go index dbbded8d5..5f729d2d8 100644 --- a/agent/app/service/firewall.go +++ b/agent/app/service/firewall.go @@ -1003,6 +1003,15 @@ func (s *FirewallService) createRules(ctx context.Context, request dto.FirewallR "target": selected, "rule": describe(item.Rule), "count": len(rules), })) } + } else if selected == filter.ProviderUFW && strings.TrimSpace(item.Rule.DestinationPort) != "" { + protocol := strings.ToLower(strings.TrimSpace(item.Rule.Protocol)) + if protocol == "" || protocol == "all" || protocol == "any" { + rules, err = filter.ExpandAtomicRules(applySelectedProviderScopeDefaults(item.Rule, selected)) + if err != nil { + record(origin, "failed", err) + continue + } + } } for part, rule := range rules { origin := itemOrigin{index: index, part: part, count: len(rules), rule: rule} diff --git a/agent/utils/firewall/filter/normalize.go b/agent/utils/firewall/filter/normalize.go index 9e2696d7b..c47933008 100644 --- a/agent/utils/firewall/filter/normalize.go +++ b/agent/utils/firewall/filter/normalize.go @@ -117,6 +117,21 @@ func ExpandAtomicRules(input FirewallRule) ([]FirewallRule, error) { families = []Family{FamilyIPv4, FamilyIPv6} } protocols := splitProtocols(input.Protocol) + if input.Scope.Provider == ProviderUFW { + protocol, err := normalizeProtocol(input.Protocol) + if err != nil { + return nil, err + } + if protocol == "all" { + destinationPort, err := normalizePortValue(input.DestinationPort, true) + if err != nil { + return nil, fmt.Errorf("%w: destination port: %v", ErrInvalidRule, err) + } + if strings.ContainsAny(destinationPort, ",-") { + protocols = []string{"tcp", "udp"} + } + } + } sourceAddresses := splitValues(input.SourceAddress) destinationAddresses := splitValues(input.DestinationAddress) sourcePorts := splitValues(input.SourcePort)