Files
cnbugs 77f8b59290 Initial commit: OpenVPN Manager v1.0
OpenVPN Web management console with multi-instance support, client cert
issuance, traffic/connection auditing, certificate expiry reminders,
auto backup/restore.

Stack:
- Backend: Go 1.21+ (Gin + JWT)
- Frontend: Vue 3 + Element Plus + ECharts + Vite
- Storage: JSON file (db.json) + filesystem (pki/, instances/, clients/, backups/)

Features:
- Multi-instance OpenVPN management (independent port/proto/subnet/PKI)
- One-click client certificate issuance with .ovpn (embedded certs)
- Certificate expiry reminders (30-day threshold)
- Connection log parsing (status-version 3)
- Auto backup/restore (tar.gz)
- Audit log for all write operations
- JWT auth (12h TTL)
- One-line install.sh for Ubuntu/Debian/RHEL/Fedora
2026-08-09 20:32:37 +08:00

78 lines
2.3 KiB
Go

package config
import (
"os"
"path/filepath"
"strconv"
)
// Config 包含 Web 管理界面的运行时配置。
// 数据目录结构:
// <DataDir>/
// config.yaml - 全局配置
// db.json - 用户/实例元数据(简化存储)
// pki/ - CA 与证书(PKI 基础设施)
// ca.crt / ca.key / dh.pem / ta.key
// instances/<name>/ - 每个 OpenVPN 实例的目录
// server.conf
// pki/{issued,private,csd}
// ccd/ - 客户端配置目录
// status.log - openvpn --status 周期输出
// logs/ - openvpn 运行日志
// clients/<inst>/<user>/ - 生成的 .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
}