// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . package serverconfigs import ( "regexp" "strings" ) // HTTPPageEncryptionConfig 页面动态加密配置 type HTTPPageEncryptionConfig struct { IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用(用于序列化) // 加密范围 HTML *HTTPHTMLEncryptionConfig `yaml:"html" json:"html"` Javascript *HTTPJavascriptEncryptionConfig `yaml:"javascript" json:"javascript"` // 密钥策略 KeyPolicy *EncryptionKeyPolicy `yaml:"keyPolicy" json:"keyPolicy"` // 白名单 ExcludeURLs []string `yaml:"excludeURLs" json:"excludeURLs"` // 缓存配置 Cache *EncryptionCacheConfig `yaml:"cache" json:"cache"` // 内部状态(初始化后计算得出) enabled bool excludeURLPatterns []*regexp.Regexp } // NewHTTPPageEncryptionConfig 创建新配置 func NewHTTPPageEncryptionConfig() *HTTPPageEncryptionConfig { return &HTTPPageEncryptionConfig{ IsOn: false, HTML: NewHTTPHTMLEncryptionConfig(), Javascript: NewHTTPJavascriptEncryptionConfig(), KeyPolicy: NewEncryptionKeyPolicy(), ExcludeURLs: []string{}, Cache: NewEncryptionCacheConfig(), } } // Init 初始化 func (this *HTTPPageEncryptionConfig) Init() error { // 计算是否启用 this.enabled = this.IsOn && ((this.HTML != nil && this.HTML.IsOn) || (this.Javascript != nil && this.Javascript.IsOn)) // 初始化 HTML 配置 if this.HTML != nil { err := this.HTML.Init() if err != nil { return err } // 如果 HTML 启用,则整体启用(需总开关开启) if this.IsOn && this.HTML.IsOn { this.enabled = true } } // 初始化 JavaScript 配置 if this.Javascript != nil { err := this.Javascript.Init() if err != nil { return err } // 如果 JavaScript 启用,则整体启用(需总开关开启) if this.IsOn && this.Javascript.IsOn { this.enabled = true } } // 初始化密钥策略 if this.KeyPolicy != nil { err := this.KeyPolicy.Init() if err != nil { return err } } // 初始化缓存配置 if this.Cache != nil { err := this.Cache.Init() if err != nil { return err } } // 编译排除 URL 正则表达式 this.excludeURLPatterns = []*regexp.Regexp{} for _, pattern := range this.ExcludeURLs { if len(pattern) > 0 { reg, err := regexp.Compile(pattern) if err == nil { this.excludeURLPatterns = append(this.excludeURLPatterns, reg) } } } return nil } // IsEnabled 检查是否启用(初始化后使用此方法) func (this *HTTPPageEncryptionConfig) IsEnabled() bool { return this.enabled } // MatchExcludeURL 检查 URL 是否在白名单中 func (this *HTTPPageEncryptionConfig) MatchExcludeURL(url string) bool { if len(this.excludeURLPatterns) == 0 { return false } for _, reg := range this.excludeURLPatterns { if reg.MatchString(url) { return true } } return false } // HTTPHTMLEncryptionConfig HTML 加密配置 type HTTPHTMLEncryptionConfig struct { IsOn bool `yaml:"isOn" json:"isOn"` // URL 匹配规则 URLPatterns []string `yaml:"urlPatterns" json:"urlPatterns"` // 加密策略 EncryptInlineScripts bool `yaml:"encryptInlineScripts" json:"encryptInlineScripts"` // 内联脚本 EncryptExternalScripts bool `yaml:"encryptExternalScripts" json:"encryptExternalScripts"` // 外部脚本 urlPatternRegexps []*regexp.Regexp } // NewHTTPHTMLEncryptionConfig 创建新配置 func NewHTTPHTMLEncryptionConfig() *HTTPHTMLEncryptionConfig { return &HTTPHTMLEncryptionConfig{ IsOn: false, URLPatterns: []string{}, EncryptInlineScripts: true, EncryptExternalScripts: true, } } // Init 初始化 func (this *HTTPHTMLEncryptionConfig) Init() error { // 编译 URL 匹配规则 this.urlPatternRegexps = []*regexp.Regexp{} for _, pattern := range this.URLPatterns { if len(pattern) > 0 { reg, err := regexp.Compile(pattern) if err == nil { this.urlPatternRegexps = append(this.urlPatternRegexps, reg) } } } return nil } // MatchURL 检查 URL 是否匹配 func (this *HTTPHTMLEncryptionConfig) MatchURL(url string) bool { if len(this.urlPatternRegexps) == 0 { return true // 如果没有配置规则,默认匹配所有 } for _, reg := range this.urlPatternRegexps { if reg.MatchString(url) { return true } } return false } // HTTPJavascriptEncryptionConfig JavaScript 加密配置 type HTTPJavascriptEncryptionConfig struct { IsOn bool `yaml:"isOn" json:"isOn"` // URL 匹配规则 URLPatterns []string `yaml:"urlPatterns" json:"urlPatterns"` urlPatternRegexps []*regexp.Regexp } // NewHTTPJavascriptEncryptionConfig 创建新配置 func NewHTTPJavascriptEncryptionConfig() *HTTPJavascriptEncryptionConfig { return &HTTPJavascriptEncryptionConfig{ IsOn: false, URLPatterns: []string{}, } } // Init 初始化 func (this *HTTPJavascriptEncryptionConfig) Init() error { // 编译 URL 匹配规则 this.urlPatternRegexps = []*regexp.Regexp{} for _, pattern := range this.URLPatterns { if len(pattern) > 0 { reg, err := regexp.Compile(pattern) if err == nil { this.urlPatternRegexps = append(this.urlPatternRegexps, reg) } } } return nil } // MatchURL 检查 URL 是否匹配 func (this *HTTPJavascriptEncryptionConfig) MatchURL(url string) bool { if len(this.urlPatternRegexps) == 0 { return true // 如果没有配置规则,默认匹配所有 } for _, reg := range this.urlPatternRegexps { if reg.MatchString(url) { return true } } return false } // EncryptionKeyPolicy 加密密钥策略 type EncryptionKeyPolicy struct { // 时间分片(秒) TimeBucket int64 `yaml:"timeBucket" json:"timeBucket"` // 默认 60-120 秒 // IP 归一化(CIDR 前缀长度) IPCIDR int `yaml:"ipCIDR" json:"ipCIDR"` // 默认 24 // UA 简化策略 UASimplify bool `yaml:"uaSimplify" json:"uaSimplify"` // 是否简化 UA // 服务器端密钥(用于 HMAC) ServerSecret string `yaml:"serverSecret" json:"serverSecret"` } // NewEncryptionKeyPolicy 创建新配置 func NewEncryptionKeyPolicy() *EncryptionKeyPolicy { return &EncryptionKeyPolicy{ TimeBucket: 60, // 默认 60 秒 IPCIDR: 24, // 默认 /24 UASimplify: true, ServerSecret: "WAFEncryptionSecret@123", // 默认密钥,生产环境应修改 } } // Init 初始化 func (this *EncryptionKeyPolicy) Init() error { if this.TimeBucket <= 0 { this.TimeBucket = 60 } if this.IPCIDR <= 0 { this.IPCIDR = 24 } if len(this.ServerSecret) == 0 { this.ServerSecret = "WAFEncryptionSecret@123" } return nil } // EncryptionCacheConfig 加密缓存配置 type EncryptionCacheConfig struct { IsOn bool `yaml:"isOn" json:"isOn"` TTL int64 `yaml:"ttl" json:"ttl"` // 缓存 TTL(秒),默认 60 MaxSize int `yaml:"maxSize" json:"maxSize"` // 最大缓存条目数,默认 1000 } // NewEncryptionCacheConfig 创建新配置 func NewEncryptionCacheConfig() *EncryptionCacheConfig { return &EncryptionCacheConfig{ IsOn: true, TTL: 60, MaxSize: 1000, } } // Init 初始化 func (this *EncryptionCacheConfig) Init() error { if this.TTL <= 0 { this.TTL = 60 } if this.MaxSize <= 0 { this.MaxSize = 1000 } return nil } // SimplifyUserAgent 简化 User-Agent func SimplifyUserAgent(ua string) string { if len(ua) == 0 { return "" } // 提取主要信息:浏览器类型和版本 ua = strings.ToLower(ua) // Chrome if strings.Contains(ua, "chrome") { return "chrome" } // Safari if strings.Contains(ua, "safari") && !strings.Contains(ua, "chrome") { return "safari" } // Firefox if strings.Contains(ua, "firefox") { return "firefox" } // Edge if strings.Contains(ua, "edge") { return "edge" } // Opera if strings.Contains(ua, "opera") { return "opera" } return "other" }