diff --git a/Wavelet/internal/apps/openflare/option/validate.go b/Wavelet/internal/apps/openflare/option/validate.go index 42139fbb..b90a70da 100644 --- a/Wavelet/internal/apps/openflare/option/validate.go +++ b/Wavelet/internal/apps/openflare/option/validate.go @@ -13,8 +13,6 @@ import ( "github.com/Rain-kl/Wavelet/internal/model" ) -const rateLimitKeyExpirationSeconds = 1200 // 20 minutes - var ( openRestySizePattern = regexp.MustCompile(`^\d+[kKmMgG]?$`) openRestyProxyBuffersPattern = regexp.MustCompile(`^\d+\s+\d+[kKmMgG]?$`) @@ -48,9 +46,6 @@ func validateOptionWithState(option model.OpenFlareOption, state map[string]stri } } - if err := validateRateLimitOption(option.Key, option.Value); err != nil { - return err - } if err := validateOpenRestyOption(option.Key, option.Value); err != nil { return err } @@ -66,25 +61,6 @@ func validateOptionWithState(option model.OpenFlareOption, state map[string]stri return validateUptimeKumaOption(option.Key, option.Value, state) } -func validateRateLimitOption(key, value string) error { - switch key { - case "GlobalApiRateLimitNum", "GlobalWebRateLimitNum", "CriticalRateLimitNum": - intValue, err := strconv.Atoi(value) - if err != nil || intValue <= 0 { - return fmt.Errorf("%s 必须为大于 0 的整数", key) - } - case "GlobalApiRateLimitDuration", "GlobalWebRateLimitDuration", "CriticalRateLimitDuration": - intValue, err := strconv.Atoi(value) - if err != nil || intValue <= 0 { - return fmt.Errorf("%s 必须为大于 0 的整数秒", key) - } - if intValue > rateLimitKeyExpirationSeconds { - return fmt.Errorf("%s 不能大于 %d 秒", key, rateLimitKeyExpirationSeconds) - } - } - return nil -} - func validatePositiveIntegerOption(key, value string) error { intValue, err := strconv.Atoi(value) if err != nil || intValue <= 0 { diff --git a/Wavelet/internal/db/migrator/goose/postgres/202606190001_create_of_options.sql b/Wavelet/internal/db/migrator/goose/postgres/202606190001_create_of_options.sql index cfe93782..93ef5e31 100644 --- a/Wavelet/internal/db/migrator/goose/postgres/202606190001_create_of_options.sql +++ b/Wavelet/internal/db/migrator/goose/postgres/202606190001_create_of_options.sql @@ -60,13 +60,7 @@ INSERT INTO of_options (key, value) VALUES ('OpenRestyCacheKeyTemplate', '$scheme$host$request_uri'), ('OpenRestyCacheLockEnabled', 'true'), ('OpenRestyCacheLockTimeout', '5s'), - ('OpenRestyCacheUseStale', 'error timeout updating http_500 http_502 http_503 http_504'), - ('GlobalApiRateLimitNum', '300'), - ('GlobalApiRateLimitDuration', '180'), - ('GlobalWebRateLimitNum', '300'), - ('GlobalWebRateLimitDuration', '180'), - ('CriticalRateLimitNum', '100'), - ('CriticalRateLimitDuration', '1200') + ('OpenRestyCacheUseStale', 'error timeout updating http_500 http_502 http_503 http_504') ON CONFLICT (key) DO NOTHING; -- +goose Down diff --git a/Wavelet/internal/db/migrator/goose/postgres/202606200003_remove_legacy_rate_limit_options.sql b/Wavelet/internal/db/migrator/goose/postgres/202606200003_remove_legacy_rate_limit_options.sql new file mode 100644 index 00000000..0a813478 --- /dev/null +++ b/Wavelet/internal/db/migrator/goose/postgres/202606200003_remove_legacy_rate_limit_options.sql @@ -0,0 +1,20 @@ +-- +goose Up +DELETE FROM of_options +WHERE key IN ( + 'GlobalApiRateLimitNum', + 'GlobalApiRateLimitDuration', + 'GlobalWebRateLimitNum', + 'GlobalWebRateLimitDuration', + 'CriticalRateLimitNum', + 'CriticalRateLimitDuration' +); + +-- +goose Down +INSERT INTO of_options (key, value) VALUES + ('GlobalApiRateLimitNum', '300'), + ('GlobalApiRateLimitDuration', '180'), + ('GlobalWebRateLimitNum', '300'), + ('GlobalWebRateLimitDuration', '180'), + ('CriticalRateLimitNum', '100'), + ('CriticalRateLimitDuration', '1200') +ON CONFLICT (key) DO NOTHING; \ No newline at end of file diff --git a/Wavelet/internal/db/migrator/goose/sqlite/202606190001_create_of_options.sql b/Wavelet/internal/db/migrator/goose/sqlite/202606190001_create_of_options.sql index 35a8a4e3..65cb6198 100644 --- a/Wavelet/internal/db/migrator/goose/sqlite/202606190001_create_of_options.sql +++ b/Wavelet/internal/db/migrator/goose/sqlite/202606190001_create_of_options.sql @@ -60,13 +60,7 @@ INSERT OR IGNORE INTO of_options (key, value) VALUES ('OpenRestyCacheKeyTemplate', '$scheme$host$request_uri'), ('OpenRestyCacheLockEnabled', 'true'), ('OpenRestyCacheLockTimeout', '5s'), - ('OpenRestyCacheUseStale', 'error timeout updating http_500 http_502 http_503 http_504'), - ('GlobalApiRateLimitNum', '300'), - ('GlobalApiRateLimitDuration', '180'), - ('GlobalWebRateLimitNum', '300'), - ('GlobalWebRateLimitDuration', '180'), - ('CriticalRateLimitNum', '100'), - ('CriticalRateLimitDuration', '1200'); + ('OpenRestyCacheUseStale', 'error timeout updating http_500 http_502 http_503 http_504'); -- +goose Down DROP TABLE IF EXISTS of_options; \ No newline at end of file diff --git a/Wavelet/internal/db/migrator/goose/sqlite/202606200003_remove_legacy_rate_limit_options.sql b/Wavelet/internal/db/migrator/goose/sqlite/202606200003_remove_legacy_rate_limit_options.sql new file mode 100644 index 00000000..8215213f --- /dev/null +++ b/Wavelet/internal/db/migrator/goose/sqlite/202606200003_remove_legacy_rate_limit_options.sql @@ -0,0 +1,19 @@ +-- +goose Up +DELETE FROM of_options +WHERE key IN ( + 'GlobalApiRateLimitNum', + 'GlobalApiRateLimitDuration', + 'GlobalWebRateLimitNum', + 'GlobalWebRateLimitDuration', + 'CriticalRateLimitNum', + 'CriticalRateLimitDuration' +); + +-- +goose Down +INSERT OR IGNORE INTO of_options (key, value) VALUES + ('GlobalApiRateLimitNum', '300'), + ('GlobalApiRateLimitDuration', '180'), + ('GlobalWebRateLimitNum', '300'), + ('GlobalWebRateLimitDuration', '180'), + ('CriticalRateLimitNum', '100'), + ('CriticalRateLimitDuration', '1200'); \ No newline at end of file diff --git a/Wavelet/internal/model/openflare_option.go b/Wavelet/internal/model/openflare_option.go index 19172244..14fa7130 100644 --- a/Wavelet/internal/model/openflare_option.go +++ b/Wavelet/internal/model/openflare_option.go @@ -108,13 +108,7 @@ var ( OpenRestyCacheLockEnabled = true OpenRestyCacheLockTimeout = "5s" OpenRestyCacheUseStale = "error timeout updating http_500 http_502 http_503 http_504" - OpenRestyMainConfigTemplate = defaultOpenRestyMainConfigTemplate - GlobalApiRateLimitNum = 300 - GlobalApiRateLimitDuration int64 = 3 * 60 - GlobalWebRateLimitNum = 300 - GlobalWebRateLimitDuration int64 = 3 * 60 - CriticalRateLimitNum = 100 - CriticalRateLimitDuration int64 = 20 * 60 + OpenRestyMainConfigTemplate = defaultOpenRestyMainConfigTemplate ) const defaultOpenRestyMainConfigTemplate = `# This file is generated by OpenFlare. Do not edit manually. @@ -235,13 +229,7 @@ func DefaultOpenFlareOptions() map[string]string { "OpenRestyCacheLockEnabled": strconv.FormatBool(OpenRestyCacheLockEnabled), "OpenRestyCacheLockTimeout": OpenRestyCacheLockTimeout, "OpenRestyCacheUseStale": OpenRestyCacheUseStale, - "OpenRestyMainConfigTemplate": OpenRestyMainConfigTemplate, - "GlobalApiRateLimitNum": strconv.Itoa(GlobalApiRateLimitNum), - "GlobalApiRateLimitDuration": strconv.FormatInt(GlobalApiRateLimitDuration, 10), - "GlobalWebRateLimitNum": strconv.Itoa(GlobalWebRateLimitNum), - "GlobalWebRateLimitDuration": strconv.FormatInt(GlobalWebRateLimitDuration, 10), - "CriticalRateLimitNum": strconv.Itoa(CriticalRateLimitNum), - "CriticalRateLimitDuration": strconv.FormatInt(CriticalRateLimitDuration, 10), + "OpenRestyMainConfigTemplate": OpenRestyMainConfigTemplate, } } @@ -434,30 +422,6 @@ func applyOptionMap(key, value string) { if v, err := strconv.Atoi(value); err == nil && v >= 1 { DatabaseAutoCleanupRetentionDays = v } - case "GlobalApiRateLimitNum": - if v, err := strconv.Atoi(value); err == nil && v > 0 { - GlobalApiRateLimitNum = v - } - case "GlobalApiRateLimitDuration": - if v, err := strconv.ParseInt(value, 10, 64); err == nil && v > 0 { - GlobalApiRateLimitDuration = v - } - case "GlobalWebRateLimitNum": - if v, err := strconv.Atoi(value); err == nil && v > 0 { - GlobalWebRateLimitNum = v - } - case "GlobalWebRateLimitDuration": - if v, err := strconv.ParseInt(value, 10, 64); err == nil && v > 0 { - GlobalWebRateLimitDuration = v - } - case "CriticalRateLimitNum": - if v, err := strconv.Atoi(value); err == nil && v > 0 { - CriticalRateLimitNum = v - } - case "CriticalRateLimitDuration": - if v, err := strconv.ParseInt(value, 10, 64); err == nil && v > 0 { - CriticalRateLimitDuration = v - } } OptionMapRWMutex.Unlock() } diff --git a/docs/changelog/index.md b/docs/changelog/index.md index e30043a9..33a6b53a 100644 --- a/docs/changelog/index.md +++ b/docs/changelog/index.md @@ -16,9 +16,9 @@ sidebar: false ## [Unreleased] -### 变更 +### 移除 -- Wavelet API 路径统一:管理端由 `/api/v1/openflare/*` 调整为 `/api/v1/d/*`;Agent/Relay/Tunnel 协议路由分别迁移至 `/api/v1/agent/*`、`/api/v1/relay/*`、`/api/v1/tunnel/*`(原 `/api/flared/*`)。同步更新 Wavelet 前端服务层与 `openflare-agent`、`openflare-relay`、`openflared` 客户端连接端点。 +- 移除 Wavelet 中从旧系统迁移但未实装的全局 API / Web / 敏感接口限流选项(`GlobalApiRateLimit*`、`GlobalWebRateLimit*`、`CriticalRateLimit*`)及相关校验与数据库种子。 ### 新增 @@ -69,6 +69,7 @@ sidebar: false ### 变更 +- Wavelet API 路径统一:管理端由 `/api/v1/openflare/*` 调整为 `/api/v1/d/*`;Agent/Relay/Tunnel 协议路由分别迁移至 `/api/v1/agent/*`、`/api/v1/relay/*`、`/api/v1/tunnel/*`(原 `/api/flared/*`)。同步更新 Wavelet 前端服务层与 `openflare-agent`、`openflare-relay`、`openflared` 客户端连接端点。 - 移除 Wavelet 顶栏 OpenFlare 服务端版本入口按钮;版本升级能力保留在 Admin 设置 OpenFlare 运维 Tab。 - 将 Wavelet 默认上游仓库调整为 `Rain-kl/OpenFlare`,站点名称、邮件模板、前端默认标题与页脚品牌统一初始化为 OpenFlare;新增 goose 迁移回填既有环境的旧 Wavelet 默认值。 - Wavelet WAF IP 组列表新增「查看」操作,支持在查看弹窗中浏览当前 IP 并移除单条 IP;自动类型同步裁剪 `ext_ips` 以与 `ip_list` 保持一致。 diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 8b14b383..1d6da05c 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -92,9 +92,6 @@ go run . --port 3000 --log-dir ./logs | `GeoIPProvider` | 节点/IP 归属解析方式 | `ipinfo` | | `DatabaseAutoCleanupEnabled` | 是否启用每日自动清理观测数据 | `false` | | `DatabaseAutoCleanupRetentionDays` | 自动清理保留天数,至少 1 天 | `30` | -| `GlobalApiRateLimitNum` / `GlobalApiRateLimitDuration` | 全局 API 限流次数 / 时间窗口 | `300` / `180` | -| `GlobalWebRateLimitNum` / `GlobalWebRateLimitDuration` | 全局 Web 限流次数 / 时间窗口 | `300` / `180` | -| `CriticalRateLimitNum` / `CriticalRateLimitDuration` | 敏感接口限流次数 / 时间窗口 | `100` / `1200` | | `UptimeKumaEnabled` | 是否启用 Uptime Kuma 自动同步 | `false` | | `UptimeKumaUrl` | Uptime Kuma 实例地址 | 空 | | `UptimeKumaUsername` | Uptime Kuma 登录用户名 | 空 |