Nginx real_ip_header 通过 GCE 入口?
Posted
技术标签:
【中文标题】Nginx real_ip_header 通过 GCE 入口?【英文标题】:Nginx real_ip_header through a GCE ingress? 【发布时间】:2018-07-17 18:07:18 【问题描述】:我的目标是通过 GCE 入口通过 nginx 服务的 Kubernetes Engine 上部署的 Angular 应用的 IP 地址过滤访问。
但在我的 nginx 上,remote_addr 不正确。
$LB_IP 是这里定义的 ip:kubernetes.io/ingress.global-static-ip-name: app-angular
我在 nginx 上使用 set_real_ip_from 从 X-Forwarded-For 设置 ip
set_real_ip_from $LB_IP;
real_ip_header X-Forwarded-For;
原始 ip 出现在 X-Forwarded-For 标头中,正如谷歌文档中所预期的那样:https://cloud.google.com/compute/docs/load-balancing/http/#components
我可以看到 X-Forwarded-For 包含 $CLIENT_IP 但 remote_addr 不正确,顺便说一下我的 IP 过滤器不起作用。有什么想法吗?
我的 nginx 日志:
10.40.40.40 - - [07/Feb/2018:11:29:48 +0000] "GET /styles.bundle.css HTTP/1.1" 200 35908 "http://MY_URL/home" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/64.0.3282.140 Safari/537.36" "$CLIENT_IP, $LB_IP"
但我想要:
$CLIENT_IP - - [07/Feb/2018:11:29:48 +0000] "GET /styles.bundle.css HTTP/1.1" 200 35908 "http://MY_URL/home" "Mozilla/5.0 (Macintosh; Intel Mac) OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36" "$CLIENT_IP, $LB_IP"
我的 Ingress 配置:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: app-angular
spec:
rules:
- host: MY_URL
http:
paths:
- backend:
serviceName: app-backend
servicePort: 80
我的后端配置:
apiVersion: v1
kind: Service
metadata:
name: app-backend
spec:
type: NodePort
selector:
app: app-angular
ports:
- port: 80
targetPort: 80
我的部署配置:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app-angular
spec:
replicas: 2
revisionHistoryLimit: 2
template:
metadata:
labels:
app: app-angular
tier: frontend
spec:
containers:
- name: app-angular
image: gcr.io/MY_PROJECT/app-angular:MY_TAG
imagePullPolicy: Always
ports:
- containerPort: 80
我的 nginx 配置:
server
listen 80;
root /usr/share/nginx/html;
location /
set_real_ip_from $LB_IP;
real_ip_header X-Forwarded-For;
allow 130.211.0.0/22; #Google IP
allow $CLIENT_IP; # FILTERED IP
allow 10.0.0.0/8; #internal network
deny all;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
有什么想法吗?
【问题讨论】:
【参考方案1】:它们是两种解决方案(感谢 gcbirzan 帮助我解决 GCP 松弛问题):
1) 使用来自 IP 地址范围的良好 IPS 更新我的 nginx 配置:
IP 地址范围可在此处找到:https://console.cloud.google.com/networking/networks/list。 您可以为一个区域或所有需要的区域添加 set_real_ip_from。 不要忘记 real_ip_recursive on;
server
listen 80;
root /usr/share/nginx/html;
location /
set_real_ip_from 10.128.0.0/20;
...
real_ip_header X-Forwarded-For;
real_ip_recursive on;
allow 130.211.0.0/22; #Google IP
allow $CLIENT_IP; # FILTERED IP
allow 10.0.0.0/8; #internal network
deny all;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
2) 更新我的后端配置:
externalTrafficPolicy:本地
apiVersion: v1
kind: Service
metadata:
name: app-backend
spec:
type: NodePort
selector:
app: app-angular
ports:
- port: 80
targetPort: 80
externalTrafficPolicy: Local
更新 nginx 配置:
现在 $remote_addr 中显示的 IP 将设置为您的客户端请求的负载均衡器 IP 和 google Infra IPS:130.211.0.0/22,35.191.0.0/16
别忘了real_ip_recursive on;
server
listen 80;
root /usr/share/nginx/html;
location /
set_real_ip_from $LB_IP;
set_real_ip_from 130.211.0.0/22;
set_real_ip_from 35.191.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
allow 130.211.0.0/22; #Google IP
allow 35.191.0.0/16; #Google IP
allow $CLIENT_IP; # FILTERED IP
allow 10.0.0.0/8; #internal network
deny all;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
【讨论】:
【参考方案2】:您提供的链接专门针对 GCP 负载平衡器。 至于 nginx 负载均衡器,您应该考虑将 ExternalTrafficPolicy annotation 添加到您的 NodePort 服务以保留客户端 IP。
我还发现了一个可追溯到 2017 年年中的类似问题,表明 certain versions of the nginx controller 存在问题,请确保您使用的图像没有此问题。
最后,您可能需要添加 use-proxy-protocol: "true" with the configuration ConfigMap,因为您使用的入口充当使用代理的 HTTP(S) 负载均衡器。
【讨论】:
感谢您的帮助,我找到了解决方案。 ExternalTrafficPolicy 是一个好方法。最后一点是不可能的:use-proxy-protocol: "true" ,因为我没有使用 nginx-ingress,所以我使用 gce ingress 和 nginx 作为我的 Angular 应用程序的 http 服务器。【参考方案3】:我们在nginx ingress
前面使用HTTP GCLB ingress
。为了让RealIP
工作,我添加了
kind: ConfigMap
apiVersion: v1
metadata:
name: ingress-nginx
labels:
k8s-addon: ingress-nginx.addons.k8s.io
data:
##
## Google Infra Blocks needed
## 130.211.0.0/22,35.191.0.0/16
##
## Google Cloud Load Balancer
## GCLB-IP/32
proxy-real-ip-cidr: 130.211.0.0/22,35.191.0.0/16,[YOUR-GCLB-IP]/32
这允许nginx
信任来自 Google 基础架构的X-Forwarded-For
。
【讨论】:
感谢您的帮助,我找到了解决方案。但我没有使用 nginx-ingress,我使用 gce ingress 和 nginx 作为我的 Angular 应用程序的 http 服务器。 啊。谢谢你的澄清。我将nginx with GCE ingress
的提及混为一谈GCLB Ingress in front of nginx Ingress
。以上是关于Nginx real_ip_header 通过 GCE 入口?的主要内容,如果未能解决你的问题,请参考以下文章