From fd3a2c95027557254aad1626e80e49f841e92b1a Mon Sep 17 00:00:00 2001 From: ssongliu Date: Mon, 29 Dec 2025 15:26:06 +0800 Subject: [PATCH] feat: ICMP ping disable compatibility with Debian 13 --- agent/app/service/firewall.go | 118 +++--------------------- agent/init/firewall/firewall.go | 18 ++++ agent/init/migration/migrate.go | 1 + agent/init/migration/migrations/init.go | 11 +++ agent/utils/firewall/client.go | 105 +++++++++++++++++++++ 5 files changed, 146 insertions(+), 107 deletions(-) diff --git a/agent/app/service/firewall.go b/agent/app/service/firewall.go index b8dcf96d8735..90962037619c 100644 --- a/agent/app/service/firewall.go +++ b/agent/app/service/firewall.go @@ -3,7 +3,6 @@ package service import ( "context" "fmt" - "os" "sort" "strconv" "strings" @@ -14,7 +13,6 @@ import ( "github.com/1Panel-dev/1Panel/agent/buserr" "github.com/1Panel-dev/1Panel/agent/constant" "github.com/1Panel-dev/1Panel/agent/global" - "github.com/1Panel-dev/1Panel/agent/utils/cmd" "github.com/1Panel-dev/1Panel/agent/utils/common" "github.com/1Panel-dev/1Panel/agent/utils/controller" "github.com/1Panel-dev/1Panel/agent/utils/firewall" @@ -23,9 +21,6 @@ import ( "github.com/jinzhu/copier" ) -const confPath = "/etc/sysctl.conf" -const panelSysctlPath = "/etc/sysctl.d/98-onepanel.conf" - type FirewallService struct{} type IFirewallService interface { @@ -62,7 +57,7 @@ func (u *FirewallService) LoadBaseInfo(tab string) (dto.FirewallBaseInfo, error) wg.Add(2) go func() { defer wg.Done() - baseInfo.PingStatus = u.pingStatus() + baseInfo.PingStatus = firewall.LoadPingStatus() baseInfo.Version, _ = client.Version() }() go func() { @@ -207,9 +202,17 @@ func (u *FirewallService) OperateFirewall(req dto.FirewallOperation) error { } needRestartDocker = true case "disablePing": - return u.updatePingStatus("0") + if err := firewall.UpdatePingStatus("0"); err != nil { + _ = settingRepo.Update("BanPing", constant.StatusDisable) + return err + } + return nil case "enablePing": - return u.updatePingStatus("1") + if err := firewall.UpdatePingStatus("1"); err != nil { + _ = settingRepo.Update("BanPing", constant.StatusEnable) + return err + } + return nil default: return fmt.Errorf("not supported operation: %s", req.Operation) } @@ -589,105 +592,6 @@ func (u *FirewallService) cleanUnUsedData(client firewall.FirewallClient) { } } -func (u *FirewallService) pingStatus() string { - data, err := os.ReadFile("/proc/sys/net/ipv4/icmp_echo_ignore_all") - if err != nil { - return constant.StatusNone - } - v6Data, v6err := os.ReadFile("/proc/sys/net/ipv6/icmp/echo_ignore_all") - if v6err != nil { - if strings.TrimSpace(string(data)) == "1" { - return constant.StatusEnable - } - return constant.StatusDisable - } else { - if strings.TrimSpace(string(data)) == "1" && strings.TrimSpace(string(v6Data)) == "1" { - return constant.StatusEnable - } - return constant.StatusDisable - } - -} - -func (u *FirewallService) updatePingStatus(enable string) error { - var targetPath string - var applyCmd string - - if _, err := os.Stat(confPath); os.IsNotExist(err) { - // Debian 13 - targetPath = panelSysctlPath - applyCmd = fmt.Sprintf("%s sysctl --system", cmd.SudoHandleCmd()) - if err := cmd.RunDefaultBashCf("%s mkdir -p /etc/sysctl.d", cmd.SudoHandleCmd()); err != nil { - return fmt.Errorf("failed to create directory /etc/sysctl.d: %v", err) - } - } else { - targetPath = confPath - applyCmd = fmt.Sprintf("%s sysctl -p", cmd.SudoHandleCmd()) - } - - lineBytes, err := os.ReadFile(targetPath) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to read %s: %v", targetPath, err) - } - - if err := cmd.RunDefaultBashCf("echo %s | %s tee /proc/sys/net/ipv4/icmp_echo_ignore_all > /dev/null", enable, cmd.SudoHandleCmd()); err != nil { - return fmt.Errorf("failed to apply ipv4 ping status temporarily: %v", err) - } - - var hasIpv6 bool - if _, err := os.Stat("/proc/sys/net/ipv6/icmp/echo_ignore_all"); err == nil { - hasIpv6 = true - if err := cmd.RunDefaultBashCf("echo %s | %s tee /proc/sys/net/ipv6/icmp/echo_ignore_all > /dev/null", enable, cmd.SudoHandleCmd()); err != nil { - global.LOG.Warnf("failed to apply ipv6 ping status temporarily: %v", err) - } - } - - var files []string - if err == nil { - files = strings.Split(string(lineBytes), "\n") - } - - var newFiles []string - hasIPv4Line, hasIPv6Line := false, false - - for _, line := range files { - if strings.HasPrefix(strings.TrimSpace(line), "net.ipv4.icmp_echo_ignore_all") { - newFiles = append(newFiles, "net.ipv4.icmp_echo_ignore_all="+enable) - hasIPv4Line = true - continue - } - if strings.HasPrefix(strings.TrimSpace(line), "net.ipv6.icmp.echo_ignore_all") { - newFiles = append(newFiles, "net.ipv6.icmp.echo_ignore_all="+enable) - hasIPv6Line = true - continue - } - newFiles = append(newFiles, line) - } - - if !hasIPv4Line { - newFiles = append(newFiles, "net.ipv4.icmp_echo_ignore_all="+enable) - } - if hasIpv6 && !hasIPv6Line { - newFiles = append(newFiles, "net.ipv6.icmp.echo_ignore_all="+enable) - } - - file, err := os.OpenFile(targetPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, constant.FilePerm) - if err != nil { - return fmt.Errorf("failed to open %s: %v", targetPath, err) - } - defer file.Close() - - if _, err = file.WriteString(strings.Join(newFiles, "\n")); err != nil { - return fmt.Errorf("failed to write to %s: %v", targetPath, err) - } - - if err := cmd.RunDefaultBashC(applyCmd); err != nil { - global.LOG.Warnf("failed to apply persistent config with '%s': %v", applyCmd, err) - } - - return nil -} - func (u *FirewallService) addPortsBeforeStart(client firewall.FirewallClient) error { if !global.IsMaster { if err := client.Port(fireClient.FireInfo{Port: global.CONF.Base.Port, Protocol: "tcp", Strategy: "accept"}, "add"); err != nil { diff --git a/agent/init/firewall/firewall.go b/agent/init/firewall/firewall.go index 5be271a779ce..98817a56792c 100644 --- a/agent/init/firewall/firewall.go +++ b/agent/init/firewall/firewall.go @@ -18,6 +18,7 @@ func Init() { if !needInit() { return } + InitPingStatus() global.LOG.Info("initializing firewall settings...") client, err := firewall.NewFirewallClient() if err != nil { @@ -122,3 +123,20 @@ func needInit() bool { fmt.Fprintf(file, "Boot Mark for 1panel\n") return true } + +func InitPingStatus() { + global.LOG.Info("initializing ban ping status from settings...") + status := firewall.LoadPingStatus() + statusInDB, _ := repo.NewISettingRepo().GetValueByKey("BanPing") + if statusInDB == status { + return + } + + enable := "1" + if statusInDB == constant.StatusDisable { + enable = "0" + } + if err := firewall.UpdatePingStatus(enable); err != nil { + global.LOG.Errorf("initialize ping status failed: %v", err) + } +} diff --git a/agent/init/migration/migrate.go b/agent/init/migration/migrate.go index 60b4307468b3..d0ed9cc88831 100644 --- a/agent/init/migration/migrate.go +++ b/agent/init/migration/migrate.go @@ -59,6 +59,7 @@ func InitAgentDB() { migrations.InitIptablesStatus, migrations.UpdateWebsite, migrations.AddisIPtoWebsiteSSL, + migrations.InitPingStatus, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/agent/init/migration/migrations/init.go b/agent/init/migration/migrations/init.go index 0c97424a0274..c954888e9388 100644 --- a/agent/init/migration/migrations/init.go +++ b/agent/init/migration/migrations/init.go @@ -789,3 +789,14 @@ var AddisIPtoWebsiteSSL = &gormigrate.Migration{ return tx.AutoMigrate(&model.WebsiteSSL{}) }, } + +var InitPingStatus = &gormigrate.Migration{ + ID: "20251201-init-ping-status", + Migrate: func(tx *gorm.DB) error { + status := firewall.LoadPingStatus() + if err := tx.Create(&model.Setting{Key: "BanPing", Value: status}).Error; err != nil { + return err + } + return nil + }, +} diff --git a/agent/utils/firewall/client.go b/agent/utils/firewall/client.go index 97b481b8c72f..fef4310c5a59 100644 --- a/agent/utils/firewall/client.go +++ b/agent/utils/firewall/client.go @@ -2,7 +2,12 @@ package firewall import ( "errors" + "fmt" + "os" + "strings" + "github.com/1Panel-dev/1Panel/agent/constant" + "github.com/1Panel-dev/1Panel/agent/global" "github.com/1Panel-dev/1Panel/agent/utils/cmd" "github.com/1Panel-dev/1Panel/agent/utils/firewall/client" ) @@ -47,3 +52,103 @@ func NewFirewallClient() (FirewallClient, error) { } return nil, errors.New("No system firewall service detected (firewalld/ufw/iptables), please check and try again!") } + +func LoadPingStatus() string { + data, err := os.ReadFile("/proc/sys/net/ipv4/icmp_echo_ignore_all") + if err != nil { + return constant.StatusNone + } + v6Data, v6err := os.ReadFile("/proc/sys/net/ipv6/icmp/echo_ignore_all") + if v6err != nil { + if strings.TrimSpace(string(data)) == "1" { + return constant.StatusEnable + } + return constant.StatusDisable + } else { + if strings.TrimSpace(string(data)) == "1" && strings.TrimSpace(string(v6Data)) == "1" { + return constant.StatusEnable + } + return constant.StatusDisable + } +} + +func UpdatePingStatus(enable string) error { + const confPath = "/etc/sysctl.conf" + const panelSysctlPath = "/etc/sysctl.d/98-onepanel.conf" + + var targetPath string + var applyCmd string + + if _, err := os.Stat(confPath); os.IsNotExist(err) { + targetPath = panelSysctlPath + applyCmd = fmt.Sprintf("%s sysctl --system", cmd.SudoHandleCmd()) + if err := cmd.RunDefaultBashCf("%s mkdir -p /etc/sysctl.d", cmd.SudoHandleCmd()); err != nil { + return fmt.Errorf("failed to create directory /etc/sysctl.d: %v", err) + } + } else { + targetPath = confPath + applyCmd = fmt.Sprintf("%s sysctl -p", cmd.SudoHandleCmd()) + } + + lineBytes, err := os.ReadFile(targetPath) + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to read %s: %v", targetPath, err) + } + + if err := cmd.RunDefaultBashCf("echo %s | %s tee /proc/sys/net/ipv4/icmp_echo_ignore_all > /dev/null", enable, cmd.SudoHandleCmd()); err != nil { + return fmt.Errorf("failed to apply ipv4 ping status temporarily: %v", err) + } + + var hasIpv6 bool + if _, err := os.Stat("/proc/sys/net/ipv6/icmp/echo_ignore_all"); err == nil { + hasIpv6 = true + if err := cmd.RunDefaultBashCf("echo %s | %s tee /proc/sys/net/ipv6/icmp/echo_ignore_all > /dev/null", enable, cmd.SudoHandleCmd()); err != nil { + global.LOG.Warnf("failed to apply ipv6 ping status temporarily: %v", err) + } + } + + var files []string + if err == nil { + files = strings.Split(string(lineBytes), "\n") + } + + var newFiles []string + hasIPv4Line, hasIPv6Line := false, false + + for _, line := range files { + if strings.HasPrefix(strings.TrimSpace(line), "net.ipv4.icmp_echo_ignore_all") { + newFiles = append(newFiles, "net.ipv4.icmp_echo_ignore_all="+enable) + hasIPv4Line = true + continue + } + if strings.HasPrefix(strings.TrimSpace(line), "net.ipv6.icmp.echo_ignore_all") { + newFiles = append(newFiles, "net.ipv6.icmp.echo_ignore_all="+enable) + hasIPv6Line = true + continue + } + newFiles = append(newFiles, line) + } + + if !hasIPv4Line { + newFiles = append(newFiles, "net.ipv4.icmp_echo_ignore_all="+enable) + } + if hasIpv6 && !hasIPv6Line { + newFiles = append(newFiles, "net.ipv6.icmp.echo_ignore_all="+enable) + } + + file, err := os.OpenFile(targetPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, constant.FilePerm) + if err != nil { + return fmt.Errorf("failed to open %s: %v", targetPath, err) + } + defer file.Close() + + if _, err = file.WriteString(strings.Join(newFiles, "\n")); err != nil { + return fmt.Errorf("failed to write to %s: %v", targetPath, err) + } + + if err := cmd.RunDefaultBashC(applyCmd); err != nil { + global.LOG.Warnf("failed to apply persistent config with '%s': %v", applyCmd, err) + } + + return nil +}