mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-07 02:20:25 +08:00
WAF cc2尝试使用指纹统计方法
This commit is contained in:
@@ -17,6 +17,7 @@ type BaseClientConn struct {
|
|||||||
hasLimit bool
|
hasLimit bool
|
||||||
|
|
||||||
isPersistent bool // 是否为持久化连接
|
isPersistent bool // 是否为持久化连接
|
||||||
|
fingerprint []byte
|
||||||
|
|
||||||
isClosed bool
|
isClosed bool
|
||||||
|
|
||||||
@@ -128,3 +129,13 @@ func (this *BaseClientConn) SetLinger(seconds int) error {
|
|||||||
func (this *BaseClientConn) SetIsPersistent(isPersistent bool) {
|
func (this *BaseClientConn) SetIsPersistent(isPersistent bool) {
|
||||||
this.isPersistent = isPersistent
|
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 设置是否为持久化
|
||||||
SetIsPersistent(isPersistent bool)
|
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
|
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{
|
return &tls.Config{
|
||||||
Certificates: nil,
|
Certificates: nil,
|
||||||
GetConfigForClient: func(clientInfo *tls.ClientHelloInfo) (config *tls.Config, e error) {
|
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))
|
tlsPolicy, _, err := this.matchSSL(this.helloServerName(clientInfo))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -50,6 +59,15 @@ func (this *BaseListener) buildTLSConfig() *tls.Config {
|
|||||||
return tlsPolicy.TLSConfig(), nil
|
return tlsPolicy.TLSConfig(), nil
|
||||||
},
|
},
|
||||||
GetCertificate: func(clientInfo *tls.ClientHelloInfo) (certificate *tls.Certificate, e error) {
|
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))
|
tlsPolicy, cert, err := this.matchSSL(this.helloServerName(clientInfo))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
package checkpoints
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/ttlcache"
|
"github.com/TeaOSLab/EdgeNode/internal/ttlcache"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/waf/requests"
|
"github.com/TeaOSLab/EdgeNode/internal/waf/requests"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/zero"
|
"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) {
|
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 keys = options.GetSlice("keys")
|
||||||
var keyValues = []string{}
|
var keyValues = []string{}
|
||||||
|
var hasRemoteAddr = false
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
|
if key == "${remoteAddr}" || key == "${rawRemoteAddr}" {
|
||||||
|
hasRemoteAddr = true
|
||||||
|
}
|
||||||
keyValues = append(keyValues, req.Format(types.String(key)))
|
keyValues = append(keyValues, req.Format(types.String(key)))
|
||||||
}
|
}
|
||||||
if len(keyValues) == 0 {
|
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, "@")
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ type Request interface {
|
|||||||
// WAFOnAction 动作回调
|
// WAFOnAction 动作回调
|
||||||
WAFOnAction(action interface{}) (goNext bool)
|
WAFOnAction(action interface{}) (goNext bool)
|
||||||
|
|
||||||
|
// WAFFingerprint 读取连接指纹
|
||||||
|
WAFFingerprint() []byte
|
||||||
|
|
||||||
// Format 格式化变量
|
// Format 格式化变量
|
||||||
Format(string) string
|
Format(string) string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user