Реализован production-hardening по fix1: env/reconfigure, IPv4-only, TLS, secrets, firewall, docs
This commit is contained in:
@@ -26,14 +26,15 @@ func Login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
token, err := service.Login(*loginDto.Username, util.SHA224String(*loginDto.Pass))
|
||||
token, forcePasswordChange, err := service.Login(*loginDto.Username, *loginDto.Pass)
|
||||
if err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
jwtVo := vo.JwtVo{
|
||||
TokenType: constant.TokenType,
|
||||
AccessToken: token,
|
||||
TokenType: constant.TokenType,
|
||||
AccessToken: token,
|
||||
ForcePasswordChange: forcePasswordChange,
|
||||
}
|
||||
vo.Success(jwtVo, c)
|
||||
}
|
||||
@@ -100,7 +101,11 @@ func SaveAccount(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
passEncrypt := util.SHA224String(*accountSaveDto.Pass)
|
||||
passEncrypt, err := util.HashPassword(*accountSaveDto.Pass)
|
||||
if err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
conPass := fmt.Sprintf("%s.%s", *accountSaveDto.Username, *accountSaveDto.ConPass)
|
||||
account := entity.Account{
|
||||
Username: accountSaveDto.Username,
|
||||
@@ -167,8 +172,12 @@ func UpdateAccount(c *gin.Context) {
|
||||
|
||||
var passEncrypt *string
|
||||
if accountUpdateDto.Pass != nil && *accountUpdateDto.Pass != "" {
|
||||
passEncryptSha224 := util.SHA224String(*accountUpdateDto.Pass)
|
||||
passEncrypt = &passEncryptSha224
|
||||
passEncryptHash, hashErr := util.HashPassword(*accountUpdateDto.Pass)
|
||||
if hashErr != nil {
|
||||
vo.Fail(hashErr.Error(), c)
|
||||
return
|
||||
}
|
||||
passEncrypt = &passEncryptHash
|
||||
}
|
||||
|
||||
account := entity.Account{
|
||||
@@ -331,6 +340,5 @@ func VerifyDefaultPass(c *gin.Context) {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
vo.Success(account.Pass != nil && *account.Pass == "02f382b76ca1ab7aa06ab03345c7712fd5b971fb0c0f2aef98bac9cd", c)
|
||||
vo.Success(account.Pass != nil && !util.IsBcryptHash(*account.Pass), c)
|
||||
}
|
||||
|
||||
|
||||
+16
-59
@@ -17,7 +17,6 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -35,7 +34,6 @@ func UpdateConfigs(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
needResetPortHopping := false
|
||||
needRestart := false
|
||||
|
||||
for _, item := range configsUpdateDto.ConfigUpdateDtos {
|
||||
@@ -81,19 +79,8 @@ func UpdateConfigs(c *gin.Context) {
|
||||
}
|
||||
|
||||
if key == constant.Hysteria2ConfigPortHopping {
|
||||
re := regexp.MustCompile(`^\d+(?:-\d+)?(?:,\d+(?:-\d+)?)*$`)
|
||||
if value != "" && !re.MatchString(value) {
|
||||
vo.Fail(fmt.Sprintf("port hopping: %s is invalid", value), c)
|
||||
return
|
||||
}
|
||||
hysteria2ConfigPortHopping, err := service.GetConfig(constant.Hysteria2ConfigPortHopping)
|
||||
if err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if *hysteria2ConfigPortHopping.Value != value {
|
||||
needResetPortHopping = true
|
||||
}
|
||||
vo.Fail("port hopping out of scope in HY2XS production", c)
|
||||
return
|
||||
}
|
||||
|
||||
if key == constant.ResetTrafficCron {
|
||||
@@ -113,13 +100,6 @@ func UpdateConfigs(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
if needResetPortHopping {
|
||||
if err := service.InitPortHopping(); err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if needRestart {
|
||||
go func() {
|
||||
_ = service.StopServer()
|
||||
@@ -197,33 +177,11 @@ func UpdateHysteria2Config(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
hysteria2Config, err := service.GetHysteria2Config()
|
||||
if err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
needResetPortHopping := false
|
||||
if hysteria2Config.Listen != nil &&
|
||||
*hysteria2Config.Listen != "" &&
|
||||
hysteria2ServerConfig.Listen != nil &&
|
||||
*hysteria2ServerConfig.Listen != "" &&
|
||||
*hysteria2ServerConfig.Listen != *hysteria2Config.Listen {
|
||||
needResetPortHopping = true
|
||||
}
|
||||
|
||||
if err = service.UpdateHysteria2Config(hysteria2ServerConfig); err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
if needResetPortHopping {
|
||||
if err := service.InitPortHopping(); err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
running := service.Hysteria2IsRunning()
|
||||
if running {
|
||||
if err = service.RestartHysteria2(); err != nil {
|
||||
@@ -242,24 +200,24 @@ func ExportHysteria2Config(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Значения по умолчанию
|
||||
config, err := dao.ListConfig("key in ?", []string{constant.HUIWebPort, constant.JwtSecret})
|
||||
config, err := dao.ListConfig("key in ?", []string{constant.HUIWebPort, constant.Hysteria2TrafficStatsSecret})
|
||||
if err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
var hUIWebPort string
|
||||
var jwtSecret string
|
||||
var trafficStatsSecret string
|
||||
for _, item := range config {
|
||||
if *item.Key == constant.HUIWebPort {
|
||||
hUIWebPort = *item.Value
|
||||
} else if *item.Key == constant.JwtSecret {
|
||||
jwtSecret = *item.Value
|
||||
} else if *item.Key == constant.Hysteria2TrafficStatsSecret {
|
||||
trafficStatsSecret = *item.Value
|
||||
}
|
||||
}
|
||||
|
||||
if hUIWebPort == "" || jwtSecret == "" {
|
||||
logrus.Errorf("hUIWebPort or jwtSecret is nil")
|
||||
if hUIWebPort == "" || trafficStatsSecret == "" {
|
||||
logrus.Errorf("hUIWebPort or trafficStatsSecret is nil")
|
||||
vo.Fail(constant.SysError, c)
|
||||
return
|
||||
}
|
||||
@@ -279,7 +237,7 @@ func ExportHysteria2Config(c *gin.Context) {
|
||||
http.Insecure = &authHttpInsecure
|
||||
auth.HTTP = &http
|
||||
hysteria2ServerConfig.Auth = &auth
|
||||
hysteria2ServerConfig.TrafficStats.Secret = &jwtSecret
|
||||
hysteria2ServerConfig.TrafficStats.Secret = &trafficStatsSecret
|
||||
|
||||
fileName := fmt.Sprintf("Hysteria2Config-%s.yaml", time.Now().Format("20060102150405"))
|
||||
filePath := constant.ExportPathDir + fileName
|
||||
@@ -325,24 +283,24 @@ func ImportHysteria2Config(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Значения по умолчанию
|
||||
config, err := dao.ListConfig("key in ?", []string{constant.HUIWebPort, constant.JwtSecret})
|
||||
config, err := dao.ListConfig("key in ?", []string{constant.HUIWebPort, constant.Hysteria2TrafficStatsSecret})
|
||||
if err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
var hUIWebPort string
|
||||
var jwtSecret string
|
||||
var trafficStatsSecret string
|
||||
for _, item := range config {
|
||||
if *item.Key == constant.HUIWebPort {
|
||||
hUIWebPort = *item.Value
|
||||
} else if *item.Key == constant.JwtSecret {
|
||||
jwtSecret = *item.Value
|
||||
} else if *item.Key == constant.Hysteria2TrafficStatsSecret {
|
||||
trafficStatsSecret = *item.Value
|
||||
}
|
||||
}
|
||||
|
||||
if hUIWebPort == "" || jwtSecret == "" {
|
||||
logrus.Errorf("hUIWebPort or jwtSecret is nil")
|
||||
if hUIWebPort == "" || trafficStatsSecret == "" {
|
||||
logrus.Errorf("hUIWebPort or trafficStatsSecret is nil")
|
||||
vo.Fail(constant.SysError, c)
|
||||
return
|
||||
}
|
||||
@@ -362,7 +320,7 @@ func ImportHysteria2Config(c *gin.Context) {
|
||||
http.Insecure = &authHttpInsecure
|
||||
auth.HTTP = &http
|
||||
hysteria2ServerConfig.Auth = &auth
|
||||
hysteria2ServerConfig.TrafficStats.Secret = &jwtSecret
|
||||
hysteria2ServerConfig.TrafficStats.Secret = &trafficStatsSecret
|
||||
|
||||
if err = service.SetHysteria2Config(hysteria2ServerConfig); err != nil {
|
||||
vo.Fail(err.Error(), c)
|
||||
@@ -501,4 +459,3 @@ func UploadCertFile(c *gin.Context) {
|
||||
}
|
||||
vo.Success(certPath, c)
|
||||
}
|
||||
|
||||
|
||||
@@ -150,4 +150,3 @@ func Hysteria2Subscribe(c *gin.Context) {
|
||||
|
||||
c.String(200, configStr)
|
||||
}
|
||||
|
||||
|
||||
@@ -114,4 +114,3 @@ func ExportLog(c *gin.Context) {
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName))
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,4 +23,3 @@ func MonitorHysteria2(c *gin.Context) {
|
||||
}
|
||||
vo.Success(hysteria2MonitorVo, c)
|
||||
}
|
||||
|
||||
|
||||
@@ -39,4 +39,3 @@ func validateField[T interface{}](c *gin.Context, field T) (T, error) {
|
||||
}
|
||||
return field, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user