mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-12 02:06:37 +08:00
[新增] POW 与 WAF 规则合并
This commit is contained in:
@@ -549,7 +549,7 @@ func TestManagerEnsureLuaAssetsWritesReadableFiles(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to read pow lua file: %v", err)
|
t.Fatalf("failed to read pow lua file: %v", err)
|
||||||
}
|
}
|
||||||
if !strings.Contains(string(data), filepath.ToSlash(manager.RuntimeConfigDir)+"/pow_config.json") {
|
if !strings.Contains(string(data), filepath.ToSlash(manager.RuntimeConfigDir)+"/waf_config.json") {
|
||||||
t.Fatalf("expected pow lua to read runtime config dir, got %s", string(data))
|
t.Fatalf("expected pow lua to read runtime config dir, got %s", string(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ end
|
|||||||
-- Lazy-load pow_config from file; reload when content changes
|
-- Lazy-load pow_config from file; reload when content changes
|
||||||
local function load_pow_config()
|
local function load_pow_config()
|
||||||
local config_paths = {
|
local config_paths = {
|
||||||
"__OPENFLARE_RUNTIME_CONFIG_DIR__/pow_config.json",
|
"__OPENFLARE_RUNTIME_CONFIG_DIR__/waf_config.json",
|
||||||
"/etc/nginx/openflare-lua/pow_config.json",
|
"/etc/nginx/openflare-lua/waf_config.json",
|
||||||
"/usr/local/openresty/nginx/conf/pow_config.json"
|
"/usr/local/openresty/nginx/conf/waf_config.json"
|
||||||
}
|
}
|
||||||
for _, config_path in ipairs(config_paths) do
|
for _, config_path in ipairs(config_paths) do
|
||||||
local f = io.open(config_path, "r")
|
local f = io.open(config_path, "r")
|
||||||
@@ -54,7 +54,7 @@ local function load_pow_config()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Clear old domain entries
|
-- Clear old domain/site entries
|
||||||
local old_keys = pow_config_dict:get("_domain_keys")
|
local old_keys = pow_config_dict:get("_domain_keys")
|
||||||
if old_keys then
|
if old_keys then
|
||||||
for domain in string.gmatch(old_keys, "[^\n]+") do
|
for domain in string.gmatch(old_keys, "[^\n]+") do
|
||||||
@@ -64,15 +64,38 @@ local function load_pow_config()
|
|||||||
|
|
||||||
local domain_keys = {}
|
local domain_keys = {}
|
||||||
if content and content ~= "" and content ~= "{}" then
|
if content and content ~= "" and content ~= "{}" then
|
||||||
local ok, entries = pcall(cjson.decode, content)
|
local ok, decoded = pcall(cjson.decode, content)
|
||||||
if ok and entries and type(entries) == "table" then
|
if ok and decoded and decoded.rule_groups and decoded.site_rule_groups then
|
||||||
for _, entry in ipairs(entries) do
|
-- Build rule groups map (group ID -> PoWConfig)
|
||||||
if entry.domains then
|
local groups = {}
|
||||||
for _, domain in ipairs(entry.domains) do
|
for _, group in ipairs(decoded.rule_groups) do
|
||||||
pow_config_dict:set(domain, cjson.encode(entry), 0)
|
if group.pow_enabled then
|
||||||
domain_keys[#domain_keys+1] = domain
|
groups[tostring(group.id)] = group.pow_config
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Build site name to pow_config map
|
||||||
|
for site, group_ids in pairs(decoded.site_rule_groups) do
|
||||||
|
local pow_config = nil
|
||||||
|
-- Check custom group IDs first
|
||||||
|
for _, id in ipairs(group_ids) do
|
||||||
|
pow_config = groups[tostring(id)]
|
||||||
|
if pow_config then
|
||||||
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- If not found, check global group IDs
|
||||||
|
if not pow_config then
|
||||||
|
for _, group in ipairs(decoded.rule_groups) do
|
||||||
|
if group.is_global and group.pow_enabled then
|
||||||
|
pow_config = group.pow_config
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if pow_config then
|
||||||
|
pow_config_dict:set(site, cjson.encode({enabled = true, config = pow_config}), 0)
|
||||||
|
domain_keys[#domain_keys+1] = site
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -91,7 +114,12 @@ if not host or host == "" then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local config_raw = pow_config_dict:get(host)
|
local site = ngx.var.openflare_waf_site or ""
|
||||||
|
if site == "" then
|
||||||
|
site = host
|
||||||
|
end
|
||||||
|
|
||||||
|
local config_raw = pow_config_dict:get(site)
|
||||||
if not config_raw then
|
if not config_raw then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -199,17 +227,22 @@ local args = ngx.req.get_uri_args()
|
|||||||
local host = args["host"] or ngx.var.host or ""
|
local host = args["host"] or ngx.var.host or ""
|
||||||
local redir = args["redir"] or ""
|
local redir = args["redir"] or ""
|
||||||
|
|
||||||
local config_raw = pow_config_dict:get(host)
|
local site = ngx.var.openflare_waf_site or ""
|
||||||
|
if site == "" then
|
||||||
|
site = host
|
||||||
|
end
|
||||||
|
|
||||||
|
local config_raw = pow_config_dict:get(site)
|
||||||
if not config_raw then
|
if not config_raw then
|
||||||
ngx.status = 403
|
ngx.status = 403
|
||||||
ngx.say("PoW not configured for this host")
|
ngx.say("PoW not configured for this site")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok, route_config = pcall(cjson.decode, config_raw)
|
local ok, route_config = pcall(cjson.decode, config_raw)
|
||||||
if not ok or not route_config or not route_config.enabled then
|
if not ok or not route_config or not route_config.enabled then
|
||||||
ngx.status = 403
|
ngx.status = 403
|
||||||
ngx.say("PoW not enabled for this host")
|
ngx.say("PoW not enabled for this site")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ func TestSyncOnceSuccess(t *testing.T) {
|
|||||||
if client.reports[0].MainConfigChecksum == "" || client.reports[0].RouteConfigChecksum == "" {
|
if client.reports[0].MainConfigChecksum == "" || client.reports[0].RouteConfigChecksum == "" {
|
||||||
t.Fatal("expected main and route config checksums to be reported")
|
t.Fatal("expected main and route config checksums to be reported")
|
||||||
}
|
}
|
||||||
if client.reports[0].SupportFileCount != 4 {
|
if client.reports[0].SupportFileCount != 3 {
|
||||||
t.Fatalf("expected support file count to be reported, got %d", client.reports[0].SupportFileCount)
|
t.Fatalf("expected support file count to be reported, got %d", client.reports[0].SupportFileCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -326,7 +326,7 @@ func TestSyncOnceRollbackOnNginxFailure(t *testing.T) {
|
|||||||
if client.reports[0].MainConfigChecksum == "" || client.reports[0].RouteConfigChecksum == "" {
|
if client.reports[0].MainConfigChecksum == "" || client.reports[0].RouteConfigChecksum == "" {
|
||||||
t.Fatal("expected failed report to include main and route config checksums")
|
t.Fatal("expected failed report to include main and route config checksums")
|
||||||
}
|
}
|
||||||
if client.reports[0].SupportFileCount != 4 {
|
if client.reports[0].SupportFileCount != 3 {
|
||||||
t.Fatalf("expected failed report to include support file count, got %d", client.reports[0].SupportFileCount)
|
t.Fatalf("expected failed report to include support file count, got %d", client.reports[0].SupportFileCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package goose
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
presslygoose "github.com/pressly/goose/v3"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
const versionDropProxyRouteLegacyPoW int64 = 202606030003
|
||||||
|
|
||||||
|
// migration202606030003 drops the legacy pow_enabled and pow_config columns
|
||||||
|
// from proxy_routes table, since PoW is now entirely managed under WAF rule groups.
|
||||||
|
func migration202606030003(backend string, ctx Context) *presslygoose.Migration {
|
||||||
|
return newGORMMigration(
|
||||||
|
versionDropProxyRouteLegacyPoW,
|
||||||
|
"202606030003_drop_proxy_route_legacy_pow.go",
|
||||||
|
backend,
|
||||||
|
ctx,
|
||||||
|
migrateDropProxyRouteLegacyPoW,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func migrateDropProxyRouteLegacyPoW(ctx Context, db *gorm.DB, backend string) error {
|
||||||
|
if err := ctx.ApplyCurrentSchema(db, backend); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Drop pow_enabled column if exists
|
||||||
|
if db.Migrator().HasColumn("proxy_routes", "pow_enabled") {
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes DROP COLUMN pow_enabled").Error; err != nil {
|
||||||
|
return fmt.Errorf("drop proxy_routes.pow_enabled: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Drop pow_config column if exists
|
||||||
|
if db.Migrator().HasColumn("proxy_routes", "pow_config") {
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes DROP COLUMN pow_config").Error; err != nil {
|
||||||
|
return fmt.Errorf("drop proxy_routes.pow_config: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ func registeredMigrations(backend string, ctx Context) []*presslygoose.Migration
|
|||||||
migration202606020001(backend, ctx),
|
migration202606020001(backend, ctx),
|
||||||
migration202606030001(backend, ctx),
|
migration202606030001(backend, ctx),
|
||||||
migration202606030002(backend, ctx),
|
migration202606030002(backend, ctx),
|
||||||
|
migration202606030003(backend, ctx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -205,6 +205,12 @@ func TestUpgradeDatabaseSchemaV15ToV16AppliesCompressedReleaseSchema(t *testing.
|
|||||||
if err := applyCurrentSchema(db, "sqlite"); err != nil {
|
if err := applyCurrentSchema(db, "sqlite"); err != nil {
|
||||||
t.Fatalf("apply current schema: %v", err)
|
t.Fatalf("apply current schema: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_enabled BOOLEAN NOT NULL DEFAULT 0").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_enabled: %v", err)
|
||||||
|
}
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_config TEXT NOT NULL DEFAULT '{}'").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_config: %v", err)
|
||||||
|
}
|
||||||
if err := ensureDefaultWAFRuleGroup(db); err != nil {
|
if err := ensureDefaultWAFRuleGroup(db); err != nil {
|
||||||
t.Fatalf("ensure default waf rule group: %v", err)
|
t.Fatalf("ensure default waf rule group: %v", err)
|
||||||
}
|
}
|
||||||
@@ -329,6 +335,13 @@ func TestEnsureDatabaseSchemaUpToDateUpgradesLegacyDatabase(t *testing.T) {
|
|||||||
if err := autoMigrateAll(db); err != nil {
|
if err := autoMigrateAll(db); err != nil {
|
||||||
t.Fatalf("auto migrate db: %v", err)
|
t.Fatalf("auto migrate db: %v", err)
|
||||||
}
|
}
|
||||||
|
// Add legacy PoW columns manually to proxy_routes table to simulate legacy schema v9-v17 state
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_enabled BOOLEAN NOT NULL DEFAULT 0").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_enabled: %v", err)
|
||||||
|
}
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_config TEXT NOT NULL DEFAULT '{}'").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_config: %v", err)
|
||||||
|
}
|
||||||
if err := db.Create(&User{
|
if err := db.Create(&User{
|
||||||
Username: "legacy",
|
Username: "legacy",
|
||||||
Password: "secret",
|
Password: "secret",
|
||||||
@@ -439,6 +452,13 @@ func TestEnsureDatabaseSchemaUpToDateAddsProxyRouteDomainCertificateFields(t *te
|
|||||||
if err := db.AutoMigrate(&legacyProxyRouteV7{}); err != nil {
|
if err := db.AutoMigrate(&legacyProxyRouteV7{}); err != nil {
|
||||||
t.Fatalf("auto migrate legacy proxy_routes v7: %v", err)
|
t.Fatalf("auto migrate legacy proxy_routes v7: %v", err)
|
||||||
}
|
}
|
||||||
|
// Add legacy PoW columns manually to proxy_routes table to simulate legacy schema v9-v17 state
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_enabled BOOLEAN NOT NULL DEFAULT 0").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_enabled: %v", err)
|
||||||
|
}
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_config TEXT NOT NULL DEFAULT '{}'").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
certID := uint(9)
|
certID := uint(9)
|
||||||
@@ -527,6 +547,12 @@ func TestEnsureDatabaseSchemaUpToDateAddsNodeIPManualOverride(t *testing.T) {
|
|||||||
if err := applyCurrentSchema(db, "sqlite"); err != nil {
|
if err := applyCurrentSchema(db, "sqlite"); err != nil {
|
||||||
t.Fatalf("apply current schema: %v", err)
|
t.Fatalf("apply current schema: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_enabled BOOLEAN NOT NULL DEFAULT 0").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_enabled: %v", err)
|
||||||
|
}
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_config TEXT NOT NULL DEFAULT '{}'").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_config: %v", err)
|
||||||
|
}
|
||||||
if err := ensureDefaultWAFRuleGroup(db); err != nil {
|
if err := ensureDefaultWAFRuleGroup(db); err != nil {
|
||||||
t.Fatalf("ensure default waf rule group: %v", err)
|
t.Fatalf("ensure default waf rule group: %v", err)
|
||||||
}
|
}
|
||||||
@@ -570,6 +596,12 @@ func TestEnsureDatabaseSchemaUpToDateV16BackfillsNodeColumnsWhenNewColumnsAlread
|
|||||||
if err := applyCurrentSchema(db, "sqlite"); err != nil {
|
if err := applyCurrentSchema(db, "sqlite"); err != nil {
|
||||||
t.Fatalf("apply current schema: %v", err)
|
t.Fatalf("apply current schema: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_enabled BOOLEAN NOT NULL DEFAULT 0").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_enabled: %v", err)
|
||||||
|
}
|
||||||
|
if err := db.Exec("ALTER TABLE proxy_routes ADD COLUMN pow_config TEXT NOT NULL DEFAULT '{}'").Error; err != nil {
|
||||||
|
t.Fatalf("failed to add legacy pow_config: %v", err)
|
||||||
|
}
|
||||||
if err := ensureDefaultWAFRuleGroup(db); err != nil {
|
if err := ensureDefaultWAFRuleGroup(db); err != nil {
|
||||||
t.Fatalf("ensure default waf rule group: %v", err)
|
t.Fatalf("ensure default waf rule group: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1131,11 +1131,23 @@ func validateDatabaseSchemaV9(db *gorm.DB, backend string) error {
|
|||||||
if err := validateDatabaseSchemaV8(db, backend); err != nil {
|
if err := validateDatabaseSchemaV8(db, backend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !db.Migrator().HasColumn(&ProxyRoute{}, "pow_enabled") {
|
hasAppliedDropPoW := false
|
||||||
return fmt.Errorf("column proxy_routes.pow_enabled is missing")
|
if db.Migrator().HasTable("goose_db_version") {
|
||||||
|
var count int64
|
||||||
|
_ = db.Table("goose_db_version").
|
||||||
|
Where("version_id = ? AND is_applied = ?", 202606030003, true).
|
||||||
|
Count(&count).Error
|
||||||
|
if count > 0 {
|
||||||
|
hasAppliedDropPoW = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !db.Migrator().HasColumn(&ProxyRoute{}, "pow_config") {
|
if !hasAppliedDropPoW {
|
||||||
return fmt.Errorf("column proxy_routes.pow_config is missing")
|
if !db.Migrator().HasColumn(&ProxyRoute{}, "pow_enabled") {
|
||||||
|
return fmt.Errorf("column proxy_routes.pow_enabled is missing")
|
||||||
|
}
|
||||||
|
if !db.Migrator().HasColumn(&ProxyRoute{}, "pow_config") {
|
||||||
|
return fmt.Errorf("column proxy_routes.pow_config is missing")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ type ProxyRoute struct {
|
|||||||
CachePolicy string `json:"cache_policy" gorm:"size:32;not null;default:''"`
|
CachePolicy string `json:"cache_policy" gorm:"size:32;not null;default:''"`
|
||||||
CacheRules string `json:"cache_rules" gorm:"type:text;not null;default:'[]'"`
|
CacheRules string `json:"cache_rules" gorm:"type:text;not null;default:'[]'"`
|
||||||
CustomHeaders string `json:"custom_headers" gorm:"type:text;not null;default:'[]'"`
|
CustomHeaders string `json:"custom_headers" gorm:"type:text;not null;default:'[]'"`
|
||||||
PoWEnabled bool `json:"pow_enabled" gorm:"column:pow_enabled;not null;default:false"`
|
|
||||||
PoWConfig string `json:"pow_config" gorm:"column:pow_config;type:text;not null;default:'{}'"`
|
|
||||||
BasicAuthEnabled bool `json:"basic_auth_enabled" gorm:"not null;default:false"`
|
BasicAuthEnabled bool `json:"basic_auth_enabled" gorm:"not null;default:false"`
|
||||||
BasicAuthUsername string `json:"basic_auth_username" gorm:"size:255;not null;default:''"`
|
BasicAuthUsername string `json:"basic_auth_username" gorm:"size:255;not null;default:''"`
|
||||||
BasicAuthPassword string `json:"basic_auth_password" gorm:"size:255;not null;default:''"`
|
BasicAuthPassword string `json:"basic_auth_password" gorm:"size:255;not null;default:''"`
|
||||||
@@ -86,8 +84,6 @@ func (route *ProxyRoute) Update() error {
|
|||||||
"cache_policy": route.CachePolicy,
|
"cache_policy": route.CachePolicy,
|
||||||
"cache_rules": route.CacheRules,
|
"cache_rules": route.CacheRules,
|
||||||
"custom_headers": route.CustomHeaders,
|
"custom_headers": route.CustomHeaders,
|
||||||
"pow_enabled": route.PoWEnabled,
|
|
||||||
"pow_config": route.PoWConfig,
|
|
||||||
"basic_auth_enabled": route.BasicAuthEnabled,
|
"basic_auth_enabled": route.BasicAuthEnabled,
|
||||||
"basic_auth_username": route.BasicAuthUsername,
|
"basic_auth_username": route.BasicAuthUsername,
|
||||||
"basic_auth_password": route.BasicAuthPassword,
|
"basic_auth_password": route.BasicAuthPassword,
|
||||||
|
|||||||
@@ -11,39 +11,6 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetActiveConfigForAgentIncludesPoWConfig(t *testing.T) {
|
|
||||||
setupServiceTestDB(t)
|
|
||||||
|
|
||||||
_, err := CreateProxyRoute(ProxyRouteInput{
|
|
||||||
Domain: "pow-agent.example.com",
|
|
||||||
OriginURL: "https://origin.internal",
|
|
||||||
Enabled: true,
|
|
||||||
PoWEnabled: true,
|
|
||||||
PoWConfig: `{"difficulty":4,"algorithm":"fast","session_ttl":86400,"challenge_ttl":300,"whitelist":{"paths":["/.well-known/*","/favicon.ico","/robots.txt"],"user_agents":["Googlebot","bingbot","Baiduspider"]},"blacklist":{"ips":[],"ip_cidrs":[],"paths":[],"path_regexes":[],"user_agents":[]}}`,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateProxyRoute failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := PublishConfigVersion("root", false); err != nil {
|
|
||||||
t.Fatalf("PublishConfigVersion failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
activeConfig, err := GetActiveConfigForAgent()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("GetActiveConfigForAgent failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, file := range activeConfig.SupportFiles {
|
|
||||||
if file.Path == "pow_config.json" || file.Path == "waf_config.json" {
|
|
||||||
t.Fatalf("agent config should not receive rendered runtime config file %s", file.Path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !strings.Contains(activeConfig.SourceConfigJSON, `"pow_enabled":true`) {
|
|
||||||
t.Fatal("expected agent config source json to include PoW source configuration")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetActiveConfigForAgentIncludesWAFConfig(t *testing.T) {
|
func TestGetActiveConfigForAgentIncludesWAFConfig(t *testing.T) {
|
||||||
setupServiceTestDB(t)
|
setupServiceTestDB(t)
|
||||||
|
|
||||||
@@ -144,39 +111,6 @@ func TestChangedWAFIPGroupsForAgentReturnsChecksumDelta(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetActiveConfigForAgentUsesTenMinutePoWSessionDefault(t *testing.T) {
|
|
||||||
setupServiceTestDB(t)
|
|
||||||
|
|
||||||
_, err := CreateProxyRoute(ProxyRouteInput{
|
|
||||||
Domain: "pow-default.example.com",
|
|
||||||
OriginURL: "https://origin.internal",
|
|
||||||
Enabled: true,
|
|
||||||
PoWEnabled: true,
|
|
||||||
PoWConfig: `{}`,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateProxyRoute failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := PublishConfigVersion("root", false); err != nil {
|
|
||||||
t.Fatalf("PublishConfigVersion failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
activeConfig, err := GetActiveConfigForAgent()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("GetActiveConfigForAgent failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, file := range activeConfig.SupportFiles {
|
|
||||||
if file.Path == "pow_config.json" {
|
|
||||||
t.Fatal("agent config should not receive rendered pow_config.json")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !strings.Contains(activeConfig.SourceConfigJSON, `"session_ttl":600`) {
|
|
||||||
t.Fatalf("expected default PoW session TTL to be in source json, got %s", activeConfig.SourceConfigJSON)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRegisterNodeWithAccessToken(t *testing.T) {
|
func TestRegisterNodeWithAccessToken(t *testing.T) {
|
||||||
setupServiceTestDB(t)
|
setupServiceTestDB(t)
|
||||||
|
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ type snapshotRoute struct {
|
|||||||
CachePolicy string `json:"cache_policy,omitempty"`
|
CachePolicy string `json:"cache_policy,omitempty"`
|
||||||
CacheRules []string `json:"cache_rules,omitempty"`
|
CacheRules []string `json:"cache_rules,omitempty"`
|
||||||
CustomHeaders []ProxyRouteCustomHeaderInput `json:"custom_headers,omitempty"`
|
CustomHeaders []ProxyRouteCustomHeaderInput `json:"custom_headers,omitempty"`
|
||||||
PoWEnabled bool `json:"pow_enabled,omitempty"`
|
|
||||||
PoWConfig *ProxyRoutePoWConfig `json:"pow_config,omitempty"`
|
|
||||||
BasicAuthEnabled bool `json:"basic_auth_enabled,omitempty"`
|
BasicAuthEnabled bool `json:"basic_auth_enabled,omitempty"`
|
||||||
BasicAuthUsername string `json:"basic_auth_username,omitempty"`
|
BasicAuthUsername string `json:"basic_auth_username,omitempty"`
|
||||||
BasicAuthPassword string `json:"basic_auth_password,omitempty"`
|
BasicAuthPassword string `json:"basic_auth_password,omitempty"`
|
||||||
@@ -551,13 +549,6 @@ func buildSnapshotRoutes(routes []*model.ProxyRoute) ([]snapshotRoute, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("路由 %s 缓存规则无效", route.Domain)
|
return nil, fmt.Errorf("路由 %s 缓存规则无效", route.Domain)
|
||||||
}
|
}
|
||||||
powConfig, err := decodeStoredPoWConfig(route.PoWEnabled, route.PoWConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("路由 %s PoW 配置无效", route.Domain)
|
|
||||||
}
|
|
||||||
if !route.PoWEnabled {
|
|
||||||
powConfig = nil
|
|
||||||
}
|
|
||||||
items = append(items, snapshotRoute{
|
items = append(items, snapshotRoute{
|
||||||
ID: route.ID,
|
ID: route.ID,
|
||||||
SiteName: normalizeProxyRouteSiteNameInput(route, route.SiteName, domains[0]),
|
SiteName: normalizeProxyRouteSiteNameInput(route, route.SiteName, domains[0]),
|
||||||
@@ -579,8 +570,6 @@ func buildSnapshotRoutes(routes []*model.ProxyRoute) ([]snapshotRoute, error) {
|
|||||||
CachePolicy: route.CachePolicy,
|
CachePolicy: route.CachePolicy,
|
||||||
CacheRules: cacheRules,
|
CacheRules: cacheRules,
|
||||||
CustomHeaders: customHeaders,
|
CustomHeaders: customHeaders,
|
||||||
PoWEnabled: route.PoWEnabled,
|
|
||||||
PoWConfig: powConfig,
|
|
||||||
BasicAuthEnabled: route.BasicAuthEnabled,
|
BasicAuthEnabled: route.BasicAuthEnabled,
|
||||||
BasicAuthUsername: route.BasicAuthUsername,
|
BasicAuthUsername: route.BasicAuthUsername,
|
||||||
BasicAuthPassword: route.BasicAuthPassword,
|
BasicAuthPassword: route.BasicAuthPassword,
|
||||||
@@ -861,17 +850,6 @@ func normalizeSnapshotRoutes(routes []snapshotRoute) []snapshotRoute {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
routes[index].LimitRate = normalizedLimitRate
|
routes[index].LimitRate = normalizedLimitRate
|
||||||
}
|
}
|
||||||
if routes[index].PoWEnabled {
|
|
||||||
raw, err := json.Marshal(routes[index].PoWConfig)
|
|
||||||
if err == nil {
|
|
||||||
normalizedPoWConfig, err := normalizePoWConfig(true, string(raw))
|
|
||||||
if err == nil {
|
|
||||||
routes[index].PoWConfig = &normalizedPoWConfig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
routes[index].PoWConfig = nil
|
|
||||||
}
|
|
||||||
if !routes[index].BasicAuthEnabled {
|
if !routes[index].BasicAuthEnabled {
|
||||||
routes[index].BasicAuthUsername = ""
|
routes[index].BasicAuthUsername = ""
|
||||||
routes[index].BasicAuthPassword = ""
|
routes[index].BasicAuthPassword = ""
|
||||||
@@ -918,7 +896,7 @@ func flattenSnapshotRoutesByDomain(routes []snapshotRoute) map[string]snapshotRo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func snapshotRouteConfigEqual(left snapshotRoute, right snapshotRoute) bool {
|
func snapshotRouteConfigEqual(left snapshotRoute, right snapshotRoute) bool {
|
||||||
if left.SiteName != right.SiteName || left.Domain != right.Domain || left.OriginURL != right.OriginURL || left.OriginHost != right.OriginHost || left.EnableHTTPS != right.EnableHTTPS || left.RedirectHTTP != right.RedirectHTTP || left.LimitConnPerServer != right.LimitConnPerServer || left.LimitConnPerIP != right.LimitConnPerIP || left.LimitRate != right.LimitRate || left.CacheEnabled != right.CacheEnabled || left.CachePolicy != right.CachePolicy || left.PoWEnabled != right.PoWEnabled || left.BasicAuthEnabled != right.BasicAuthEnabled || left.BasicAuthUsername != right.BasicAuthUsername || left.BasicAuthPassword != right.BasicAuthPassword || left.UpstreamType != right.UpstreamType || !uintPtrEqual(left.TunnelNodeID, right.TunnelNodeID) || left.TunnelTargetAddr != right.TunnelTargetAddr || left.TunnelTargetProto != right.TunnelTargetProto || !uintPtrEqual(left.PagesProjectID, right.PagesProjectID) || !snapshotPagesDeploymentEqual(left.PagesDeployment, right.PagesDeployment) || !uintSliceEqual(left.CertIDs, right.CertIDs) || !uintSliceEqual(left.DomainCertIDs, right.DomainCertIDs) {
|
if left.SiteName != right.SiteName || left.Domain != right.Domain || left.OriginURL != right.OriginURL || left.OriginHost != right.OriginHost || left.EnableHTTPS != right.EnableHTTPS || left.RedirectHTTP != right.RedirectHTTP || left.LimitConnPerServer != right.LimitConnPerServer || left.LimitConnPerIP != right.LimitConnPerIP || left.LimitRate != right.LimitRate || left.CacheEnabled != right.CacheEnabled || left.CachePolicy != right.CachePolicy || left.BasicAuthEnabled != right.BasicAuthEnabled || left.BasicAuthUsername != right.BasicAuthUsername || left.BasicAuthPassword != right.BasicAuthPassword || left.UpstreamType != right.UpstreamType || !uintPtrEqual(left.TunnelNodeID, right.TunnelNodeID) || left.TunnelTargetAddr != right.TunnelTargetAddr || left.TunnelTargetProto != right.TunnelTargetProto || !uintPtrEqual(left.PagesProjectID, right.PagesProjectID) || !snapshotPagesDeploymentEqual(left.PagesDeployment, right.PagesDeployment) || !uintSliceEqual(left.CertIDs, right.CertIDs) || !uintSliceEqual(left.DomainCertIDs, right.DomainCertIDs) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if len(left.Domains) != len(right.Domains) {
|
if len(left.Domains) != len(right.Domains) {
|
||||||
@@ -953,9 +931,6 @@ func snapshotRouteConfigEqual(left snapshotRoute, right snapshotRoute) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !snapshotPoWConfigEqual(left.PoWConfig, right.PoWConfig) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,26 +961,6 @@ func snapshotWAFConfigEqual(left snapshotWAFDocument, right snapshotWAFDocument)
|
|||||||
return string(leftJSON) == string(rightJSON)
|
return string(leftJSON) == string(rightJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
func snapshotPoWConfigEqual(left *ProxyRoutePoWConfig, right *ProxyRoutePoWConfig) bool {
|
|
||||||
if left == nil || right == nil {
|
|
||||||
return left == nil && right == nil
|
|
||||||
}
|
|
||||||
return left.Difficulty == right.Difficulty &&
|
|
||||||
left.Algorithm == right.Algorithm &&
|
|
||||||
left.SessionTTL == right.SessionTTL &&
|
|
||||||
left.ChallengeTTL == right.ChallengeTTL &&
|
|
||||||
stringSliceEqual(left.Whitelist.IPs, right.Whitelist.IPs) &&
|
|
||||||
stringSliceEqual(left.Whitelist.IPCidrs, right.Whitelist.IPCidrs) &&
|
|
||||||
stringSliceEqual(left.Whitelist.Paths, right.Whitelist.Paths) &&
|
|
||||||
stringSliceEqual(left.Whitelist.PathRegexes, right.Whitelist.PathRegexes) &&
|
|
||||||
stringSliceEqual(left.Whitelist.UserAgents, right.Whitelist.UserAgents) &&
|
|
||||||
stringSliceEqual(left.Blacklist.IPs, right.Blacklist.IPs) &&
|
|
||||||
stringSliceEqual(left.Blacklist.IPCidrs, right.Blacklist.IPCidrs) &&
|
|
||||||
stringSliceEqual(left.Blacklist.Paths, right.Blacklist.Paths) &&
|
|
||||||
stringSliceEqual(left.Blacklist.PathRegexes, right.Blacklist.PathRegexes) &&
|
|
||||||
stringSliceEqual(left.Blacklist.UserAgents, right.Blacklist.UserAgents)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringSliceEqual(left []string, right []string) bool {
|
func stringSliceEqual(left []string, right []string) bool {
|
||||||
if len(left) != len(right) {
|
if len(left) != len(right) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -982,31 +982,31 @@ func TestPublishConfigVersionDetectsPoWChanges(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("initial PublishConfigVersion failed: %v", err)
|
t.Fatalf("initial PublishConfigVersion failed: %v", err)
|
||||||
}
|
}
|
||||||
if !strings.Contains(firstRelease.Version.SupportFilesJSON, `"path":"pow_config.json"`) {
|
if !strings.Contains(firstRelease.Version.SupportFilesJSON, `"path":"waf_config.json"`) {
|
||||||
t.Fatal("expected publish to include pow_config.json support file")
|
t.Fatal("expected publish to include waf_config.json support file")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = UpdateProxyRoute(route.ID, ProxyRouteInput{
|
group, err := CreateWAFRuleGroup(WAFRuleGroupInput{
|
||||||
Domain: route.Domain,
|
Name: "pow group",
|
||||||
OriginURL: route.OriginURL,
|
Enabled: true,
|
||||||
Enabled: true,
|
BlockStatusCode: 418,
|
||||||
PoWEnabled: true,
|
PoWEnabled: true,
|
||||||
PoWConfig: `{"difficulty":5,"algorithm":"slow","session_ttl":7200,"challenge_ttl":180,"whitelist":{"ips":["127.0.0.1"],"ip_cidrs":[],"paths":[],"path_regexes":[],"user_agents":[]},"blacklist":{"ips":[],"ip_cidrs":[],"paths":["/login"],"path_regexes":[],"user_agents":[]}}`,
|
PoWConfig: json.RawMessage(`{"difficulty":5,"algorithm":"slow","session_ttl":7200,"challenge_ttl":180,"whitelist":{"ips":["127.0.0.1"],"ip_cidrs":[],"paths":[],"path_regexes":[],"user_agents":[]},"blacklist":{"ips":[],"ip_cidrs":[],"paths":["/login"],"path_regexes":[],"user_agents":[]}}`),
|
||||||
RedirectHTTP: false,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("UpdateProxyRoute failed: %v", err)
|
t.Fatalf("CreateWAFRuleGroup failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = ReplaceWAFSiteRuleGroups(route.ID, []uint{group.ID}); err != nil {
|
||||||
|
t.Fatalf("ReplaceWAFSiteRuleGroups failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
diff, err := DiffConfigVersion()
|
diff, err := DiffConfigVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("DiffConfigVersion failed: %v", err)
|
t.Fatalf("DiffConfigVersion failed: %v", err)
|
||||||
}
|
}
|
||||||
if len(diff.ModifiedDomains) != 1 || diff.ModifiedDomains[0] != "pow.example.com" {
|
if !diff.WAFConfigChanged {
|
||||||
t.Fatalf("expected PoW change to mark domain as modified, got %#v", diff.ModifiedDomains)
|
t.Fatal("expected PoW change (via WAF Rule Group) to trigger WAF config change")
|
||||||
}
|
|
||||||
if len(diff.ModifiedSites) != 1 || diff.ModifiedSites[0] != "pow.example.com" {
|
|
||||||
t.Fatalf("expected PoW change to mark site as modified, got %#v", diff.ModifiedSites)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
secondRelease, err := PublishConfigVersion("root", false)
|
secondRelease, err := PublishConfigVersion("root", false)
|
||||||
@@ -1053,18 +1053,18 @@ func TestPublishConfigVersionDetectsPoWChanges(t *testing.T) {
|
|||||||
if err := json.Unmarshal([]byte(secondRelease.Version.SupportFilesJSON), &supportFiles); err != nil {
|
if err := json.Unmarshal([]byte(secondRelease.Version.SupportFilesJSON), &supportFiles); err != nil {
|
||||||
t.Fatalf("failed to decode support files: %v", err)
|
t.Fatalf("failed to decode support files: %v", err)
|
||||||
}
|
}
|
||||||
foundPowSupportFile := false
|
foundWafSupportFile := false
|
||||||
for _, file := range supportFiles {
|
for _, file := range supportFiles {
|
||||||
if file.Path != "pow_config.json" {
|
if file.Path != "waf_config.json" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
foundPowSupportFile = true
|
foundWafSupportFile = true
|
||||||
if !strings.Contains(file.Content, `"difficulty":5`) {
|
if !strings.Contains(file.Content, `"difficulty":5`) {
|
||||||
t.Fatalf("expected pow support file to persist config, got %s", file.Content)
|
t.Fatalf("expected waf support file to persist pow config, got %s", file.Content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !foundPowSupportFile {
|
if !foundWafSupportFile {
|
||||||
t.Fatal("expected publish to include pow_config.json support file")
|
t.Fatal("expected publish to include waf_config.json support file")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1081,15 +1081,13 @@ func TestPublishConfigVersionRendersBasicAuthWithPoW(t *testing.T) {
|
|||||||
t.Fatalf("CreateTLSCertificate failed: %v", err)
|
t.Fatalf("CreateTLSCertificate failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = CreateProxyRoute(ProxyRouteInput{
|
route, err := CreateProxyRoute(ProxyRouteInput{
|
||||||
Domain: "xbot.example.com",
|
Domain: "xbot.example.com",
|
||||||
OriginURL: "http://c1:36185",
|
OriginURL: "http://c1:36185",
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
EnableHTTPS: true,
|
EnableHTTPS: true,
|
||||||
CertID: &certificate.ID,
|
CertID: &certificate.ID,
|
||||||
RedirectHTTP: true,
|
RedirectHTTP: true,
|
||||||
PoWEnabled: true,
|
|
||||||
PoWConfig: `{"difficulty":4,"algorithm":"fast","session_ttl":600,"challenge_ttl":300,"whitelist":{"ips":[],"ip_cidrs":[],"paths":[],"path_regexes":[],"user_agents":[]},"blacklist":{"ips":[],"ip_cidrs":[],"paths":[],"path_regexes":[],"user_agents":[]}}`,
|
|
||||||
BasicAuthEnabled: true,
|
BasicAuthEnabled: true,
|
||||||
BasicAuthUsername: "admin",
|
BasicAuthUsername: "admin",
|
||||||
BasicAuthPassword: "123",
|
BasicAuthPassword: "123",
|
||||||
@@ -1098,6 +1096,21 @@ func TestPublishConfigVersionRendersBasicAuthWithPoW(t *testing.T) {
|
|||||||
t.Fatalf("CreateProxyRoute failed: %v", err)
|
t.Fatalf("CreateProxyRoute failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group, err := CreateWAFRuleGroup(WAFRuleGroupInput{
|
||||||
|
Name: "pow group",
|
||||||
|
Enabled: true,
|
||||||
|
BlockStatusCode: 418,
|
||||||
|
PoWEnabled: true,
|
||||||
|
PoWConfig: json.RawMessage(`{"difficulty":4,"algorithm":"fast","session_ttl":600,"challenge_ttl":300,"whitelist":{"ips":[],"ip_cidrs":[],"paths":[],"path_regexes":[],"user_agents":[]},"blacklist":{"ips":[],"ip_cidrs":[],"paths":[],"path_regexes":[],"user_agents":[]}}`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CreateWAFRuleGroup failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = ReplaceWAFSiteRuleGroups(route.ID, []uint{group.ID}); err != nil {
|
||||||
|
t.Fatalf("ReplaceWAFSiteRuleGroups failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
result, err := PublishConfigVersion("root", false)
|
result, err := PublishConfigVersion("root", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("PublishConfigVersion failed: %v", err)
|
t.Fatalf("PublishConfigVersion failed: %v", err)
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ type ProxyRouteInput struct {
|
|||||||
CachePolicy string `json:"cache_policy"`
|
CachePolicy string `json:"cache_policy"`
|
||||||
CacheRules []string `json:"cache_rules"`
|
CacheRules []string `json:"cache_rules"`
|
||||||
CustomHeaders []ProxyRouteCustomHeaderInput `json:"custom_headers"`
|
CustomHeaders []ProxyRouteCustomHeaderInput `json:"custom_headers"`
|
||||||
PoWEnabled bool `json:"pow_enabled"`
|
|
||||||
PoWConfig string `json:"pow_config"`
|
|
||||||
BasicAuthEnabled bool `json:"basic_auth_enabled"`
|
BasicAuthEnabled bool `json:"basic_auth_enabled"`
|
||||||
BasicAuthUsername string `json:"basic_auth_username"`
|
BasicAuthUsername string `json:"basic_auth_username"`
|
||||||
BasicAuthPassword string `json:"basic_auth_password"`
|
BasicAuthPassword string `json:"basic_auth_password"`
|
||||||
@@ -96,8 +94,6 @@ type ProxyRouteView struct {
|
|||||||
CacheRuleList []string `json:"cache_rule_list"`
|
CacheRuleList []string `json:"cache_rule_list"`
|
||||||
CustomHeaders string `json:"custom_headers"`
|
CustomHeaders string `json:"custom_headers"`
|
||||||
CustomHeaderList []ProxyRouteCustomHeaderInput `json:"custom_header_list"`
|
CustomHeaderList []ProxyRouteCustomHeaderInput `json:"custom_header_list"`
|
||||||
PoWEnabled bool `json:"pow_enabled"`
|
|
||||||
PoWConfig *ProxyRoutePoWConfig `json:"pow_config"`
|
|
||||||
BasicAuthEnabled bool `json:"basic_auth_enabled"`
|
BasicAuthEnabled bool `json:"basic_auth_enabled"`
|
||||||
BasicAuthUsername string `json:"basic_auth_username"`
|
BasicAuthUsername string `json:"basic_auth_username"`
|
||||||
BasicAuthPassword string `json:"basic_auth_password"`
|
BasicAuthPassword string `json:"basic_auth_password"`
|
||||||
@@ -239,15 +235,6 @@ func buildProxyRoute(route *model.ProxyRoute, input ProxyRouteInput) (*model.Pro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
powConfig, err := normalizePoWConfig(input.PoWEnabled, input.PoWConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
powConfigJSON, err := json.Marshal(powConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !input.EnableHTTPS {
|
if !input.EnableHTTPS {
|
||||||
input.RedirectHTTP = false
|
input.RedirectHTTP = false
|
||||||
input.CertID = nil
|
input.CertID = nil
|
||||||
@@ -330,8 +317,6 @@ func buildProxyRoute(route *model.ProxyRoute, input ProxyRouteInput) (*model.Pro
|
|||||||
route.CachePolicy = normalizeCachePolicy(input.CacheEnabled, cachePolicy)
|
route.CachePolicy = normalizeCachePolicy(input.CacheEnabled, cachePolicy)
|
||||||
route.CacheRules = string(cacheRulesJSON)
|
route.CacheRules = string(cacheRulesJSON)
|
||||||
route.CustomHeaders = string(customHeadersJSON)
|
route.CustomHeaders = string(customHeadersJSON)
|
||||||
route.PoWEnabled = input.PoWEnabled
|
|
||||||
route.PoWConfig = string(powConfigJSON)
|
|
||||||
route.BasicAuthEnabled = input.BasicAuthEnabled
|
route.BasicAuthEnabled = input.BasicAuthEnabled
|
||||||
route.BasicAuthUsername = input.BasicAuthUsername
|
route.BasicAuthUsername = input.BasicAuthUsername
|
||||||
route.BasicAuthPassword = input.BasicAuthPassword
|
route.BasicAuthPassword = input.BasicAuthPassword
|
||||||
@@ -395,10 +380,6 @@ func buildProxyRouteView(route *model.ProxyRoute) (*ProxyRouteView, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
powConfig, err := decodeStoredPoWConfig(route.PoWEnabled, route.PoWConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
certIDs, err := decodeStoredCertIDs(route.CertIDs, route.CertID)
|
certIDs, err := decodeStoredCertIDs(route.CertIDs, route.CertID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -439,8 +420,6 @@ func buildProxyRouteView(route *model.ProxyRoute) (*ProxyRouteView, error) {
|
|||||||
CacheRuleList: cacheRules,
|
CacheRuleList: cacheRules,
|
||||||
CustomHeaders: route.CustomHeaders,
|
CustomHeaders: route.CustomHeaders,
|
||||||
CustomHeaderList: customHeaders,
|
CustomHeaderList: customHeaders,
|
||||||
PoWEnabled: route.PoWEnabled,
|
|
||||||
PoWConfig: powConfig,
|
|
||||||
BasicAuthEnabled: route.BasicAuthEnabled,
|
BasicAuthEnabled: route.BasicAuthEnabled,
|
||||||
BasicAuthUsername: route.BasicAuthUsername,
|
BasicAuthUsername: route.BasicAuthUsername,
|
||||||
BasicAuthPassword: route.BasicAuthPassword,
|
BasicAuthPassword: route.BasicAuthPassword,
|
||||||
|
|||||||
@@ -34,12 +34,7 @@ func Render(doc Document, certificateFiles []SupportFile) (*Result, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
powConfig, err := RenderPoWConfig(doc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
files := append([]SupportFile(nil), certificateFiles...)
|
files := append([]SupportFile(nil), certificateFiles...)
|
||||||
files = append(files, SupportFile{Path: "pow_config.json", Content: powConfig})
|
|
||||||
files = append(files, SupportFile{Path: "waf_config.json", Content: wafConfig})
|
files = append(files, SupportFile{Path: "waf_config.json", Content: wafConfig})
|
||||||
files = DedupeSupportFiles(files)
|
files = DedupeSupportFiles(files)
|
||||||
return &Result{
|
return &Result{
|
||||||
@@ -88,9 +83,6 @@ func RenderRouteConfig(doc Document, certificateFiles []SupportFile) (string, er
|
|||||||
cacheConfig := routeCacheConfig{Enabled: route.CacheEnabled, Policy: route.CachePolicy, Rules: route.CacheRules}
|
cacheConfig := routeCacheConfig{Enabled: route.CacheEnabled, Policy: route.CachePolicy, Rules: route.CacheRules}
|
||||||
limitConfig := routeLimitConfig{LimitConnPerServer: route.LimitConnPerServer, LimitConnPerIP: route.LimitConnPerIP, LimitRate: route.LimitRate}
|
limitConfig := routeLimitConfig{LimitConnPerServer: route.LimitConnPerServer, LimitConnPerIP: route.LimitConnPerIP, LimitRate: route.LimitRate}
|
||||||
powEnabled, _ := getPoWConfigForRoute(route.ID, doc.WAF)
|
powEnabled, _ := getPoWConfigForRoute(route.ID, doc.WAF)
|
||||||
if route.PoWEnabled {
|
|
||||||
powEnabled = true
|
|
||||||
}
|
|
||||||
if normalizeRouteUpstreamType(route.UpstreamType) == "pages" {
|
if normalizeRouteUpstreamType(route.UpstreamType) == "pages" {
|
||||||
if route.PagesDeployment == nil {
|
if route.PagesDeployment == nil {
|
||||||
return "", fmt.Errorf("route %s pages deployment is missing", route.Domain)
|
return "", fmt.Errorf("route %s pages deployment is missing", route.Domain)
|
||||||
@@ -214,12 +206,6 @@ func RenderPoWConfig(doc Document) (string, error) {
|
|||||||
entries := make([]domainEntry, 0)
|
entries := make([]domainEntry, 0)
|
||||||
for _, route := range doc.Routes {
|
for _, route := range doc.Routes {
|
||||||
powEnabled, powConfig := getPoWConfigForRoute(route.ID, doc.WAF)
|
powEnabled, powConfig := getPoWConfigForRoute(route.ID, doc.WAF)
|
||||||
if route.PoWEnabled {
|
|
||||||
powEnabled = true
|
|
||||||
if route.PoWConfig != nil {
|
|
||||||
powConfig = route.PoWConfig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !powEnabled {
|
if !powEnabled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -234,19 +220,21 @@ func RenderPoWConfig(doc Document) (string, error) {
|
|||||||
|
|
||||||
func RenderWAFConfig(snapshot WAFDocument) (string, error) {
|
func RenderWAFConfig(snapshot WAFDocument) (string, error) {
|
||||||
type wafRuntimeRuleGroup struct {
|
type wafRuntimeRuleGroup struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
IsGlobal bool `json:"is_global"`
|
IsGlobal bool `json:"is_global"`
|
||||||
BlockStatusCode int `json:"block_status_code"`
|
BlockStatusCode int `json:"block_status_code"`
|
||||||
BlockResponseBody string `json:"block_response_body"`
|
BlockResponseBody string `json:"block_response_body"`
|
||||||
IPWhitelist []string `json:"ip_whitelist"`
|
IPWhitelist []string `json:"ip_whitelist"`
|
||||||
IPBlacklist []string `json:"ip_blacklist"`
|
IPBlacklist []string `json:"ip_blacklist"`
|
||||||
IPWhitelistGroups []uint `json:"ip_whitelist_group_ids,omitempty"`
|
IPWhitelistGroups []uint `json:"ip_whitelist_group_ids,omitempty"`
|
||||||
IPBlacklistGroups []uint `json:"ip_blacklist_group_ids,omitempty"`
|
IPBlacklistGroups []uint `json:"ip_blacklist_group_ids,omitempty"`
|
||||||
CountryWhitelist []string `json:"country_whitelist"`
|
CountryWhitelist []string `json:"country_whitelist"`
|
||||||
CountryBlacklist []string `json:"country_blacklist"`
|
CountryBlacklist []string `json:"country_blacklist"`
|
||||||
RegionWhitelist []string `json:"region_whitelist"`
|
RegionWhitelist []string `json:"region_whitelist"`
|
||||||
RegionBlacklist []string `json:"region_blacklist"`
|
RegionBlacklist []string `json:"region_blacklist"`
|
||||||
|
PoWEnabled bool `json:"pow_enabled"`
|
||||||
|
PoWConfig *PoWConfig `json:"pow_config,omitempty"`
|
||||||
}
|
}
|
||||||
type wafRuntimeConfig struct {
|
type wafRuntimeConfig struct {
|
||||||
DefaultBlockStatusCode int `json:"default_block_status_code"`
|
DefaultBlockStatusCode int `json:"default_block_status_code"`
|
||||||
@@ -268,6 +256,10 @@ func RenderWAFConfig(snapshot WAFDocument) (string, error) {
|
|||||||
globalGroupIDs = append(globalGroupIDs, group.ID)
|
globalGroupIDs = append(globalGroupIDs, group.ID)
|
||||||
}
|
}
|
||||||
enabledGroupIDs[group.ID] = struct{}{}
|
enabledGroupIDs[group.ID] = struct{}{}
|
||||||
|
powConfig := group.PoWConfig
|
||||||
|
if !group.PoWEnabled {
|
||||||
|
powConfig = nil
|
||||||
|
}
|
||||||
groups = append(groups, wafRuntimeRuleGroup{
|
groups = append(groups, wafRuntimeRuleGroup{
|
||||||
ID: group.ID,
|
ID: group.ID,
|
||||||
Name: group.Name,
|
Name: group.Name,
|
||||||
@@ -282,6 +274,8 @@ func RenderWAFConfig(snapshot WAFDocument) (string, error) {
|
|||||||
CountryBlacklist: group.CountryBlacklist,
|
CountryBlacklist: group.CountryBlacklist,
|
||||||
RegionWhitelist: group.RegionWhitelist,
|
RegionWhitelist: group.RegionWhitelist,
|
||||||
RegionBlacklist: group.RegionBlacklist,
|
RegionBlacklist: group.RegionBlacklist,
|
||||||
|
PoWEnabled: group.PoWEnabled,
|
||||||
|
PoWConfig: powConfig,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
sort.Slice(groups, func(i, j int) bool {
|
sort.Slice(groups, func(i, j int) bool {
|
||||||
|
|||||||
Reference in New Issue
Block a user