fix(openflare): trust Cloudflare client IP ranges by default

This commit is contained in:
ryan
2026-10-07 23:51:36 +08:00
parent 7483897d3c
commit 6f63715182
15 changed files with 354 additions and 1 deletions
@@ -0,0 +1,7 @@
-- +goose Up
INSERT INTO w_system_configs (key, value, type, visibility, description, created_at, updated_at)
VALUES ('openresty_trusted_proxy_cidrs', '["173.245.48.0/20","103.21.244.0/22","103.22.200.0/22","103.31.4.0/22","141.101.64.0/18","108.162.192.0/18","190.93.240.0/20","188.114.96.0/20","197.234.240.0/22","198.41.128.0/17","162.158.0.0/15","104.16.0.0/13","104.24.0.0/14","172.64.0.0/13","131.0.72.0/22","2400:cb00::/32","2606:4700::/32","2803:f800::/32","2405:b500::/32","2405:8100::/32","2a06:98c0::/29","2c0f:f248::/32"]', 'business', 0, '可信代理 IPv4/IPv6 CIDR JSON 数组', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
ON CONFLICT (key) DO NOTHING;
-- +goose Down
DELETE FROM w_system_configs WHERE key = 'openresty_trusted_proxy_cidrs';
@@ -0,0 +1,7 @@
-- +goose Up
INSERT INTO w_system_configs (key, value, type, visibility, description, created_at, updated_at)
VALUES ('openresty_trusted_proxy_cidrs', '["173.245.48.0/20","103.21.244.0/22","103.22.200.0/22","103.31.4.0/22","141.101.64.0/18","108.162.192.0/18","190.93.240.0/20","188.114.96.0/20","197.234.240.0/22","198.41.128.0/17","162.158.0.0/15","104.16.0.0/13","104.24.0.0/14","172.64.0.0/13","131.0.72.0/22","2400:cb00::/32","2606:4700::/32","2803:f800::/32","2405:b500::/32","2405:8100::/32","2a06:98c0::/29","2c0f:f248::/32"]', 'business', 0, '可信代理 IPv4/IPv6 CIDR JSON 数组', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
ON CONFLICT (key) DO NOTHING;
-- +goose Down
DELETE FROM w_system_configs WHERE key = 'openresty_trusted_proxy_cidrs';
@@ -5,7 +5,9 @@ package migrator
import (
"context"
"encoding/json"
"io/fs"
"slices"
"strings"
"testing"
@@ -13,6 +15,7 @@ import (
db "github.com/Rain-kl/Wavelet/internal/infra/persistence"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/internal/repository"
openrestyrender "github.com/Rain-kl/Wavelet/pkg/render/openresty"
"github.com/alicebob/miniredis/v2"
"github.com/glebarez/sqlite"
"github.com/redis/go-redis/v9"
@@ -24,7 +27,38 @@ import (
// (初始系统配置 + 各期配置迁移/新增 seed:of_options 迁移、文件白名单、磁盘缓存、
// 登录会话 TTL、升级源、存储、FRPS Web UI、Pages、OpenResty 限流、单 IP 限频、
// 错误页、SW 离线、日志保留期、指标保留期等);新增配置 seed 迁移时需同步更新本常量。
const expectedMigratedSystemConfigCount = 96
const expectedMigratedSystemConfigCount = 97
func TestTrustedProxyCIDRMigrationDefaultsMatchRenderer(t *testing.T) {
want := openrestyrender.DefaultTrustedProxyCIDRs()
if len(want) != 22 {
t.Fatalf("renderer default contains %d proxy ranges, want 22", len(want))
}
for _, migrationPath := range []string{
"goose/postgres/202610070005_add_openresty_trusted_proxy_cidrs.sql",
"goose/sqlite/202610070005_add_openresty_trusted_proxy_cidrs.sql",
} {
migration, err := fs.ReadFile(migrationFS, migrationPath)
if err != nil {
t.Fatal(err)
}
seed, ok := strings.CutPrefix(string(migration), "-- +goose Up\nINSERT INTO w_system_configs (key, value, type, visibility, description, created_at, updated_at)\nVALUES ('openresty_trusted_proxy_cidrs', '")
if !ok {
t.Fatalf("%s does not contain the expected CIDR seed", migrationPath)
}
seed, _, ok = strings.Cut(seed, "', 'business'")
if !ok {
t.Fatalf("%s CIDR seed value is malformed", migrationPath)
}
var got []string
if err := json.Unmarshal([]byte(seed), &got); err != nil {
t.Fatalf("decode %s CIDR seed: %v", migrationPath, err)
}
if !slices.Equal(got, want) {
t.Errorf("%s CIDR seed differs from renderer default", migrationPath)
}
}
}
func TestGooseMigrationVersionsAreUniquePerDialect(t *testing.T) {
for _, dir := range []string{"goose/postgres", "goose/sqlite"} {
@@ -88,6 +122,17 @@ func TestMigrateInitializesSQLiteDatabase(t *testing.T) {
if systemConfigCount != expectedMigratedSystemConfigCount {
t.Errorf("Migrate() w_system_configs count = %d, want %d", systemConfigCount, expectedMigratedSystemConfigCount)
}
var trustedProxyConfig model.SystemConfig
if err := sqliteDB.Where("key = ?", model.ConfigKeyOpenRestyTrustedProxyCIDRs).First(&trustedProxyConfig).Error; err != nil {
t.Fatalf("Migrate() trusted proxy CIDR config error = %v", err)
}
var trustedProxyCIDRs []string
if err := json.Unmarshal([]byte(trustedProxyConfig.Value), &trustedProxyCIDRs); err != nil {
t.Fatalf("decode trusted proxy CIDR config: %v", err)
}
if !slices.Equal(trustedProxyCIDRs, openrestyrender.DefaultTrustedProxyCIDRs()) {
t.Errorf("Migrate() trusted proxy CIDRs = %#v, want default Cloudflare ranges", trustedProxyCIDRs)
}
var logMigrationConfig model.SystemConfig
if err := sqliteDB.Where("key = ?", model.ConfigKeyLogDBMigration).First(&logMigrationConfig).Error; err != nil {