mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-12 16:00:33 +00:00
fix: improve firewall compatibility
This commit is contained in:
@@ -582,6 +582,18 @@ func (s *FirewallService) createRules(ctx context.Context, request dto.FirewallR
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
importPrioritySupported := true
|
||||
if adapter, ok := runtime.(*filterfirewalld.Adapter); ok && slices.ContainsFunc(request.Items, func(item dto.FirewallRuleCreateItem) bool {
|
||||
return item.SourceKind == constant.FirewallRuleSourceImported
|
||||
}) {
|
||||
importPrioritySupported, err = adapter.SupportsRichRulePriority(ctx)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
if !importPrioritySupported && t != nil {
|
||||
t.Log("firewalld does not support rich rule priority; ignoring priority for imported rules, original rule ordering is not preserved")
|
||||
}
|
||||
}
|
||||
preparedItems := make([]*createItem, 0, len(request.Items))
|
||||
var stop error
|
||||
for index, item := range request.Items {
|
||||
@@ -593,6 +605,16 @@ func (s *FirewallService) createRules(ctx context.Context, request dto.FirewallR
|
||||
continue
|
||||
}
|
||||
item.Rule.OrderIndex = nil
|
||||
if item.SourceKind == constant.FirewallRuleSourceImported && !importPrioritySupported {
|
||||
item.Rule.Priority = nil
|
||||
if item.Rule.Scope.Provider == filter.ProviderFirewalld && item.Raw != "" && item.ParseStatus != "" && item.ParseStatus != filter.ParseStatusSupported && item.Rule.NativeKind != filter.NativeKindZoneService {
|
||||
item.Raw, err = filterfirewalld.RemoveRichRulePriority(item.Raw)
|
||||
if err != nil {
|
||||
record(createItem{index: index, request: item}, "skipped", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
rules, err := expandFirewallCreateRule(item, selected)
|
||||
if err != nil {
|
||||
status := "failed"
|
||||
@@ -693,7 +715,7 @@ func (s *FirewallService) createRules(ctx context.Context, request dto.FirewallR
|
||||
record(*item, "skipped", buserr.New("ErrRecordExist"))
|
||||
continue
|
||||
}
|
||||
if converted {
|
||||
if converted && importPrioritySupported {
|
||||
priority++
|
||||
}
|
||||
if existing[key] {
|
||||
@@ -713,7 +735,7 @@ func (s *FirewallService) createRules(ctx context.Context, request dto.FirewallR
|
||||
}
|
||||
ufwActions[matchKey] = map[filter.Action]bool{item.request.Rule.Action: true}
|
||||
}
|
||||
if converted {
|
||||
if converted && importPrioritySupported {
|
||||
if priority > 32767 {
|
||||
return result, fmt.Errorf("%w: firewalld import order exceeds the priority range", filter.ErrExpansionLimit)
|
||||
}
|
||||
@@ -729,18 +751,19 @@ func (s *FirewallService) createRules(ctx context.Context, request dto.FirewallR
|
||||
continue
|
||||
}
|
||||
item.request = prepared
|
||||
actualKey, err := firewallRuleDuplicateKey(filter.ObservedRule{Rule: prepared.Rule, ParseStatus: prepared.ParseStatus}, false)
|
||||
}
|
||||
pending[key] = true
|
||||
if converted {
|
||||
actualKey, err := firewallRuleDuplicateKey(filter.ObservedRule{Rule: item.request.Rule, ParseStatus: item.request.ParseStatus}, false)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
pending[key] = true
|
||||
if existing[actualKey] || pending[actualKey] {
|
||||
record(*item, "skipped", buserr.New("ErrRecordExist"))
|
||||
continue
|
||||
}
|
||||
pending[actualKey] = true
|
||||
}
|
||||
pending[key] = true
|
||||
mergedItems = append(mergedItems, item)
|
||||
}
|
||||
for _, item := range mergedItems {
|
||||
|
||||
@@ -92,6 +92,9 @@ func dockerPolicyRuleKey(tokens []string, backend string) string {
|
||||
if address, err := netip.ParseAddr(value); err == nil {
|
||||
value = netip.PrefixFrom(address, address.BitLen()).String()
|
||||
} else if prefix, err := netip.ParsePrefix(value); err == nil {
|
||||
if prefix.Bits() == 0 {
|
||||
continue
|
||||
}
|
||||
value = prefix.Masked().String()
|
||||
}
|
||||
}
|
||||
@@ -156,7 +159,13 @@ func parseDockerGuardPolicies(output, family string) (PolicyInventory, error) {
|
||||
group.acceptedSource = append(group.acceptedSource, source)
|
||||
case action == "accept":
|
||||
group.acceptAll = true
|
||||
case action == "return" && source != "":
|
||||
case action == "return":
|
||||
if source == "" {
|
||||
source = "0.0.0.0/0"
|
||||
if family == FamilyIPv6 {
|
||||
source = "::/0"
|
||||
}
|
||||
}
|
||||
group.allowedSource = append(group.allowedSource, source)
|
||||
case action == "drop" && source != "":
|
||||
group.droppedSource = append(group.droppedSource, source)
|
||||
|
||||
@@ -50,7 +50,7 @@ func (a *Adapter) CheckRule(ctx context.Context, rule filter.FirewallRule) error
|
||||
if rule.Priority == nil || *rule.Priority == 0 {
|
||||
return nil
|
||||
}
|
||||
supported, err := a.supportsRichRulePriority(ctx)
|
||||
supported, err := a.SupportsRichRulePriority(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func (a *Adapter) CheckRule(ctx context.Context, rule filter.FirewallRule) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Adapter) supportsRichRulePriority(ctx context.Context) (bool, error) {
|
||||
func (a *Adapter) SupportsRichRulePriority(ctx context.Context) (bool, error) {
|
||||
a.prioritySupportMu.Lock()
|
||||
defer a.prioritySupportMu.Unlock()
|
||||
if a.richRulePrioritySupported != nil {
|
||||
@@ -82,6 +82,52 @@ func (a *Adapter) supportsRichRulePriority(ctx context.Context) (bool, error) {
|
||||
return supported, nil
|
||||
}
|
||||
|
||||
func RemoveRichRulePriority(raw string) (string, error) {
|
||||
if strings.ContainsAny(raw, "\r\n\x00") {
|
||||
return "", filter.ErrInvalidRule
|
||||
}
|
||||
parts := make([]string, 0)
|
||||
removed := false
|
||||
for start := 0; start < len(raw); {
|
||||
if raw[start] == ' ' || raw[start] == '\t' {
|
||||
start++
|
||||
continue
|
||||
}
|
||||
end, quote := start, byte(0)
|
||||
for end < len(raw) {
|
||||
char := raw[end]
|
||||
if char == '\\' && quote != '\'' {
|
||||
end += 2
|
||||
continue
|
||||
}
|
||||
if quote != 0 {
|
||||
if char == quote {
|
||||
quote = 0
|
||||
}
|
||||
} else if char == '\'' || char == '"' {
|
||||
quote = char
|
||||
} else if char == ' ' || char == '\t' {
|
||||
break
|
||||
}
|
||||
end++
|
||||
}
|
||||
if quote != 0 || end > len(raw) {
|
||||
return "", filter.ErrInvalidRule
|
||||
}
|
||||
token := raw[start:end]
|
||||
if strings.HasPrefix(token, "priority=") {
|
||||
removed = true
|
||||
} else {
|
||||
parts = append(parts, token)
|
||||
}
|
||||
start = end
|
||||
}
|
||||
if !removed || len(parts) == 0 || parts[0] != "rule" {
|
||||
return raw, nil
|
||||
}
|
||||
return strings.Join(parts, " "), nil
|
||||
}
|
||||
|
||||
func parseFirewalldVersion(output string) (int, int, error) {
|
||||
version := strings.TrimSpace(output)
|
||||
parts := strings.Split(version, ".")
|
||||
|
||||
Reference in New Issue
Block a user