2020-11-09 10:45:44 +08:00
|
|
|
|
package iplibrary
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
2020-12-17 17:36:10 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
2020-11-09 10:45:44 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
2021-02-02 15:26:00 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
2021-11-05 14:58:10 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/waf"
|
2020-11-09 10:45:44 +08:00
|
|
|
|
"github.com/iwind/TeaGo/Tea"
|
2021-11-14 20:34:04 +08:00
|
|
|
|
"github.com/iwind/TeaGo/types"
|
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
|
"os"
|
2020-11-09 10:45:44 +08:00
|
|
|
|
"sync"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
var SharedIPListManager = NewIPListManager()
|
2020-11-10 09:22:17 +08:00
|
|
|
|
var IPListUpdateNotify = make(chan bool, 1)
|
2020-11-09 10:45:44 +08:00
|
|
|
|
|
|
|
|
|
|
func init() {
|
2021-09-16 15:58:10 +08:00
|
|
|
|
events.On(events.EventLoaded, func() {
|
2020-11-09 10:45:44 +08:00
|
|
|
|
go SharedIPListManager.Start()
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-11-14 20:34:04 +08:00
|
|
|
|
var versionCacheFile = "ip_list_version.cache"
|
|
|
|
|
|
|
2021-09-16 15:58:10 +08:00
|
|
|
|
// IPListManager IP名单管理
|
2020-11-09 10:45:44 +08:00
|
|
|
|
type IPListManager struct {
|
|
|
|
|
|
// 缓存文件
|
|
|
|
|
|
// 每行一个数据:id|from|to|expiredAt
|
|
|
|
|
|
cacheFile string
|
|
|
|
|
|
|
|
|
|
|
|
version int64
|
|
|
|
|
|
pageSize int64
|
|
|
|
|
|
|
|
|
|
|
|
listMap map[int64]*IPList
|
|
|
|
|
|
locker sync.Mutex
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func NewIPListManager() *IPListManager {
|
|
|
|
|
|
return &IPListManager{
|
|
|
|
|
|
cacheFile: Tea.Root + "/configs/ip_list.cache",
|
2021-11-14 20:34:04 +08:00
|
|
|
|
pageSize: 500,
|
2020-11-09 10:45:44 +08:00
|
|
|
|
listMap: map[int64]*IPList{},
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (this *IPListManager) Start() {
|
|
|
|
|
|
// TODO 从缓存当中读取数据
|
|
|
|
|
|
|
2021-11-14 20:34:04 +08:00
|
|
|
|
// 从缓存中读取位置
|
|
|
|
|
|
this.version = this.readLocalVersion()
|
|
|
|
|
|
|
2020-11-09 10:45:44 +08:00
|
|
|
|
// 第一次读取
|
|
|
|
|
|
err := this.loop()
|
|
|
|
|
|
if err != nil {
|
2021-11-10 21:51:56 +08:00
|
|
|
|
remotelogs.ErrorObject("IP_LIST_MANAGER", err)
|
2020-11-09 10:45:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-21 11:00:46 +08:00
|
|
|
|
ticker := time.NewTicker(60 * time.Second)
|
2020-11-09 10:45:44 +08:00
|
|
|
|
events.On(events.EventQuit, func() {
|
|
|
|
|
|
ticker.Stop()
|
|
|
|
|
|
})
|
2020-11-15 11:58:08 +08:00
|
|
|
|
countErrors := 0
|
2020-11-10 09:22:17 +08:00
|
|
|
|
for {
|
|
|
|
|
|
select {
|
|
|
|
|
|
case <-ticker.C:
|
|
|
|
|
|
case <-IPListUpdateNotify:
|
|
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
|
err := this.loop()
|
|
|
|
|
|
if err != nil {
|
2020-11-15 11:58:08 +08:00
|
|
|
|
countErrors++
|
2020-11-10 09:22:17 +08:00
|
|
|
|
|
2021-11-10 21:51:56 +08:00
|
|
|
|
remotelogs.ErrorObject("IP_LIST_MANAGER", err)
|
2020-11-10 09:22:17 +08:00
|
|
|
|
|
2020-11-15 11:58:08 +08:00
|
|
|
|
// 连续错误小于3次的我们立即重试
|
|
|
|
|
|
if countErrors <= 3 {
|
|
|
|
|
|
select {
|
|
|
|
|
|
case IPListUpdateNotify <- true:
|
|
|
|
|
|
default:
|
|
|
|
|
|
}
|
2020-11-10 09:22:17 +08:00
|
|
|
|
}
|
2020-11-15 11:58:08 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
countErrors = 0
|
2020-11-09 10:45:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (this *IPListManager) loop() error {
|
|
|
|
|
|
for {
|
|
|
|
|
|
hasNext, err := this.fetch()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
if !hasNext {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
2021-11-14 20:34:04 +08:00
|
|
|
|
time.Sleep(1 * time.Second)
|
2020-11-09 10:45:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (this *IPListManager) fetch() (hasNext bool, err error) {
|
|
|
|
|
|
rpcClient, err := rpc.SharedRPC()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return false, err
|
|
|
|
|
|
}
|
|
|
|
|
|
itemsResp, err := rpcClient.IPItemRPC().ListIPItemsAfterVersion(rpcClient.Context(), &pb.ListIPItemsAfterVersionRequest{
|
|
|
|
|
|
Version: this.version,
|
|
|
|
|
|
Size: this.pageSize,
|
|
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return false, err
|
|
|
|
|
|
}
|
|
|
|
|
|
items := itemsResp.IpItems
|
|
|
|
|
|
if len(items) == 0 {
|
|
|
|
|
|
return false, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
this.locker.Lock()
|
2021-10-04 17:42:38 +08:00
|
|
|
|
var changedLists = map[*IPList]bool{}
|
2020-11-09 10:45:44 +08:00
|
|
|
|
for _, item := range items {
|
|
|
|
|
|
list, ok := this.listMap[item.ListId]
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
list = NewIPList()
|
|
|
|
|
|
this.listMap[item.ListId] = list
|
|
|
|
|
|
}
|
2021-10-04 17:42:38 +08:00
|
|
|
|
|
|
|
|
|
|
changedLists[list] = true
|
|
|
|
|
|
|
2020-11-09 10:45:44 +08:00
|
|
|
|
if item.IsDeleted {
|
|
|
|
|
|
list.Delete(item.Id)
|
2021-02-06 17:34:33 +08:00
|
|
|
|
|
2021-11-05 14:58:10 +08:00
|
|
|
|
// 从临时名单中删除
|
|
|
|
|
|
if len(item.IpFrom) > 0 && len(item.IpTo) == 0 {
|
|
|
|
|
|
switch item.ListType {
|
|
|
|
|
|
case "black":
|
|
|
|
|
|
waf.SharedIPBlackList.RemoveIP(item.IpFrom)
|
|
|
|
|
|
case "white":
|
|
|
|
|
|
waf.SharedIPWhiteList.RemoveIP(item.IpFrom)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-02-06 17:34:33 +08:00
|
|
|
|
// 操作事件
|
|
|
|
|
|
SharedActionManager.DeleteItem(item.ListType, item)
|
|
|
|
|
|
|
2020-11-09 10:45:44 +08:00
|
|
|
|
continue
|
|
|
|
|
|
}
|
2021-02-06 17:34:33 +08:00
|
|
|
|
|
2021-10-04 17:42:38 +08:00
|
|
|
|
list.AddDelay(&IPItem{
|
2021-02-06 17:34:33 +08:00
|
|
|
|
Id: item.Id,
|
|
|
|
|
|
Type: item.Type,
|
|
|
|
|
|
IPFrom: utils.IP2Long(item.IpFrom),
|
|
|
|
|
|
IPTo: utils.IP2Long(item.IpTo),
|
|
|
|
|
|
ExpiredAt: item.ExpiredAt,
|
|
|
|
|
|
EventLevel: item.EventLevel,
|
2020-11-09 10:45:44 +08:00
|
|
|
|
})
|
2021-02-06 17:34:33 +08:00
|
|
|
|
|
|
|
|
|
|
// 事件操作
|
|
|
|
|
|
SharedActionManager.DeleteItem(item.ListType, item)
|
|
|
|
|
|
SharedActionManager.AddItem(item.ListType, item)
|
2020-11-09 10:45:44 +08:00
|
|
|
|
}
|
2021-10-04 17:42:38 +08:00
|
|
|
|
|
|
|
|
|
|
for changedList := range changedLists {
|
|
|
|
|
|
changedList.Sort()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-09 10:45:44 +08:00
|
|
|
|
this.locker.Unlock()
|
|
|
|
|
|
this.version = items[len(items)-1].Version
|
|
|
|
|
|
|
2021-11-14 20:34:04 +08:00
|
|
|
|
// 写入版本号到缓存当中
|
|
|
|
|
|
this.updateLocalVersion(this.version)
|
|
|
|
|
|
|
2020-11-09 10:45:44 +08:00
|
|
|
|
return true, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (this *IPListManager) FindList(listId int64) *IPList {
|
|
|
|
|
|
this.locker.Lock()
|
|
|
|
|
|
list, _ := this.listMap[listId]
|
|
|
|
|
|
this.locker.Unlock()
|
|
|
|
|
|
return list
|
|
|
|
|
|
}
|
2021-11-14 20:34:04 +08:00
|
|
|
|
|
|
|
|
|
|
func (this *IPListManager) readLocalVersion() int64 {
|
|
|
|
|
|
data, err := ioutil.ReadFile(Tea.ConfigFile(versionCacheFile))
|
|
|
|
|
|
if err != nil || len(data) == 0 {
|
|
|
|
|
|
return 0
|
|
|
|
|
|
}
|
|
|
|
|
|
return types.Int64(string(data))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (this *IPListManager) updateLocalVersion(version int64) {
|
|
|
|
|
|
fp, err := os.OpenFile(Tea.ConfigFile(versionCacheFile), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
remotelogs.Warn("IP_LIST", "write local version cache failed: "+err.Error())
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
_, err = fp.WriteString(types.String(version))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
remotelogs.Warn("IP_LIST", "write local version cache failed: "+err.Error())
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
_ = fp.Close()
|
|
|
|
|
|
}
|