From c1c324af2323266a4d289dfe526e8abea24c3f61 Mon Sep 17 00:00:00 2001 From: ssongliu Date: Thu, 30 Mar 2023 16:07:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=98=B2=E7=81=AB?= =?UTF-8?q?=E5=A2=99=E5=BC=80=E5=85=B3=E5=8F=8A=E8=A1=8C=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/firewall.go | 46 ++- backend/app/dto/firewall.go | 10 + backend/app/service/firewall.go | 41 ++ backend/router/ro_host.go | 2 + backend/utils/firewall/client.go | 5 +- backend/utils/firewall/client/firewalld.go | 13 +- backend/utils/firewall/client/ufw.go | 27 +- cmd/server/docs/docs.go | 380 ++++++++++++++++++ cmd/server/docs/swagger.json | 380 ++++++++++++++++++ cmd/server/docs/swagger.yaml | 244 +++++++++++ frontend/src/api/interface/host.ts | 5 + frontend/src/api/modules/host.ts | 6 + frontend/src/lang/modules/zh.ts | 10 + frontend/src/views/host/firewall/ip/index.vue | 69 +++- .../src/views/host/firewall/port/index.vue | 74 +++- .../src/views/host/firewall/status/index.vue | 84 ++++ 16 files changed, 1373 insertions(+), 23 deletions(-) create mode 100644 frontend/src/views/host/firewall/status/index.vue diff --git a/backend/app/api/v1/firewall.go b/backend/app/api/v1/firewall.go index 80ce04716..ed148ed58 100644 --- a/backend/app/api/v1/firewall.go +++ b/backend/app/api/v1/firewall.go @@ -8,6 +8,22 @@ import ( "github.com/gin-gonic/gin" ) +// @Tags Firewall +// @Summary Load firewall base info +// @Description 获取防火墙基础信息 +// @Success 200 {object} dto.FirewallBaseInfo +// @Security ApiKeyAuth +// @Router /hosts/firewall/base [get] +func (b *BaseApi) LoadFirewallBaseInfo(c *gin.Context) { + data, err := firewallService.LoadBaseInfo() + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, data) +} + // @Tags Firewall // @Summary Page firewall rules // @Description 获取防火墙规则列表分页 @@ -35,6 +51,34 @@ func (b *BaseApi) SearchFirewallRule(c *gin.Context) { }) } +// @Tags Firewall +// @Summary Page firewall status +// @Description 修改防火墙状态 +// @Accept json +// @Param request body dto.FirewallOperation true "request" +// @Success 200 {object} dto.PageResult +// @Security ApiKeyAuth +// @Router /hosts/firewall/operate [post] +// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"} +func (b *BaseApi) OperateFirewall(c *gin.Context) { + var req dto.FirewallOperation + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := global.VALID.Struct(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + + if err := firewallService.OperateFirewall(req.Operation); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, nil) +} + // @Tags Firewall // @Summary Create group // @Description 创建防火墙端口规则 @@ -65,7 +109,7 @@ func (b *BaseApi) OperatePortRule(c *gin.Context) { // @Summary Create group // @Description 创建防火墙 IP 规则 // @Accept json -// @Param request body dto.AddressCreate true "request" +// @Param request body dto.AddrRuleOperate true "request" // @Success 200 // @Security ApiKeyAuth // @Router /hosts/firewall/ip [post] diff --git a/backend/app/dto/firewall.go b/backend/app/dto/firewall.go index 85b049e1d..fb209f2af 100644 --- a/backend/app/dto/firewall.go +++ b/backend/app/dto/firewall.go @@ -1,11 +1,21 @@ package dto +type FirewallBaseInfo struct { + Name string `json:"name"` + Status string `json:"status"` + Version string `json:"version"` +} + type RuleSearch struct { PageInfo Info string `json:"info"` Type string `json:"type" validate:"required"` } +type FirewallOperation struct { + Operation string `json:"operation" validate:"required,oneof=start stop reload"` +} + type PortRuleOperate struct { Operation string `json:"operation" validate:"required,oneof=add remove"` Address string `json:"address"` diff --git a/backend/app/service/firewall.go b/backend/app/service/firewall.go index 444404f0a..e60f48dfa 100644 --- a/backend/app/service/firewall.go +++ b/backend/app/service/firewall.go @@ -1,6 +1,7 @@ package service import ( + "fmt" "strings" "github.com/1Panel-dev/1Panel/backend/app/dto" @@ -12,7 +13,9 @@ import ( type FirewallService struct{} type IFirewallService interface { + LoadBaseInfo() (dto.FirewallBaseInfo, error) SearchWithPage(search dto.RuleSearch) (int64, interface{}, error) + OperateFirewall(operation string) error OperatePortRule(req dto.PortRuleOperate, reload bool) error OperateAddressRule(req dto.AddrRuleOperate, reload bool) error UpdatePortRule(req dto.PortRuleUpdate) error @@ -24,6 +27,28 @@ func NewIFirewallService() IFirewallService { return &FirewallService{} } +func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) { + var baseInfo dto.FirewallBaseInfo + client, err := firewall.NewFirewallClient() + if err != nil { + return baseInfo, err + } + baseInfo.Name = client.Name() + baseInfo.Status, err = client.Status() + if err != nil { + return baseInfo, err + } + if baseInfo.Status == "not running" { + baseInfo.Version = "-" + return baseInfo, err + } + baseInfo.Version, err = client.Version() + if err != nil { + return baseInfo, err + } + return baseInfo, nil +} + func (u *FirewallService) SearchWithPage(req dto.RuleSearch) (int64, interface{}, error) { var ( datas []fireClient.FireInfo @@ -75,6 +100,22 @@ func (u *FirewallService) SearchWithPage(req dto.RuleSearch) (int64, interface{} return int64(total), backDatas, nil } +func (u *FirewallService) OperateFirewall(operation string) error { + client, err := firewall.NewFirewallClient() + if err != nil { + return err + } + switch operation { + case "start": + return client.Start() + case "stop": + return client.Stop() + case "reload": + return client.Reload() + } + return fmt.Errorf("not support such operation: %s", operation) +} + func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool) error { client, err := firewall.NewFirewallClient() if err != nil { diff --git a/backend/router/ro_host.go b/backend/router/ro_host.go index 6617f742f..fe3c38767 100644 --- a/backend/router/ro_host.go +++ b/backend/router/ro_host.go @@ -26,7 +26,9 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) { hostRouter.POST("/test/byid/:id", baseApi.TestByID) hostRouter.GET(":id", baseApi.GetHostInfo) + hostRouter.GET("/firewall/base", baseApi.LoadFirewallBaseInfo) hostRouter.POST("/firewall/search", baseApi.SearchFirewallRule) + hostRouter.POST("/firewall/operate", baseApi.OperateFirewall) hostRouter.POST("/firewall/port", baseApi.OperatePortRule) hostRouter.POST("/firewall/ip", baseApi.OperateIPRule) hostRouter.POST("/firewall/batch", baseApi.BatchOperateRule) diff --git a/backend/utils/firewall/client.go b/backend/utils/firewall/client.go index 37fd4501f..d455daad6 100644 --- a/backend/utils/firewall/client.go +++ b/backend/utils/firewall/client.go @@ -10,6 +10,7 @@ type FirewallClient interface { Stop() error Reload() error Status() (string, error) + Version() (string, error) ListPort() ([]client.FireInfo, error) ListAddress() ([]client.FireInfo, error) @@ -20,10 +21,10 @@ type FirewallClient interface { func NewFirewallClient() (FirewallClient, error) { // if _, err := os.Stat("/usr/sbin/firewalld"); err == nil { - // return client.NewFirewalld() + return client.NewFirewalld() // } // if _, err := os.Stat("/usr/sbin/ufw"); err == nil { - return client.NewUfw() + // return client.NewUfw() // } // return nil, errors.New("no such type") } diff --git a/backend/utils/firewall/client/firewalld.go b/backend/utils/firewall/client/firewalld.go index 5c3df7e70..d79b911da 100644 --- a/backend/utils/firewall/client/firewalld.go +++ b/backend/utils/firewall/client/firewalld.go @@ -26,13 +26,18 @@ func (f *Firewall) Name() string { } func (f *Firewall) Status() (string, error) { - stdout, err := f.Client.Run("firewall-cmd --state") - if err != nil { - return "", fmt.Errorf("load the firewall status failed, err: %s", stdout) - } + stdout, _ := f.Client.Run("firewall-cmd --state") return strings.ReplaceAll(stdout, "\n", ""), nil } +func (f *Firewall) Version() (string, error) { + stdout, err := f.Client.Run("firewall-cmd --version") + if err != nil { + return "", fmt.Errorf("load the firewall version failed, err: %s", stdout) + } + return strings.ReplaceAll(stdout, "\n ", ""), nil +} + func (f *Firewall) Start() error { stdout, err := f.Client.Run("systemctl start firewalld") if err != nil { diff --git a/backend/utils/firewall/client/ufw.go b/backend/utils/firewall/client/ufw.go index d1ca15809..456c1cf24 100644 --- a/backend/utils/firewall/client/ufw.go +++ b/backend/utils/firewall/client/ufw.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/utils/ssh" ) @@ -26,24 +27,44 @@ func (f *Ufw) Name() string { } func (f *Ufw) Status() (string, error) { - stdout, err := f.Client.Run("sudo ufw status") + stdout, err := f.Client.Run("sudo ufw status | grep Status") if err != nil { return "", fmt.Errorf("load the firewall status failed, err: %s", stdout) } - if stdout == "Status: inactive\n" { + if stdout == "Status: active\n" { return "running", nil } return "not running", nil } +func (f *Ufw) Version() (string, error) { + stdout, err := f.Client.Run("sudo ufw version | grep ufw") + if err != nil { + return "", fmt.Errorf("load the firewall status failed, err: %s", stdout) + } + info := strings.ReplaceAll(stdout, "\n", "") + return strings.ReplaceAll(info, "ufw ", ""), nil +} + func (f *Ufw) Start() error { - stdout, err := f.Client.Run("sudo ufw enable") + stdout, err := f.Client.Run("echo y | sudo ufw enable") if err != nil { return fmt.Errorf("enable the firewall failed, err: %s", stdout) } return nil } +func (f *Ufw) PingStatus() (string, error) { + stdout, err := f.Client.Run("cat /etc/ufw/sysctl.conf | grep net/ipv4/icmp_echo_ignore_all= ") + if err != nil { + return constant.StatusDisable, fmt.Errorf("enable the firewall failed, err: %s", stdout) + } + if stdout == "net/ipv4/icmp_echo_ignore_all=1\n" { + return constant.StatusEnable, nil + } + return constant.StatusDisable, nil +} + func (f *Ufw) Stop() error { stdout, err := f.Client.Run("sudo ufw disable") if err != nil { diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index a1d06bfe2..bb57ee85a 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -5066,6 +5066,251 @@ var doc = `{ } } }, + "/hosts/firewall/base": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取防火墙基础信息", + "tags": [ + "Firewall" + ], + "summary": "Load firewall base info", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.FirewallBaseInfo" + } + } + } + } + }, + "/hosts/firewall/ip": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "批量删除防火墙规则", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Create group", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.BatchRuleOperate" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/hosts/firewall/operate": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "修改防火墙状态", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Page firewall status", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.FirewallOperation" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.PageResult" + } + } + }, + "x-panel-log": { + "BeforeFuntions": [], + "bodyKeys": [ + "operation" + ], + "formatEN": "[operation] firewall", + "formatZH": "[operation] 防火墙", + "paramKeys": [] + } + } + }, + "/hosts/firewall/port": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "创建防火墙端口规则", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Create group", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PortRuleOperate" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "x-panel-log": { + "BeforeFuntions": [], + "bodyKeys": [ + "port", + "strategy" + ], + "formatEN": "create port rules {[strategy][port]}", + "formatZH": "添加端口规则 {[strategy] [port]}", + "paramKeys": [] + } + } + }, + "/hosts/firewall/search": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取防火墙规则列表分页", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Page firewall rules", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.SearchWithPage" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.PageResult" + } + } + } + } + }, + "/hosts/firewall/update/ip": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新 ip 防火墙规则", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Create group", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.AddrRuleUpdate" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/hosts/firewall/update/port": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新端口防火墙规则", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Create group", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PortRuleUpdate" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/hosts/group": { "post": { "security": [ @@ -8512,6 +8757,44 @@ var doc = `{ } }, "definitions": { + "dto.AddrRuleOperate": { + "type": "object", + "required": [ + "address", + "operation", + "strategy" + ], + "properties": { + "address": { + "type": "string" + }, + "operation": { + "type": "string", + "enum": [ + "add", + "remove" + ] + }, + "strategy": { + "type": "string", + "enum": [ + "accept", + "drop" + ] + } + } + }, + "dto.AddrRuleUpdate": { + "type": "object", + "properties": { + "newRule": { + "$ref": "#/definitions/dto.AddrRuleOperate" + }, + "oldRule": { + "$ref": "#/definitions/dto.AddrRuleOperate" + } + } + }, "dto.BackupOperate": { "type": "object", "required": [ @@ -8578,6 +8861,23 @@ var doc = `{ } } }, + "dto.BatchRuleOperate": { + "type": "object", + "required": [ + "type" + ], + "properties": { + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.PortRuleOperate" + } + }, + "type": { + "type": "string" + } + } + }, "dto.CaptchaResponse": { "type": "object", "properties": { @@ -9380,6 +9680,36 @@ var doc = `{ } } }, + "dto.FirewallBaseInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "dto.FirewallOperation": { + "type": "object", + "required": [ + "operation" + ], + "properties": { + "operation": { + "type": "string", + "enum": [ + "start", + "stop", + "reload" + ] + } + } + }, "dto.ForBuckets": { "type": "object", "required": [ @@ -10142,6 +10472,56 @@ var doc = `{ } } }, + "dto.PortRuleOperate": { + "type": "object", + "required": [ + "operation", + "port", + "protocol", + "strategy" + ], + "properties": { + "address": { + "type": "string" + }, + "operation": { + "type": "string", + "enum": [ + "add", + "remove" + ] + }, + "port": { + "type": "string" + }, + "protocol": { + "type": "string", + "enum": [ + "tcp", + "udp", + "tcp/udp" + ] + }, + "strategy": { + "type": "string", + "enum": [ + "accept", + "drop" + ] + } + } + }, + "dto.PortRuleUpdate": { + "type": "object", + "properties": { + "newRule": { + "$ref": "#/definitions/dto.PortRuleOperate" + }, + "oldRule": { + "$ref": "#/definitions/dto.PortRuleOperate" + } + } + }, "dto.PortUpdate": { "type": "object", "required": [ diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index 5445b3c13..7407089e4 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -5052,6 +5052,251 @@ } } }, + "/hosts/firewall/base": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取防火墙基础信息", + "tags": [ + "Firewall" + ], + "summary": "Load firewall base info", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.FirewallBaseInfo" + } + } + } + } + }, + "/hosts/firewall/ip": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "批量删除防火墙规则", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Create group", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.BatchRuleOperate" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/hosts/firewall/operate": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "修改防火墙状态", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Page firewall status", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.FirewallOperation" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.PageResult" + } + } + }, + "x-panel-log": { + "BeforeFuntions": [], + "bodyKeys": [ + "operation" + ], + "formatEN": "[operation] firewall", + "formatZH": "[operation] 防火墙", + "paramKeys": [] + } + } + }, + "/hosts/firewall/port": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "创建防火墙端口规则", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Create group", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PortRuleOperate" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "x-panel-log": { + "BeforeFuntions": [], + "bodyKeys": [ + "port", + "strategy" + ], + "formatEN": "create port rules {[strategy][port]}", + "formatZH": "添加端口规则 {[strategy] [port]}", + "paramKeys": [] + } + } + }, + "/hosts/firewall/search": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取防火墙规则列表分页", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Page firewall rules", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.SearchWithPage" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.PageResult" + } + } + } + } + }, + "/hosts/firewall/update/ip": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新 ip 防火墙规则", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Create group", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.AddrRuleUpdate" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/hosts/firewall/update/port": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新端口防火墙规则", + "consumes": [ + "application/json" + ], + "tags": [ + "Firewall" + ], + "summary": "Create group", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PortRuleUpdate" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/hosts/group": { "post": { "security": [ @@ -8498,6 +8743,44 @@ } }, "definitions": { + "dto.AddrRuleOperate": { + "type": "object", + "required": [ + "address", + "operation", + "strategy" + ], + "properties": { + "address": { + "type": "string" + }, + "operation": { + "type": "string", + "enum": [ + "add", + "remove" + ] + }, + "strategy": { + "type": "string", + "enum": [ + "accept", + "drop" + ] + } + } + }, + "dto.AddrRuleUpdate": { + "type": "object", + "properties": { + "newRule": { + "$ref": "#/definitions/dto.AddrRuleOperate" + }, + "oldRule": { + "$ref": "#/definitions/dto.AddrRuleOperate" + } + } + }, "dto.BackupOperate": { "type": "object", "required": [ @@ -8564,6 +8847,23 @@ } } }, + "dto.BatchRuleOperate": { + "type": "object", + "required": [ + "type" + ], + "properties": { + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.PortRuleOperate" + } + }, + "type": { + "type": "string" + } + } + }, "dto.CaptchaResponse": { "type": "object", "properties": { @@ -9366,6 +9666,36 @@ } } }, + "dto.FirewallBaseInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "dto.FirewallOperation": { + "type": "object", + "required": [ + "operation" + ], + "properties": { + "operation": { + "type": "string", + "enum": [ + "start", + "stop", + "reload" + ] + } + } + }, "dto.ForBuckets": { "type": "object", "required": [ @@ -10128,6 +10458,56 @@ } } }, + "dto.PortRuleOperate": { + "type": "object", + "required": [ + "operation", + "port", + "protocol", + "strategy" + ], + "properties": { + "address": { + "type": "string" + }, + "operation": { + "type": "string", + "enum": [ + "add", + "remove" + ] + }, + "port": { + "type": "string" + }, + "protocol": { + "type": "string", + "enum": [ + "tcp", + "udp", + "tcp/udp" + ] + }, + "strategy": { + "type": "string", + "enum": [ + "accept", + "drop" + ] + } + } + }, + "dto.PortRuleUpdate": { + "type": "object", + "properties": { + "newRule": { + "$ref": "#/definitions/dto.PortRuleOperate" + }, + "oldRule": { + "$ref": "#/definitions/dto.PortRuleOperate" + } + } + }, "dto.PortUpdate": { "type": "object", "required": [ diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index 0600d462a..3a5f3b98d 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -1,5 +1,31 @@ basePath: /api/v1 definitions: + dto.AddrRuleOperate: + properties: + address: + type: string + operation: + enum: + - add + - remove + type: string + strategy: + enum: + - accept + - drop + type: string + required: + - address + - operation + - strategy + type: object + dto.AddrRuleUpdate: + properties: + newRule: + $ref: '#/definitions/dto.AddrRuleOperate' + oldRule: + $ref: '#/definitions/dto.AddrRuleOperate' + type: object dto.BackupOperate: properties: accessKey: @@ -43,6 +69,17 @@ definitions: required: - ids type: object + dto.BatchRuleOperate: + properties: + rules: + items: + $ref: '#/definitions/dto.PortRuleOperate' + type: array + type: + type: string + required: + - type + type: object dto.CaptchaResponse: properties: captchaID: @@ -583,6 +620,26 @@ definitions: required: - path type: object + dto.FirewallBaseInfo: + properties: + name: + type: string + status: + type: string + version: + type: string + type: object + dto.FirewallOperation: + properties: + operation: + enum: + - start + - stop + - reload + type: string + required: + - operation + type: object dto.ForBuckets: properties: accessKey: @@ -1091,6 +1148,41 @@ definitions: hostPort: type: integer type: object + dto.PortRuleOperate: + properties: + address: + type: string + operation: + enum: + - add + - remove + type: string + port: + type: string + protocol: + enum: + - tcp + - udp + - tcp/udp + type: string + strategy: + enum: + - accept + - drop + type: string + required: + - operation + - port + - protocol + - strategy + type: object + dto.PortRuleUpdate: + properties: + newRule: + $ref: '#/definitions/dto.PortRuleOperate' + oldRule: + $ref: '#/definitions/dto.PortRuleOperate' + type: object dto.PortUpdate: properties: serverPort: @@ -5820,6 +5912,158 @@ paths: formatEN: delete host [addrs] formatZH: 删除主机 [addrs] paramKeys: [] + /hosts/firewall/base: + get: + description: 获取防火墙基础信息 + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.FirewallBaseInfo' + security: + - ApiKeyAuth: [] + summary: Load firewall base info + tags: + - Firewall + /hosts/firewall/ip: + post: + consumes: + - application/json + description: 批量删除防火墙规则 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.BatchRuleOperate' + responses: + "200": + description: "" + security: + - ApiKeyAuth: [] + summary: Create group + tags: + - Firewall + /hosts/firewall/operate: + post: + consumes: + - application/json + description: 修改防火墙状态 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.FirewallOperation' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.PageResult' + security: + - ApiKeyAuth: [] + summary: Page firewall status + tags: + - Firewall + x-panel-log: + BeforeFuntions: [] + bodyKeys: + - operation + formatEN: '[operation] firewall' + formatZH: '[operation] 防火墙' + paramKeys: [] + /hosts/firewall/port: + post: + consumes: + - application/json + description: 创建防火墙端口规则 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.PortRuleOperate' + responses: + "200": + description: "" + security: + - ApiKeyAuth: [] + summary: Create group + tags: + - Firewall + x-panel-log: + BeforeFuntions: [] + bodyKeys: + - port + - strategy + formatEN: create port rules {[strategy][port]} + formatZH: 添加端口规则 {[strategy] [port]} + paramKeys: [] + /hosts/firewall/search: + post: + consumes: + - application/json + description: 获取防火墙规则列表分页 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.SearchWithPage' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.PageResult' + security: + - ApiKeyAuth: [] + summary: Page firewall rules + tags: + - Firewall + /hosts/firewall/update/ip: + post: + consumes: + - application/json + description: 更新 ip 防火墙规则 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.AddrRuleUpdate' + responses: + "200": + description: "" + security: + - ApiKeyAuth: [] + summary: Create group + tags: + - Firewall + /hosts/firewall/update/port: + post: + consumes: + - application/json + description: 更新端口防火墙规则 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.PortRuleUpdate' + responses: + "200": + description: "" + security: + - ApiKeyAuth: [] + summary: Create group + tags: + - Firewall /hosts/group: post: consumes: diff --git a/frontend/src/api/interface/host.ts b/frontend/src/api/interface/host.ts index 1295b76e3..b49c18c9a 100644 --- a/frontend/src/api/interface/host.ts +++ b/frontend/src/api/interface/host.ts @@ -53,6 +53,11 @@ export namespace Host { info?: string; } + export interface FirewallBase { + name: string; + status: string; + version: string; + } export interface RuleSearch extends ReqPage { info: string; type: string; diff --git a/frontend/src/api/modules/host.ts b/frontend/src/api/modules/host.ts index 2faafba58..3dbdd747c 100644 --- a/frontend/src/api/modules/host.ts +++ b/frontend/src/api/modules/host.ts @@ -72,9 +72,15 @@ export const deleteCommand = (params: { ids: number[] }) => { }; // firewall +export const loadFireBaseInfo = () => { + return http.get(`/hosts/firewall/base`); +}; export const searchFireRule = (params: Host.RuleSearch) => { return http.post>(`/hosts/firewall/search`, params); }; +export const operateFire = (operation: string) => { + return http.post(`/hosts/firewall/operate`, { operation: operation }); +}; export const operatePortRule = (params: Host.RulePort) => { return http.post(`/hosts/firewall/port`, params); }; diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index bdb3625d2..38748c9a9 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -22,6 +22,8 @@ const message = { clean: '清空', login: '登录', close: '关闭', + stop: '关闭', + start: '开启', view: '详情', watch: '追踪', handle: '执行', @@ -1182,8 +1184,14 @@ const message = { cookieBlockList: 'Cookie 黑名单', firewall: '防火墙', + firewallHelper: '{0}系统防火墙', + firewallNotStart: '当前未开启防火墙服务,请先开启!', + stopFirewallHelper: '停用系统防火墙,服务器将失去安全防护,是否继续操作?', + startFirewallHelper: '启用系统防火墙后,可以更好的防护当前的服务器安全,是否继续操作?', protocol: '协议', port: '端口', + changeStrategy: '修改{0}策略', + changeStrategyHelper: '修改 [{1}] {0}策略为 [{2}],设置后该{0}将{2}外部访问,是否继续操作?', portHelper: '支持输入多个端口,如 80,81 或者范围端口,如 80-88', strategy: '策略', accept: '允许', @@ -1191,6 +1199,8 @@ const message = { source: '来源', anyWhere: '所有 IP', address: '指定 IP', + allow: '放行', + deny: '屏蔽', addressHelper1: '支持输入多个 IP ,如 172.16.10.11,172.16.10.99', addressHelper2: '支持输入 IP 段,如 172.16.10.0/24', addressHelper3: '支持输入 IP 范围,如 172.16.10.11-172.16.10.99', diff --git a/frontend/src/views/host/firewall/ip/index.vue b/frontend/src/views/host/firewall/ip/index.vue index f229bd085..cbee42814 100644 --- a/frontend/src/views/host/firewall/ip/index.vue +++ b/frontend/src/views/host/firewall/ip/index.vue @@ -1,7 +1,13 @@