Problem Description
Service in the namespace with the tag of istio-injection: enabled
cannot obtain the real IP of the client through X-Forwarded-For
.
Solution
Upgrade Istio
Check and upgrade the Istio version to 1.7
or higher.
Set up externalTrafficPolicy
Set externalTrafficPolicy
to Local
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: istiocontrolplane
spec:
profile: default
components:
ingressGateways:
- name: istio-ingressgateway
enabled: true
k8s:
service:
externalTrafficPolicy: Local
Wait for the ingressgateway redeployment to complete.
Next, deploy the httpbin
service as a verification.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# httpbin.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "httpbin.makeoptim.com"
gateways:
- gateway/makeoptim-gateway
http:
- route:
- destination:
port:
number: 8000
host: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
spec:
ports:
- name: http
port: 8000
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
containers:
- image: docker.io/citizenstig/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 8000
After deploying httpbin
, directly visit and view Headers
, you can see that there is an additional X-Envoy-External-Address
header, and it points to the real IP of the client.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
❯ curl httpbin.makeoptim.com/get
{
"args": {},
"headers": {
"Accept": "*/*",
"Content-Length": "0",
"Host": "httpbin.makeoptim.com",
"User-Agent": "curl/7.64.1",
"X-B3-Parentspanid": "50419cd0b3ae983a",
"X-B3-Sampled": "0",
"X-B3-Spanid": "5a0bbd2e611fa59e",
"X-B3-Traceid": "33c8c481a13746c050419cd0b3ae983a",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-External-Address": "38.75.137.213",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/default;Hash=abb1a2a76a04fe7476cd38738e98a228b39dbf6a88936fd249ee23839ec98234;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account",
"X-Request-Id": "2fe85688-cf60-4f61-b9bb-25e354625124"
},
"origin": "38.75.137.213",
"url": "http://httpbin.makeoptim.com/get"
}
You can get the client’s real IP through X-Envoy-External-Address
header. The following is an example of Golang code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package http
import "net/http"
var clientIPHeaders = []string{"X-Envoy-External-Address", "X-Forwarded-For", "X-Real-Ip", "X-Appengine-Remote-Addr"}
// ClientIP get client IP with possible headers.
func ClientIP(request *http.Request) string {
for _, v := range clientIPHeaders {
ip := request.Header.Get(v)
if ip != "" {
return ip
}
}
return ""
}
Reference
Further reading
- 集群内无法访问外部服务
- configmap istio-ca-root-cert not found
- Istio 支持 HTTP/1.0
- Istio 自定义 Ingress(入口)网关
- 如何为公开多个端口的服务配置 VirtualService?
- no matches for kind “MonitoringDashboard” in version “monitoring.kiali.io/v1alpha1”
- Kubernetes LoadBalancer Service External IP 一直处于 pending 状态
- Set up IP White/Black Listing for services