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
2 changes: 1 addition & 1 deletion agent/app/api/v2/firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func (b *BaseApi) OperateFilterRule(c *gin.Context) {
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := iptablesService.OperateRule(req); err != nil {
if err := iptablesService.OperateRule(req, true); err != nil {
helper.InternalServer(c, err)
return
}
Expand Down
51 changes: 38 additions & 13 deletions agent/app/service/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

type IIptablesService interface {
Search(req dto.SearchPageWithType) (int64, interface{}, error)
OperateRule(req dto.IptablesRuleOp) error
OperateRule(req dto.IptablesRuleOp, withSave bool) error
BatchOperate(req dto.IptablesBatchOperate) error
LoadChainStatus(req dto.OperationWithName) dto.IptablesChainStatus

Expand Down Expand Up @@ -63,7 +63,7 @@
return int64(total), records, nil
}

func (s *IptablesService) OperateRule(req dto.IptablesRuleOp) error {
func (s *IptablesService) OperateRule(req dto.IptablesRuleOp, withSave bool) error {

Check failure on line 66 in agent/app/service/iptables.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 23 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZq1hDgzwPINW-fhMcw5&open=AZq1hDgzwPINW-fhMcw5&pullRequest=11056
action := "ACCEPT"
if req.Strategy == "drop" {
action = "DROP"
Expand Down Expand Up @@ -122,22 +122,37 @@
}
}

if !withSave {
return nil
}
if err := iptables.SaveRulesToFile(iptables.FilterTab, req.Chain, name); err != nil {
global.LOG.Errorf("persistence for %s failed, err: %v", iptables.Chain1PanelBasic, err)
}
return nil
}

func (s *IptablesService) BatchOperate(req dto.IptablesBatchOperate) error {
if len(req.Rules) == 0 {
return errors.New("no rules to operate")
}
for _, rule := range req.Rules {
if err := s.OperateRule(rule); err != nil {
if err := s.OperateRule(rule, false); err != nil {
return err
}
}
chain := iptables.Chain1PanelInput
fileName := iptables.InputFileName
if req.Rules[0].Chain == iptables.Chain1PanelOutput {
chain = iptables.Chain1PanelOutput
fileName = iptables.OutputFileName
}
if err := iptables.SaveRulesToFile(iptables.FilterTab, chain, fileName); err != nil {
global.LOG.Errorf("persistence for %s failed, err: %v", iptables.Chain1PanelBasic, err)
}
return nil
}

func (s *IptablesService) Operate(req dto.IptablesOp) error {

Check failure on line 155 in agent/app/service/iptables.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 48 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZq1hDgzwPINW-fhMcw6&open=AZq1hDgzwPINW-fhMcw6&pullRequest=11056
targetChain := iptables.ChainInput
if req.Name == iptables.Chain1PanelOutput {
targetChain = iptables.ChainOutput
Expand Down Expand Up @@ -168,6 +183,12 @@
if err := iptables.BindChain(iptables.FilterTab, iptables.ChainInput, iptables.Chain1PanelBasicAfter, 3); err != nil {
return err
}
if err := iptables.SaveRulesToFile(iptables.FilterTab, iptables.Chain1PanelBasicBefore, iptables.BasicBeforeFileName); err != nil {
return err
}
if err := iptables.SaveRulesToFile(iptables.FilterTab, iptables.Chain1PanelBasicAfter, iptables.BasicAfterFileName); err != nil {
return err
}
return nil
case "init-forward":
return client.EnableIptablesForward()
Expand Down Expand Up @@ -310,16 +331,7 @@
if err := iptables.AddRule(iptables.FilterTab, iptables.Chain1PanelBasicBefore, iptables.EstablishedRule); err != nil {
return err
}
panelPort := ""
if !global.IsMaster {
panelPort = global.CONF.Base.Port
} else {
var portSetting model.Setting
_ = global.CoreDB.Where("key = ?", "ServerPort").First(&portSetting).Error
if len(portSetting.Value) != 0 {
panelPort = portSetting.Value
}
}
panelPort := LoadPanelPort()
if len(panelPort) == 0 {
return errors.New("find 1panel service port failed")
}
Expand All @@ -337,3 +349,16 @@
}
return nil
}

func LoadPanelPort() string {
if !global.IsMaster {
return global.CONF.Base.Port
} else {
var portSetting model.Setting
_ = global.CoreDB.Where("key = ?", "ServerPort").First(&portSetting).Error
if len(portSetting.Value) != 0 {
return portSetting.Value
}
}
return ""
}
77 changes: 71 additions & 6 deletions agent/init/firewall/firwall.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,89 @@
package firewall

import (
"fmt"

"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/service"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/firewall"
"github.com/1Panel-dev/1Panel/agent/utils/firewall/client/iptables"
)

func Init() {

Check failure on line 13 in agent/init/firewall/firwall.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 31 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZq1hDnIwPINW-fhMcw9&open=AZq1hDnIwPINW-fhMcw9&pullRequest=11056
client, err := firewall.NewFirewallClient()
if err != nil {
return
}
clientName := client.Name()
if clientName == "ufw" || clientName == "iptables" {
_ = iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelForward, iptables.ForwardFileName)
_ = iptables.LoadRulesFromFile(iptables.NatTab, iptables.Chain1PanelPreRouting, iptables.ForwardFileName1)
_ = iptables.LoadRulesFromFile(iptables.NatTab, iptables.Chain1PanelPostRouting, iptables.ForwardFileName2)
if err := iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelForward, iptables.ForwardFileName); err != nil {
global.LOG.Errorf("load forward rules from file failed, err: %v", err)
return
}
if err := iptables.LoadRulesFromFile(iptables.NatTab, iptables.Chain1PanelPreRouting, iptables.ForwardFileName1); err != nil {
global.LOG.Errorf("load prerouting rules from file failed, err: %v", err)
return
}
if err := iptables.LoadRulesFromFile(iptables.NatTab, iptables.Chain1PanelPostRouting, iptables.ForwardFileName2); err != nil {
global.LOG.Errorf("load postrouting rules from file failed, err: %v", err)
return
}
global.LOG.Infof("loaded iptables rules for forward from file successfully")
}
if clientName == "ufw" {
_ = iptables.UnbindChain(iptables.FilterTab, iptables.ChainInput, iptables.Chain1PanelBasicAfter)
_ = iptables.UnbindChain(iptables.FilterTab, iptables.ChainInput, iptables.Chain1PanelBasicBefore)
_ = iptables.UnbindChain(iptables.FilterTab, iptables.ChainInput, iptables.Chain1PanelBasic)
_ = iptables.UnbindChain(iptables.FilterTab, iptables.ChainInput, iptables.Chain1PanelInput)
_ = iptables.UnbindChain(iptables.FilterTab, iptables.ChainOutput, iptables.Chain1PanelOutput)
}
if clientName == "iptables" {
_ = iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelBasic, iptables.BasicFileName)
_ = iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelInput, iptables.InputFileName)
_ = iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelOutput, iptables.OutputFileName)
if err := iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelBasicBefore, iptables.BasicBeforeFileName); err != nil {
global.LOG.Errorf("load basic before rules from file failed, err: %v", err)
return
}
if err := iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelBasic, iptables.BasicFileName); err != nil {
global.LOG.Errorf("load basic rules from file failed, err: %v", err)
return
}
if err := iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelBasicAfter, iptables.BasicAfterFileName); err != nil {
global.LOG.Errorf("load basic after rules from file failed, err: %v", err)
return
}
if err := iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelInput, iptables.InputFileName); err != nil {
global.LOG.Errorf("load input rules from file failed, err: %v", err)
return
}
if err := iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelOutput, iptables.OutputFileName); err != nil {
global.LOG.Errorf("load output rules from file failed, err: %v", err)
return
}
global.LOG.Infof("loaded iptables rules for basic, input and output from file successfully")

panelPort := service.LoadPanelPort()
if len(panelPort) == 0 {
global.LOG.Errorf("find 1panel service port failed")
return
}
if err := iptables.AddRule(iptables.FilterTab, iptables.Chain1PanelBasicBefore, fmt.Sprintf("-p tcp -m tcp --dport %v -j ACCEPT", panelPort)); err != nil {
global.LOG.Errorf("add port accept rule %v failed, err: %v", panelPort, err)
return
}

iptablesService := service.IptablesService{}
if err := iptablesService.Operate(dto.IptablesOp{Operate: "bind-base"}); err != nil {
global.LOG.Errorf("bind base chains failed, err: %v", err)
return
}
if err := iptablesService.Operate(dto.IptablesOp{Name: iptables.Chain1PanelOutput, Operate: "bind"}); err != nil {
global.LOG.Errorf("bind output chains failed, err: %v", err)
return
}
if err := iptablesService.Operate(dto.IptablesOp{Name: iptables.Chain1PanelInput, Operate: "bind"}); err != nil {
global.LOG.Errorf("bind input chains failed, err: %v", err)
return
}
}

}
12 changes: 10 additions & 2 deletions agent/utils/firewall/client/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
return datas, nil
}

func (i *Iptables) Port(port FireInfo, operation string) error {

Check failure on line 111 in agent/utils/firewall/client/iptables.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 16 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZq1hDm2wPINW-fhMcw7&open=AZq1hDm2wPINW-fhMcw7&pullRequest=11056
if operation != "add" && operation != "remove" {
return buserr.New("ErrCmdIllegal")
}
Expand Down Expand Up @@ -144,15 +144,19 @@
}
}

name := iptables.BasicFileName
if port.Chain == iptables.Chain1PanelBasicBefore {
name = iptables.BasicBeforeFileName
}
if port.Chain == iptables.Chain1PanelBasic {
if err := iptables.SaveRulesToFile(iptables.FilterTab, iptables.Chain1PanelBasic, iptables.BasicFileName); err != nil {
if err := iptables.SaveRulesToFile(iptables.FilterTab, port.Chain, name); err != nil {
global.LOG.Errorf("persistence for %s failed, err: %v", iptables.Chain1PanelBasic, err)
}
}
return nil
}

func (i *Iptables) RichRules(rule FireInfo, operation string) error {

Check failure on line 159 in agent/utils/firewall/client/iptables.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 24 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZq1hDm2wPINW-fhMcw8&open=AZq1hDm2wPINW-fhMcw8&pullRequest=11056
if operation != "add" && operation != "remove" {
return buserr.New("ErrCmdIllegal")
}
Expand Down Expand Up @@ -207,8 +211,12 @@
}
}

name := iptables.BasicFileName
if rule.Chain == iptables.Chain1PanelBasicBefore {
name = iptables.BasicBeforeFileName
}
if rule.Chain == iptables.Chain1PanelBasic {
if err := iptables.SaveRulesToFile(iptables.FilterTab, iptables.Chain1PanelBasic, iptables.BasicFileName); err != nil {
if err := iptables.SaveRulesToFile(iptables.FilterTab, rule.Chain, name); err != nil {
global.LOG.Errorf("persistence for %s failed, err: %v", iptables.Chain1PanelBasic, err)
}
}
Expand Down
50 changes: 19 additions & 31 deletions agent/utils/firewall/client/iptables/persistence.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import (
)

const (
BasicFileName = "1panel_basic.rules"
InputFileName = "1panel_input.rules"
OutputFileName = "1panel_out.rules"
ForwardFileName = "1panel_forward.rules"
ForwardFileName1 = "1panel_forward_pre.rules"
ForwardFileName2 = "1panel_forward_post.rules"
BasicBeforeFileName = "1panel_basic_before.rules"
BasicFileName = "1panel_basic.rules"
BasicAfterFileName = "1panel_basic_after.rules"
InputFileName = "1panel_input.rules"
OutputFileName = "1panel_out.rules"
ForwardFileName = "1panel_forward.rules"
ForwardFileName1 = "1panel_forward_pre.rules"
ForwardFileName2 = "1panel_forward_post.rules"
)

func SaveRulesToFile(tab, chain, fileName string) error {
Expand Down Expand Up @@ -63,39 +65,25 @@ func LoadRulesFromFile(tab, chain, fileName string) error {
return nil
}

file, err := os.Open(rulesFile)
if err != nil {
return fmt.Errorf("failed to open rules file: %w", err)
if err := AddChain(tab, chain); err != nil {
global.LOG.Errorf("create chain %s failed: %v", chain, err)
return err
}
defer file.Close()

var rules []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue
}
rules = append(rules, line)
}

if err := scanner.Err(); err != nil {
return fmt.Errorf("failed to read rules file: %w", err)
data, err := os.ReadFile(rulesFile)
if err != nil {
global.LOG.Errorf("read rules from file %s failed, err: %v", rulesFile, err)
return err
}

rules := strings.Split(string(data), "\n")
if err := ClearChain(tab, chain); err != nil {
global.LOG.Warnf("Failed to clear existing rules from %s: %v", chain, err)
global.LOG.Warnf("clear existing rules from %s failed, err: %v", chain, err)
}

appliedCount := 0
for _, rule := range rules {
if strings.HasPrefix(rule, fmt.Sprintf("-A %s", chain)) {
ruleArgs := strings.TrimPrefix(rule, "-A ")
if err := Run(tab, "-A "+ruleArgs); err != nil {
global.LOG.Errorf("Failed to apply rule '%s': %v", rule, err)
continue
if err := Run(tab, rule); err != nil {
global.LOG.Errorf("apply rule '%s' failed, err: %v", rule, err)
}
appliedCount++
}
}

Expand Down
Loading