New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sanitize and/or provide useful X-Forwarded-For header #7679
Comments
Ingress gateways should run with externalTrafficPolicy set to Local (see #7328) |
@kyessenov Good find, thanks! Indeed, changing That leaves us with sanitization that won't break |
It depends on which lbs are in the front of ingress. If there is a trusted lb like gcp lb or elb is in front, then you want the left most address set by in xff, if the fronting lb already sanitizes. this should be configurable by deployment. |
There is a load balancer source ip range in kube. Not sure if that helps. Else we can look into ip tagging filter or add a source subnet field in the filter chain match so that we can enable it via api (users specify source ip ranges in the gateway spec). |
I think source subnet match is easiest way forward. |
@mandarjog you can configure number of trusted proxies (xff_num_trusted_hops), which, while not perfect, works for the "behind cloud load balancer" use case. |
@kyessenov my istio-ingressgateway config apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"istio-ingressgateway","chart":"gateways-1.0.0","heritage":"Tiller","istio":"ingressgateway","release":"istio"},"name":"istio-ingressgateway","namespace":"istio-system"},"spec":{"ports":[{"name":"http2","nodePort":31380,"port":80,"targetPort":80},{"name":"https","nodePort":31390,"port":443},{"name":"tcp","nodePort":31400,"port":31400},{"name":"tcp-pilot-grpc-tls","port":15011,"targetPort":15011},{"name":"tcp-citadel-grpc-tls","port":8060,"targetPort":8060},{"name":"http2-prometheus","port":15030,"targetPort":15030},{"name":"http2-grafana","port":15031,"targetPort":15031}],"selector":{"app":"istio-ingressgateway","istio":"ingressgateway"},"type":"LoadBalancer"}}
creationTimestamp: 2018-08-09T09:07:09Z
labels:
app: istio-ingressgateway
chart: gateways-1.0.0
heritage: Tiller
istio: ingressgateway
release: istio
name: istio-ingressgateway
namespace: istio-system
resourceVersion: "1430477"
selfLink: /api/v1/namespaces/istio-system/services/istio-ingressgateway
uid: 98cb3523-9bb3-11e8-91cb-000c29469214
spec:
clusterIP: 172.21.188.124
externalIPs:
- 10.7.0.194
externalTrafficPolicy: Cluster
ports:
- name: http2
nodePort: 31380
port: 80
protocol: TCP
targetPort: 80
- name: https
nodePort: 31390
port: 443
protocol: TCP
targetPort: 443
- name: tcp
nodePort: 31400
port: 31400
protocol: TCP
targetPort: 31400
- name: tcp-pilot-grpc-tls
nodePort: 30833
port: 15011
protocol: TCP
targetPort: 15011
- name: tcp-citadel-grpc-tls
nodePort: 32514
port: 8060
protocol: TCP
targetPort: 8060
- name: http2-prometheus
nodePort: 30431
port: 15030
protocol: TCP
targetPort: 15030
- name: http2-grafana
nodePort: 31506
port: 15031
protocol: TCP
targetPort: 15031
selector:
app: istio-ingressgateway
istio: ingressgateway
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer: {} |
We can add a helm deployment option in the istio-ingressgateway proxy, where the user can specify if the gateway is an edge proxy, or it is located behind a trusted load balancer. This will get passed via proxy node Metadata to Pilot, which will generate the correct Envoy config with the correct combination of use_remote_address and xff_num_trusted_hops as described here: Let me know if you see issues with this approach for 1.0.1. |
@rshriram's proposal to filter on source IP with a CIDR or similar would handle cases where an ingress gateway wants to strip an xff header from some but not all of its clients. The current approach is all or nothing - the ingress gateway trusts all of its clients or none of its clients. Is that flexible enough? |
@duderino Envoy does not have support for filtering x-forwarded-for , it would need to be added. What are the best practices in the industry to prevent spoofing and how do other proxies handle it? I wonder why Envoy went with the num_hops solely. @PiotrSikora |
filtering based on IP is discussed here also as a possible fix: cloudfoundry/gorouter#179 |
@PiotrSikora We want to cut a build on Friday, what is the status of this bug |
Should this work with AWS ELB? |
@rkpagadala I am working on this as per this proposal: #7679 (comment) |
@andraxylia I thought the plan for 1.0.1 was to only strip |
@PiotrSikora the agreement was to have a flag for edge proxy, on by default, and to strip only for edge proxies. This way, when externalTrafficPolicy is fixed, we don't need to revisit this issue anymore, it will just work. |
@exiaohao Did you find a fix for this? I'm seeing the same thing. |
You can specify the parameter gateways.istio-ingressgateway.externalTrafficPolicy to Local if using Helm to deploy. |
This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions. |
@kyessenov |
@osswangxining |
for anyone who had the issue with setting externalTrafficPolicy from Cluster to Local you would need to make sure istio-ingress is running on the node you are connecting to. for example in my case I had 4 ingress gateway when I changed externalTrafficPolicy on the service from Cluster to Local I couldnt get access to my internal containers. so what I had to do was add podaffinity to make sure istio-ingressgateway is running on the hosts that traffic is going to. when you are changing Cluster to Local it basically stops kubernetes service to proxy traffic to another host. for example if you have host A and B and you are accessing host B but istio-ingressgateway is running on host A changing externalTrafficPolicy Cluster to Local would break the traffic. that was the issue I had. or change ingressgateway to run as DaemonSet
|
/cc @incfly |
Does #23292 fix this or is it just a part of it? |
Is there a way to configure the ingress-gateway to run on all nodes via the helm values ? Whats the correct way to do this ? |
Envoy doesn't sanitize XFF headers, you can only set which XFF to use and the trusted proxies in front is supposed to sanitize if needed. The Gateway topology API allows users to easily specify which XFF to choose but doesn't guarantee sanitization. |
🚧 This issue or pull request has been closed due to not having had activity from an Istio team member since 2020-07-27. If you feel this issue or pull request deserves attention, please reopen the issue. Please see this wiki page for more information. Thank you for your contributions. Created by the issue and PR lifecycle manager. |
Describe the bug
X-Forwarded-For
header isn't sanitized before being forwarded by ingress gateway, which means that malicious client can easily spoof its source address by sendingX-Forwarded-For
header with fake IP address, and while the fake IP address won't be used by ingress gateway (because of theuse_remote_address: true
setting), it might be accepted by workloads trusting ingress to pass client's IP using this header.Note that the presence of spoofed
X-Forwarded-For
header results in eitherX-Envoy-Internal
orX-Envoy-External-Address
being forwarded to the workload.Furthermore, even without spoofing, both
X-Forwarded-For
andX-Envoy-External-Address
headers contain IP address ofkube-proxy
(e.g.10.128.0.5
) and not client's IP, rendering it pretty useless.External request:
External request with spoofed
X-Forwarded-For
header:Expected behavior
X-Forwarded-For
header should contain valid client's IP, and ingress gateway should sanitize and/or strip untrusted values before forwarding requests to backend services.Note that we should account for trusted load balancers being deployed in front of ingress gateway and forwarding valid client's IP using this header.
Steps to reproduce the bug
Deploy sample
httpbin
service and expose it via ingress gateway from the official guide and issuecurl
commands mentioned above.Version
Is Istio Auth enabled or not?
n/a
Environment
GKE
cc @louiscryan @costinm @rshriram
The text was updated successfully, but these errors were encountered: