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
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user