From fc1584e7dafdae7ef132c5aacb414107934b29e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Wed, 23 Oct 2024 03:05:40 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BD=95=E8=A7=81=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B=E9=98=B2=E7=81=AB=E5=A2=99=E8=A7=84=E5=88=99=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/apps/phpmyadmin/service.go | 1 + internal/apps/pureftpd/service.go | 1 + internal/data/setting.go | 1 + internal/http/request/firewall.go | 1 + internal/service/firewall.go | 5 ++-- pkg/firewall/consts.go | 8 +++++ pkg/firewall/firewall.go | 46 ++++++++++++++++++++++++++++- web/src/views/safe/RuleView.vue | 2 +- web/src/views/ssh/IndexView.vue | 24 +++++++-------- web/src/views/task/CronView.vue | 9 +++--- 10 files changed, 78 insertions(+), 20 deletions(-) diff --git a/internal/apps/phpmyadmin/service.go b/internal/apps/phpmyadmin/service.go index 67359587..80b5932e 100644 --- a/internal/apps/phpmyadmin/service.go +++ b/internal/apps/phpmyadmin/service.go @@ -78,6 +78,7 @@ func (s *Service) UpdatePort(w http.ResponseWriter, r *http.Request) { fw := firewall.NewFirewall() err = fw.Port(firewall.FireInfo{ + Type: firewall.TypeNormal, PortStart: req.Port, PortEnd: req.Port, Direction: firewall.DirectionIn, diff --git a/internal/apps/pureftpd/service.go b/internal/apps/pureftpd/service.go index 9bdd47b3..951f1173 100644 --- a/internal/apps/pureftpd/service.go +++ b/internal/apps/pureftpd/service.go @@ -156,6 +156,7 @@ func (s *Service) UpdatePort(w http.ResponseWriter, r *http.Request) { fw := firewall.NewFirewall() err = fw.Port(firewall.FireInfo{ + Type: firewall.TypeNormal, PortStart: req.Port, PortEnd: req.Port, Direction: firewall.DirectionIn, diff --git a/internal/data/setting.go b/internal/data/setting.go index 1e64813a..5268b5ba 100644 --- a/internal/data/setting.go +++ b/internal/data/setting.go @@ -205,6 +205,7 @@ func (r *settingRepo) UpdatePanelSetting(ctx context.Context, setting *request.P // 放行端口 fw := firewall.NewFirewall() err = fw.Port(firewall.FireInfo{ + Type: firewall.TypeNormal, PortStart: uint(config.HTTP.Port), PortEnd: uint(config.HTTP.Port), Direction: firewall.DirectionIn, diff --git a/internal/http/request/firewall.go b/internal/http/request/firewall.go index 93bc8465..0119cee8 100644 --- a/internal/http/request/firewall.go +++ b/internal/http/request/firewall.go @@ -5,6 +5,7 @@ type FirewallStatus struct { } type FirewallRule struct { + Type string `json:"type"` Family string `json:"family" validate:"required,oneof=ipv4 ipv6"` PortStart uint `json:"port_start" validate:"required,gte=1,lte=65535"` PortEnd uint `json:"port_end" validate:"required,gte=1,lte=65535"` diff --git a/internal/service/firewall.go b/internal/service/firewall.go index c1a857b2..9e24bd36 100644 --- a/internal/service/firewall.go +++ b/internal/service/firewall.go @@ -86,6 +86,7 @@ func (s *FirewallService) GetRules(w http.ResponseWriter, r *http.Request) { } } filledRules = append(filledRules, map[string]any{ + "type": rule.Type, "family": rule.Family, "port_start": rule.PortStart, "port_end": rule.PortEnd, @@ -113,7 +114,7 @@ func (s *FirewallService) CreateRule(w http.ResponseWriter, r *http.Request) { } if err = s.firewall.Port(firewall.FireInfo{ - Family: req.Family, PortStart: req.PortStart, PortEnd: req.PortEnd, Protocol: firewall.Protocol(req.Protocol), Address: req.Address, Strategy: firewall.Strategy(req.Strategy), Direction: firewall.Direction(req.Direction), + Type: firewall.Type(req.Type), Family: req.Family, PortStart: req.PortStart, PortEnd: req.PortEnd, Protocol: firewall.Protocol(req.Protocol), Address: req.Address, Strategy: firewall.Strategy(req.Strategy), Direction: firewall.Direction(req.Direction), }, firewall.OperationAdd); err != nil { Error(w, http.StatusInternalServerError, "%v", err) return @@ -130,7 +131,7 @@ func (s *FirewallService) DeleteRule(w http.ResponseWriter, r *http.Request) { } if err = s.firewall.Port(firewall.FireInfo{ - Family: req.Family, PortStart: req.PortStart, PortEnd: req.PortEnd, Protocol: firewall.Protocol(req.Protocol), Address: req.Address, Strategy: firewall.Strategy(req.Strategy), Direction: firewall.Direction(req.Direction), + Type: firewall.Type(req.Type), Family: req.Family, PortStart: req.PortStart, PortEnd: req.PortEnd, Protocol: firewall.Protocol(req.Protocol), Address: req.Address, Strategy: firewall.Strategy(req.Strategy), Direction: firewall.Direction(req.Direction), }, firewall.OperationRemove); err != nil { Error(w, http.StatusInternalServerError, "%v", err) return diff --git a/pkg/firewall/consts.go b/pkg/firewall/consts.go index 2e74f2c6..8fa19716 100644 --- a/pkg/firewall/consts.go +++ b/pkg/firewall/consts.go @@ -7,6 +7,13 @@ var ( OperationRemove Operation = "remove" // 移除 ) +type Type string + +var ( + TypeRich Type = "rich" // rich + TypeNormal Type = "normal" // normal +) + type Protocol string var ( @@ -31,6 +38,7 @@ var ( ) type FireInfo struct { + Type Type `json:"type"` // rich or normal Family string `json:"family"` // ipv4 ipv6 Address string `json:"address"` // 源地址或目标地址 PortStart uint `json:"port_start"` // 1-65535 diff --git a/pkg/firewall/firewall.go b/pkg/firewall/firewall.go index 6a5a5d7a..b2c75cf0 100644 --- a/pkg/firewall/firewall.go +++ b/pkg/firewall/firewall.go @@ -54,6 +54,7 @@ func (r *Firewall) ListRule() ([]FireInfo, error) { continue } var item FireInfo + item.Type = TypeNormal if strings.Contains(port, "/") { ruleItem := strings.Split(port, "/") portItem := strings.Split(ruleItem[0], "-") @@ -82,6 +83,32 @@ func (r *Firewall) ListRule() ([]FireInfo, error) { }() wg.Wait() + + slices.SortFunc(data, func(a FireInfo, b FireInfo) int { + if a.PortStart != b.PortStart { + return int(a.PortStart - b.PortStart) + } + if a.PortEnd != b.PortEnd { + return int(a.PortEnd - b.PortEnd) + } + if a.Protocol != b.Protocol { + return strings.Compare(string(a.Protocol), string(b.Protocol)) + } + if a.Family != b.Family { + return strings.Compare(a.Family, b.Family) + } + if a.Strategy != b.Strategy { + return strings.Compare(string(a.Strategy), string(b.Strategy)) + } + if a.Direction != b.Direction { + return strings.Compare(string(a.Direction), string(b.Direction)) + } + if a.Type != b.Type { + return strings.Compare(string(a.Type), string(b.Type)) + } + return 0 + }) + return data, nil } @@ -113,6 +140,22 @@ func (r *Firewall) ListForward() ([]FireForwardInfo, error) { } } + slices.SortFunc(data, func(a FireForwardInfo, b FireForwardInfo) int { + if a.Port != b.Port { + return int(a.Port - b.Port) + } + if a.TargetPort != b.TargetPort { + return int(a.TargetPort - b.TargetPort) + } + if a.Protocol != b.Protocol { + return strings.Compare(string(a.Protocol), string(b.Protocol)) + } + if a.TargetIP != b.TargetIP { + return strings.Compare(a.TargetIP, b.TargetIP) + } + return 0 + }) + return data, nil } @@ -144,7 +187,7 @@ func (r *Firewall) Port(rule FireInfo, operation Operation) error { return fmt.Errorf("invalid port range: %d-%d", rule.PortStart, rule.PortEnd) } // 不支持的切换使用rich rules - if (rule.Family != "" && rule.Family != "ipv4") || rule.Direction != "in" || rule.Address != "" || rule.Strategy != "accept" { + if (rule.Family != "" && rule.Family != "ipv4") || rule.Direction != "in" || rule.Address != "" || rule.Strategy != "accept" || rule.Type == TypeRich { return r.RichRules(rule, operation) } @@ -245,6 +288,7 @@ func (r *Firewall) parseRichRule(line string) (FireInfo, error) { } fireInfo := FireInfo{ + Type: TypeRich, Family: match[1], Address: match[3], Protocol: Protocol(match[5]), diff --git a/web/src/views/safe/RuleView.vue b/web/src/views/safe/RuleView.vue index 64e000cc..467cd799 100644 --- a/web/src/views/safe/RuleView.vue +++ b/web/src/views/safe/RuleView.vue @@ -286,7 +286,7 @@ onMounted(() => { ([]) @@ -60,7 +60,7 @@ const fetchData = async () => { type: 'primary', size: 'small', onClick: () => { - updateModal.value = true + update.value = true updateId.value = item.id } }, @@ -114,7 +114,7 @@ const handleDelete = async (id: number) => { term.value.dispose() } if (list.value.length === 0) { - createModal.value = true + create.value = true } } } @@ -172,10 +172,10 @@ const closeSession = () => { try { term.value.dispose() sshWs?.close() + terminal.value!.innerHTML = '' } catch { /* empty */ } - terminal.value!.innerHTML = '' } const onResize = () => { @@ -206,12 +206,12 @@ const onTermWheel = (event: WheelEvent) => { } } -watch(createModal, () => { - if (!createModal.value) fetchData() +watch(create, () => { + if (!create.value) fetchData() }) -watch(updateModal, () => { - if (!updateModal.value) { +watch(update, () => { + if (!update.value) { fetchData() updateId.value = 0 } @@ -233,7 +233,7 @@ onUnmounted(() => {