You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.4 KiB
Go
155 lines
4.4 KiB
Go
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"
|
|
)
|
|
|
|
type FirewallClient interface {
|
|
Name() string // ufw firewalld
|
|
Start() error
|
|
Stop() error
|
|
Restart() error
|
|
Reload() error
|
|
Status() (bool, error)
|
|
Version() (string, error)
|
|
|
|
ListPort() ([]client.FireInfo, error)
|
|
ListForward() ([]client.FireInfo, error)
|
|
ListAddress() ([]client.FireInfo, error)
|
|
|
|
Port(port client.FireInfo, operation string) error
|
|
RichRules(rule client.FireInfo, operation string) error
|
|
PortForward(info client.Forward, operation string) error
|
|
|
|
EnableForward() error
|
|
}
|
|
|
|
func NewFirewallClient() (FirewallClient, error) {
|
|
firewalld := cmd.Which("firewalld")
|
|
ufw := cmd.Which("ufw")
|
|
|
|
if firewalld && ufw {
|
|
return nil, errors.New("It is detected that the system has both firewalld and ufw services. To avoid conflicts, please uninstall and try again!")
|
|
}
|
|
if firewalld {
|
|
return client.NewFirewalld()
|
|
}
|
|
if ufw {
|
|
return client.NewUfw()
|
|
}
|
|
|
|
iptables := cmd.Which("iptables")
|
|
if iptables {
|
|
return client.NewIptables()
|
|
}
|
|
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
|
|
}
|