1.4.5.2
This commit is contained in:
81
EdgeNode/internal/encryption/cache.go
Normal file
81
EdgeNode/internal/encryption/cache.go
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package encryption
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/ttlcache"
|
||||
)
|
||||
|
||||
// EncryptionCache 加密缓存
|
||||
type EncryptionCache struct {
|
||||
cache *ttlcache.Cache[[]byte]
|
||||
}
|
||||
|
||||
var sharedCache *EncryptionCache
|
||||
var sharedCacheOnce sync.Once
|
||||
|
||||
// SharedEncryptionCache 获取共享缓存实例
|
||||
func SharedEncryptionCache(maxSize int, ttl time.Duration) *EncryptionCache {
|
||||
sharedCacheOnce.Do(func() {
|
||||
sharedCache = NewEncryptionCache(maxSize, ttl)
|
||||
})
|
||||
return sharedCache
|
||||
}
|
||||
|
||||
// NewEncryptionCache 创建新缓存
|
||||
func NewEncryptionCache(maxSize int, ttl time.Duration) *EncryptionCache {
|
||||
cache := ttlcache.NewCache[[]byte](
|
||||
ttlcache.NewMaxItemsOption(maxSize),
|
||||
ttlcache.NewGCConfigOption().
|
||||
WithBaseInterval(ttl).
|
||||
WithMinInterval(ttl/2).
|
||||
WithMaxInterval(ttl*2).
|
||||
WithAdaptive(true),
|
||||
)
|
||||
|
||||
return &EncryptionCache{
|
||||
cache: cache,
|
||||
}
|
||||
}
|
||||
|
||||
// Get 获取缓存值
|
||||
func (this *EncryptionCache) Get(key string) ([]byte, bool) {
|
||||
item := this.cache.Read(key)
|
||||
if item == nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 检查是否过期
|
||||
if item.ExpiresAt() < fasttime.Now().Unix() {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 复制数据,避免外部修改
|
||||
result := make([]byte, len(item.Value))
|
||||
copy(result, item.Value)
|
||||
return result, true
|
||||
}
|
||||
|
||||
// Set 设置缓存值
|
||||
func (this *EncryptionCache) Set(key string, value []byte, ttlSeconds int64) {
|
||||
// 复制数据,避免外部修改
|
||||
copied := make([]byte, len(value))
|
||||
copy(copied, value)
|
||||
|
||||
expiresAt := fasttime.Now().Unix() + ttlSeconds
|
||||
this.cache.Write(key, copied, expiresAt)
|
||||
}
|
||||
|
||||
// Clear 清空缓存(TTL 缓存会自动过期,这里不需要手动清空)
|
||||
func (this *EncryptionCache) Clear() {
|
||||
// TTL 缓存会自动过期,不需要手动清空
|
||||
}
|
||||
|
||||
// Len 获取缓存大小
|
||||
func (this *EncryptionCache) Len() int {
|
||||
return this.cache.Count()
|
||||
}
|
||||
97
EdgeNode/internal/encryption/key_generator.go
Normal file
97
EdgeNode/internal/encryption/key_generator.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package encryption
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
)
|
||||
|
||||
// GenerateEncryptionKey 生成加密密钥
|
||||
// 返回 keyID 和 actualKey
|
||||
func GenerateEncryptionKey(remoteIP string, userAgent string, policy *serverconfigs.EncryptionKeyPolicy) (keyID string, actualKey string) {
|
||||
if policy == nil {
|
||||
policy = serverconfigs.NewEncryptionKeyPolicy()
|
||||
}
|
||||
|
||||
// 1. 时间分片
|
||||
timeBucket := time.Now().Unix() / policy.TimeBucket
|
||||
|
||||
// 2. IP 归一化(CIDR)
|
||||
ipPrefix := GetCIDRPrefix(remoteIP, policy.IPCIDR)
|
||||
|
||||
// 3. UA 简化
|
||||
uaHash := userAgent
|
||||
if policy.UASimplify {
|
||||
uaHash = serverconfigs.SimplifyUserAgent(userAgent)
|
||||
}
|
||||
uaHashValue := sha256.Sum256([]byte(uaHash))
|
||||
|
||||
// 4. 生成 KeyID(用于缓存)
|
||||
keyID = fmt.Sprintf("%s_%d_%x", ipPrefix, timeBucket, uaHashValue[:8])
|
||||
|
||||
// 5. 生成实际密钥(HMAC-SHA256)
|
||||
hmacKey := hmac.New(sha256.New, []byte(policy.ServerSecret))
|
||||
hmacKey.Write([]byte(fmt.Sprintf("%s_%s_%d", ipPrefix, uaHash, timeBucket)))
|
||||
finalKey := hex.EncodeToString(hmacKey.Sum(nil))
|
||||
|
||||
return keyID, finalKey
|
||||
}
|
||||
|
||||
// GetCIDRPrefix 获取 IP 的 CIDR 前缀
|
||||
func GetCIDRPrefix(ipString string, prefixLen int) string {
|
||||
ip := net.ParseIP(ipString)
|
||||
if ip == nil {
|
||||
return "0.0.0.0"
|
||||
}
|
||||
|
||||
ipv4 := ip.To4()
|
||||
if ipv4 != nil {
|
||||
// IPv4
|
||||
if prefixLen > 32 {
|
||||
prefixLen = 32
|
||||
}
|
||||
if prefixLen < 0 {
|
||||
prefixLen = 0
|
||||
}
|
||||
|
||||
// 计算掩码
|
||||
mask := net.CIDRMask(prefixLen, 32)
|
||||
if mask == nil {
|
||||
return "0.0.0.0"
|
||||
}
|
||||
|
||||
// 应用掩码
|
||||
maskedIP := ipv4.Mask(mask)
|
||||
return maskedIP.String()
|
||||
}
|
||||
|
||||
// IPv6
|
||||
ipv6 := ip.To16()
|
||||
if ipv6 != nil {
|
||||
if prefixLen > 128 {
|
||||
prefixLen = 128
|
||||
}
|
||||
if prefixLen < 0 {
|
||||
prefixLen = 0
|
||||
}
|
||||
|
||||
// 计算掩码
|
||||
mask := net.CIDRMask(prefixLen, 128)
|
||||
if mask == nil {
|
||||
return "::"
|
||||
}
|
||||
|
||||
// 应用掩码
|
||||
maskedIP := ipv6.Mask(mask)
|
||||
return maskedIP.String()
|
||||
}
|
||||
|
||||
return "0.0.0.0"
|
||||
}
|
||||
Reference in New Issue
Block a user