package config import ( "os" "path/filepath" "strconv" ) // Config 包含 Web 管理界面的运行时配置。 // 数据目录结构: // / // config.yaml - 全局配置 // db.json - 用户/实例元数据(简化存储) // pki/ - CA 与证书(PKI 基础设施) // ca.crt / ca.key / dh.pem / ta.key // instances// - 每个 OpenVPN 实例的目录 // server.conf // pki/{issued,private,csd} // ccd/ - 客户端配置目录 // status.log - openvpn --status 周期输出 // logs/ - openvpn 运行日志 // clients/// - 生成的 .ovpn 文件 // backups/ - 备份归档 type Config struct { Host string `yaml:"host"` Port int `yaml:"port"` DataDir string `yaml:"data_dir"` JWTSecret string `yaml:"jwt_secret"` AdminUser string `yaml:"admin_user"` AdminPass string `yaml:"admin_pass"` LogLevel string `yaml:"log_level"` OpenVPNBin string `yaml:"openvpn_bin"` EasyrsaBin string `yaml:"easyrsa_bin"` } func Load(dataDir string) *Config { c := &Config{ Host: getenv("OVPNMGR_HOST", "0.0.0.0"), Port: getenvInt("OVPNMGR_PORT", 8089), DataDir: dataDir, JWTSecret: getenv("OVPNMGR_JWT_SECRET", "change-me-in-prod-please"), AdminUser: getenv("OVPNMGR_ADMIN_USER", "admin"), AdminPass: getenv("OVPNMGR_ADMIN_PASS", "admin123"), LogLevel: getenv("OVPNMGR_LOG_LEVEL", "info"), OpenVPNBin: getenv("OVPNMGR_OPENVPN_BIN", "openvpn"), EasyrsaBin: getenv("OVPNMGR_EASYRSA_BIN", "easyrsa"), } return c } func (c *Config) PKIDir() string { return filepath.Join(c.DataDir, "pki") } func (c *Config) InstancesDir() string { return filepath.Join(c.DataDir, "instances") } func (c *Config) InstanceDir(name string) string { return filepath.Join(c.InstancesDir(), name) } func (c *Config) ClientsDir() string { return filepath.Join(c.DataDir, "clients") } func (c *Config) BackupsDir() string { return filepath.Join(c.DataDir, "backups") } func (c *Config) DBFile() string { return filepath.Join(c.DataDir, "db.json") } func getenv(k, def string) string { if v := os.Getenv(k); v != "" { return v } return def } func getenvInt(k string, def int) int { v := os.Getenv(k) if v == "" { return def } n, err := strconv.Atoi(v) if err != nil { return def } return n }