feat: 优化防火墙响应速度 (#2261)

pull/2268/head
ssongliu 2023-09-12 17:14:15 +08:00 committed by GitHub
parent ecb7a2ebee
commit 16446ecaf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 80 additions and 40 deletions

View File

@ -5,10 +5,12 @@ import (
"os" "os"
"strconv" "strconv"
"strings" "strings"
"sync"
"github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd" "github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/1Panel-dev/1Panel/backend/utils/common" "github.com/1Panel-dev/1Panel/backend/utils/common"
"github.com/1Panel-dev/1Panel/backend/utils/firewall" "github.com/1Panel-dev/1Panel/backend/utils/firewall"
@ -39,7 +41,6 @@ func NewIFirewallService() IFirewallService {
func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) { func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) {
var baseInfo dto.FirewallBaseInfo var baseInfo dto.FirewallBaseInfo
baseInfo.PingStatus = u.pingStatus()
baseInfo.Status = "not running" baseInfo.Status = "not running"
baseInfo.Version = "-" baseInfo.Version = "-"
baseInfo.Name = "-" baseInfo.Name = "-"
@ -51,17 +52,22 @@ func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) {
return baseInfo, err return baseInfo, err
} }
baseInfo.Name = client.Name() baseInfo.Name = client.Name()
baseInfo.Status, err = client.Status()
if err != nil { var wg sync.WaitGroup
return baseInfo, err wg.Add(3)
} go func() {
if baseInfo.Status == "not running" { defer wg.Done()
return baseInfo, err baseInfo.PingStatus = u.pingStatus()
} }()
baseInfo.Version, err = client.Version() go func() {
if err != nil { defer wg.Done()
return baseInfo, err baseInfo.Status, _ = client.Status()
} }()
go func() {
defer wg.Done()
baseInfo.Version, _ = client.Version()
}()
wg.Wait()
return baseInfo, nil return baseInfo, nil
} }
@ -220,6 +226,8 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
} }
protos := strings.Split(req.Protocol, "/") protos := strings.Split(req.Protocol, "/")
itemAddress := strings.Split(strings.TrimSuffix(req.Address, ","), ",") itemAddress := strings.Split(strings.TrimSuffix(req.Address, ","), ",")
var wg sync.WaitGroup
if client.Name() == "ufw" { if client.Name() == "ufw" {
if strings.Contains(req.Port, ",") || strings.Contains(req.Port, "-") { if strings.Contains(req.Port, ",") || strings.Contains(req.Port, "-") {
for _, proto := range protos { for _, proto := range protos {
@ -230,10 +238,14 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
req.Address = addr req.Address = addr
req.Port = strings.ReplaceAll(req.Port, "-", ":") req.Port = strings.ReplaceAll(req.Port, "-", ":")
req.Protocol = proto req.Protocol = proto
if err := u.operatePort(client, req); err != nil { wg.Add(1)
return err go func(req dto.PortRuleOperate) {
} defer wg.Done()
_ = u.addPortRecord(req) if err := u.operatePort(client, req); err != nil {
global.LOG.Errorf("%s port %s/%s failed (strategy: %s, address: %s), err: %v", req.Operation, req.Port, req.Protocol, req.Strategy, req.Address, err)
}
_ = u.addPortRecord(req)
}(req)
} }
} }
return nil return nil
@ -246,10 +258,14 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
addr = "Anywhere" addr = "Anywhere"
} }
req.Address = addr req.Address = addr
if err := u.operatePort(client, req); err != nil { wg.Add(1)
return err go func(req dto.PortRuleOperate) {
} defer wg.Done()
_ = u.addPortRecord(req) if err := u.operatePort(client, req); err != nil {
global.LOG.Errorf("%s port %s/%s failed (strategy: %s, address: %s), err: %v", req.Operation, req.Port, req.Protocol, req.Strategy, req.Address, err)
}
_ = u.addPortRecord(req)
}(req)
} }
return nil return nil
} }
@ -260,10 +276,14 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
for _, addr := range itemAddress { for _, addr := range itemAddress {
req.Protocol = proto req.Protocol = proto
req.Address = addr req.Address = addr
if err := u.operatePort(client, req); err != nil { wg.Add(1)
return err go func(req dto.PortRuleOperate) {
} defer wg.Done()
_ = u.addPortRecord(req) if err := u.operatePort(client, req); err != nil {
global.LOG.Errorf("%s port %s/%s failed (strategy: %s, address: %s), err: %v", req.Operation, req.Port, req.Protocol, req.Strategy, req.Address, err)
}
_ = u.addPortRecord(req)
}(req)
} }
} else { } else {
ports := strings.Split(itemPorts, ",") ports := strings.Split(itemPorts, ",")
@ -275,15 +295,24 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
req.Address = addr req.Address = addr
req.Port = port req.Port = port
req.Protocol = proto req.Protocol = proto
if err := u.operatePort(client, req); err != nil { wg.Add(1)
return err go func(req dto.PortRuleOperate) {
} defer wg.Done()
_ = u.addPortRecord(req) if err := u.operatePort(client, req); err != nil {
global.LOG.Errorf("%s port %s/%s failed (strategy: %s, address: %s), err: %v", req.Operation, req.Port, req.Protocol, req.Strategy, req.Address, err)
}
_ = u.addPortRecord(req)
}(req)
} }
} }
} }
} }
return client.Reload()
wg.Wait()
if reload {
return client.Reload()
}
return nil
} }
func (u *FirewallService) OperateAddressRule(req dto.AddrRuleOperate, reload bool) error { func (u *FirewallService) OperateAddressRule(req dto.AddrRuleOperate, reload bool) error {
@ -297,17 +326,22 @@ func (u *FirewallService) OperateAddressRule(req dto.AddrRuleOperate, reload boo
return err return err
} }
var wg sync.WaitGroup
addressList := strings.Split(req.Address, ",") addressList := strings.Split(req.Address, ",")
for _, addr := range addressList { for _, addr := range addressList {
if len(addr) == 0 { if len(addr) == 0 {
continue continue
} }
fireInfo.Address = addr fireInfo.Address = addr
if err := client.RichRules(fireInfo, req.Operation); err != nil { wg.Add(1)
return err go func(req dto.AddrRuleOperate) {
} defer wg.Done()
req.Address = addr if err := client.RichRules(fireInfo, req.Operation); err != nil {
_ = u.addAddressRecord(req) global.LOG.Errorf("%s address %s failed (strategy: %s), err: %v", req.Operation, req.Address, req.Strategy, err)
}
req.Address = fireInfo.Address
_ = u.addAddressRecord(req)
}(req)
} }
if reload { if reload {
return client.Reload() return client.Reload()
@ -356,19 +390,25 @@ func (u *FirewallService) BatchOperateRule(req dto.BatchRuleOperate) error {
if err != nil { if err != nil {
return err return err
} }
var wgBatch sync.WaitGroup
if req.Type == "port" { if req.Type == "port" {
for _, rule := range req.Rules { for _, rule := range req.Rules {
if err := u.OperatePortRule(rule, false); err != nil { wgBatch.Add(1)
return err go func(item dto.PortRuleOperate) {
} defer wgBatch.Done()
_ = u.OperatePortRule(item, false)
}(rule)
} }
wgBatch.Wait()
return client.Reload() return client.Reload()
} }
for _, rule := range req.Rules { for _, rule := range req.Rules {
itemRule := dto.AddrRuleOperate{Operation: rule.Operation, Address: rule.Address, Strategy: rule.Strategy} itemRule := dto.AddrRuleOperate{Operation: rule.Operation, Address: rule.Address, Strategy: rule.Strategy}
if err := u.OperateAddressRule(itemRule, false); err != nil { wgBatch.Add(1)
return err go func(item dto.AddrRuleOperate) {
} defer wgBatch.Done()
_ = u.OperateAddressRule(item, false)
}(itemRule)
} }
return client.Reload() return client.Reload()
} }