package config import ( "crypto/rand" "encoding/hex" "fmt" "os" "path/filepath" "github.com/google/uuid" "github.com/spf13/viper" ) // Config 全局配置结构 type Config struct { App AppConfig `mapstructure:"app"` Server ServerConfig `mapstructure:"server"` Database DatabaseConfig `mapstructure:"database"` JWT JWTConfig `mapstructure:"jwt"` Log LogConfig `mapstructure:"log"` Encryption EncryptionConfig `mapstructure:"encryption"` WireGuard WireGuardConfig `mapstructure:"wireguard"` STUN STUNConfig `mapstructure:"stun"` TURN TURNConfig `mapstructure:"turn"` } // AppConfig 应用配置 type AppConfig struct { Version string `mapstructure:"version"` // 版本号 BuildDate string `mapstructure:"build_date"` // 构建日期 } // ServerConfig 服务器配置 type ServerConfig struct { Port int `mapstructure:"port"` Mode string `mapstructure:"mode"` // debug, release, test StaticPath string `mapstructure:"static_path"` // 前端静态文件目录 } // DatabaseConfig 数据库配置 type DatabaseConfig struct { Type string `mapstructure:"type"` Path string `mapstructure:"path"` } // JWTConfig JWT 配置 type JWTConfig struct { Secret string `mapstructure:"secret"` AccessTokenDur string `mapstructure:"access_token_duration"` RefreshTokenDur string `mapstructure:"refresh_token_duration"` } // LogConfig 日志配置 type LogConfig struct { Level string `mapstructure:"level"` Format string `mapstructure:"format"` Output string `mapstructure:"output"` MaxSize int `mapstructure:"max_size"` MaxBackups int `mapstructure:"max_backups"` MaxAge int `mapstructure:"max_age"` } // EncryptionConfig 加密配置 type EncryptionConfig struct { NetworkSecretKey string `mapstructure:"network_secret_key"` } // WireGuardConfig WireGuard 配置(固定使用用户态) type WireGuardConfig struct { // 已删除 PreferredMode 字段 - 统一使用 wireguard-go 用户态 } // STUNConfig STUN 配置 type STUNConfig struct { DefaultServers []string `mapstructure:"default_servers"` // 默认 STUN 服务器列表 SelectionStrategy string `mapstructure:"selection_strategy"` // 选择策略:auto, domestic, international, custom AutoTest bool `mapstructure:"auto_test"` // 是否启用自动测试 TestInterval int `mapstructure:"test_interval"` // 测试间隔(秒) Timeout int `mapstructure:"timeout"` // 超时时间(秒) } // TURNConfig TURN 配置 type TURNConfig struct { DefaultServers []TURNServerConfig `mapstructure:"default_servers"` // 默认 TURN 服务器列表 } // TURNServerConfig TURN 服务器配置 type TURNServerConfig struct { URL string `mapstructure:"url"` // TURN 服务器 URL Username string `mapstructure:"username"` // 用户名 Credential string `mapstructure:"credential"` // 凭证 AuthType string `mapstructure:"auth_type"` // 鉴权方式:credential, token, secret } // Load 加载配置文件 func Load(configPath string) (*Config, error) { // 如果未指定配置文件路径,使用默认路径 if configPath == "" { configPath = "config.yaml" } // 检查配置文件是否存在 if _, err := os.Stat(configPath); os.IsNotExist(err) { // 尝试从示例文件复制 examplePath := "configs/config.example.yaml" if _, err := os.Stat(examplePath); err == nil { // 创建目录 dir := filepath.Dir(configPath) if dir != "." { os.MkdirAll(dir, 0755) } // 复制示例配置 data, _ := os.ReadFile(examplePath) os.WriteFile(configPath, data, 0644) } } // 读取配置文件 viper.SetConfigFile(configPath) viper.AutomaticEnv() if err := viper.ReadInConfig(); err != nil { return nil, fmt.Errorf("读取配置文件失败:%w", err) } var config Config if err := viper.Unmarshal(&config); err != nil { return nil, fmt.Errorf("解析配置文件失败:%w", err) } // 自动填充默认值 if config.Server.Port == 0 { config.Server.Port = 9531 } if config.Server.Mode == "" { config.Server.Mode = "release" } // 自动生成 JWT Secret if config.JWT.Secret == "" { config.JWT.Secret = generateJWTSecret() } // 自动生成加密密钥 if config.Encryption.NetworkSecretKey == "" { config.Encryption.NetworkSecretKey = generateEncryptionKey() } return &config, nil } // generateJWTSecret 使用 crypto/rand 生成随机 JWT Secret func generateJWTSecret() string { b := make([]byte, 32) _, err := rand.Read(b) if err != nil { // 极端情况回退(几乎不会发生) return uuid.New().String() } return hex.EncodeToString(b) } // generateEncryptionKey 使用 crypto/rand 生成加密密钥 func generateEncryptionKey() string { key := make([]byte, 32) _, err := rand.Read(key) if err != nil { // 极端情况回退(几乎不会发生) return uuid.New().String() + uuid.New().String() } return hex.EncodeToString(key) }