Files
s-ui/service/server.go
T
Alireza Ahmadi d873c86ef8 remove ech pqs
2025-05-27 22:00:58 +02:00

211 lines
5.5 KiB
Go

package service
import (
"encoding/base64"
"os"
"runtime"
"s-ui/config"
"s-ui/logger"
"strconv"
"strings"
"time"
"github.com/sagernet/sing-box/common/tls"
"github.com/shirou/gopsutil/v4/cpu"
"github.com/shirou/gopsutil/v4/host"
"github.com/shirou/gopsutil/v4/mem"
"github.com/shirou/gopsutil/v4/net"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
type ServerService struct{}
func (s *ServerService) GetStatus(request string) *map[string]interface{} {
status := make(map[string]interface{}, 0)
requests := strings.Split(request, ",")
for _, req := range requests {
switch req {
case "cpu":
status["cpu"] = s.GetCpuPercent()
case "mem":
status["mem"] = s.GetMemInfo()
case "net":
status["net"] = s.GetNetInfo()
case "sys":
status["uptime"] = s.GetUptime()
status["sys"] = s.GetSystemInfo()
case "sbd":
status["sbd"] = s.GetSingboxInfo()
}
}
return &status
}
func (s *ServerService) GetCpuPercent() float64 {
percents, err := cpu.Percent(0, false)
if err != nil {
logger.Warning("get cpu percent failed:", err)
return 0
} else {
return percents[0]
}
}
func (s *ServerService) GetUptime() uint64 {
upTime, err := host.Uptime()
if err != nil {
logger.Warning("get uptime failed:", err)
return 0
} else {
return upTime
}
}
func (s *ServerService) GetMemInfo() map[string]interface{} {
info := make(map[string]interface{}, 0)
memInfo, err := mem.VirtualMemory()
if err != nil {
logger.Warning("get virtual memory failed:", err)
} else {
info["current"] = memInfo.Used
info["total"] = memInfo.Total
}
return info
}
func (s *ServerService) GetNetInfo() map[string]interface{} {
info := make(map[string]interface{}, 0)
ioStats, err := net.IOCounters(false)
if err != nil {
logger.Warning("get io counters failed:", err)
} else if len(ioStats) > 0 {
ioStat := ioStats[0]
info["sent"] = ioStat.BytesSent
info["recv"] = ioStat.BytesRecv
info["psent"] = ioStat.PacketsSent
info["precv"] = ioStat.PacketsRecv
} else {
logger.Warning("can not find io counters")
}
return info
}
func (s *ServerService) GetSingboxInfo() map[string]interface{} {
var rtm runtime.MemStats
runtime.ReadMemStats(&rtm)
isRunning := corePtr.IsRunning()
uptime := uint32(0)
if isRunning {
uptime = corePtr.GetInstance().Uptime()
}
return map[string]interface{}{
"running": isRunning,
"stats": map[string]interface{}{
"NumGoroutine": uint32(runtime.NumGoroutine()),
"Alloc": rtm.Alloc,
"Uptime": uptime,
},
}
}
func (s *ServerService) GetSystemInfo() map[string]interface{} {
info := make(map[string]interface{}, 0)
var rtm runtime.MemStats
runtime.ReadMemStats(&rtm)
info["appMem"] = rtm.Sys
info["appThreads"] = uint32(runtime.NumGoroutine())
cpuInfo, err := cpu.Info()
if err == nil {
info["cpuType"] = cpuInfo[0].ModelName
}
info["cpuCount"] = runtime.NumCPU()
info["hostName"], _ = os.Hostname()
info["appVersion"] = config.GetVersion()
ipv4 := make([]string, 0)
ipv6 := make([]string, 0)
// get ip address
netInterfaces, _ := net.Interfaces()
for i := 0; i < len(netInterfaces); i++ {
if len(netInterfaces[i].Flags) > 2 && netInterfaces[i].Flags[0] == "up" && netInterfaces[i].Flags[1] != "loopback" {
addrs := netInterfaces[i].Addrs
for _, address := range addrs {
if strings.Contains(address.Addr, ".") {
ipv4 = append(ipv4, address.Addr)
} else if address.Addr[0:6] != "fe80::" {
ipv6 = append(ipv6, address.Addr)
}
}
}
}
info["ipv4"] = ipv4
info["ipv6"] = ipv6
return info
}
func (s *ServerService) GetLogs(count string, level string) []string {
c, err := strconv.Atoi(count)
if err != nil {
c = 10
}
return logger.GetLogs(c, level)
}
func (s *ServerService) GenKeypair(keyType string, options string) []string {
if len(keyType) == 0 {
return []string{"No keypair to generate"}
}
switch keyType {
case "ech":
return s.generateECHKeyPair(options)
case "tls":
return s.generateTLSKeyPair(options)
case "reality":
return s.generateRealityKeyPair()
case "wireguard":
return s.generateWireGuardKey(options)
}
return []string{"Failed to generate keypair"}
}
func (s *ServerService) generateECHKeyPair(serverName string) []string {
configPem, keyPem, err := tls.ECHKeygenDefault(serverName)
if err != nil {
return []string{"Failed to generate ECH keypair: ", err.Error()}
}
return append(strings.Split(configPem, "\n"), strings.Split(keyPem, "\n")...)
}
func (s *ServerService) generateTLSKeyPair(serverName string) []string {
privateKeyPem, publicKeyPem, err := tls.GenerateCertificate(nil, nil, time.Now, serverName, time.Now().AddDate(0, 12, 0))
if err != nil {
return []string{"Failed to generate TLS keypair: ", err.Error()}
}
return append(strings.Split(string(privateKeyPem), "\n"), strings.Split(string(publicKeyPem), "\n")...)
}
func (s *ServerService) generateRealityKeyPair() []string {
privateKey, err := wgtypes.GeneratePrivateKey()
if err != nil {
return []string{"Failed to generate Reality keypair: ", err.Error()}
}
publicKey := privateKey.PublicKey()
return []string{"PrivateKey: " + base64.RawURLEncoding.EncodeToString(privateKey[:]), "PublicKey: " + base64.RawURLEncoding.EncodeToString(publicKey[:])}
}
func (s *ServerService) generateWireGuardKey(pk string) []string {
if len(pk) > 0 {
key, _ := wgtypes.ParseKey(pk)
return []string{key.PublicKey().String()}
}
wgKeys, err := wgtypes.GeneratePrivateKey()
if err != nil {
return []string{"Failed to generate wireguard keypair: ", err.Error()}
}
return []string{"PrivateKey: " + wgKeys.String(), "PublicKey: " + wgKeys.PublicKey().String()}
}