aws / aws-xray-daemon

The AWS X-Ray daemon listens for traffic on UDP port 2000, gathers raw segment data, and relays it to the AWS X-Ray API.
Apache License 2.0
190 stars 68 forks source link

InvalidSignatureException for GetSamplingRules when using daemon in EKS with Istio service mesh #199

Closed SPopenko closed 1 year ago

SPopenko commented 1 year ago

Hello guys! Did someone faced with the issue described below and have any recommendations how to avoid that?

Environment:

Problem: Istio side car (envoy) may add additional headers to each outbound request when any service calls X-ray daemon to get GetSamplingRules and that cause InvalidSignatureException from daemon.

Here is trace: From busy box with side car

` /home # curl -X POST 10.0.2.88:2000/GetSamplingRules -v

From busy box without side car `bash-5.2$ curl -X POST 10.0.2.88:2000/GetSamplingRules -v

wangzlei commented 1 year ago

Provide XRay SDK GetSamplingTargets/GetSamplingRules mechanism for your reference: GetSamplingTargets/GetSamplingRules request is sent from xray SDK(running in user's application) in plain http, the request arrives at xray daemon, then is signed and forward to xray service.

XRay SDK  -> XRay Daemon(sigv4) -> XRay service

So updating headers before XRay Daemon is ok. But update the request after XRay daemon will cause invalid exception.

SPopenko commented 1 year ago

@wangzlei you are right, but the issue was a bit deeper.

Envoy proxy (that is used as Istio sidecar) makes modifications for all outbound requests from Xray SDK (in own service) to Xray Daemon. It adds bunch of headers but only one cause the issue.

Envoy adds "X-Forwarded-Proto: http" header, that is fair enough, since like you said, SDK and daemon communicate via plain http. This header cause invalid signature exception from AWS X-ray service if included in request (even if one run it from postman).

My workaround is adding custom Lua filter for envoy:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: xray-patch
  namespace: default
  annotations:
    name: Fix commnuication between service and xray 
    description: Replase x-forwarded-proto to https
spec:
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: SIDECAR_OUTBOUND
        listener:
          portNumber: 2000
          filterChain:
            filter:
              name: envoy.filters.network.http_connection_manager
              subFilter:
                name: envoy.filters.http.router
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.lua
          typed_config:
            '@type': 'type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua'
            inlineCode: |
              function envoy_on_request(request_handle)
                request_handle:headers():replace("x-forwarded-proto", "https")
              end

Note: envoy filters are pretty 'dangerous' (could break your mesh if works in a wrong way) and are very sensitive to Istio/Envoy version