machineid

package module
v1.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 16, 2025 License: MIT Imports: 18 Imported by: 0

README

machineid

GoDoc Go Report Card

高性能跨平台机器码生成库,支持多种操作系统和容器环境,提供安全的机器标识和授权管理功能。

Image of Gopher 47

✨ 主要特性

🚀 核心功能
  • 跨平台支持 - 支持 Windows、Linux、macOS、FreeBSD、AIX 等多种操作系统
  • 容器环境适配 - 自动检测和适配 Docker、Containerd 等容器运行时
  • 无管理员权限 - 所有功能均无需管理员或 root 权限
  • 简洁稳定 - 核心功能基于系统机器码,可选硬件绑定增强安全性
🔒 安全特性
  • HMAC-SHA256 加密 - 使用加密安全的哈希算法保护机器标识
  • 应用级绑定 - 支持应用特定的机器码生成
  • MAC 地址绑定 - 可选的硬件绑定增强安全性
  • 证书授权管理 - 完整的 PKI 证书签发和验证系统
⚡ 性能优化
  • 智能缓存 - 内存缓存机制减少重复计算
  • 并发安全 - 全面的并发保护和线程安全设计
  • 快速响应 - 优化的算法确保毫秒级响应

📦 安装

go get github.com/darkit/machineid

命令行工具安装:

go install github.com/darkit/machineid/cmd/machineid@latest

🚀 快速开始

基础用法
package main

import (
    "fmt"
    "log"
    "github.com/darkit/machineid"
)

func main() {
    // 获取原始机器码
    id, err := machineid.ID()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("机器码: %s\n", id)
    
    // 获取应用专属的受保护机器码(推荐)
    protectedID, err := machineid.ProtectedID("your.app.id")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("受保护机器码: %s\n", protectedID)
}
高级功能
package main

import (
    "fmt"
    "log"
    "github.com/darkit/machineid"
)

func main() {
    // 获取系统信息摘要
    info, err := machineid.GetInfo("your.app.id")
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("机器码: %s\n", info.MachineID)
    fmt.Printf("受保护机器码: %s\n", info.ProtectedID)
    fmt.Printf("MAC地址: %s\n", info.MACAddress)
    fmt.Printf("是否为容器: %t\n", info.IsContainer)
    if info.ContainerID != "" {
        fmt.Printf("容器ID: %s\n", info.ContainerID)
    }
}
智能硬件绑定
// ProtectedID 现在自动使用最佳可用的硬件绑定方式
// 优先级:硬件指纹 > MAC地址 > 纯机器码
protectedID, err := machineid.ProtectedID("your.app.id")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("智能保护机器码: %s\n", protectedID)

// 直接获取MAC地址(可选)
macAddr, err := machineid.GetMACAddress()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("主网卡MAC: %s\n", macAddr)
自定义绑定提供者

如果需要扩展绑定来源(例如磁盘序列号、云厂商元数据),可以注册自定义提供者:

machineid.RegisterBindingProvider("disk", func(appID, machineID string) (string, bool, error) {
    serial, err := readDiskSerial()
    if err != nil || serial == "" {
        return "", false, err
    }
    return serial, true, nil
})

当内置硬件指纹和 MAC 绑定不可用时,ProtectedID 会尝试自定义提供者,并在 BindingResult 中返回 Mode="custom"Provider="disk" 等信息。

容器环境检测
// 检查是否运行在容器中
if machineid.IsContainer() {
    fmt.Println("运行在容器环境中")
} else {
    fmt.Println("运行在物理机或虚拟机中")
}

🔧 API 参考

核心函数
函数 描述 返回值
ID() 获取原始机器码 (string, error)
ProtectedID(appID) 获取智能硬件绑定的保护机器码(推荐) (string, error)
GetInfo(appID) 获取完整系统信息(推荐) (*Info, error)
GetMACAddress() 获取主网卡MAC地址 (string, error)
IsContainer() 检查是否在容器环境 bool
ClearCache() 清除所有缓存 void
Info 结构体
type Info struct {
    MachineID   string `json:"machine_id"`            // 原始机器码
    ProtectedID string `json:"protected_id"`          // 智能保护机器码
    MACAddress  string `json:"mac_address,omitempty"` // MAC地址
    IsContainer bool   `json:"is_container"`          // 是否容器环境
    ContainerID string `json:"container_id,omitempty"` // 容器ID
}

🏗️ 证书授权管理

本库还提供了完整的 PKI 证书管理功能,用于软件授权和客户信息管理。

📚 详细文档:完整的证书管理功能请参阅 cert包文档

主要功能
  • CA证书生成 - 自定义根证书和私钥管理
  • 客户端证书签发 - 基于机器码的证书签发
  • 证书验证 - 完整的证书链验证和有效性检查
  • 客户信息提取 - 从证书中提取完整客户资料
  • 智能监控 - 自动监控证书状态和到期预警
  • 安全防护 - 4级安全防护(反调试、虚拟机检测等)
  • 批量处理 - 大规模证书操作支持
基础授权管理
package main

import (
    "time"
    "github.com/darkit/machineid"
    "github.com/darkit/machineid/cert"
)

func main() {
    // 创建授权管理器(默认开发友好,无安全检查)
    auth, err := cert.NewAuthorizer().
        WithRuntimeVersion("2.5.0"). // 设置当前运行的软件版本
        Build()
    if err != nil {
        panic(err)
    }

    // 获取机器码(使用标准ProtectedIDResult 以保留绑定来源)
    bindingResult, _ := machineid.ProtectedIDResult("your.app.id")
    machineID := bindingResult.Hash

    // 构建证书请求
    request, err := cert.NewClientRequest().
        WithMachineID(machineID).
        WithBindingResult(bindingResult).
        WithExpiry(time.Now().AddDate(1, 0, 0)).
        WithCompany("示例科技公司", "研发部").
        WithContact("张经理", "13800138000", "[email protected]").
        WithMinClientVersion("2.0.0").
        WithValidityDays(365).
        Build()

    // 签发证书
    certificate, err := auth.IssueClientCert(request)
    if err != nil {
        panic(err)
    }

    // 验证证书
    err = auth.ValidateCert(certificate.CertPEM, machineID)
    if err != nil {
        panic(err)
    }

    // 提取客户信息
    clientInfo, err := auth.ExtractClientInfo(certificate.CertPEM)
    if err == nil {
        fmt.Printf("授权给: %s (%s)\n", clientInfo.CompanyName, clientInfo.ContactPerson)
        fmt.Printf("联系方式: %s\n", clientInfo.ContactEmail)
        fmt.Printf("绑定模式: %s\n", clientInfo.BindingMode)
        fmt.Printf("绑定提供者: %s\n", clientInfo.BindingProvider)
        fmt.Printf("到期时间: %s\n", clientInfo.ExpiryDate.Format("2006-01-02"))
    }

    // 启动智能监控(可选)
    watchCallback := func(event cert.WatchEvent, info *cert.ClientInfo, err error) {
        switch event {
        case cert.WatchEventExpiring:
            fmt.Printf("警告: 证书即将到期 - %s\n", info.CompanyName)
        case cert.WatchEventExpired:
            fmt.Printf("紧急: 证书已过期 - %s\n", info.CompanyName)
        }
    }
    
    // 启动监控(1小时检查间隔,7天预警期)
    watcher, _ := auth.Watch(certificate.CertPEM, machineID, watchCallback)
    defer watcher.Stop()
}

💡 版本提示WithRuntimeVersion 表示当前正在运行的软件实际版本,用于校验证书要求;WithMinClientVersion 表示签发证书时要求客户端至少达到的版本,两者互不冲突。

环境配置和安全等级
// 开发环境(无安全检查,推荐)
devAuth, _ := cert.ForDevelopment().Build()

// 生产环境(基础安全检查)
prodAuth, _ := cert.ForProduction().Build()

// 高安全环境(完整反调试保护)
secureAuth, _ := cert.NewAuthorizer().WithSecureDefaults().Build()

// 关键系统(最高安全级别)
criticalAuth, _ := cert.NewAuthorizer().WithCriticalSecurity().Build()
证书管理新增功能
客户信息提取
// 从任何证书中提取完整的客户信息
clientInfo, err := auth.ExtractClientInfo(certPEM)
if err != nil {
    // 处理错误
}

fmt.Printf("公司: %s\n", clientInfo.CompanyName)
fmt.Printf("联系人: %s (%s)\n", clientInfo.ContactPerson, clientInfo.ContactEmail)
fmt.Printf("到期时间: %s\n", clientInfo.ExpiryDate.Format("2006-01-02"))
智能监控回调
// 定义监控回调处理不同事件
watchCallback := func(event cert.WatchEvent, clientInfo *cert.ClientInfo, err error) {
    switch event {
    case cert.WatchEventExpiring:
        // 证书即将到期(默认7天预警)
        sendRenewalNotification(clientInfo)
    case cert.WatchEventExpired:
        // 证书已过期
        disableService(clientInfo)
    case cert.WatchEventRevoked:
        // 证书被吊销
        handleSecurityIncident(clientInfo)
    }
}

// 启动监控(支持自定义间隔)
watcher, err := auth.Watch(certPEM, machineID, watchCallback,
    time.Hour,        // 检查间隔(可选,默认1小时)
    3*24*time.Hour)   // 预警期(可选,默认7天)

// 监控管理器(管理多个证书)
manager := cert.NewWatcherManager()
manager.AddWatcher("license1", watcher1)
manager.AddWatcher("license2", watcher2)

🔍 工作原理

机器码来源
操作系统 主要来源 备用来源
Windows 注册表 MachineGuid -
Linux /var/lib/dbus/machine-id /etc/machine-id, $HOME/.config/machine-id
macOS IOPlatformUUID -
FreeBSD /etc/hostid smbios.system.uuid
AIX uname -u -
容器环境处理

Linux 容器检测

  • 检查 /proc/self/cgroup/proc/self/mountinfo
  • 支持 Docker、Containerd、Podman 等容器运行时
  • 环境变量检测:CONTAINER_IDDOCKER_CONTAINER_ID

其他系统

  • 检查 /.dockerenv 文件
  • 环境变量检测
安全考虑
  1. 原始机器码保护

    • 原始机器码应视为机密信息
    • 生产环境建议使用 ProtectedID() 而非 ID()
  2. 加密算法

    • 使用 HMAC-SHA256 进行应用绑定
    • 返回64位十六进制字符串
  3. 智能硬件绑定

    • ProtectedID() 自动选择最佳可用的硬件绑定方式
    • 优先级:硬件指纹 > MAC地址 > 纯机器码
    • 在不同环境下提供最佳的稳定性和安全性平衡

📱 命令行工具

# 获取原始机器码
machineid

# 获取应用专属机器码
machineid --appid MyApp

# 输出示例
# 原始: 8245d07ef271816592fbd6172e521a945bdc4e3dca2fd91ef57cddf5a298b73f
# 应用专属: DCEF03E8DB3B602695BAFE227E6CC73180807D3A0FDAB459EC0A8FA2DCA1E99E

🧪 测试

# 运行所有测试
go test -v

# 运行基准测试
go test -bench=.

# 测试覆盖率
go test -cover

🔄 迁移指南

从原版 denisbrodbeck/machineid 迁移

本版本与原版 API 完全兼容,主要改进包括:

  1. ProtectedID 智能优化:自动选择最佳硬件绑定方式,提供更好的稳定性
  2. 新增功能:容器检测、系统信息、缓存机制
  3. 性能优化:并发安全、智能缓存
  4. 扩展模块:证书授权管理
版本兼容性
// 原版用法(仍然支持)
id, _ := machineid.ID()
protectedID, _ := machineid.ProtectedID("app")

// 新版建议用法
info, _ := machineid.GetInfo("app")
// 使用 info.MachineID 和 info.ProtectedID

🤝 贡献指南

  1. Fork 本项目
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启 Pull Request

📋 已知限制

  1. 虚拟机克隆:克隆的虚拟机可能具有相同的机器码
  2. 系统重装:重装操作系统通常会更改机器码
  3. 容器环境:容器中的机器码基于容器 ID,重新创建容器会改变
  4. Linux 用户目录:用户级机器码文件 $HOME/.config/machine-id 在某些环境下可能不可用

🔗 相关链接

📄 许可证

MIT License - 详见 LICENSE 文件

🙏 致谢


⭐ 如果这个项目对你有帮助,请给我们一个 Star!

Documentation

Overview

Package machineid provides support for reading the unique machine id of most OSs (without admin privileges).

https://github.com/darkit/machineid

https://godoc.org/github.com/darkit/machineid/cmd/machineid

This package is Cross-Platform (tested on Win7+, Debian 8+, Ubuntu 14.04+, OS X 10.6+, FreeBSD 11+) and does not use any internal hardware IDs (no MAC, BIOS, or CPU).

Returned machine IDs are generally stable for the OS installation and usually stay the same after updates or hardware changes.

This package allows sharing of machine IDs in a secure way by calculating HMAC-SHA256 over a user provided app ID, which is keyed by the machine id.

Caveat: Image-based environments have usually the same machine-id (perfect clone). Linux users can generate a new id with `dbus-uuidgen` and put the id into `/var/lib/dbus/machine-id` and `/etc/machine-id`. Windows users can use the `sysprep` toolchain to create images, which produce valid images ready for distribution.

Index

Constants

View Source
const (
	// the environment variable name pointing to the machine id pathname
	ENV_VARNAME = "MACHINE_ID_FILE"
)

Variables

This section is empty.

Functions

func ClearCache added in v1.0.6

func ClearCache()

ClearCache 清除所有缓存,强制下次调用重新获取

func ClearHardwareCache added in v1.0.6

func ClearHardwareCache()

ClearHardwareCache 清除硬件信息缓存

func GetHardwareFingerprint added in v1.0.6

func GetHardwareFingerprint() (string, error)

GetHardwareFingerprint 生成硬件指纹

func GetHardwareInfo added in v1.0.6

func GetHardwareInfo() (*linuxHardwareInfo, error)

GetHardwareInfo 获取详细硬件信息

func GetMACAddress added in v1.0.6

func GetMACAddress() (string, error)

GetMACAddress 获取主网卡的MAC地址,提供给用户直接使用

func ID

func ID() (string, error)

ID returns the platform specific machine id of the current host OS. Regard the returned id as "confidential" and consider using ProtectedID() instead.

func IsContainer added in v1.0.6

func IsContainer() bool

IsContainer 检查当前程序是否运行在容器环境中

func ProtectedID

func ProtectedID(appID string) (string, error)

ProtectedID returns a hashed version of the machine ID in a cryptographically secure way, using intelligent priority-based hardware binding when available.

Priority order: 1. Hardware fingerprint (most stable) 2. MAC address binding (fallback) 3. Pure machine ID (basic)

func ProtectedIDWithHardware added in v1.0.6

func ProtectedIDWithHardware(appID string) (string, error)

ProtectedIDWithHardware 基于硬件指纹的保护ID

func ProtectedIDWithMAC added in v1.0.6

func ProtectedIDWithMAC(appID string) (string, error)

ProtectedIDWithMAC returns a hashed version of the machine ID bound to MAC address. Deprecated: Use ProtectedID instead, which intelligently handles hardware binding.

func RegisterBindingProvider added in v1.0.9

func RegisterBindingProvider(name string, provider BindingProviderFunc)

RegisterBindingProvider 注册自定义绑定提供者,名称需唯一

func RegisterContainerHintProvider added in v1.0.9

func RegisterContainerHintProvider(provider ContainerHintProvider)

RegisterContainerHintProvider 注册自定义容器指纹提供者

Types

type BindingMode added in v1.0.7

type BindingMode string

BindingMode 表示保护ID最终采用的绑定模式

const (
	BindingModeFingerprint BindingMode = "fingerprint"
	BindingModeMAC         BindingMode = "mac"
	BindingModeMachineID   BindingMode = "machine_id"
	BindingModeCustom      BindingMode = "custom"
)

type BindingProviderFunc added in v1.0.9

type BindingProviderFunc func(appID, machineID string) (value string, stable bool, err error)

BindingProviderFunc 提供额外绑定方式

type BindingResult added in v1.0.7

type BindingResult struct {
	Hash             string
	Mode             BindingMode
	Provider         string
	FingerprintError error
	MACError         error
	ContainerMode    string // ContainerMode 容器绑定模式: "host"/"container"/"hybrid"/"none"
	ContainerID      string // ContainerID 容器ID(如果检测到)
}

BindingResult 描述生成保护ID时采用的模式与降级原因

func ProtectedIDResult added in v1.0.7

func ProtectedIDResult(appID string) (*BindingResult, error)

ProtectedIDResult 返回包含详细绑定信息的结果

func ProtectedIDWithContainerAware added in v1.0.9

func ProtectedIDWithContainerAware(appID string, config *ContainerBindingConfig) (*BindingResult, error)

ProtectedIDWithContainerAware 容器感知的保护ID生成

容器绑定逻辑说明: - 非容器环境:保持历史行为,走“硬件指纹 → MAC → machine-id”的优先级链路(ContainerMode="none")。 - 容器环境:根据 ContainerBindingConfig 选择策略:

  • host_hardware:在容器具备宿主机硬件可见性时,优先使用宿主机硬件指纹;不可用且允许降级则落到容器级。
  • container_scoped:仅使用容器命名空间/挂载等稳定特征派生;再不行使用容器 ID;最后落回标准 machine-id。
  • hybrid:尽量组合宿主机硬件指纹与容器稳定特征,兼顾稳定性与隔离性。

func ProtectedIDWithMACResult added in v1.0.7

func ProtectedIDWithMACResult(appID string) (*BindingResult, error)

ProtectedIDWithMACResult 返回强制 MAC 绑定模式下的详细结果

type ContainerBindingConfig added in v1.0.9

type ContainerBindingConfig struct {
	Mode                ContainerBindingMode
	PreferHostHardware  bool
	FallbackToContainer bool
	PersistentVolume    string
}

ContainerBindingConfig 描述容器绑定的策略配置。

说明:

  • Mode 用于指定绑定模式:自动/强制宿主机/强制容器级。
  • PreferHostHardware 用于在自动模式下表达偏好:尽可能使用宿主机硬件作为绑定依据。
  • FallbackToContainer 用于在宿主机硬件不可用/不稳定时是否允许降级到容器级。
  • PersistentVolume 用于指向持久卷路径:当采用容器级标识时,可用来存储/读取稳定标识, 以避免每次容器重建都改变绑定结果。

func DefaultContainerBindingConfig added in v1.0.9

func DefaultContainerBindingConfig() *ContainerBindingConfig

DefaultContainerBindingConfig 返回默认容器绑定配置。

默认策略: - Mode: 自动检测 - PreferHostHardware: true(优先使用宿主机硬件) - FallbackToContainer: true(宿主机硬件不可用时允许降级) - PersistentVolume: 空(由业务自行配置持久卷路径)

func (*ContainerBindingConfig) Validate added in v1.0.9

func (c *ContainerBindingConfig) Validate() error

Validate 校验配置是否自洽。

该方法只做“静态配置”层面的校验(例如字段组合是否合理),不做路径存在性/权限等运行时校验, 以避免在库初始化阶段引入文件系统副作用。

type ContainerBindingMode added in v1.0.9

type ContainerBindingMode int

ContainerBindingMode 表示容器绑定配置模式。

该配置用于在“宿主机级绑定”(更稳定、更贴近真实硬件)与“容器级绑定”(更适合容器镜像复制/隔离) 之间做选择。业务侧可通过配置控制机器码派生逻辑在容器环境下的行为。

const (
	// ContainerBindingAuto 表示自动检测:由运行时根据环境与可用硬件信息选择绑定级别。
	ContainerBindingAuto ContainerBindingMode = iota
	// ContainerBindingHost 表示强制宿主机:优先/强制使用宿主机硬件信息进行绑定。
	ContainerBindingHost
	// ContainerBindingContainer 表示强制容器级:使用容器环境内可用信息派生容器级标识。
	ContainerBindingContainer
)

func (ContainerBindingMode) String added in v1.0.9

func (m ContainerBindingMode) String() string

type ContainerHintProvider added in v1.0.9

type ContainerHintProvider func() []string

ContainerHintProvider 提供用于容器派生机器码的附加指纹

type FingerprintStatus added in v1.0.7

type FingerprintStatus struct {
	Value  string
	Stable bool
}

FingerprintStatus 描述硬件指纹的值与稳定性

func GetHardwareFingerprintStatus added in v1.0.7

func GetHardwareFingerprintStatus() (*FingerprintStatus, error)

GetHardwareFingerprintStatus 返回指纹值及稳定性

type HardwareInfo added in v1.0.9

type HardwareInfo interface {
	// ProductUUID 返回主机级产品 UUID(例如 SMBIOS/DMI UUID)。
	ProductUUID() string

	// BoardSerial 返回主板序列号(若可用)。
	BoardSerial() string

	// CPUSignature 返回 CPU 的可重复签名(不要求是真正的序列号;可为族/型号/步进组合)。
	CPUSignature() string

	// DiskSerials 返回磁盘序列号列表(尽量只包含物理盘,且保持顺序稳定)。
	DiskSerials() []string

	// TPMSupported 返回是否检测到 TPM(或等价硬件安全模块)可用。
	TPMSupported() bool

	// Fingerprint 返回当前平台的硬件指纹(通常为 hash),以及可能的错误。
	Fingerprint() (string, error)

	// IsStable 返回当前硬件信息是否“稳定到足以用于绑定”。
	IsStable() bool
}

HardwareInfo 是跨平台统一的“硬件信息视图”接口。

设计目标:

  1. 跨平台一致性:不同平台(Linux/Windows/macOS/其他)应尽量输出同一语义的字段。 - “同一语义”指:同一个方法在各平台返回的应是同类硬件标识(例如 ProductUUID 都是主机级 UUID)。
  2. 稳定性优先:硬件特征优先于软件特征。硬件特征不应随重装系统/改主机名而变化。
  3. 向后兼容:该接口是新增能力,不要求改动现有结构体字段与对外 API。
  4. 最小依赖:实现侧应尽量使用操作系统原生信息源(sysfs/registry/ioreg 等),避免引入额外依赖。
  5. 失败可降级:信息源缺失(例如容器、权限不足、文件不存在)时,不应导致整体失败;返回空值即可。

注意:

  • DiskSerials 返回应尽量排序并去重,以保证指纹可重复。
  • Fingerprint 返回的指纹值应只依赖稳定特征;IsStable 用于标识“足够稳定”的硬件组合是否可得。

type HardwareWeight added in v1.0.6

type HardwareWeight struct {
	Name   string
	Value  string
	Weight int
}

HardwareWeight 硬件信息权重

type Info added in v1.0.6

type Info struct {
	MachineID   string `json:"machine_id"`             // 原始机器码
	ProtectedID string `json:"protected_id"`           // 应用保护机器码
	MACAddress  string `json:"mac_address,omitempty"`  // MAC地址(可选硬件绑定)
	IsContainer bool   `json:"is_container"`           // 是否容器环境
	ContainerID string `json:"container_id,omitempty"` // 容器ID
}

Info 返回系统信息摘要

func GetInfo added in v1.0.6

func GetInfo(appID string) (*Info, error)

GetInfo 获取系统信息摘要

type MACInfo added in v1.0.7

type MACInfo struct {
	Address string
	Stable  bool
	Iface   string
}

MACInfo 描述筛选到的 MAC 地址与其稳定性

Directories

Path Synopsis
cmd
authorize command
hardware command
machineid command
Package main provides the command line app for reading the unique machine id of most OSs.
Package main provides the command line app for reading the unique machine id of most OSs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL