mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	WAF cc2尝试使用指纹统计方法
This commit is contained in:
		@@ -17,6 +17,7 @@ type BaseClientConn struct {
 | 
			
		||||
	hasLimit   bool
 | 
			
		||||
 | 
			
		||||
	isPersistent bool // 是否为持久化连接
 | 
			
		||||
	fingerprint  []byte
 | 
			
		||||
 | 
			
		||||
	isClosed bool
 | 
			
		||||
 | 
			
		||||
@@ -128,3 +129,13 @@ func (this *BaseClientConn) SetLinger(seconds int) error {
 | 
			
		||||
func (this *BaseClientConn) SetIsPersistent(isPersistent bool) {
 | 
			
		||||
	this.isPersistent = isPersistent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetFingerprint 设置指纹信息
 | 
			
		||||
func (this *BaseClientConn) SetFingerprint(fingerprint []byte) {
 | 
			
		||||
	this.fingerprint = fingerprint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fingerprint 读取指纹信息
 | 
			
		||||
func (this *BaseClientConn) Fingerprint() []byte {
 | 
			
		||||
	return this.fingerprint
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,4 +26,10 @@ type ClientConnInterface interface {
 | 
			
		||||
 | 
			
		||||
	// SetIsPersistent 设置是否为持久化
 | 
			
		||||
	SetIsPersistent(isPersistent bool)
 | 
			
		||||
 | 
			
		||||
	// SetFingerprint 设置指纹信息
 | 
			
		||||
	SetFingerprint(fingerprint []byte)
 | 
			
		||||
 | 
			
		||||
	// Fingerprint 读取指纹信息
 | 
			
		||||
	Fingerprint() []byte
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -68,3 +68,17 @@ func (this *ClientTLSConn) SetIsPersistent(isPersistent bool) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *ClientTLSConn) Fingerprint() []byte {
 | 
			
		||||
	tlsConn, ok := this.rawConn.(*tls.Conn)
 | 
			
		||||
	if ok {
 | 
			
		||||
		var rawConn = tlsConn.NetConn()
 | 
			
		||||
		if rawConn != nil {
 | 
			
		||||
			clientConn, ok := rawConn.(*ClientConn)
 | 
			
		||||
			if ok {
 | 
			
		||||
				return clientConn.fingerprint
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -402,3 +402,17 @@ func (this *HTTPRequest) WAFOnAction(action interface{}) (goNext bool) {
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *HTTPRequest) WAFFingerprint() []byte {
 | 
			
		||||
	var requestConn = this.RawReq.Context().Value(HTTPConnContextKey)
 | 
			
		||||
	if requestConn == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clientConn, ok := requestConn.(ClientConnInterface)
 | 
			
		||||
	if ok {
 | 
			
		||||
		return clientConn.Fingerprint()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,15 @@ func (this *BaseListener) buildTLSConfig() *tls.Config {
 | 
			
		||||
	return &tls.Config{
 | 
			
		||||
		Certificates: nil,
 | 
			
		||||
		GetConfigForClient: func(clientInfo *tls.ClientHelloInfo) (config *tls.Config, e error) {
 | 
			
		||||
			// 指纹信息
 | 
			
		||||
			var fingerprint = this.calculateFingerprint(clientInfo)
 | 
			
		||||
			if len(fingerprint) > 0 {
 | 
			
		||||
				clientConn, ok := clientInfo.Conn.(ClientConnInterface)
 | 
			
		||||
				if ok {
 | 
			
		||||
					clientConn.SetFingerprint(fingerprint)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			tlsPolicy, _, err := this.matchSSL(this.helloServerName(clientInfo))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
@@ -50,6 +59,15 @@ func (this *BaseListener) buildTLSConfig() *tls.Config {
 | 
			
		||||
			return tlsPolicy.TLSConfig(), nil
 | 
			
		||||
		},
 | 
			
		||||
		GetCertificate: func(clientInfo *tls.ClientHelloInfo) (certificate *tls.Certificate, e error) {
 | 
			
		||||
			// 指纹信息
 | 
			
		||||
			var fingerprint = this.calculateFingerprint(clientInfo)
 | 
			
		||||
			if len(fingerprint) > 0 {
 | 
			
		||||
				clientConn, ok := clientInfo.Conn.(ClientConnInterface)
 | 
			
		||||
				if ok {
 | 
			
		||||
					clientConn.SetFingerprint(fingerprint)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			tlsPolicy, cert, err := this.matchSSL(this.helloServerName(clientInfo))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								internal/nodes/listener_base_ext.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								internal/nodes/listener_base_ext.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
//go:build !plus
 | 
			
		||||
 | 
			
		||||
package nodes
 | 
			
		||||
 | 
			
		||||
import "crypto/tls"
 | 
			
		||||
 | 
			
		||||
func (this *BaseListener) calculateFingerprint(clientInfo *tls.ClientHelloInfo) []byte {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
package checkpoints
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeNode/internal/ttlcache"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeNode/internal/waf/requests"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeNode/internal/zero"
 | 
			
		||||
@@ -35,7 +36,11 @@ type CC2Checkpoint struct {
 | 
			
		||||
func (this *CC2Checkpoint) RequestValue(req requests.Request, param string, options maps.Map, ruleId int64) (value interface{}, hasRequestBody bool, sysErr error, userErr error) {
 | 
			
		||||
	var keys = options.GetSlice("keys")
 | 
			
		||||
	var keyValues = []string{}
 | 
			
		||||
	var hasRemoteAddr = false
 | 
			
		||||
	for _, key := range keys {
 | 
			
		||||
		if key == "${remoteAddr}" || key == "${rawRemoteAddr}" {
 | 
			
		||||
			hasRemoteAddr = true
 | 
			
		||||
		}
 | 
			
		||||
		keyValues = append(keyValues, req.Format(types.String(key)))
 | 
			
		||||
	}
 | 
			
		||||
	if len(keyValues) == 0 {
 | 
			
		||||
@@ -66,8 +71,29 @@ func (this *CC2Checkpoint) RequestValue(req requests.Request, param string, opti
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var expiresAt = time.Now().Unix() + period
 | 
			
		||||
	var ccKey = "WAF-CC-" + types.String(ruleId) + "-" + strings.Join(keyValues, "@")
 | 
			
		||||
	value = ccCache.IncreaseInt64(ccKey, 1, time.Now().Unix()+period, false)
 | 
			
		||||
	value = ccCache.IncreaseInt64(ccKey, 1, expiresAt, false)
 | 
			
		||||
 | 
			
		||||
	// 基于指纹统计
 | 
			
		||||
	if hasRemoteAddr {
 | 
			
		||||
		var fingerprint = req.WAFFingerprint()
 | 
			
		||||
		if len(fingerprint) > 0 {
 | 
			
		||||
			var fpKeyValues = []string{}
 | 
			
		||||
			for _, key := range keys {
 | 
			
		||||
				if key == "${remoteAddr}" || key == "${rawRemoteAddr}" {
 | 
			
		||||
					fpKeyValues = append(fpKeyValues, fmt.Sprintf("%x", fingerprint))
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				fpKeyValues = append(fpKeyValues, req.Format(types.String(key)))
 | 
			
		||||
			}
 | 
			
		||||
			var fpCCKey = "WAF-CC-" + types.String(ruleId) + "-" + strings.Join(fpKeyValues, "@")
 | 
			
		||||
			var fpValue = ccCache.IncreaseInt64(fpCCKey, 1, expiresAt, false)
 | 
			
		||||
			if fpValue > value.(int64) {
 | 
			
		||||
				value = fpValue
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,9 @@ type Request interface {
 | 
			
		||||
	// WAFOnAction 动作回调
 | 
			
		||||
	WAFOnAction(action interface{}) (goNext bool)
 | 
			
		||||
 | 
			
		||||
	// WAFFingerprint 读取连接指纹
 | 
			
		||||
	WAFFingerprint() []byte
 | 
			
		||||
 | 
			
		||||
	// Format 格式化变量
 | 
			
		||||
	Format(string) string
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user