fix(fix3): runtime env hardening and public endpoint source-of-truth

This commit is contained in:
2026-04-28 04:45:43 +05:00
parent 96d9bbcece
commit 12c65c8e31
23 changed files with 131 additions and 238 deletions
+4 -148
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
"hy2xs-admin/dao"
"hy2xs-admin/model/bo"
"hy2xs-admin/model/constant"
@@ -15,8 +14,6 @@ import (
"hy2xs-admin/service"
"hy2xs-admin/util"
"io"
"os"
"path/filepath"
"strconv"
"strings"
"time"
@@ -167,24 +164,7 @@ func GetHysteria2Config(c *gin.Context) {
}
func UpdateHysteria2Config(c *gin.Context) {
hysteria2ServerConfig, err := validateField(c, bo.Hysteria2ServerConfig{})
if err != nil {
return
}
if err = service.UpdateHysteria2Config(hysteria2ServerConfig); err != nil {
vo.Fail(err.Error(), c)
return
}
running := service.Hysteria2IsRunning()
if running {
if err = service.RestartHysteria2(); err != nil {
vo.Fail(err.Error(), c)
return
}
}
vo.Success(nil, c)
vo.Fail("managed by orchestrator: use hy2xs-orchestrator reconfigure", c)
}
func ExportHysteria2Config(c *gin.Context) {
@@ -253,84 +233,7 @@ func ExportHysteria2Config(c *gin.Context) {
}
func ImportHysteria2Config(c *gin.Context) {
file, header, err := c.Request.FormFile("file")
if err != nil {
vo.Fail(constant.SysError, c)
return
}
if header.Size > 1024*1024*2 {
vo.Fail("the file is too big", c)
return
}
if !strings.HasSuffix(header.Filename, ".yaml") {
vo.Fail("file format not supported", c)
return
}
content, err := io.ReadAll(file)
if err != nil {
vo.Fail("yaml file read err", c)
return
}
var hysteria2ServerConfig bo.Hysteria2ServerConfig
if err = yaml.Unmarshal(content, &hysteria2ServerConfig); err != nil {
vo.Fail("content Unmarshal err", c)
return
}
// Значения по умолчанию
config, err := dao.ListConfig("key in ?", []string{constant.HUIWebPort, constant.Hysteria2TrafficStatsSecret})
if err != nil {
vo.Fail(err.Error(), c)
return
}
var hUIWebPort string
var trafficStatsSecret string
for _, item := range config {
if *item.Key == constant.HUIWebPort {
hUIWebPort = *item.Value
} else if *item.Key == constant.Hysteria2TrafficStatsSecret {
trafficStatsSecret = *item.Value
}
}
if hUIWebPort == "" || trafficStatsSecret == "" {
logrus.Errorf("hUIWebPort or trafficStatsSecret is nil")
vo.Fail(constant.SysError, c)
return
}
authHttpUrl, err := service.GetAuthHttpUrl()
if err != nil {
vo.Fail(err.Error(), c)
return
}
authType := "http"
authHttpInsecure := true
var auth bo.ServerConfigAuth
auth.Type = &authType
var http bo.ServerConfigAuthHTTP
http.URL = &authHttpUrl
http.Insecure = &authHttpInsecure
auth.HTTP = &http
hysteria2ServerConfig.Auth = &auth
hysteria2ServerConfig.TrafficStats.Secret = &trafficStatsSecret
if err = service.SetHysteria2Config(hysteria2ServerConfig); err != nil {
vo.Fail(err.Error(), c)
return
}
running := service.Hysteria2IsRunning()
if running {
if err = service.RestartHysteria2(); err != nil {
vo.Fail(err.Error(), c)
return
}
}
vo.Success(nil, c)
vo.Fail("managed by orchestrator: use hy2xs-orchestrator reconfigure", c)
}
func ExportConfig(c *gin.Context) {
@@ -401,56 +304,9 @@ func Hysteria2AcmePath(c *gin.Context) {
}
func RestartServer(c *gin.Context) {
go func() {
_ = service.StopServer()
}()
vo.Success(nil, c)
vo.Fail("managed by orchestrator: use hy2xs-orchestrator reconfigure", c)
}
func UploadCertFile(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
vo.Fail(constant.SysError, c)
return
}
ext := filepath.Ext(file.Filename)
if ext != ".crt" && ext != ".key" {
vo.Fail("file format not supported", c)
return
}
if file.Size > 1024*1024 {
vo.Fail("the file is too big", c)
return
}
err = filepath.WalkDir(constant.BinDir, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
fileExt := filepath.Ext(path)
if !d.IsDir() && fileExt == ext {
if err := os.Remove(path); err != nil {
return fmt.Errorf("failed to delete file: %s, error: %v", path, err)
}
}
return nil
})
if err != nil {
logrus.Errorf("error during file deletion: %v", err)
vo.Fail("delete file failed", c)
return
}
wd, err := os.Getwd()
if err != nil {
vo.Fail(constant.SysError, c)
return
}
safeFilename := filepath.Base(file.Filename)
certPath := filepath.Join(wd, constant.BinDir, safeFilename)
if err := c.SaveUploadedFile(file, certPath); err != nil {
vo.Fail("file upload failed", c)
return
}
vo.Success(certPath, c)
vo.Fail("managed by orchestrator: use hy2xs-orchestrator reconfigure", c)
}
+3 -10
View File
@@ -64,7 +64,7 @@ func Hysteria2Url(c *gin.Context) {
return
}
url, err := service.Hysteria2Url(*hysteria2UrlDto.AccountId, *hysteria2UrlDto.Hostname)
url, err := service.Hysteria2Url(*hysteria2UrlDto.AccountId)
if err != nil {
vo.Fail(err.Error(), c)
return
@@ -88,8 +88,7 @@ func Hysteria2SubscribeUrl(c *gin.Context) {
return
}
subscribeUrl, err := service.Hysteria2SubscribeUrl(*hysteria2SubscribeUrlDto.AccountId,
*hysteria2SubscribeUrlDto.Protocol,
*hysteria2SubscribeUrlDto.Host)
*hysteria2SubscribeUrlDto.Protocol)
if err != nil {
vo.Fail(err.Error(), c)
return
@@ -114,12 +113,6 @@ func Hysteria2Subscribe(c *gin.Context) {
return
}
userAgent := strings.ToLower(c.Request.Header.Get("User-Agent"))
host := c.Request.Host
if host == "" {
vo.Fail("Host is empty", c)
return
}
var clientType string
if strings.Contains(userAgent, constant.Shadowrocket) {
@@ -134,7 +127,7 @@ func Hysteria2Subscribe(c *gin.Context) {
clientType = constant.Clash
}
userInfo, configStr, err := service.Hysteria2Subscribe(conPass, clientType, host)
userInfo, configStr, err := service.Hysteria2Subscribe(conPass, clientType)
if err != nil {
vo.Fail(err.Error(), c)
return