feat: implement VPN platform management and real protocol services
This commit is contained in:
commit
58c036c34c
45 files changed
+9244
No files matched your search
+108
@@ -0,0 +1,108 @@
|
||||
// VPN 管理平台 —— 单二进制交付(前端静态资源内嵌) // Logan.Li
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"vpn-platform/backend/internal/api"
|
||||
"vpn-platform/backend/internal/core"
|
||||
"vpn-platform/backend/internal/monitor"
|
||||
"vpn-platform/backend/internal/service"
|
||||
"vpn-platform/backend/internal/service/custom"
|
||||
"vpn-platform/backend/internal/service/frp"
|
||||
"vpn-platform/backend/internal/service/ipsec"
|
||||
"vpn-platform/backend/internal/service/l2tp"
|
||||
"vpn-platform/backend/internal/service/openvpn"
|
||||
"vpn-platform/backend/internal/service/wireguard"
|
||||
"vpn-platform/backend/internal/store"
|
||||
)
|
||||
|
||||
//go:embed all:dist
|
||||
var webFS embed.FS
|
||||
|
||||
func main() {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
// 数据目录:默认 ./data,可用 VPN_DATA_DIR 覆盖
|
||||
dataDir := service.BaseDir()
|
||||
if err := store.Init(dataDir); err != nil {
|
||||
log.Fatalf("初始化存储失败: %v", err)
|
||||
}
|
||||
// OpenVPN invokes this same, already-installed binary from its
|
||||
// auth-user-pass-verify hook. Keep it before HTTP startup so the hook has a
|
||||
// short-lived process and a meaningful exit status.
|
||||
if len(os.Args) > 1 && os.Args[1] == "openvpn-auth" {
|
||||
if err := openvpn.RunAuthHelper(os.Args[2:]); err != nil {
|
||||
log.Printf("OpenVPN 用户认证失败: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 注册内置协议
|
||||
mgr := core.NewManager()
|
||||
mgr.Register(wireguard.New())
|
||||
mgr.Register(ipsec.New())
|
||||
mgr.Register(l2tp.New())
|
||||
mgr.Register(frp.New())
|
||||
mgr.Register(openvpn.New())
|
||||
// 加载数据库中的自定义协议插件
|
||||
custom.LoadAll(mgr)
|
||||
|
||||
r := gin.New()
|
||||
r.Use(gin.Recovery())
|
||||
|
||||
srv := api.NewServer(mgr)
|
||||
srv.RegisterRoutes(r)
|
||||
|
||||
// 内嵌前端(SPA 回退到 index.html)
|
||||
dist, err := fs.Sub(webFS, "dist")
|
||||
if err != nil {
|
||||
log.Fatalf("内嵌资源损坏: %v", err)
|
||||
}
|
||||
fileServer := http.FileServer(http.FS(dist))
|
||||
r.NoRoute(func(c *gin.Context) {
|
||||
path := strings.TrimPrefix(c.Request.URL.Path, "/")
|
||||
if path == "" {
|
||||
path = "index.html"
|
||||
}
|
||||
if f, err := dist.Open(path); err == nil {
|
||||
f.Close()
|
||||
fileServer.ServeHTTP(c.Writer, c.Request)
|
||||
return
|
||||
}
|
||||
// SPA fallback
|
||||
c.Request.URL.Path = "/"
|
||||
fileServer.ServeHTTP(c.Writer, c.Request)
|
||||
})
|
||||
|
||||
// 状态采集 + 自启恢复
|
||||
monitor.Start(mgr, 15*time.Second)
|
||||
monitor.AutoStartAll(mgr)
|
||||
|
||||
addr := os.Getenv("VPN_LISTEN_ADDR")
|
||||
if addr == "" {
|
||||
addr = ":8080"
|
||||
}
|
||||
log.Printf("VPN 管理平台已启动: http://localhost%s (默认账号 admin / admin123)", addr)
|
||||
log.Printf("协议依赖检测:")
|
||||
for _, p := range mgr.List() {
|
||||
ok, dep := p.Available()
|
||||
mark := "✓"
|
||||
if !ok {
|
||||
mark = "✗"
|
||||
}
|
||||
log.Printf(" [%s] %-10s %s", mark, p.Name(), dep)
|
||||
}
|
||||
if err := r.Run(addr); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user