From cd266d2567e2411dcf70049f8d408dc6b22a242b Mon Sep 17 00:00:00 2001 From: ssongliu <73214554+ssongliu@users.noreply.github.com> Date: Mon, 23 Dec 2024 22:05:31 +0800 Subject: [PATCH] feat: Synchronously update the firewall when modifying connection information (#7536) --- core/app/service/setting.go | 89 ++++++++++++++++++++++++++++++--- core/configs/system.go | 1 - core/constant/errs.go | 1 + core/constant/status.go | 1 + core/i18n/lang/en.yaml | 1 + core/i18n/lang/zh-Hant.yaml | 1 + core/i18n/lang/zh.yaml | 1 + core/init/hook/hook.go | 5 -- core/utils/cmd/cmd.go | 9 ++++ core/utils/firewall/firewall.go | 50 ++++++++++++++++++ core/utils/xpack/xpack.go | 14 ++---- 11 files changed, 151 insertions(+), 22 deletions(-) create mode 100644 core/utils/firewall/firewall.go diff --git a/core/app/service/setting.go b/core/app/service/setting.go index ca3e62e71..92923a9a1 100644 --- a/core/app/service/setting.go +++ b/core/app/service/setting.go @@ -9,6 +9,7 @@ import ( "net" "os" "path" + "regexp" "strconv" "strings" "time" @@ -21,6 +22,8 @@ import ( "github.com/1Panel-dev/1Panel/core/utils/cmd" "github.com/1Panel-dev/1Panel/core/utils/common" "github.com/1Panel-dev/1Panel/core/utils/encrypt" + "github.com/1Panel-dev/1Panel/core/utils/firewall" + "github.com/1Panel-dev/1Panel/core/utils/xpack" "github.com/gin-gonic/gin" ) @@ -75,6 +78,13 @@ func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) { } func (u *SettingService) Update(key, value string) error { + oldVal, err := settingRepo.Get(repo.WithByKey(key)) + if err != nil { + return err + } + if oldVal.Value == value { + return nil + } switch key { case "AppStoreLastModified": exist, _ := settingRepo.Get(repo.WithByKey("AppStoreLastModified")) @@ -82,8 +92,6 @@ func (u *SettingService) Update(key, value string) error { _ = settingRepo.Create("AppStoreLastModified", value) return nil } - case "MasterAddr": - global.CONF.System.MasterAddr = value } if err := settingRepo.Update(key, value); err != nil { @@ -105,7 +113,12 @@ func (u *SettingService) Update(key, value string) error { } case "UserName", "Password": _ = global.SESSION.Clean() - + case "MasterAddr": + go func() { + if err := xpack.UpdateMasterAddr(value); err != nil { + global.LOG.Errorf("update master addr failed, err: %v", err) + } + }() } return nil @@ -174,16 +187,40 @@ func (u *SettingService) UpdatePort(port uint) error { if common.ScanPort(int(port)) { return buserr.WithDetail(constant.ErrPortInUsed, port, nil) } - // TODO 修改防火墙端口 + oldPort, err := settingRepo.Get(repo.WithByKey("Port")) + if err != nil { + return err + } + if oldPort.Value == fmt.Sprintf("%v", port) { + return nil + } + if err := firewall.UpdatePort(oldPort.Value, fmt.Sprintf("%v", port)); err != nil { + return err + } if err := settingRepo.Update("ServerPort", strconv.Itoa(int(port))); err != nil { return err } go func() { time.Sleep(1 * time.Second) - _, err := cmd.Exec("systemctl restart 1panel.service") + defer func() { + if _, err := cmd.Exec("systemctl restart 1panel.service"); err != nil { + global.LOG.Errorf("restart system port failed, err: %v", err) + } + }() + masterAddr, err := settingRepo.Get(repo.WithByKey("MasterAddr")) if err != nil { - global.LOG.Errorf("restart system port failed, err: %v", err) + global.LOG.Errorf("load master addr from db failed, err: %v", err) + return + } + if len(masterAddr.Value) != 0 { + oldMasterPort := loadPort(masterAddr.Value) + if len(oldMasterPort) != 0 { + if err := xpack.UpdateMasterAddr(strings.ReplaceAll(masterAddr.Value, oldMasterPort, fmt.Sprintf("%v", port))); err != nil { + global.LOG.Errorf("update master addr from db failed, err: %v", err) + return + } + } } }() return nil @@ -250,7 +287,31 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error { if err := settingRepo.Update("SSL", req.SSL); err != nil { return err } - return u.UpdateSystemSSL() + + if err := u.UpdateSystemSSL(); err != nil { + return err + } + + go func() { + oldSSL, _ := settingRepo.Get(repo.WithByKey("SSL")) + if oldSSL.Value != req.SSL { + masterAddr, err := settingRepo.Get(repo.WithByKey("MasterAddr")) + if err != nil { + global.LOG.Errorf("load master addr from db failed, err: %v", err) + return + } + addrItem := masterAddr.Value + if req.SSL == constant.StatusDisable { + addrItem = strings.ReplaceAll(addrItem, "https://", "http://") + } else { + addrItem = strings.ReplaceAll(addrItem, "http://", "https://") + } + if err := xpack.UpdateMasterAddr(addrItem); err != nil { + global.LOG.Errorf("update master addr from db failed, err: %v", err) + } + } + }() + return nil } func (u *SettingService) LoadFromCert() (*dto.SSLInfo, error) { @@ -452,3 +513,17 @@ func checkCertValid() error { return nil } + +func loadPort(address string) string { + re := regexp.MustCompile(`(?:(?:\[([0-9a-fA-F:]+)\])|([^:/\s]+))(?::(\d+))?$`) + matches := re.FindStringSubmatch(address) + if len(matches) <= 0 { + return "" + } + var port string + port = matches[3] + if len(port) != 0 { + return port + } + return "" +} diff --git a/core/configs/system.go b/core/configs/system.go index 5c63be9a3..ffcc155f8 100644 --- a/core/configs/system.go +++ b/core/configs/system.go @@ -5,7 +5,6 @@ type System struct { Ipv6 string `mapstructure:"ipv6"` BindAddress string `mapstructure:"bindAddress"` SSL string `mapstructure:"ssl"` - MasterAddr string `mapstructure:"masterAddr"` DbCoreFile string `mapstructure:"db_core_file"` EncryptKey string `mapstructure:"encrypt_key"` BaseDir string `mapstructure:"base_dir"` diff --git a/core/constant/errs.go b/core/constant/errs.go index ac34d7713..3265cbf47 100644 --- a/core/constant/errs.go +++ b/core/constant/errs.go @@ -76,4 +76,5 @@ var ( ErrFreeNodeLimit = "ErrFreeNodeLimit" ErrNodeBound = "ErrNodeBound" ErrNodeBind = "ErrNodeBind" + ConnInfoNotMatch = "ConnInfoNotMatch" ) diff --git a/core/constant/status.go b/core/constant/status.go index cc5979fde..2f78fba17 100644 --- a/core/constant/status.go +++ b/core/constant/status.go @@ -8,6 +8,7 @@ const ( StatusWaiting = "Waiting" StatusPacking = "Packing" StatusSending = "Sending" + StatusChecking = "Checking" StatusStarting = "Starting" StatusHealthy = "Healthy" StatusUnhealthy = "Unhealthy" diff --git a/core/i18n/lang/en.yaml b/core/i18n/lang/en.yaml index f93717601..56900f0b5 100644 --- a/core/i18n/lang/en.yaml +++ b/core/i18n/lang/en.yaml @@ -82,6 +82,7 @@ RestartAfterUpgrade: "Start Service After Upgrade" #add node TaskAddNode: "Add Node" GenerateSSLInfo: "Generate Node SSL Information" +ConnInfoNotMatch: "Connection information does not match"; MakeAgentPackage: "Generate Node Installation Package" SendAgent: "Distribute Node Installation Package" StartService: "Start Service" \ No newline at end of file diff --git a/core/i18n/lang/zh-Hant.yaml b/core/i18n/lang/zh-Hant.yaml index ef61db72b..e10890099 100644 --- a/core/i18n/lang/zh-Hant.yaml +++ b/core/i18n/lang/zh-Hant.yaml @@ -82,6 +82,7 @@ RestartAfterUpgrade: "升級後啟動服務" #node create TaskAddNode: "添加節點" GenerateSSLInfo: "生成節點 SSL 信息" +ConnInfoNotMatch: "連接信息不匹配"; MakeAgentPackage: "生成節點安裝包" SendAgent: "下發節點安裝包" StartService: "啟動服務" \ No newline at end of file diff --git a/core/i18n/lang/zh.yaml b/core/i18n/lang/zh.yaml index 6fe3641f5..d7f26d31b 100644 --- a/core/i18n/lang/zh.yaml +++ b/core/i18n/lang/zh.yaml @@ -84,6 +84,7 @@ RestartAfterUpgrade: "升级后启动服务" #add node TaskAddNode: "添加节点" GenerateSSLInfo: "生成节点 SSL 信息" +ConnInfoNotMatch: "连接信息不匹配" MakeAgentPackage: "生成节点安装包" SendAgent: "下发节点安装包" StartService: "启动服务" \ No newline at end of file diff --git a/core/init/hook/hook.go b/core/init/hook/hook.go index 69b1e2f41..ae1871c0f 100644 --- a/core/init/hook/hook.go +++ b/core/init/hook/hook.go @@ -14,11 +14,6 @@ import ( func Init() { settingRepo := repo.NewISettingRepo() - masterSetting, err := settingRepo.Get(repo.WithByKey("MasterAddr")) - if err != nil { - global.LOG.Errorf("load master addr from setting failed, err: %v", err) - } - global.CONF.System.MasterAddr = masterSetting.Value portSetting, err := settingRepo.Get(repo.WithByKey("ServerPort")) if err != nil { global.LOG.Errorf("load service port from setting failed, err: %v", err) diff --git a/core/utils/cmd/cmd.go b/core/utils/cmd/cmd.go index 264326bad..1af39d077 100644 --- a/core/utils/cmd/cmd.go +++ b/core/utils/cmd/cmd.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "os/exec" + "strings" "time" "github.com/1Panel-dev/1Panel/core/buserr" @@ -22,6 +23,14 @@ func SudoHandleCmd() string { return "" } +func Which(name string) bool { + stdout, err := Execf("which %s", name) + if err != nil || (len(strings.ReplaceAll(stdout, "\n", "")) == 0) { + return false + } + return true +} + func Execf(cmdStr string, a ...interface{}) (string, error) { cmd := exec.Command("bash", "-c", fmt.Sprintf(cmdStr, a...)) var stdout, stderr bytes.Buffer diff --git a/core/utils/firewall/firewall.go b/core/utils/firewall/firewall.go new file mode 100644 index 000000000..b9a175404 --- /dev/null +++ b/core/utils/firewall/firewall.go @@ -0,0 +1,50 @@ +package firewall + +import ( + "fmt" + + "github.com/1Panel-dev/1Panel/core/utils/cmd" +) + +func UpdatePort(oldPort, newPort string) error { + firewalld := cmd.Which("firewalld") + if firewalld { + status, _ := cmd.Exec("LANGUAGE=en_US:en firewall-cmd --state") + isRunning := status == "running\n" + if isRunning { + return firewallUpdatePort(oldPort, newPort) + } + } + + ufw := cmd.Which("ufw") + if !ufw { + return nil + } + status, _ := cmd.Exec("LANGUAGE=en_US:en ufw status | grep Status") + isRuning := status == "Status: active\n" + if isRuning { + return ufwUpdatePort(oldPort, newPort) + } + return nil +} + +func firewallUpdatePort(oldPort, newPort string) error { + stdout, err := cmd.Execf("firewall-cmd --zone=public --add-port=%s/tcp --permanent", newPort) + if err != nil { + return fmt.Errorf("add (port: %s/tcp) failed, err: %s", newPort, stdout) + } + + _, _ = cmd.Execf("firewall-cmd --zone=public --remove-port=%s/tcp --permanent", oldPort) + _, _ = cmd.Exec("firewall-cmd --reload") + return nil +} + +func ufwUpdatePort(oldPort, newPort string) error { + stdout, err := cmd.Execf("ufw allow %s", newPort) + if err != nil { + return fmt.Errorf("add (port: %s/tcp) failed, err: %s", newPort, stdout) + } + + _, _ = cmd.Execf("ufw delete allow %s", oldPort) + return nil +} diff --git a/core/utils/xpack/xpack.go b/core/utils/xpack/xpack.go index b29434909..423f14617 100644 --- a/core/utils/xpack/xpack.go +++ b/core/utils/xpack/xpack.go @@ -6,16 +6,12 @@ import ( "github.com/gin-gonic/gin" ) -func Proxy(c *gin.Context, currentNode string) { - return -} +func Proxy(c *gin.Context, currentNode string) { return } -func UpdateGroup(name string, group, newGroup uint) error { - return nil -} +func UpdateGroup(name string, group, newGroup uint) error { return nil } -func CheckBackupUsed(id uint) error { - return nil -} +func CheckBackupUsed(id uint) error { return nil } func InitAgentRouter(Router *gin.RouterGroup) {} + +func UpdateMasterAddr(newAddr string) error { return nil }