首页 > 解决方案 > 如何从将 x-real-ip 和 x-forward-for 添加到标头的负载均衡器中获取 gRPC 中的客户端 IP 地址?

问题描述

如何从将 x-real-ip 和 x-forward-for 添加到标头的负载均衡器中获取 Go gRPC 中的客户端 IP 地址?

“对等”库给了我唯一的负载均衡器 ip。(来自这个答案:Get client's IP address from load balance server by X-Forwarded-For

明确一点:我需要获取此信息的上下文位于 GRPC 服务器处理程序内部。它可能在拦截器中或在请求处理程序中:

例子:

func (s *myservice) MethodName(ctx context.Context, request *pb.MethodRequest) (*pb.MethodResponse, error) {

    // How to get ip from ctx ? 
    // I have tryied peer but it gives me the loadbalancer ip
    peer, ok := peer.FromContext(ctx)

    return &pb.MethodResponse{Pong: "ok"}, nil
}

如果我也能从拦截器中得到这个就可以了……任何一种方式都对我有用。

func (a *MyInterceptor) Unary() grpc.UnaryServerInterceptor {
    return func(
        ctx context.Context,
        req interface{},
        info *grpc.UnaryServerInfo,
        handler grpc.UnaryHandler,
    ) (interface{}, error) {
        log.Debug("--> My interceptor: " + info.FullMethod)

        
        // How to get ip from ctx ? 
        
        return handler(ctx, req)
    }
}

PS:我使用 Kong 作为负载均衡器。https://docs.konghq.com/0.14.x/loadbalancing/

标签: gogrpcamazon-elbkongaws-load-balancer

解决方案


查看负载均衡器文档,您可以看到有一组标头X-Real-IP https://docs.konghq.com/0.14.x/configuration/#real_ip_header

这应该在 ctx 的元数据中返回。不幸的是,我无法对此进行测试,但请告诉我它是否有效

func (a *MyInterceptor) Unary() grpc.UnaryServerInterceptor {
    return func(
        ctx context.Context,
        req interface{},
        info *grpc.UnaryServerInfo,
        handler grpc.UnaryHandler,
    ) (interface{}, error) {
        log.Debug("--> My interceptor: " + info.FullMethod)

        
        // How to get ip from ctx ?
        var realIP string
        m, ok := metadata.FromIncomingContext(ctx)
        if ok {
            realIP := md.Get("X-Real-IP") 
        }
        // do what you need with realIP
        return handler(ctx, req)
    }
}

推荐阅读