Реализован production-hardening по fix1: env/reconfigure, IPv4-only, TLS, secrets, firewall, docs

This commit is contained in:
2026-04-26 07:27:06 +05:00
parent 2b4a45ad23
commit 3fccd5c442
109 changed files with 1773 additions and 569 deletions
+35 -22
View File
@@ -8,11 +8,28 @@ import (
"hy2xs-admin/model/bo"
"hy2xs-admin/model/constant"
"hy2xs-admin/proxy"
"net"
"net/url"
"strconv"
"strings"
"time"
)
func parseListenPort(listen string) (int, error) {
host, port, err := net.SplitHostPort(listen)
if err != nil {
return 0, err
}
if host == "" || port == "" {
return 0, errors.New("invalid listen address")
}
value, convErr := strconv.Atoi(port)
if convErr != nil || value < 1 || value > 65535 {
return 0, errors.New("invalid listen port")
}
return value, nil
}
func Hysteria2Auth(conPass string) (int64, string, error) {
if !Hysteria2IsRunning() {
return 0, "", errors.New("hysteria2 is not running")
@@ -45,11 +62,11 @@ func Hysteria2Online() (map[string]int64, error) {
if err != nil {
return nil, errors.New("get hysteria2 apiPort err")
}
jwtSecretConfig, err := dao.GetConfig("key = ?", constant.JwtSecret)
trafficSecretConfig, err := dao.GetConfig("key = ?", constant.Hysteria2TrafficStatsSecret)
if err != nil {
return nil, err
}
onlineUsers, err := proxy.NewHysteria2Api(apiPort).OnlineUsers(*jwtSecretConfig.Value)
onlineUsers, err := proxy.NewHysteria2Api(apiPort).OnlineUsers(*trafficSecretConfig.Value)
if err != nil {
return nil, err
}
@@ -76,11 +93,11 @@ func Hysteria2Kick(ids []int64, kickUtilTime int64) error {
if err != nil {
return errors.New("get hysteria2 apiPort err")
}
jwtSecretConfig, err := dao.GetConfig("key = ?", constant.JwtSecret)
trafficSecretConfig, err := dao.GetConfig("key = ?", constant.Hysteria2TrafficStatsSecret)
if err != nil {
return err
}
if err = proxy.NewHysteria2Api(apiPort).KickUsers(keys, *jwtSecretConfig.Value); err != nil {
if err = proxy.NewHysteria2Api(apiPort).KickUsers(keys, *trafficSecretConfig.Value); err != nil {
return err
}
return nil
@@ -125,13 +142,13 @@ func Hysteria2Subscribe(conPass string, clientType string, host string) (string,
hysteria2Name = *hysteria2ConfigRemark.Value
}
hysteria2ConfigPortHopping, err := dao.GetConfig("key = ?", constant.Hysteria2ConfigPortHopping)
userInfo := ""
configStr := ""
listenPort, err := parseListenPort(*hysteria2Config.Listen)
if err != nil {
return "", "", err
}
userInfo := ""
configStr := ""
publicHost := strings.Split(host, ":")[0]
if clientType == constant.Shadowrocket || clientType == constant.Clash {
userInfo = fmt.Sprintf("upload=%d; download=%d; total=%d; expire=%d",
*account.Upload,
@@ -142,9 +159,8 @@ func Hysteria2Subscribe(conPass string, clientType string, host string) (string,
hysteria2 := bo.Hysteria2{
Name: hysteria2Name,
Type: "hysteria2",
Server: strings.Split(host, ":")[0],
Port: strings.Split(*hysteria2Config.Listen, ":")[1],
Ports: *hysteria2ConfigPortHopping.Value,
Server: publicHost,
Port: strconv.Itoa(listenPort),
Password: conPass,
}
@@ -226,6 +242,13 @@ func Hysteria2Url(accountId int64, hostname string) (string, error) {
if hysteria2Config.Listen == nil || *hysteria2Config.Listen == "" {
return "", errors.New("hysteria2 config is empty")
}
port, err := parseListenPort(*hysteria2Config.Listen)
if err != nil {
return "", err
}
if hostname == "" || hostname == "0.0.0.0" {
return "", errors.New("invalid public host")
}
account, err := dao.GetAccount("id = ?", accountId)
if err != nil {
@@ -259,15 +282,6 @@ func Hysteria2Url(accountId int64, hostname string) (string, error) {
urlConfig += fmt.Sprintf("&downmbps=%s", url.PathEscape(*hysteria2Config.Bandwidth.Down))
}
hysteria2ConfigPortHopping, err := dao.GetConfig("key = ?", constant.Hysteria2ConfigPortHopping)
if err != nil {
return "", err
}
if *hysteria2ConfigPortHopping.Value != "" {
// shadowrocket
urlConfig += fmt.Sprintf("&mport=%s", *hysteria2ConfigPortHopping.Value)
}
hysteria2ConfigRemark, err := dao.GetConfig("key = ?", constant.Hysteria2ConfigRemark)
if err != nil {
return "", err
@@ -278,6 +292,5 @@ func Hysteria2Url(accountId int64, hostname string) (string, error) {
if urlConfig != "" {
urlConfig = "/?" + strings.TrimPrefix(urlConfig, "&")
}
return fmt.Sprintf("hysteria2://%s@%s%s", *account.ConPass, hostname, *hysteria2Config.Listen) + urlConfig, nil
return fmt.Sprintf("hysteria2://%s@%s:%d", *account.ConPass, hostname, port) + urlConfig, nil
}