// 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" }