feat: 首次安装启动记录到文件做唯一身份

This commit is contained in:
TsMask
2024-04-19 19:57:10 +08:00
parent ed94c373ff
commit 1f520d95e3
2 changed files with 167 additions and 1 deletions

View File

@@ -8,6 +8,7 @@ import (
"be.ems/src/framework/errorcatch"
"be.ems/src/framework/middleware"
"be.ems/src/framework/middleware/security"
"be.ems/src/framework/utils/machine"
"be.ems/src/modules/chart"
"be.ems/src/modules/common"
"be.ems/src/modules/crontask"
@@ -37,6 +38,9 @@ func AppEngine() *gin.Engine {
// 设置程序内全局资源访问
config.SetAssetsDirFS(assetsDir)
// 首次安装启动记录
machine.Launch()
// 读取服务配置
app.ForwardedByClientIP = config.Get("server.proxy").(bool)
return app
@@ -108,7 +112,7 @@ func initDefeat(app *gin.Engine) {
app.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{
"code": 404,
"msg": fmt.Sprintf("%s Not Found", c.Request.RequestURI),
"msg": fmt.Sprintf("Not Found %s", c.Request.RequestURI),
})
})
}

View File

@@ -0,0 +1,162 @@
package machine
import (
"crypto/rand"
"encoding/json"
"fmt"
"hash/fnv"
"os"
"runtime"
"time"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/crypto"
"be.ems/src/framework/utils/parse"
"github.com/shirou/gopsutil/mem"
)
// 机器的唯一标识符
var Code string
// 初始信息
var LaunchInfo map[string]any
// codeGenerate 生成机器的唯一标识符
func codeGenerate() string {
var machineID string
// 获取主机名
hostname, err := os.Hostname()
if err != nil {
panic(err)
}
machineID += hostname
// 获取 CPU 信息
numCPU := runtime.NumCPU()
machineID += fmt.Sprintf("%d", numCPU)
// 获取操作系统信息
osInfo := runtime.GOOS
machineID += osInfo
// 获取内存信息
memInfo, _ := mem.VirtualMemory()
machineID += fmt.Sprintf("%d", memInfo.Total)
// 使用哈希函数生成机器码
h := fnv.New32a()
h.Write([]byte(machineID))
machineCode := h.Sum32()
return fmt.Sprintf("%x", machineCode)
}
// 网管本地路径
func filePath() string {
filePath := "/usr/local/etc/omc/machine.ini"
if runtime.GOOS == "windows" {
filePath = fmt.Sprintf("C:%s", filePath)
}
return filePath
}
// codeFileRead 读取机器保留的信息
func codeFileRead() (map[string]any, error) {
var mapData map[string]any
// 读取文件内容
bytes, err := os.ReadFile(filePath())
if err != nil {
logger.Warnf("CodeFileRead ReadFile => %s", err.Error())
return mapData, fmt.Errorf("not file")
}
content := string(bytes)
// 解密
contentDe, err := crypto.StringDecryptByAES(content)
if err != nil {
logger.Errorf("CodeFileRead decrypt: %v", err.Error())
return mapData, fmt.Errorf("decrypt fail")
}
// 序列化Map
mapData, err = parse.ConvertConfigToMap("json", string(contentDe))
if err != nil {
logger.Warnf("NeConfPara5GRead ConvertConfigToMap => %s", err.Error())
return mapData, fmt.Errorf("content error")
}
return mapData, nil
}
// codeFileWrite 写入机器保留的信息
func codeFileWrite(data map[string]any) error {
jsonByte, _ := json.Marshal(data)
// 加密
contentEn, err := crypto.StringEncryptByAES(string(jsonByte))
if err != nil {
logger.Errorf("insert encrypt: %v", err.Error())
return fmt.Errorf("encrypt fail")
}
return parse.ConvertConfigToFile("txt", filePath(), contentEn)
}
// Launch 记录首次安装启动初始信息
func Launch() {
Code = codeGenerate()
// 检查文件是否存在
if _, err := os.Stat(filePath()); err != nil {
LaunchInfo = map[string]any{
"code": Code, // 机器码
"firstTime": time.Now().UnixMilli(), // 首次启动使用时间
"sysGuide": true, // 首次引导
"sysGuideTime": 0, // 引导完成时间
}
codeFileWrite(LaunchInfo)
} else {
// 创建一个用于存储密钥的字节数组
key := make([]byte, 32)
// 使用crypto/rand包生成安全的随机字节序列
_, err := rand.Read(key)
if err != nil {
fmt.Println("Error generating random key:", err)
return
}
// 将随机生成的字节序列作为密钥打印出来
fmt.Printf("Generated AES-256 key: %x\n", key)
// 读取记录文件
data, err := codeFileRead()
if err != nil {
// 文件异常就重新生成
os.Remove(filePath())
Launch()
return
}
LaunchInfo = data
}
}
// SetLaunchInfo 新增额外的初始信息
func SetLaunchInfo(info map[string]any) error {
if info == nil {
return fmt.Errorf("not info")
}
// 固定值禁止变更
constKeys := []string{"code", "firstTime"}
for k, v := range info {
constKey := false
for _, ck := range constKeys {
if ck == k {
constKey = true
break
}
}
if constKey {
continue
} else {
LaunchInfo[k] = v
}
}
return codeFileWrite(LaunchInfo)
}