From f33ce88a3a71a0279b77e58d9d306280aace9f8a Mon Sep 17 00:00:00 2001 From: GoEdgeLab Date: Sun, 14 Nov 2021 20:35:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DIPTables+IPSet=E7=BB=84?= =?UTF-8?q?=E5=90=88=E6=97=B6=E5=9C=A8IPTables=E4=B8=AD=E7=94=9F=E6=88=90?= =?UTF-8?q?=E4=BA=86=E5=A4=9A=E4=B8=AA=E9=87=8D=E5=A4=8D=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E7=9A=84Bug=EF=BC=9B=E5=A2=9E=E5=8A=A0IPSet=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E5=80=BC=E4=B8=BA1000000=EF=BC=9BIP=E8=8C=83=E5=9B=B4=E5=8F=AA?= =?UTF-8?q?=E6=94=AF=E6=8C=81D=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/iplibrary/action_ipset.go | 85 +++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/internal/iplibrary/action_ipset.go b/internal/iplibrary/action_ipset.go index 1110f75..a5b632a 100644 --- a/internal/iplibrary/action_ipset.go +++ b/internal/iplibrary/action_ipset.go @@ -5,9 +5,11 @@ import ( "errors" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" + "github.com/iwind/TeaGo/types" "os/exec" "runtime" "strconv" + "strings" "time" ) @@ -23,14 +25,21 @@ import ( // - 添加Item:ipset add edge_ip_list 192.168.2.32 timeout 30 // - 删除Item: ipset del edge_ip_list 192.168.2.32 // - 创建set:ipset create edge_ip_list hash:ip timeout 0 +// - 查看统计:ipset -t list edge_black_list +// - 删除set:ipset destroy edge_black_list type IPSetAction struct { BaseAction - config *firewallconfigs.FirewallActionIPSetConfig + config *firewallconfigs.FirewallActionIPSetConfig + errorBuf *bytes.Buffer + + ipsetNotfound bool } func NewIPSetAction() *IPSetAction { - return &IPSetAction{} + return &IPSetAction{ + errorBuf: &bytes.Buffer{}, + } } func (this *IPSetAction) Init(config *firewallconfigs.FirewallActionConfig) error { @@ -54,7 +63,7 @@ func (this *IPSetAction) Init(config *firewallconfigs.FirewallActionConfig) erro return err } { - cmd := exec.Command(path, "create", this.config.WhiteName, "hash:ip", "timeout", "0") + cmd := exec.Command(path, "create", this.config.WhiteName, "hash:ip", "timeout", "0", "maxelem", "1000000") stderr := bytes.NewBuffer([]byte{}) cmd.Stderr = stderr err := cmd.Run() @@ -68,7 +77,7 @@ func (this *IPSetAction) Init(config *firewallconfigs.FirewallActionConfig) erro } } { - cmd := exec.Command(path, "create", this.config.BlackName, "hash:ip", "timeout", "0") + cmd := exec.Command(path, "create", this.config.BlackName, "hash:ip", "timeout", "0", "maxelem", "1000000") stderr := bytes.NewBuffer([]byte{}) cmd.Stderr = stderr err := cmd.Run() @@ -163,24 +172,39 @@ func (this *IPSetAction) Init(config *firewallconfigs.FirewallActionConfig) erro } { - cmd := exec.Command(path, "-A", "INPUT", "-m", "set", "--match-set", this.config.WhiteName, "src", "-j", "ACCEPT") - stderr := bytes.NewBuffer([]byte{}) - cmd.Stderr = stderr + // 检查规则是否存在 + var cmd = exec.Command(path, "-C", "INPUT", "-m", "set", "--match-set", this.config.WhiteName, "src", "-j", "ACCEPT") err := cmd.Run() - if err != nil { - output := stderr.Bytes() - return errors.New("iptables add rule: " + err.Error() + ", output: " + string(output)) + var exists = err == nil + + // 添加规则 + if !exists { + var cmd = exec.Command(path, "-A", "INPUT", "-m", "set", "--match-set", this.config.WhiteName, "src", "-j", "ACCEPT") + stderr := bytes.NewBuffer([]byte{}) + cmd.Stderr = stderr + err := cmd.Run() + if err != nil { + output := stderr.Bytes() + return errors.New("iptables add rule: " + err.Error() + ", output: " + string(output)) + } } } { - cmd := exec.Command(path, "-A", "INPUT", "-m", "set", "--match-set", this.config.BlackName, "src", "-j", "REJECT") - stderr := bytes.NewBuffer([]byte{}) - cmd.Stderr = stderr + // 检查规则是否存在 + var cmd = exec.Command(path, "-C", "INPUT", "-m", "set", "--match-set", this.config.BlackName, "src", "-j", "REJECT") err := cmd.Run() - if err != nil { - output := stderr.Bytes() - return errors.New("iptables add rule: " + err.Error() + ", output: " + string(output)) + var exists = err == nil + + if !exists { + var cmd = exec.Command(path, "-A", "INPUT", "-m", "set", "--match-set", this.config.BlackName, "src", "-j", "REJECT") + stderr := bytes.NewBuffer([]byte{}) + cmd.Stderr = stderr + err := cmd.Run() + if err != nil { + output := stderr.Bytes() + return errors.New("iptables add rule: " + err.Error() + ", output: " + string(output)) + } } } } @@ -212,6 +236,16 @@ func (this *IPSetAction) runAction(action string, listType IPListType, item *pb. return nil } for _, cidr := range cidrList { + index := strings.Index(cidr, "/") + if index <= 0 { + continue + } + + // 只支持/24以下的 + if types.Int(cidr[index+1:]) < 24 { + continue + } + item.IpFrom = cidr item.IpTo = "" err := this.runActionSingleIP(action, listType, item) @@ -246,6 +280,11 @@ func (this *IPSetAction) runActionSingleIP(action string, listType IPListType, i if len(path) == 0 { path, err = exec.LookPath("ipset") if err != nil { + // 找不到ipset命令错误只提示一次 + if this.ipsetNotfound { + return nil + } + this.ipsetNotfound = true return err } } @@ -264,13 +303,21 @@ func (this *IPSetAction) runActionSingleIP(action string, listType IPListType, i args = append(args, "timeout", strconv.FormatInt(item.ExpiredAt-timestamp, 10)) } - //logs.Println(args) - if runtime.GOOS == "darwin" { // MAC OS直接返回 return nil } + this.errorBuf.Reset() cmd := exec.Command(path, args...) - return cmd.Run() + cmd.Stderr = this.errorBuf + err = cmd.Run() + if err != nil { + var errString = this.errorBuf.String() + if action == "deleteItem" && strings.Contains(errString, "not added") { + return nil + } + return errors.New(strings.TrimSpace(errString)) + } + return nil }