mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-16 10:00:26 +08:00
WAF动作增加显示HTML内容
This commit is contained in:
@@ -3,6 +3,7 @@ package iplibrary
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BaseAction struct {
|
type BaseAction struct {
|
||||||
@@ -12,6 +13,11 @@ func (this *BaseAction) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理HTTP请求
|
||||||
|
func (this *BaseAction) DoHTTP(req *http.Request, resp http.ResponseWriter) (goNext bool, err error) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (this *BaseAction) convertParams(params maps.Map, ptr interface{}) error {
|
func (this *BaseAction) convertParams(params maps.Map, ptr interface{}) error {
|
||||||
data, err := json.Marshal(params)
|
data, err := json.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
55
internal/iplibrary/action_html.go
Normal file
55
internal/iplibrary/action_html.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package iplibrary
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HTML动作
|
||||||
|
type HTMLAction struct {
|
||||||
|
BaseAction
|
||||||
|
|
||||||
|
config *firewallconfigs.FirewallActionHTMLConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取新对象
|
||||||
|
func NewHTMLAction() *HTMLAction {
|
||||||
|
return &HTMLAction{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
func (this *HTMLAction) Init(config *firewallconfigs.FirewallActionConfig) error {
|
||||||
|
this.config = &firewallconfigs.FirewallActionHTMLConfig{}
|
||||||
|
err := this.convertParams(config.Params, this.config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加
|
||||||
|
func (this *HTMLAction) AddItem(listType IPListType, item *pb.IPItem) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
func (this *HTMLAction) DeleteItem(listType IPListType, item *pb.IPItem) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭
|
||||||
|
func (this *HTMLAction) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理HTTP请求
|
||||||
|
func (this *HTMLAction) DoHTTP(req *http.Request, resp http.ResponseWriter) (goNext bool, err error) {
|
||||||
|
if this.config == nil {
|
||||||
|
goNext = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp.WriteHeader(http.StatusForbidden) // TODO改成可以配置
|
||||||
|
_, _ = resp.Write([]byte(this.config.Content))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package iplibrary
|
|||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ActionInterface interface {
|
type ActionInterface interface {
|
||||||
@@ -17,4 +18,7 @@ type ActionInterface interface {
|
|||||||
|
|
||||||
// 关闭
|
// 关闭
|
||||||
Close() error
|
Close() error
|
||||||
|
|
||||||
|
// 处理HTTP请求
|
||||||
|
DoHTTP(req *http.Request, resp http.ResponseWriter) (goNext bool, err error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ func (this *ActionManager) UpdateActions(actions []*firewallconfigs.FirewallActi
|
|||||||
// 检查配置是否一致
|
// 检查配置是否一致
|
||||||
oldConfigJSON, err := json.Marshal(this.configMap[newAction.Id])
|
oldConfigJSON, err := json.Marshal(this.configMap[newAction.Id])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "action "+strconv.FormatInt(newAction.Id, 10) + ", type:" + newAction.Type+": "+err.Error())
|
remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type+": "+err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
newConfigJSON, err := json.Marshal(newAction)
|
newConfigJSON, err := json.Marshal(newAction)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "action "+strconv.FormatInt(newAction.Id, 10) + ", type:" + newAction.Type+": "+err.Error())
|
remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type+": "+err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if bytes.Compare(newConfigJSON, oldConfigJSON) != 0 {
|
if bytes.Compare(newConfigJSON, oldConfigJSON) != 0 {
|
||||||
@@ -75,7 +75,7 @@ func (this *ActionManager) UpdateActions(actions []*firewallconfigs.FirewallActi
|
|||||||
// 之所以要重新创建,是因为前后的动作类型可能有变化,完全重建可以避免不必要的麻烦
|
// 之所以要重新创建,是因为前后的动作类型可能有变化,完全重建可以避免不必要的麻烦
|
||||||
newInstance, err := this.createInstance(newAction)
|
newInstance, err := this.createInstance(newAction)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "reload action "+strconv.FormatInt(newAction.Id, 10) + ", type:" + newAction.Type+": "+err.Error())
|
remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "reload action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type+": "+err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "reloaded "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type)
|
remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "reloaded "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type)
|
||||||
@@ -85,7 +85,7 @@ func (this *ActionManager) UpdateActions(actions []*firewallconfigs.FirewallActi
|
|||||||
// 创建
|
// 创建
|
||||||
instance, err := this.createInstance(newAction)
|
instance, err := this.createInstance(newAction)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "load new action "+strconv.FormatInt(newAction.Id, 10) + ", type:" + newAction.Type+": "+err.Error())
|
remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "load new action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type+": "+err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "loaded action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type)
|
remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "loaded action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type)
|
||||||
@@ -108,6 +108,13 @@ func (this *ActionManager) UpdateActions(actions []*firewallconfigs.FirewallActi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查找事件对应的动作
|
||||||
|
func (this *ActionManager) FindEventActions(eventLevel string) []ActionInterface {
|
||||||
|
this.locker.Lock()
|
||||||
|
defer this.locker.Unlock()
|
||||||
|
return this.eventMap[eventLevel]
|
||||||
|
}
|
||||||
|
|
||||||
// 执行添加IP动作
|
// 执行添加IP动作
|
||||||
func (this *ActionManager) AddItem(listType IPListType, item *pb.IPItem) {
|
func (this *ActionManager) AddItem(listType IPListType, item *pb.IPItem) {
|
||||||
instances, ok := this.eventMap[item.EventLevel]
|
instances, ok := this.eventMap[item.EventLevel]
|
||||||
@@ -147,6 +154,8 @@ func (this *ActionManager) createInstance(config *firewallconfigs.FirewallAction
|
|||||||
instance = NewScriptAction()
|
instance = NewScriptAction()
|
||||||
case firewallconfigs.FirewallActionTypeHTTPAPI:
|
case firewallconfigs.FirewallActionTypeHTTPAPI:
|
||||||
instance = NewHTTPAPIAction()
|
instance = NewHTTPAPIAction()
|
||||||
|
case firewallconfigs.FirewallActionTypeHTML:
|
||||||
|
instance = NewHTMLAction()
|
||||||
}
|
}
|
||||||
if instance == nil {
|
if instance == nil {
|
||||||
return nil, errors.New("can not create instance for type '" + config.Type + "'")
|
return nil, errors.New("can not create instance for type '" + config.Type + "'")
|
||||||
|
|||||||
@@ -110,27 +110,40 @@ func (this *IPList) Contains(ip uint64) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 是否包含一组IP
|
// 是否包含一组IP
|
||||||
func (this *IPList) ContainsIPStrings(ipStrings []string) bool {
|
func (this *IPList) ContainsIPStrings(ipStrings []string) (found bool, item *IPItem) {
|
||||||
if len(ipStrings) == 0 {
|
if len(ipStrings) == 0 {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
this.locker.RLock()
|
this.locker.RLock()
|
||||||
if this.isAll {
|
if this.isAll {
|
||||||
|
itemIds := this.ipMap[0]
|
||||||
|
if len(itemIds) > 0 {
|
||||||
|
itemId := itemIds[0]
|
||||||
|
item = this.itemsMap[itemId]
|
||||||
|
}
|
||||||
|
|
||||||
this.locker.RUnlock()
|
this.locker.RUnlock()
|
||||||
return true
|
found = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
for _, ipString := range ipStrings {
|
for _, ipString := range ipStrings {
|
||||||
if len(ipString) == 0 {
|
if len(ipString) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, ok := this.ipMap[utils.IP2Long(ipString)]
|
itemIds, ok := this.ipMap[utils.IP2Long(ipString)]
|
||||||
if ok {
|
if ok {
|
||||||
|
if len(itemIds) > 0 {
|
||||||
|
itemId := itemIds[0]
|
||||||
|
item = this.itemsMap[itemId]
|
||||||
|
}
|
||||||
|
|
||||||
this.locker.RUnlock()
|
this.locker.RUnlock()
|
||||||
return true
|
found = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.locker.RUnlock()
|
this.locker.RUnlock()
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在不加锁的情况下删除某个Item
|
// 在不加锁的情况下删除某个Item
|
||||||
|
|||||||
@@ -49,25 +49,47 @@ func (this *HTTPRequest) checkWAFRequest(firewallPolicy *firewallconfigs.HTTPFir
|
|||||||
inbound := firewallPolicy.Inbound
|
inbound := firewallPolicy.Inbound
|
||||||
if inbound.AllowListRef != nil && inbound.AllowListRef.IsOn && inbound.AllowListRef.ListId > 0 {
|
if inbound.AllowListRef != nil && inbound.AllowListRef.IsOn && inbound.AllowListRef.ListId > 0 {
|
||||||
list := iplibrary.SharedIPListManager.FindList(inbound.AllowListRef.ListId)
|
list := iplibrary.SharedIPListManager.FindList(inbound.AllowListRef.ListId)
|
||||||
if list != nil && list.ContainsIPStrings(remoteAddrs) {
|
if list != nil {
|
||||||
breakChecking = true
|
found, _ := list.ContainsIPStrings(remoteAddrs)
|
||||||
return
|
if found {
|
||||||
|
breakChecking = true
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查IP黑名单
|
// 检查IP黑名单
|
||||||
if inbound.DenyListRef != nil && inbound.DenyListRef.IsOn && inbound.DenyListRef.ListId > 0 {
|
if inbound.DenyListRef != nil && inbound.DenyListRef.IsOn && inbound.DenyListRef.ListId > 0 {
|
||||||
list := iplibrary.SharedIPListManager.FindList(inbound.DenyListRef.ListId)
|
list := iplibrary.SharedIPListManager.FindList(inbound.DenyListRef.ListId)
|
||||||
if list != nil && list.ContainsIPStrings(remoteAddrs) {
|
if list != nil {
|
||||||
// TODO 可以配置对封禁的处理方式等
|
found, item := list.ContainsIPStrings(remoteAddrs)
|
||||||
// TODO 需要记录日志信息
|
if found {
|
||||||
this.writer.WriteHeader(http.StatusForbidden)
|
// 触发事件
|
||||||
this.writer.Close()
|
if item != nil && len(item.EventLevel) > 0 {
|
||||||
|
actions := iplibrary.SharedActionManager.FindEventActions(item.EventLevel)
|
||||||
|
for _, action := range actions {
|
||||||
|
goNext, err := action.DoHTTP(this.RawReq, this.RawWriter)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("REQUEST", "do action '"+err.Error()+"' failed: "+err.Error())
|
||||||
|
return true, false
|
||||||
|
}
|
||||||
|
if !goNext {
|
||||||
|
this.disableLog = true
|
||||||
|
return true, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 停止日志
|
// TODO 需要记录日志信息
|
||||||
this.disableLog = true
|
|
||||||
|
|
||||||
return true, false
|
this.writer.WriteHeader(http.StatusForbidden)
|
||||||
|
this.writer.Close()
|
||||||
|
|
||||||
|
// 停止日志
|
||||||
|
this.disableLog = true
|
||||||
|
|
||||||
|
return true, false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user