Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 11 additions & 107 deletions agent/app/service/firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package service
import (
"context"
"fmt"
"os"
"sort"
"strconv"
"strings"
Expand All @@ -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"
Expand All @@ -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 {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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 {
Expand Down
18 changes: 18 additions & 0 deletions agent/init/firewall/firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func Init() {
if !needInit() {
return
}
InitPingStatus()
global.LOG.Info("initializing firewall settings...")
client, err := firewall.NewFirewallClient()
if err != nil {
Expand Down Expand Up @@ -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)
}
}
1 change: 1 addition & 0 deletions agent/init/migration/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func InitAgentDB() {
migrations.InitIptablesStatus,
migrations.UpdateWebsite,
migrations.AddisIPtoWebsiteSSL,
migrations.InitPingStatus,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
Expand Down
11 changes: 11 additions & 0 deletions agent/init/migration/migrations/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
}
105 changes: 105 additions & 0 deletions agent/utils/firewall/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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
}
Loading