[优化] 添加 WAF IP 组功能,包括 CRUD 接口和前端页面支持

This commit is contained in:
ryan
2026-06-01 08:46:24 +08:00
parent d5f46138d5
commit 95d7045b4a
32 changed files with 2214 additions and 44 deletions
@@ -199,6 +199,10 @@ func RenderWAFConfig(snapshot WAFDocument) (string, error) {
groups := make([]wafRuntimeRuleGroup, 0, len(snapshot.RuleGroups))
globalGroupIDs := make([]uint, 0)
enabledGroupIDs := make(map[uint]struct{}, len(snapshot.RuleGroups))
ipGroupsByID := make(map[uint]WAFIPGroup, len(snapshot.IPGroups))
for _, group := range snapshot.IPGroups {
ipGroupsByID[group.ID] = group
}
for _, group := range snapshot.RuleGroups {
if !group.Enabled {
continue
@@ -211,7 +215,19 @@ func RenderWAFConfig(snapshot WAFDocument) (string, error) {
globalGroupIDs = append(globalGroupIDs, group.ID)
}
enabledGroupIDs[group.ID] = struct{}{}
groups = append(groups, wafRuntimeRuleGroup{ID: group.ID, Name: group.Name, IsGlobal: group.IsGlobal, BlockStatusCode: statusCode, BlockResponseBody: group.BlockResponseBody, IPWhitelist: group.IPWhitelist, IPBlacklist: group.IPBlacklist, CountryWhitelist: group.CountryWhitelist, CountryBlacklist: group.CountryBlacklist, RegionWhitelist: group.RegionWhitelist, RegionBlacklist: group.RegionBlacklist})
groups = append(groups, wafRuntimeRuleGroup{
ID: group.ID,
Name: group.Name,
IsGlobal: group.IsGlobal,
BlockStatusCode: statusCode,
BlockResponseBody: group.BlockResponseBody,
IPWhitelist: expandWAFIPGroups(group.IPWhitelist, group.IPWhitelistGroups, ipGroupsByID),
IPBlacklist: expandWAFIPGroups(group.IPBlacklist, group.IPBlacklistGroups, ipGroupsByID),
CountryWhitelist: group.CountryWhitelist,
CountryBlacklist: group.CountryBlacklist,
RegionWhitelist: group.RegionWhitelist,
RegionBlacklist: group.RegionBlacklist,
})
}
sort.Slice(groups, func(i, j int) bool {
if groups[i].IsGlobal != groups[j].IsGlobal {
@@ -234,6 +250,20 @@ func RenderWAFConfig(snapshot WAFDocument) (string, error) {
return string(data), err
}
func expandWAFIPGroups(direct []string, groupIDs []uint, ipGroupsByID map[uint]WAFIPGroup) []string {
items := append([]string{}, direct...)
for _, id := range groupIDs {
group, ok := ipGroupsByID[id]
if !ok || !group.Enabled {
continue
}
items = append(items, group.IPList...)
}
items = uniqueStrings(items)
sort.Strings(items)
return items
}
func ChecksumBundle(mainConfig string, routeConfig string, supportFiles []SupportFile) string {
var builder strings.Builder
builder.WriteString(mainConfig)
@@ -683,6 +713,23 @@ func uniqueUintIDs(values []uint) []uint {
return result
}
func uniqueStrings(values []string) []string {
seen := make(map[string]struct{}, len(values))
result := make([]string, 0, len(values))
for _, value := range values {
item := strings.TrimSpace(value)
if item == "" {
continue
}
if _, ok := seen[item]; ok {
continue
}
seen[item] = struct{}{}
result = append(result, item)
}
return result
}
func resolveUpstreamServerName(originURL string, originHost string) string {
parsed, err := url.Parse(originURL)
if err != nil || !strings.EqualFold(parsed.Scheme, "https") {
@@ -127,6 +127,8 @@ type WAFRuleGroup struct {
BlockResponseBody string `json:"block_response_body,omitempty"`
IPWhitelist []string `json:"ip_whitelist,omitempty"`
IPBlacklist []string `json:"ip_blacklist,omitempty"`
IPWhitelistGroups []uint `json:"ip_whitelist_group_ids,omitempty"`
IPBlacklistGroups []uint `json:"ip_blacklist_group_ids,omitempty"`
CountryWhitelist []string `json:"country_whitelist,omitempty"`
CountryBlacklist []string `json:"country_blacklist,omitempty"`
RegionWhitelist []string `json:"region_whitelist,omitempty"`
@@ -135,6 +137,14 @@ type WAFRuleGroup struct {
PoWConfig *PoWConfig `json:"pow_config,omitempty"`
}
type WAFIPGroup struct {
ID uint `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Enabled bool `json:"enabled"`
IPList []string `json:"ip_list,omitempty"`
}
type WAFBinding struct {
RouteID uint `json:"route_id"`
SiteName string `json:"site_name"`
@@ -143,6 +153,7 @@ type WAFBinding struct {
type WAFDocument struct {
RuleGroups []WAFRuleGroup `json:"rule_groups"`
IPGroups []WAFIPGroup `json:"ip_groups,omitempty"`
Bindings []WAFBinding `json:"bindings"`
}