From de753420340ed252d8308851ce7ff81f465b924c Mon Sep 17 00:00:00 2001 From: XOF Date: Mon, 15 Dec 2025 01:12:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20config/config.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/config.go | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 config/config.go diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..4394d3b --- /dev/null +++ b/config/config.go @@ -0,0 +1,97 @@ +// config/config.go +package config + +import ( + "log" + "os" + "strconv" + "strings" + "time" +) + +type Config struct { + // 认证 + Username string + Password string + SessionSecret string + SessionTimeout time.Duration + + // 安全 + RateLimit int + RateLimitWindow time.Duration + MaxResponseSize int64 + + // 代理 + AllowedSchemes []string + BlockedDomains map[string]bool + BlockedCIDRs []string + UserAgent string + + // 缓存 + CacheEnabled bool + CacheMaxSize int64 + CacheTTL time.Duration +} + +func LoadFromEnv() *Config { + cfg := &Config{ + Username: getEnv("AUTH_USERNAME", "admin"), + Password: getEnv("AUTH_PASSWORD", "changeme"), + SessionSecret: getEnv("SESSION_SECRET", generateRandomString(64)), + SessionTimeout: parseDuration(getEnv("SESSION_TIMEOUT", "30m")), + + RateLimit: parseInt(getEnv("RATE_LIMIT_REQUESTS", "100")), + RateLimitWindow: parseDuration(getEnv("RATE_LIMIT_WINDOW", "1m")), + MaxResponseSize: parseInt64(getEnv("MAX_RESPONSE_SIZE", "52428800")), // 50MB + + AllowedSchemes: strings.Split(getEnv("ALLOWED_SCHEMES", "http,https"), ","), + BlockedDomains: parseBlockedDomains(getEnv("BLOCKED_DOMAINS", "localhost,127.0.0.1,0.0.0.0,internal,*.local")), + BlockedCIDRs: strings.Split(getEnv("BLOCKED_CIDRS", "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16,::1/128,fc00::/7,fe80::/10"), ","), + UserAgent: getEnv("USER_AGENT", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"), + + CacheEnabled: getEnv("CACHE_ENABLED", "true") == "true", + CacheMaxSize: parseInt64(getEnv("CACHE_MAX_SIZE", "104857600")), // 100MB + CacheTTL: parseDuration(getEnv("CACHE_TTL", "1h")), + } + + if cfg.Password == "changeme" { + log.Fatal("Please set AUTH_PASSWORD in .env file") + } + + return cfg +} + +func getEnv(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} + +func parseInt(s string) int { + v, _ := strconv.Atoi(s) + return v +} + +func parseInt64(s string) int64 { + v, _ := strconv.ParseInt(s, 10, 64) + return v +} + +func parseDuration(s string) time.Duration { + d, _ := time.ParseDuration(s) + return d +} + +func parseBlockedDomains(s string) map[string]bool { + domains := make(map[string]bool) + for _, d := range strings.Split(s, ",") { + domains[strings.TrimSpace(d)] = true + } + return domains +} + +func generateRandomString(n int) string { + // 简单实现,生产环境应使用 crypto/rand + return "change_this_to_random_string_in_production" +}