feat: bind each node to the binary it runs at its first handshake; refuse changes that are not in a CI-signed manifest [CI]
ci/woodpecker/push/main-amd64-build Pipeline failed
ci/woodpecker/push/main-amd64-build Pipeline failed
This commit is contained in:
1 parent
117d34a2af
commit
4841f7b15b
40 files changed
+1011
-21
No files matched your search
@@ -72,6 +72,9 @@ public sealed class FleetLinkOptions
|
||||
/// 服务器必须在挑战里证明自己,之后这条链路用应用层加密;否则按旧的方式(没有固定信任根的节点)。
|
||||
/// </summary>
|
||||
public IServerVerifier? ServerVerifier { get; init; }
|
||||
|
||||
/// <summary>握手时自述正在运行的二进制(哈希和 CI 签名的清单);没有就不上报(旧行为)。</summary>
|
||||
public Func<BinaryAttestation?>? Attestation { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -223,6 +226,16 @@ public sealed class FleetLink
|
||||
}
|
||||
|
||||
/// <summary>挑战 → 签名 → 认证结果。失败返回原因;服务端禁用该节点时不再重试。</summary>
|
||||
private void Attest(AuthParams auth)
|
||||
{
|
||||
if (_options.Attestation?.Invoke() is { } attestation)
|
||||
{
|
||||
auth.Binary = attestation.Sha256;
|
||||
auth.Release = attestation.Manifest;
|
||||
auth.ReleaseSignature = attestation.Signature;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string?> AuthenticateAsync(SecureTransport transport, CancellationToken ct)
|
||||
{
|
||||
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(15), _time);
|
||||
@@ -257,6 +270,7 @@ public sealed class FleetLink
|
||||
Signature = Convert.ToBase64String(_options.Identity.Sign(SignaturePurpose.AuthSecure, _options.NodeId.Value, nonce.Nonce, serverEphemeralText, nodeEphemeralText)),
|
||||
NodeEphemeral = nodeEphemeralText,
|
||||
};
|
||||
Attest(authParams);
|
||||
RpcMessage secureRequest = RpcMessage.Request(1, FleetMethods.Auth, authParams, FleetRpcContext.Default.AuthParams);
|
||||
await transport.SendAsync(new RpcFrame(FrameKind.Text, JsonSerializer.SerializeToUtf8Bytes(secureRequest, FleetRpcContext.Default.RpcMessage)), linked.Token);
|
||||
transport.Enable(LinkCipher.ForNode(ephemeral, serverEphemeral, nonce.Nonce));
|
||||
@@ -264,6 +278,7 @@ public sealed class FleetLink
|
||||
else
|
||||
{
|
||||
authParams = new AuthParams { NodeId = _options.NodeId.Value, Signature = Convert.ToBase64String(_options.Identity.Sign(SignaturePurpose.Auth, _options.NodeId.Value, nonce.Nonce)) };
|
||||
Attest(authParams);
|
||||
RpcMessage request = RpcMessage.Request(1, FleetMethods.Auth, authParams, FleetRpcContext.Default.AuthParams);
|
||||
await transport.SendAsync(new RpcFrame(FrameKind.Text, JsonSerializer.SerializeToUtf8Bytes(request, FleetRpcContext.Default.RpcMessage)), linked.Token);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user