using Fleet.Core; namespace Fleet.Hosting; /// /// 节点自己要求有属主(passkey):拨号方和监听方共用这一份,启动时检查。 /// /// 属主是安装命令带来、注册时固定在 trust.json 里的 passkey 凭证 id(必须是操作员集合里的凭证)。节点据此知道自己绑定在哪个 passkey 上, /// 才敢把更多的接口和操作交给它(extension 会话、加密内容都只认属主的 passkey);没有属主的节点没有人能授权它的敏感能力,所以不运行。 /// 这是节点本地的强制,不依赖面板:面板被攻破也改不了节点已经固定的属主。 /// /// public static class OwnerGuard { /// 设为 1 放行没有属主的节点(只给没有信任根的老面板)。 public const string AllowEnvironmentVariable = "MOSHIRO_ALLOW_NO_OWNER"; /// 没问题返回 null;否则是要告诉运维的原因。 public static string? Problem(TrustAnchor trust, bool require) { if (!require || Environment.GetEnvironmentVariable(AllowEnvironmentVariable) == "1") { return null; } if (!trust.Pinned) { return "this node has no owner: it was not enrolled with a trust root and owner passkeys; enroll it again with the command from the panel (or set " + AllowEnvironmentVariable + "=1 for a panel without a trust root)"; } return trust.Controllers.Count == 0 ? "none of this node's owner passkeys is in the operator set any more; enroll it again with a command from the panel" : null; } /// 读身份目录里固定的信任根,检查属主;不行就记一条错误并返回 false(调用方应当退出)。 public static bool Check(string identityDirectory, bool require, INodeLog log) { TrustAnchor trust = TrustAnchor.Load(identityDirectory, log); if (Problem(trust, require) is { } problem) { log.Error("startup failed", ("err", problem)); return false; } return true; } }