如何从将 x-real-ip 和 x-forward-for 添加到 header 的负载均衡器获取 gRPC 中的客户端 IP 地址?
How can I get the client IP address in gRPC from a load balancer that adds x-real-ip and x-forward-for to the header?
如何从将 x-real-ip 和 x-forward-for 添加到 header 的负载均衡器中获取 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/
您可以从请求 object 中读取 headers。
func handler(w http.ResponseWriter, r *http.Request) {
realIP := r.Header.Get("x-real-ip")
forwardFor := r.Header.Get("x-forward-for");
// ...
}
查看负载均衡器文档,您可以看到有 header 组 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)
}
}
如何从将 x-real-ip 和 x-forward-for 添加到 header 的负载均衡器中获取 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/
您可以从请求 object 中读取 headers。
func handler(w http.ResponseWriter, r *http.Request) {
realIP := r.Header.Get("x-real-ip")
forwardFor := r.Header.Get("x-forward-for");
// ...
}
查看负载均衡器文档,您可以看到有 header 组 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)
}
}