You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于.NET gRPC命名管道IPC,服务器端如何获取客户端进程ID?

在.NET gRPC NamedPipe IPC中获取客户端进程ID并实现证书指纹校验

gRPC的默认NamedPipe传输层不会直接在ServerCallContext中暴露客户端进程ID,需要通过底层管道句柄结合Windows API来获取,再结合进程路径完成证书指纹校验。以下是具体实现方案:

1. 通过NamedPipe底层句柄获取客户端PID

gRPC的NamedPipe传输基于System.IO.Pipes.NamedPipeServerStream,可以通过自定义管道监听逻辑,利用Windows API从管道句柄中提取客户端进程ID:

1.1 实现PID获取的P/Invoke方法

using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Principal;

[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint GetNamedPipeClientProcessId(IntPtr pipeHandle, out uint clientProcessId);

private static uint GetClientProcessId(SafePipeHandle pipeHandle)
{
    if (!GetNamedPipeClientProcessId(pipeHandle.DangerousGetHandle(), out var pid))
    {
        throw new Win32Exception(Marshal.GetLastWin32Error());
    }
    return pid;
}

1.2 自定义gRPC NamedPipe监听逻辑

绕过gRPC默认的ListenNamedPipe,手动创建管道流并传递PID到请求上下文:

var pipeName = "YourIPC_PipeName";
var server = new Grpc.Core.Server
{
    Services = { YourService.BindService(new YourServiceImpl()) },
    // 这里端口设为0,因为我们用自定义NamedPipe传输
    Ports = { new ServerPort("localhost", 0, ServerCredentials.Insecure) }
};

// 启动自定义管道监听任务
_ = Task.Run(async () =>
{
    while (!server.ShutdownTask.IsCompleted)
    {
        using var pipeStream = new NamedPipeServerStream(
            pipeName,
            PipeDirection.InOut,
            NamedPipeServerStream.MaxAllowedServerInstances,
            PipeTransmissionMode.Byte,
            PipeOptions.Asynchronous | PipeOptions.WriteThrough);

        // 等待客户端连接
        await pipeStream.WaitForConnectionAsync();

        try
        {
            // 获取客户端PID
            var clientPid = GetClientProcessId(pipeStream.SafePipeHandle);
            
            // 将PID存入自定义元数据,传递给gRPC请求上下文
            var metadata = new Metadata { { "client-pid", clientPid.ToString() } };
            
            // 将管道流交给gRPC传输处理
            var transport = new NamedPipeServerTransport(pipeStream, metadata);
            await server.ServerManager.AddTransportAsync(transport);
        }
        catch (Exception ex)
        {
            // 处理连接异常
            Console.WriteLine($"Pipe connection error: {ex.Message}");
        }
    }
});

await server.StartAsync();

2. 在服务方法中校验客户端证书指纹

从请求上下文提取PID,通过进程路径读取证书并校验指纹:

public override async Task<YourResponse> YourRpcMethod(YourRequest request, ServerCallContext context)
{
    // 从元数据中获取客户端PID
    if (!context.RequestHeaders.TryGet("client-pid", out var pidHeader) || !uint.TryParse(pidHeader.Value, out var clientPid))
    {
        throw new RpcException(new Status(StatusCode.Unauthenticated, "Missing or invalid client PID"));
    }

    try
    {
        // 获取客户端进程路径
        using var clientProcess = Process.GetProcessById((int)clientPid);
        var processPath = clientProcess.MainModule.FileName;

        // 读取进程文件的证书指纹
        var actualFingerprint = GetProcessCertificateFingerprint(processPath);
        
        // 替换为你的预期指纹
        const string expectedFingerprint = "your-expected-cert-fingerprint-here";
        
        if (!string.Equals(actualFingerprint, expectedFingerprint, StringComparison.OrdinalIgnoreCase))
        {
            throw new RpcException(new Status(StatusCode.PermissionDenied, "Invalid client certificate fingerprint"));
        }
    }
    catch (Exception ex)
    {
        throw new RpcException(new Status(StatusCode.Unauthenticated, $"Client validation failed: {ex.Message}"));
    }

    // 执行业务逻辑
    return new YourResponse();
}

// 读取PE文件的证书指纹
private string GetProcessCertificateFingerprint(string filePath)
{
    var signedCert = X509Certificate.CreateFromSignedFile(filePath);
    using var cert = new X509Certificate2(signedCert);
    // 返回小写无分隔符的指纹
    return BitConverter.ToString(cert.GetCertHash()).Replace("-", "").ToLowerInvariant();
}

注意事项

  • 权限要求:服务器进程需要拥有读取客户端进程主模块的权限,可能需要以管理员身份运行。
  • 管道安全:创建NamedPipeServerStream时,可通过PipeSecurity设置访问控制列表,限制只有指定用户或进程能连接管道。
  • 异常处理:需处理进程不存在、无主模块、无数字签名等异常场景,避免服务器崩溃。

内容的提问来源于stack exchange,提问作者amateurPro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:52:42