mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	增加IP动作
This commit is contained in:
		@@ -20,7 +20,7 @@ func Notify(event string) {
 | 
				
			|||||||
	locker.Lock()
 | 
						locker.Lock()
 | 
				
			||||||
	callbacks, _ := eventsMap[event]
 | 
						callbacks, _ := eventsMap[event]
 | 
				
			||||||
	locker.Unlock()
 | 
						locker.Unlock()
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, callback := range callbacks {
 | 
						for _, callback := range callbacks {
 | 
				
			||||||
		callback()
 | 
							callback()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								internal/iplibrary/action_base.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								internal/iplibrary/action_base.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BaseAction struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *BaseAction) Close() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *BaseAction) convertParams(params maps.Map, ptr interface{}) error {
 | 
				
			||||||
 | 
						data, err := json.Marshal(params)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err = json.Unmarshal(data, ptr)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										22
									
								
								internal/iplibrary/action_errors.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								internal/iplibrary/action_errors.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 是否是致命错误
 | 
				
			||||||
 | 
					type FataError struct {
 | 
				
			||||||
 | 
						err string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *FataError) Error() string {
 | 
				
			||||||
 | 
						return this.err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewFataError(err string) error {
 | 
				
			||||||
 | 
						return &FataError{err: err}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func IsFatalError(err error) bool {
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, ok := err.(*FataError)
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										147
									
								
								internal/iplibrary/action_firewalld.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								internal/iplibrary/action_firewalld.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Firewalld动作管理
 | 
				
			||||||
 | 
					// 常用命令:
 | 
				
			||||||
 | 
					//  - 查询列表: firewall-cmd --list-all
 | 
				
			||||||
 | 
					//  - 添加IP:firewall-cmd --add-rich-rule="rule family='ipv4' source address='192.168.2.32' reject" --timeout=30s
 | 
				
			||||||
 | 
					//  - 删除IP:firewall-cmd --remove-rich-rule="rule family='ipv4' source address='192.168.2.32' reject" --timeout=30s
 | 
				
			||||||
 | 
					type FirewalldAction struct {
 | 
				
			||||||
 | 
						BaseAction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config *firewallconfigs.FirewallActionFirewalldConfig
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewFirewalldAction() *FirewalldAction {
 | 
				
			||||||
 | 
						return &FirewalldAction{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *FirewalldAction) Init(config *firewallconfigs.FirewallActionConfig) error {
 | 
				
			||||||
 | 
						this.config = &firewallconfigs.FirewallActionFirewalldConfig{}
 | 
				
			||||||
 | 
						err := this.convertParams(config.Params, this.config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *FirewalldAction) AddItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("addItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *FirewalldAction) DeleteItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("deleteItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *FirewalldAction) runAction(action string, listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						if item.Type == "all" {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(item.IpTo) == 0 {
 | 
				
			||||||
 | 
							return this.runActionSingleIP(action, listType, item)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cidrList, err := iPv4RangeToCIDRRange(item.IpFrom, item.IpTo)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							// 不合法的范围不予处理即可
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(cidrList) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, cidr := range cidrList {
 | 
				
			||||||
 | 
							item.IpFrom = cidr
 | 
				
			||||||
 | 
							item.IpTo = ""
 | 
				
			||||||
 | 
							err := this.runActionSingleIP(action, listType, item)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *FirewalldAction) runActionSingleIP(action string, listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						timestamp := time.Now().Unix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if item.ExpiredAt > 0 && timestamp > item.ExpiredAt {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						path := this.config.Path
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						if len(path) == 0 {
 | 
				
			||||||
 | 
							path, err = exec.LookPath("firewall-cmd")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(path) == 0 {
 | 
				
			||||||
 | 
							return errors.New("can not find 'firewall-cmd'")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opt := ""
 | 
				
			||||||
 | 
						switch action {
 | 
				
			||||||
 | 
						case "addItem":
 | 
				
			||||||
 | 
							opt = "--add-rich-rule"
 | 
				
			||||||
 | 
						case "deleteItem":
 | 
				
			||||||
 | 
							opt = "--remove-rich-rule"
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return errors.New("invalid action '" + action + "'")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opt += "=rule family='"
 | 
				
			||||||
 | 
						switch item.Type {
 | 
				
			||||||
 | 
						case "ipv4":
 | 
				
			||||||
 | 
							opt += "ipv4"
 | 
				
			||||||
 | 
						case "ipv6":
 | 
				
			||||||
 | 
							opt += "ipv6"
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							// 我们忽略不能识别的Family
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opt += "' source address='"
 | 
				
			||||||
 | 
						if len(item.IpFrom) == 0 {
 | 
				
			||||||
 | 
							return errors.New("invalid ip from")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opt += item.IpFrom + "' "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch listType {
 | 
				
			||||||
 | 
						case IPListTypeWhite:
 | 
				
			||||||
 | 
							opt += " accept"
 | 
				
			||||||
 | 
						case IPListTypeBlack:
 | 
				
			||||||
 | 
							opt += " reject"
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							// 我们忽略不能识别的列表类型
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args := []string{opt}
 | 
				
			||||||
 | 
						if item.ExpiredAt > timestamp {
 | 
				
			||||||
 | 
							args = append(args, "--timeout="+fmt.Sprintf("%d", item.ExpiredAt-timestamp)+"s")
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							// TODO 思考是否需要permanent,不然--reload之后会丢失
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if runtime.GOOS == "darwin" {
 | 
				
			||||||
 | 
							// MAC OS直接返回
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cmd := exec.Command(path, args...)
 | 
				
			||||||
 | 
						stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
						cmd.Stderr = stderr
 | 
				
			||||||
 | 
						err = cmd.Run()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return errors.New(err.Error() + ", output: " + string(stderr.Bytes()))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										79
									
								
								internal/iplibrary/action_firewalld_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								internal/iplibrary/action_firewalld_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFirewalldAction_AddItem(t *testing.T) {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							action := NewFirewalldAction()
 | 
				
			||||||
 | 
							action.config = &firewallconfigs.FirewallActionFirewalldConfig{
 | 
				
			||||||
 | 
								Path: "/usr/bin/firewalld",
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := action.AddItem(IPListTypeWhite, &pb.IPItem{
 | 
				
			||||||
 | 
								Type:      "ipv4",
 | 
				
			||||||
 | 
								Id:        1,
 | 
				
			||||||
 | 
								IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
								ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log("ok")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							action := NewFirewalldAction()
 | 
				
			||||||
 | 
							action.config = &firewallconfigs.FirewallActionFirewalldConfig{
 | 
				
			||||||
 | 
								Path: "/usr/bin/firewalld",
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := action.AddItem(IPListTypeBlack, &pb.IPItem{
 | 
				
			||||||
 | 
								Type:      "ipv4",
 | 
				
			||||||
 | 
								Id:        1,
 | 
				
			||||||
 | 
								IpFrom:    "192.168.1.101",
 | 
				
			||||||
 | 
								ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log("ok")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFirewalldAction_DeleteItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewFirewalldAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionFirewalldConfig{
 | 
				
			||||||
 | 
							Path: "/usr/bin/firewalld",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := action.DeleteItem(IPListTypeWhite, &pb.IPItem{
 | 
				
			||||||
 | 
							Type:      "ipv4",
 | 
				
			||||||
 | 
							Id:        1,
 | 
				
			||||||
 | 
							IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
							ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFirewalldAction_MultipleItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewFirewalldAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionFirewalldConfig{
 | 
				
			||||||
 | 
							Path: "/usr/bin/firewalld",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := action.AddItem(IPListTypeBlack, &pb.IPItem{
 | 
				
			||||||
 | 
							Type:      "ipv4",
 | 
				
			||||||
 | 
							Id:        1,
 | 
				
			||||||
 | 
							IpFrom:    "192.168.1.30",
 | 
				
			||||||
 | 
							IpTo:      "192.168.1.200",
 | 
				
			||||||
 | 
							ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										81
									
								
								internal/iplibrary/action_http_api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								internal/iplibrary/action_http_api.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var httpAPIClient = &http.Client{
 | 
				
			||||||
 | 
						Timeout: 5 * time.Second,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HTTPAPIAction struct {
 | 
				
			||||||
 | 
						BaseAction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config *firewallconfigs.FirewallActionHTTPAPIConfig
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewHTTPAPIAction() *HTTPAPIAction {
 | 
				
			||||||
 | 
						return &HTTPAPIAction{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPAPIAction) Init(config *firewallconfigs.FirewallActionConfig) error {
 | 
				
			||||||
 | 
						this.config = &firewallconfigs.FirewallActionHTTPAPIConfig{}
 | 
				
			||||||
 | 
						err := this.convertParams(config.Params, this.config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(this.config.URL) == 0 {
 | 
				
			||||||
 | 
							return NewFataError("'url' should not be empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPAPIAction) AddItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("addItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPAPIAction) DeleteItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("deleteItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPAPIAction) runAction(action string, listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						if item == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO 增加节点ID等信息
 | 
				
			||||||
 | 
						m := maps.Map{
 | 
				
			||||||
 | 
							"action":   action,
 | 
				
			||||||
 | 
							"listType": listType,
 | 
				
			||||||
 | 
							"item": maps.Map{
 | 
				
			||||||
 | 
								"type":      item.Type,
 | 
				
			||||||
 | 
								"ipFrom":    item.IpFrom,
 | 
				
			||||||
 | 
								"ipTo":      item.IpTo,
 | 
				
			||||||
 | 
								"expiredAt": item.ExpiredAt,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mJSON, err := json.Marshal(m)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req, err := http.NewRequest(http.MethodPost, this.config.URL, bytes.NewReader(mJSON))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.Header.Set("User-Agent", "GoEdge-Node/"+teaconst.Version)
 | 
				
			||||||
 | 
						resp, err := httpAPIClient.Do(req)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_ = resp.Body.Close()
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								internal/iplibrary/action_http_api_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								internal/iplibrary/action_http_api_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHTTPAPIAction_AddItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewHTTPAPIAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionHTTPAPIConfig{
 | 
				
			||||||
 | 
							URL:            "http://127.0.0.1:2345/post",
 | 
				
			||||||
 | 
							TimeoutSeconds: 0,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := action.AddItem(IPListTypeBlack, &pb.IPItem{
 | 
				
			||||||
 | 
							Type:   "ipv4",
 | 
				
			||||||
 | 
							Id:     1,
 | 
				
			||||||
 | 
							IpFrom: "192.168.1.100",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHTTPAPIAction_DeleteItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewHTTPAPIAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionHTTPAPIConfig{
 | 
				
			||||||
 | 
							URL:            "http://127.0.0.1:2345/post",
 | 
				
			||||||
 | 
							TimeoutSeconds: 0,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := action.DeleteItem(IPListTypeBlack, &pb.IPItem{
 | 
				
			||||||
 | 
							Type:   "ipv4",
 | 
				
			||||||
 | 
							Id:     1,
 | 
				
			||||||
 | 
							IpFrom: "192.168.1.100",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								internal/iplibrary/action_interface.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								internal/iplibrary/action_interface.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ActionInterface interface {
 | 
				
			||||||
 | 
						// 初始化
 | 
				
			||||||
 | 
						Init(config *firewallconfigs.FirewallActionConfig) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 添加
 | 
				
			||||||
 | 
						AddItem(listType IPListType, item *pb.IPItem) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 删除
 | 
				
			||||||
 | 
						DeleteItem(listType IPListType, item *pb.IPItem) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 关闭
 | 
				
			||||||
 | 
						Close() error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										276
									
								
								internal/iplibrary/action_ipset.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								internal/iplibrary/action_ipset.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,276 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IPSet动作
 | 
				
			||||||
 | 
					// 相关命令:
 | 
				
			||||||
 | 
					//   - 利用Firewalld管理set:
 | 
				
			||||||
 | 
					//       - 添加:firewall-cmd --permanent --new-ipset=edge_ip_list --type=hash:ip --option="timeout=0"
 | 
				
			||||||
 | 
					//       - 删除:firewall-cmd --permanent --delete-ipset=edge_ip_list
 | 
				
			||||||
 | 
					//       - 重载:firewall-cmd --reload
 | 
				
			||||||
 | 
					//       - firewalld+ipset: firewall-cmd --permanent --add-rich-rule="rule source ipset='edge_ip_list' reject"
 | 
				
			||||||
 | 
					//   - 利用IPTables管理set:
 | 
				
			||||||
 | 
					//       - 添加:iptables -A INPUT -m set --match-set edge_ip_list src -j REJECT
 | 
				
			||||||
 | 
					//   - 添加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
 | 
				
			||||||
 | 
					type IPSetAction struct {
 | 
				
			||||||
 | 
						BaseAction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config *firewallconfigs.FirewallActionIPSetConfig
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewIPSetAction() *IPSetAction {
 | 
				
			||||||
 | 
						return &IPSetAction{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPSetAction) Init(config *firewallconfigs.FirewallActionConfig) error {
 | 
				
			||||||
 | 
						this.config = &firewallconfigs.FirewallActionIPSetConfig{}
 | 
				
			||||||
 | 
						err := this.convertParams(config.Params, this.config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(this.config.WhiteName) == 0 {
 | 
				
			||||||
 | 
							return NewFataError("white list name should not be empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(this.config.BlackName) == 0 {
 | 
				
			||||||
 | 
							return NewFataError("black list name should not be empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 创建ipset
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							path, err := exec.LookPath("ipset")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd := exec.Command(path, "create", this.config.WhiteName, "hash:ip", "timeout", "0")
 | 
				
			||||||
 | 
								stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
								cmd.Stderr = stderr
 | 
				
			||||||
 | 
								err := cmd.Run()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									output := stderr.Bytes()
 | 
				
			||||||
 | 
									if !bytes.Contains(output, []byte("already exists")) {
 | 
				
			||||||
 | 
										return errors.New("create ipset '" + this.config.WhiteName + "': " + err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										err = nil
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd := exec.Command(path, "create", this.config.BlackName, "hash:ip", "timeout", "0")
 | 
				
			||||||
 | 
								stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
								cmd.Stderr = stderr
 | 
				
			||||||
 | 
								err := cmd.Run()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									output := stderr.Bytes()
 | 
				
			||||||
 | 
									if !bytes.Contains(output, []byte("already exists")) {
 | 
				
			||||||
 | 
										return errors.New("create ipset '" + this.config.BlackName + "': " + err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										err = nil
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// firewalld
 | 
				
			||||||
 | 
						if this.config.AutoAddToFirewalld {
 | 
				
			||||||
 | 
							path, err := exec.LookPath("firewall-cmd")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd := exec.Command(path, "--permanent", "--new-ipset="+this.config.WhiteName, "--type=hash:ip", "--option=timeout=0", "--option=maxelem=1000000")
 | 
				
			||||||
 | 
								stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
								cmd.Stderr = stderr
 | 
				
			||||||
 | 
								err := cmd.Run()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									output := stderr.Bytes()
 | 
				
			||||||
 | 
									if bytes.Contains(output, []byte("NAME_CONFLICT")) {
 | 
				
			||||||
 | 
										err = nil
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										return errors.New("firewall-cmd add ipset '" + this.config.WhiteName + "': " + err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd := exec.Command(path, "--permanent", "--add-rich-rule=rule source ipset='"+this.config.WhiteName+"' accept")
 | 
				
			||||||
 | 
								stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
								cmd.Stderr = stderr
 | 
				
			||||||
 | 
								err := cmd.Run()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									output := stderr.Bytes()
 | 
				
			||||||
 | 
									return errors.New("firewall-cmd add rich rule '" + this.config.WhiteName + "': " + err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd := exec.Command(path, "--permanent", "--new-ipset="+this.config.BlackName, "--type=hash:ip", "--option=timeout=0", "--option=maxelem=1000000")
 | 
				
			||||||
 | 
								stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
								cmd.Stderr = stderr
 | 
				
			||||||
 | 
								err := cmd.Run()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									output := stderr.Bytes()
 | 
				
			||||||
 | 
									if bytes.Contains(output, []byte("NAME_CONFLICT")) {
 | 
				
			||||||
 | 
										err = nil
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										return errors.New("firewall-cmd add ipset '" + this.config.BlackName + "': " + err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd := exec.Command(path, "--permanent", "--add-rich-rule=rule source ipset='"+this.config.BlackName+"' reject")
 | 
				
			||||||
 | 
								stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
								cmd.Stderr = stderr
 | 
				
			||||||
 | 
								err := cmd.Run()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									output := stderr.Bytes()
 | 
				
			||||||
 | 
									return errors.New("firewall-cmd add rich rule '" + this.config.WhiteName + "': " + err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// reload
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd := exec.Command(path, "--reload")
 | 
				
			||||||
 | 
								stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
								cmd.Stderr = stderr
 | 
				
			||||||
 | 
								err := cmd.Run()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									output := stderr.Bytes()
 | 
				
			||||||
 | 
									return errors.New("firewall-cmd reload: " + err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// iptables
 | 
				
			||||||
 | 
						if this.config.AutoAddToIPTables {
 | 
				
			||||||
 | 
							path, err := exec.LookPath("iptables")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								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
 | 
				
			||||||
 | 
								err := cmd.Run()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									output := stderr.Bytes()
 | 
				
			||||||
 | 
									return errors.New("iptables add rule: " + err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPSetAction) AddItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("addItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPSetAction) DeleteItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("deleteItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPSetAction) runAction(action string, listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						if item.Type == "all" {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(item.IpTo) == 0 {
 | 
				
			||||||
 | 
							return this.runActionSingleIP(action, listType, item)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cidrList, err := iPv4RangeToCIDRRange(item.IpFrom, item.IpTo)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							// 不合法的范围不予处理即可
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(cidrList) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, cidr := range cidrList {
 | 
				
			||||||
 | 
							item.IpFrom = cidr
 | 
				
			||||||
 | 
							item.IpTo = ""
 | 
				
			||||||
 | 
							err := this.runActionSingleIP(action, listType, item)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPSetAction) runActionSingleIP(action string, listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						if item.Type == "all" {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						listName := ""
 | 
				
			||||||
 | 
						switch listType {
 | 
				
			||||||
 | 
						case IPListTypeWhite:
 | 
				
			||||||
 | 
							listName = this.config.WhiteName
 | 
				
			||||||
 | 
						case IPListTypeBlack:
 | 
				
			||||||
 | 
							listName = this.config.BlackName
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							// 不支持的类型
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(listName) == 0 {
 | 
				
			||||||
 | 
							return errors.New("empty list name for '" + listType + "'")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						path := this.config.Path
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						if len(path) == 0 {
 | 
				
			||||||
 | 
							path, err = exec.LookPath("ipset")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ipset add edge_ip_list 192.168.2.32 timeout 30
 | 
				
			||||||
 | 
						args := []string{}
 | 
				
			||||||
 | 
						switch action {
 | 
				
			||||||
 | 
						case "addItem":
 | 
				
			||||||
 | 
							args = append(args, "add")
 | 
				
			||||||
 | 
						case "deleteItem":
 | 
				
			||||||
 | 
							args = append(args, "del")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args = append(args, listName, item.IpFrom)
 | 
				
			||||||
 | 
						timestamp := time.Now().Unix()
 | 
				
			||||||
 | 
						if item.ExpiredAt > timestamp {
 | 
				
			||||||
 | 
							args = append(args, "timeout", strconv.FormatInt(item.ExpiredAt-timestamp, 10))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//logs.Println(args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if runtime.GOOS == "darwin" {
 | 
				
			||||||
 | 
							// MAC OS直接返回
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd := exec.Command(path, args...)
 | 
				
			||||||
 | 
						return cmd.Run()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										81
									
								
								internal/iplibrary/action_ipset_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								internal/iplibrary/action_ipset_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestIPSetAction_Init(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewIPSetAction()
 | 
				
			||||||
 | 
						err := action.Init(&firewallconfigs.FirewallActionConfig{
 | 
				
			||||||
 | 
							Params: maps.Map{
 | 
				
			||||||
 | 
								"path":      "/usr/bin/iptables",
 | 
				
			||||||
 | 
								"whiteName": "white-list",
 | 
				
			||||||
 | 
								"blackName": "black-list",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestIPSetAction_AddItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewIPSetAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionIPSetConfig{
 | 
				
			||||||
 | 
							Path:      "/usr/bin/iptables",
 | 
				
			||||||
 | 
							WhiteName: "white-list",
 | 
				
			||||||
 | 
							BlackName: "black-list",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							err := action.AddItem(IPListTypeWhite, &pb.IPItem{
 | 
				
			||||||
 | 
								Type:      "ipv4",
 | 
				
			||||||
 | 
								Id:        1,
 | 
				
			||||||
 | 
								IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
								ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log("ok")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							err := action.AddItem(IPListTypeBlack, &pb.IPItem{
 | 
				
			||||||
 | 
								Type:      "ipv4",
 | 
				
			||||||
 | 
								Id:        1,
 | 
				
			||||||
 | 
								IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
								ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log("ok")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestIPSetAction_DeleteItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewIPSetAction()
 | 
				
			||||||
 | 
						err := action.Init(&firewallconfigs.FirewallActionConfig{
 | 
				
			||||||
 | 
							Params: maps.Map{
 | 
				
			||||||
 | 
								"path":      "/usr/bin/firewalld",
 | 
				
			||||||
 | 
								"whiteName": "white-list",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err = action.DeleteItem(IPListTypeWhite, &pb.IPItem{
 | 
				
			||||||
 | 
							Type:      "ipv4",
 | 
				
			||||||
 | 
							Id:        1,
 | 
				
			||||||
 | 
							IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
							ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										119
									
								
								internal/iplibrary/action_iptables.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								internal/iplibrary/action_iptables.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IPTables动作
 | 
				
			||||||
 | 
					// 相关命令:
 | 
				
			||||||
 | 
					//   iptables -A INPUT -s "192.168.2.32" -j ACCEPT
 | 
				
			||||||
 | 
					//   iptables -A INPUT -s "192.168.2.32" -j REJECT
 | 
				
			||||||
 | 
					//   iptables -D ...
 | 
				
			||||||
 | 
					type IPTablesAction struct {
 | 
				
			||||||
 | 
						BaseAction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config *firewallconfigs.FirewallActionIPTablesConfig
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewIPTablesAction() *IPTablesAction {
 | 
				
			||||||
 | 
						return &IPTablesAction{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPTablesAction) Init(config *firewallconfigs.FirewallActionConfig) error {
 | 
				
			||||||
 | 
						this.config = &firewallconfigs.FirewallActionIPTablesConfig{}
 | 
				
			||||||
 | 
						err := this.convertParams(config.Params, this.config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPTablesAction) AddItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("addItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPTablesAction) DeleteItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("deleteItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPTablesAction) runAction(action string, listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						if item.Type == "all" {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(item.IpTo) == 0 {
 | 
				
			||||||
 | 
							return this.runActionSingleIP(action, listType, item)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cidrList, err := iPv4RangeToCIDRRange(item.IpFrom, item.IpTo)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							// 不合法的范围不予处理即可
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(cidrList) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, cidr := range cidrList {
 | 
				
			||||||
 | 
							item.IpFrom = cidr
 | 
				
			||||||
 | 
							item.IpTo = ""
 | 
				
			||||||
 | 
							err := this.runActionSingleIP(action, listType, item)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IPTablesAction) runActionSingleIP(action string, listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						if item.Type == "all" {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						path := this.config.Path
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						if len(path) == 0 {
 | 
				
			||||||
 | 
							path, err = exec.LookPath("iptables")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						iptablesAction := ""
 | 
				
			||||||
 | 
						switch action {
 | 
				
			||||||
 | 
						case "addItem":
 | 
				
			||||||
 | 
							iptablesAction = "-A"
 | 
				
			||||||
 | 
						case "deleteItem":
 | 
				
			||||||
 | 
							iptablesAction = "-D"
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args := []string{iptablesAction, "INPUT", "-s", item.IpFrom, "-j"}
 | 
				
			||||||
 | 
						switch listType {
 | 
				
			||||||
 | 
						case IPListTypeWhite:
 | 
				
			||||||
 | 
							args = append(args, "ACCEPT")
 | 
				
			||||||
 | 
						case IPListTypeBlack:
 | 
				
			||||||
 | 
							args = append(args, "REJECT")
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if runtime.GOOS == "darwin" {
 | 
				
			||||||
 | 
							// MAC OS直接返回
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd := exec.Command(path, args...)
 | 
				
			||||||
 | 
						stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
						cmd.Stderr = stderr
 | 
				
			||||||
 | 
						err = cmd.Run()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							output := stderr.Bytes()
 | 
				
			||||||
 | 
							if bytes.Contains(output, []byte("No chain/target/match")) {
 | 
				
			||||||
 | 
								err = nil
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return errors.New(err.Error() + ", output: " + string(output))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								internal/iplibrary/action_iptables_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								internal/iplibrary/action_iptables_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestIPTablesAction_AddItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewIPTablesAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionIPTablesConfig{
 | 
				
			||||||
 | 
							Path: "/usr/bin/iptables",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							err := action.AddItem(IPListTypeWhite, &pb.IPItem{
 | 
				
			||||||
 | 
								Type:      "ipv4",
 | 
				
			||||||
 | 
								Id:        1,
 | 
				
			||||||
 | 
								IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
								ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log("ok")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							err := action.AddItem(IPListTypeBlack, &pb.IPItem{
 | 
				
			||||||
 | 
								Type:      "ipv4",
 | 
				
			||||||
 | 
								Id:        1,
 | 
				
			||||||
 | 
								IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
								ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log("ok")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestIPTablesAction_DeleteItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewIPTablesAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionIPTablesConfig{
 | 
				
			||||||
 | 
							Path: "/usr/bin/firewalld",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := action.DeleteItem(IPListTypeWhite, &pb.IPItem{
 | 
				
			||||||
 | 
							Type:      "ipv4",
 | 
				
			||||||
 | 
							Id:        1,
 | 
				
			||||||
 | 
							IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
							ExpiredAt: time.Now().Unix() + 30,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										164
									
								
								internal/iplibrary/action_manager.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								internal/iplibrary/action_manager.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var SharedActionManager = NewActionManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 动作管理器定义
 | 
				
			||||||
 | 
					type ActionManager struct {
 | 
				
			||||||
 | 
						locker sync.Mutex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						eventMap    map[string][]ActionInterface                    // eventLevel => []instance
 | 
				
			||||||
 | 
						configMap   map[int64]*firewallconfigs.FirewallActionConfig // id => config
 | 
				
			||||||
 | 
						instanceMap map[int64]ActionInterface                       // id => instance
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 获取动作管理对象
 | 
				
			||||||
 | 
					func NewActionManager() *ActionManager {
 | 
				
			||||||
 | 
						return &ActionManager{
 | 
				
			||||||
 | 
							configMap:   map[int64]*firewallconfigs.FirewallActionConfig{},
 | 
				
			||||||
 | 
							instanceMap: map[int64]ActionInterface{},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 更新配置
 | 
				
			||||||
 | 
					func (this *ActionManager) UpdateActions(actions []*firewallconfigs.FirewallActionConfig) {
 | 
				
			||||||
 | 
						this.locker.Lock()
 | 
				
			||||||
 | 
						defer this.locker.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 关闭不存在的
 | 
				
			||||||
 | 
						newActionsMap := map[int64]*firewallconfigs.FirewallActionConfig{}
 | 
				
			||||||
 | 
						for _, action := range actions {
 | 
				
			||||||
 | 
							newActionsMap[action.Id] = action
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, oldAction := range this.configMap {
 | 
				
			||||||
 | 
							_, ok := newActionsMap[oldAction.Id]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								instance, ok := this.instanceMap[oldAction.Id]
 | 
				
			||||||
 | 
								if ok {
 | 
				
			||||||
 | 
									_ = instance.Close()
 | 
				
			||||||
 | 
									delete(this.instanceMap, oldAction.Id)
 | 
				
			||||||
 | 
									remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "close action "+strconv.FormatInt(oldAction.Id, 10))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 添加新的或者更新老的
 | 
				
			||||||
 | 
						for _, newAction := range newActionsMap {
 | 
				
			||||||
 | 
							oldInstance, ok := this.instanceMap[newAction.Id]
 | 
				
			||||||
 | 
							if ok {
 | 
				
			||||||
 | 
								// 检查配置是否一致
 | 
				
			||||||
 | 
								oldConfigJSON, err := json.Marshal(this.configMap[newAction.Id])
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "action "+strconv.FormatInt(newAction.Id, 10) + ", type:" + newAction.Type+": "+err.Error())
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								newConfigJSON, err := json.Marshal(newAction)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "action "+strconv.FormatInt(newAction.Id, 10) + ", type:" + newAction.Type+": "+err.Error())
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if bytes.Compare(newConfigJSON, oldConfigJSON) != 0 {
 | 
				
			||||||
 | 
									_ = oldInstance.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// 重新创建
 | 
				
			||||||
 | 
									// 之所以要重新创建,是因为前后的动作类型可能有变化,完全重建可以避免不必要的麻烦
 | 
				
			||||||
 | 
									newInstance, err := this.createInstance(newAction)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "reload action "+strconv.FormatInt(newAction.Id, 10) + ", type:" + newAction.Type+": "+err.Error())
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "reloaded "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type)
 | 
				
			||||||
 | 
									this.instanceMap[newAction.Id] = newInstance
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// 创建
 | 
				
			||||||
 | 
								instance, err := this.createInstance(newAction)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "load new action "+strconv.FormatInt(newAction.Id, 10) + ", type:" + newAction.Type+": "+err.Error())
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "loaded action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type)
 | 
				
			||||||
 | 
								this.instanceMap[newAction.Id] = instance
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 更新配置
 | 
				
			||||||
 | 
						this.configMap = newActionsMap
 | 
				
			||||||
 | 
						this.eventMap = map[string][]ActionInterface{}
 | 
				
			||||||
 | 
						for _, action := range this.configMap {
 | 
				
			||||||
 | 
							instance, ok := this.instanceMap[action.Id]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							instances, _ := this.eventMap[action.EventLevel]
 | 
				
			||||||
 | 
							instances = append(instances, instance)
 | 
				
			||||||
 | 
							this.eventMap[action.EventLevel] = instances
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 执行添加IP动作
 | 
				
			||||||
 | 
					func (this *ActionManager) AddItem(listType IPListType, item *pb.IPItem) {
 | 
				
			||||||
 | 
						instances, ok := this.eventMap[item.EventLevel]
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							for _, instance := range instances {
 | 
				
			||||||
 | 
								err := instance.AddItem(listType, item)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "add item '"+fmt.Sprintf("%d", item.Id)+"': "+err.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 执行删除IP动作
 | 
				
			||||||
 | 
					func (this *ActionManager) DeleteItem(listType IPListType, item *pb.IPItem) {
 | 
				
			||||||
 | 
						instances, ok := this.eventMap[item.EventLevel]
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							for _, instance := range instances {
 | 
				
			||||||
 | 
								err := instance.DeleteItem(listType, item)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "delete item '"+fmt.Sprintf("%d", item.Id)+"': "+err.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *ActionManager) createInstance(config *firewallconfigs.FirewallActionConfig) (ActionInterface, error) {
 | 
				
			||||||
 | 
						var instance ActionInterface
 | 
				
			||||||
 | 
						switch config.Type {
 | 
				
			||||||
 | 
						case firewallconfigs.FirewallActionTypeIPSet:
 | 
				
			||||||
 | 
							instance = NewIPSetAction()
 | 
				
			||||||
 | 
						case firewallconfigs.FirewallActionTypeFirewalld:
 | 
				
			||||||
 | 
							instance = NewFirewalldAction()
 | 
				
			||||||
 | 
						case firewallconfigs.FirewallActionTypeIPTables:
 | 
				
			||||||
 | 
							instance = NewIPTablesAction()
 | 
				
			||||||
 | 
						case firewallconfigs.FirewallActionTypeScript:
 | 
				
			||||||
 | 
							instance = NewScriptAction()
 | 
				
			||||||
 | 
						case firewallconfigs.FirewallActionTypeHTTPAPI:
 | 
				
			||||||
 | 
							instance = NewHTTPAPIAction()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if instance == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("can not create instance for type '" + config.Type + "'")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := instance.Init(config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							// 如果是警告错误,我们只是提示
 | 
				
			||||||
 | 
							if !IsFatalError(err) {
 | 
				
			||||||
 | 
								remotelogs.Error("IPLIBRARY/ACTION_MANAGER/CREATE_INSTANCE", "init '"+config.Type+"' failed: "+err.Error())
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return instance, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								internal/iplibrary/action_manager_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								internal/iplibrary/action_manager_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestActionManager_UpdateActions(t *testing.T) {
 | 
				
			||||||
 | 
						manager := NewActionManager()
 | 
				
			||||||
 | 
						manager.UpdateActions([]*firewallconfigs.FirewallActionConfig{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Id:   1,
 | 
				
			||||||
 | 
								Type: "ipset",
 | 
				
			||||||
 | 
								Params: maps.Map{
 | 
				
			||||||
 | 
									"whiteName": "edge-white-list",
 | 
				
			||||||
 | 
									"blackName": "edge-black-list",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						t.Log("===config===")
 | 
				
			||||||
 | 
						for _, c := range manager.configMap {
 | 
				
			||||||
 | 
							t.Log(c.Id, c.Type)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("===instance===")
 | 
				
			||||||
 | 
						for id, c := range manager.instanceMap {
 | 
				
			||||||
 | 
							t.Log(id, c)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						manager.UpdateActions([]*firewallconfigs.FirewallActionConfig{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Id:   1,
 | 
				
			||||||
 | 
								Type: "ipset",
 | 
				
			||||||
 | 
								Params: maps.Map{
 | 
				
			||||||
 | 
									"whiteName": "edge-white-list",
 | 
				
			||||||
 | 
									"blackName": "edge-black-list",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Id:   2,
 | 
				
			||||||
 | 
								Type: "iptables",
 | 
				
			||||||
 | 
								Params: maps.Map{
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Log("===config===")
 | 
				
			||||||
 | 
						for _, c := range manager.configMap {
 | 
				
			||||||
 | 
							t.Log(c.Id, c.Type)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("===instance===")
 | 
				
			||||||
 | 
						for id, c := range manager.instanceMap {
 | 
				
			||||||
 | 
							t.Logf("%d: %#v", id, c)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								internal/iplibrary/action_script.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								internal/iplibrary/action_script.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 脚本命令动作
 | 
				
			||||||
 | 
					type ScriptAction struct {
 | 
				
			||||||
 | 
						BaseAction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config *firewallconfigs.FirewallActionScriptConfig
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewScriptAction() *ScriptAction {
 | 
				
			||||||
 | 
						return &ScriptAction{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *ScriptAction) Init(config *firewallconfigs.FirewallActionConfig) error {
 | 
				
			||||||
 | 
						this.config = &firewallconfigs.FirewallActionScriptConfig{}
 | 
				
			||||||
 | 
						err := this.convertParams(config.Params, this.config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(this.config.Path) == 0 {
 | 
				
			||||||
 | 
							return NewFataError("'path' should not be empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *ScriptAction) AddItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("addItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *ScriptAction) DeleteItem(listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						return this.runAction("deleteItem", listType, item)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *ScriptAction) runAction(action string, listType IPListType, item *pb.IPItem) error {
 | 
				
			||||||
 | 
						// TODO 智能支持 .sh 脚本文件
 | 
				
			||||||
 | 
						cmd := exec.Command(this.config.Path)
 | 
				
			||||||
 | 
						cmd.Env = []string{
 | 
				
			||||||
 | 
							"ACTION=" + action,
 | 
				
			||||||
 | 
							"TYPE=" + item.Type,
 | 
				
			||||||
 | 
							"IP_FROM=" + item.IpFrom,
 | 
				
			||||||
 | 
							"IP_TO=" + item.IpTo,
 | 
				
			||||||
 | 
							"EXPIRED_AT=" + fmt.Sprintf("%d", item.ExpiredAt),
 | 
				
			||||||
 | 
							"LIST_TYPE=" + listType,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(this.config.Cwd) > 0 {
 | 
				
			||||||
 | 
							cmd.Dir = this.config.Cwd
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							cmd.Dir = filepath.Dir(this.config.Path)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stderr := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
						cmd.Stderr = stderr
 | 
				
			||||||
 | 
						err := cmd.Run()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return errors.New(err.Error() + ", output: " + string(stderr.Bytes()))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								internal/iplibrary/action_script_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								internal/iplibrary/action_script_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestScriptAction_AddItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewScriptAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionScriptConfig{
 | 
				
			||||||
 | 
							Path: "/tmp/ip-item.sh",
 | 
				
			||||||
 | 
							Cwd:  "",
 | 
				
			||||||
 | 
							Args: nil,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := action.AddItem(IPListTypeBlack, &pb.IPItem{
 | 
				
			||||||
 | 
							Type:      "ipv4",
 | 
				
			||||||
 | 
							Id:        1,
 | 
				
			||||||
 | 
							IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
							ExpiredAt: time.Now().Unix(),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestScriptAction_DeleteItem(t *testing.T) {
 | 
				
			||||||
 | 
						action := NewScriptAction()
 | 
				
			||||||
 | 
						action.config = &firewallconfigs.FirewallActionScriptConfig{
 | 
				
			||||||
 | 
							Path: "/tmp/ip-item.sh",
 | 
				
			||||||
 | 
							Cwd:  "",
 | 
				
			||||||
 | 
							Args: nil,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := action.DeleteItem(IPListTypeBlack, &pb.IPItem{
 | 
				
			||||||
 | 
							Type:      "ipv4",
 | 
				
			||||||
 | 
							Id:        1,
 | 
				
			||||||
 | 
							IpFrom:    "192.168.1.100",
 | 
				
			||||||
 | 
							ExpiredAt: time.Now().Unix(),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log("ok")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										85
									
								
								internal/iplibrary/action_utils.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								internal/iplibrary/action_utils.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"math"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Convert IPv4 range into CIDR
 | 
				
			||||||
 | 
					// 来自:https://gist.github.com/P-A-R-U-S/a090dd90c5104ce85a29c32669dac107
 | 
				
			||||||
 | 
					func iPv4RangeToCIDRRange(ipStart string, ipEnd string) (cidrs []string, err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cidr2mask := []uint32{
 | 
				
			||||||
 | 
							0x00000000, 0x80000000, 0xC0000000,
 | 
				
			||||||
 | 
							0xE0000000, 0xF0000000, 0xF8000000,
 | 
				
			||||||
 | 
							0xFC000000, 0xFE000000, 0xFF000000,
 | 
				
			||||||
 | 
							0xFF800000, 0xFFC00000, 0xFFE00000,
 | 
				
			||||||
 | 
							0xFFF00000, 0xFFF80000, 0xFFFC0000,
 | 
				
			||||||
 | 
							0xFFFE0000, 0xFFFF0000, 0xFFFF8000,
 | 
				
			||||||
 | 
							0xFFFFC000, 0xFFFFE000, 0xFFFFF000,
 | 
				
			||||||
 | 
							0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00,
 | 
				
			||||||
 | 
							0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0,
 | 
				
			||||||
 | 
							0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFF8,
 | 
				
			||||||
 | 
							0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ipStartUint32 := iPv4ToUint32(ipStart)
 | 
				
			||||||
 | 
						ipEndUint32 := iPv4ToUint32(ipEnd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ipStartUint32 > ipEndUint32 {
 | 
				
			||||||
 | 
							log.Fatalf("start IP:%s must be less than end IP:%s", ipStart, ipEnd)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for ipEndUint32 >= ipStartUint32 {
 | 
				
			||||||
 | 
							maxSize := 32
 | 
				
			||||||
 | 
							for maxSize > 0 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								maskedBase := ipStartUint32 & cidr2mask[maxSize-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if maskedBase != ipStartUint32 {
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								maxSize--
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							x := math.Log(float64(ipEndUint32-ipStartUint32+1)) / math.Log(2)
 | 
				
			||||||
 | 
							maxDiff := 32 - int(math.Floor(x))
 | 
				
			||||||
 | 
							if maxSize < maxDiff {
 | 
				
			||||||
 | 
								maxSize = maxDiff
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cidrs = append(cidrs, uInt32ToIPv4(ipStartUint32)+"/"+strconv.Itoa(maxSize))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ipStartUint32 += uint32(math.Exp2(float64(32 - maxSize)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return cidrs, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Convert IPv4 to uint32
 | 
				
			||||||
 | 
					func iPv4ToUint32(iPv4 string) uint32 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ipOctets := [4]uint64{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, v := range strings.SplitN(iPv4, ".", 4) {
 | 
				
			||||||
 | 
							ipOctets[i], _ = strconv.ParseUint(v, 10, 32)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result := (ipOctets[0] << 24) | (ipOctets[1] << 16) | (ipOctets[2] << 8) | ipOctets[3]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return uint32(result)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Convert uint32 to IP
 | 
				
			||||||
 | 
					func uInt32ToIPv4(iPuInt32 uint32) (iP string) {
 | 
				
			||||||
 | 
						iP = fmt.Sprintf("%d.%d.%d.%d",
 | 
				
			||||||
 | 
							iPuInt32>>24,
 | 
				
			||||||
 | 
							(iPuInt32&0x00FFFFFF)>>16,
 | 
				
			||||||
 | 
							(iPuInt32&0x0000FFFF)>>8,
 | 
				
			||||||
 | 
							iPuInt32&0x000000FF)
 | 
				
			||||||
 | 
						return iP
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								internal/iplibrary/action_utils_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								internal/iplibrary/action_utils_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestIPv4RangeToCIDRRange(t *testing.T) {
 | 
				
			||||||
 | 
						t.Log(iPv4RangeToCIDRRange("192.168.0.0", "192.168.255.255"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -12,11 +12,12 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// IP条目
 | 
					// IP条目
 | 
				
			||||||
type IPItem struct {
 | 
					type IPItem struct {
 | 
				
			||||||
	Type      string
 | 
						Type       string `json:"type"`
 | 
				
			||||||
	Id        int64
 | 
						Id         int64  `json:"id"`
 | 
				
			||||||
	IPFrom    uint64
 | 
						IPFrom     uint64 `json:"ipFrom"`
 | 
				
			||||||
	IPTo      uint64
 | 
						IPTo       uint64 `json:"ipTo"`
 | 
				
			||||||
	ExpiredAt int64
 | 
						ExpiredAt  int64  `json:"expiredAt"`
 | 
				
			||||||
 | 
						EventLevel string `json:"eventLevel"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 检查是否包含某个IP
 | 
					// 检查是否包含某个IP
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								internal/iplibrary/list_type.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								internal/iplibrary/list_type.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					package iplibrary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type IPListType = string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IPListTypeWhite IPListType = "white"
 | 
				
			||||||
 | 
						IPListTypeBlack IPListType = "black"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@@ -120,15 +120,25 @@ func (this *IPListManager) fetch() (hasNext bool, err error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if item.IsDeleted {
 | 
							if item.IsDeleted {
 | 
				
			||||||
			list.Delete(item.Id)
 | 
								list.Delete(item.Id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// 操作事件
 | 
				
			||||||
 | 
								SharedActionManager.DeleteItem(item.ListType, item)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		list.Add(&IPItem{
 | 
							list.Add(&IPItem{
 | 
				
			||||||
			Id:        item.Id,
 | 
								Id:         item.Id,
 | 
				
			||||||
			Type:      item.Type,
 | 
								Type:       item.Type,
 | 
				
			||||||
			IPFrom:    utils.IP2Long(item.IpFrom),
 | 
								IPFrom:     utils.IP2Long(item.IpFrom),
 | 
				
			||||||
			IPTo:      utils.IP2Long(item.IpTo),
 | 
								IPTo:       utils.IP2Long(item.IpTo),
 | 
				
			||||||
			ExpiredAt: item.ExpiredAt,
 | 
								ExpiredAt:  item.ExpiredAt,
 | 
				
			||||||
 | 
								EventLevel: item.EventLevel,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 事件操作
 | 
				
			||||||
 | 
							SharedActionManager.DeleteItem(item.ListType, item)
 | 
				
			||||||
 | 
							SharedActionManager.AddItem(item.ListType, item)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	this.locker.Unlock()
 | 
						this.locker.Unlock()
 | 
				
			||||||
	this.version = items[len(items)-1].Version
 | 
						this.version = items[len(items)-1].Version
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -369,6 +369,7 @@ func (this *Node) syncConfig() error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sharedWAFManager.UpdatePolicies(nodeConfig.FindAllFirewallPolicies())
 | 
						sharedWAFManager.UpdatePolicies(nodeConfig.FindAllFirewallPolicies())
 | 
				
			||||||
 | 
						iplibrary.SharedActionManager.UpdateActions(nodeConfig.FirewallActions)
 | 
				
			||||||
	sharedNodeConfig = nodeConfig
 | 
						sharedNodeConfig = nodeConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 发送事件
 | 
						// 发送事件
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user