我在运行NGINX的自托管服务器上有一个带有外部负载均衡器的Kubernetes集群。我试图激活proxy_protocol以获取客户端的real_ip,但NGINX日志是
2020/05/11 14:57:54 [error] 29614#29614: *1325 broken header: "▒▒▒▒▒▒▒Ωߑa"5▒li<c▒*▒ ▒▒▒s▒ ▒6▒▒▒▒▒X▒▒o▒▒▒E▒▒i▒{ ▒/▒0▒+▒,̨̩▒▒ ▒▒
▒▒/5▒" while reading PROXY protocol, client: 51.178.168.233, server: 0.0.0.0:443下面是我的NGINX配置文件:
worker_processes 4;
worker_rlimit_nofile 40000;
events {
worker_connections 8192;
}
stream {
upstream rancher_servers_http {
least_conn;
server <IP_NODE_1>:80 max_fails=3 fail_timeout=5s;
server <IP_NODE_2>:80 max_fails=3 fail_timeout=5s;
server <IP_NODE_3>:80 max_fails=3 fail_timeout=5s;
}
server {
listen 80;
proxy_protocol on;
proxy_pass rancher_servers_http;
}
upstream rancher_servers_https {
least_conn;
server <IP_NODE_1>:443 max_fails=3 fail_timeout=5s;
server <IP_NODE_2>:443 max_fails=3 fail_timeout=5s;
server <IP_NODE_3>:443 max_fails=3 fail_timeout=5s;
}
server {
listen 443 ssl proxy_protocol;
ssl_certificate /certs/fullchain.pem;
ssl_certificate_key /certs/privkey.pem;
proxy_pass rancher_servers_https;
proxy_protocol on;
}
}这是我的入口控制器的configmap:
apiVersion: v1
data:
compute-full-forwarded-for: "true"
proxy-body-size: 500M
proxy-protocol: "true"
use-forwarded-headers: "true"
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"v1","data":null,"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"ingress-nginx"},"name":"nginx-configuration","namespace":"ingress-nginx"}}'
creationTimestamp: "2019-12-09T13:26:59Z"
labels:
app: ingress-nginx
name: nginx-configuration
namespace: ingress-nginx在我添加proxy_protocol指令之前,一切都很好,但是现在我得到了所有这些broken headers错误,并且在没有connection reset错误的情况下,我无法访问到入口后面的任何服务。
我的配置有什么问题?
我应该使用http反向代理而不是tcp反向代理吗?
谢谢。
我还应该说,我的集群中没有任何类型的LoadBalancer服务。我应该要一个吗?我正在考虑Metallb,但我不知道它会给我的配置增加什么,因为我已经在用nginx对节点进行负载平衡。
发布于 2020-05-16 00:24:17
Nginx允许您指定是在传入请求还是传出请求中使用proxy_protocol,并且您混淆了这两个请求。
要在传入连接中使用proxy_protocol,必须将proxy_protocol添加到listen行,如下所示:
listen 443 ssl proxy_protocol;要在传出连接中使用proxy_protocol,必须使用独立的proxy_protocol指令,如下所示:
proxy_protocol on;他们不一样。在负载均衡器中,传入的连接来自不使用代理协议的浏览器。您只希望在发出的请求中使用代理协议,到kubernetes集群中的nginx入口。
因此,从proxy_protocol指令中删除listen参数,它应该可以工作。
此外,您还需要在nginx-ingress配置中使用use-forwarded-headers: "false"。它控制着是否使用X-Forwarded-For & co。传入连接中的头(从nginx入口(从负载均衡器传出)的角度来看),并且在这些连接中使用代理协议而不是头。启用它后,您的用户可以通过指定X转发-For来欺骗IP,这可能是一个安全问题。(只有当nginx-ingress优先于代理协议的报头时(我不确定)
旁白:nginx-入口本身已经负载平衡了所有豆荚之间的流量。使用您的体系结构,您将运行两层负载平衡器,这可能是不必要的。如果您想简化,请强制nginx在单个节点上运行(例如,使用nodeSelector ),并将所有通信量发送到该节点。如果希望将负载均衡器保持在专用机器上,则可以将第4台计算机加入集群,并确保它只运行nginx入口(带有污染和公差)。
另外,请确保您正在使用hostNetwork运行nginx-ingress : true,否则可能会有另一层平衡( kubernetes,kubernetes服务代理)。
https://serverfault.com/questions/1017914
复制相似问题