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,88 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"openvpn-manager/internal/api"
|
||||
"openvpn-manager/internal/config"
|
||||
"openvpn-manager/internal/service"
|
||||
"openvpn-manager/internal/store"
|
||||
"openvpn-manager/pkg/openvpn"
|
||||
)
|
||||
|
||||
func main() {
|
||||
dataDir := flag.String("data", "", "data directory (default $OVPNMGR_DATA or ./data)")
|
||||
distDir := flag.String("dist", "", "frontend dist directory (default $OVPNMGR_DIST or ./dist)")
|
||||
flag.Parse()
|
||||
|
||||
if *dataDir == "" {
|
||||
*dataDir = os.Getenv("OVPNMGR_DATA")
|
||||
}
|
||||
if *dataDir == "" {
|
||||
*dataDir = "./data"
|
||||
}
|
||||
if *distDir == "" {
|
||||
*distDir = os.Getenv("OVPNMGR_DIST")
|
||||
}
|
||||
if *distDir == "" {
|
||||
*distDir = "./dist"
|
||||
}
|
||||
abs, _ := filepath.Abs(*dataDir)
|
||||
cfg := config.Load(abs)
|
||||
|
||||
if err := os.MkdirAll(cfg.PKIDir(), 0o700); err != nil {
|
||||
log.Fatalf("mkdir pki: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(cfg.InstancesDir(), 0o755); err != nil {
|
||||
log.Fatalf("mkdir instances: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(cfg.ClientsDir(), 0o755); err != nil {
|
||||
log.Fatalf("mkdir clients: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(cfg.BackupsDir(), 0o755); err != nil {
|
||||
log.Fatalf("mkdir backups: %v", err)
|
||||
}
|
||||
|
||||
st, err := store.Open(cfg.DBFile())
|
||||
if err != nil {
|
||||
log.Fatalf("open store: %v", err)
|
||||
}
|
||||
ovm := openvpn.NewManager(cfg.OpenVPNBin, cfg.DataDir)
|
||||
if err := ovm.EnsureCA(); err != nil {
|
||||
log.Printf("warn: ensure CA: %v", err)
|
||||
}
|
||||
svc := service.New(cfg, st, ovm)
|
||||
|
||||
addr := cfg.Host + ":" + itoa(cfg.Port)
|
||||
log.Printf("openvpn-manager listening on %s, data=%s, dist=%s", addr, cfg.DataDir, *distDir)
|
||||
srv := api.NewServer(cfg, svc)
|
||||
if err := srv.Router(*distDir).Run(addr); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func itoa(n int) string {
|
||||
if n == 0 {
|
||||
return "0"
|
||||
}
|
||||
neg := false
|
||||
if n < 0 {
|
||||
neg = true
|
||||
n = -n
|
||||
}
|
||||
var buf [20]byte
|
||||
i := len(buf)
|
||||
for n > 0 {
|
||||
i--
|
||||
buf[i] = byte('0' + n%10)
|
||||
n /= 10
|
||||
}
|
||||
if neg {
|
||||
i--
|
||||
buf[i] = '-'
|
||||
}
|
||||
return string(buf[i:])
|
||||
}
|
||||
Reference in New Issue
Block a user