markhuyong / git-favorites

pocket collenction arititcles
Apache License 2.0
2 stars 0 forks source link

代理协议Proxy protocol #6

Open markhuyong opened 2 years ago

markhuyong commented 2 years ago

https://mp.weixin.qq.com/s?src=11&timestamp=1641883311&ver=3551&signature=qVHH9xarhyeY4wA8NFsQVayJUpTLuZtjefF4UTbvHKEz4B4L9zcC522E5EoHR1a-cEfFBcsHQV1d3fn1y0Qdv*6LGaxE2lZNTdUNsZKEhjHxTYXEWAKL3MVusQwmxO0V&new=1

github-actions[bot] commented 2 years ago

代理协议Proxy protocol by 点融黑帮

前言

Nginx获取用户真实IP是个常见的需求,基本上现在所有HTTP的项目都会使用Nginx做反向代理、负载均衡等。

但是在某些复杂的网络及架构下,Nginx获取用户IP就不是那么容易了。

一般在做7层代理时,我们会通过添加XFF头来传递用户真实IP,这还比较方便。

但是如果Nginx前面还有一个做4层代理的HAProxy时,获取用户真实IP就不是那么容易了。

这时用代理协议会特别的爽。

一、代理协议

代理协议(Proxy protocol),是HAProxy的作者Willy Tarreau于2010年开发和设计的一个Internet协议,通过为tcp添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等),在网络情况复杂又需要获取用户真实IP时非常有用。

代理协议分为V1和V2两个版本,V1是人类易读的,V2是二进制格式的。

由于Nginx目前只支持V1版本,所以这里只先简单介绍下V1版本的格式。

Proxy protocol V1的格式如下:

PROXY 协议栈 源IP 目的IP 源端口 目的端口rn

例如:

PROXY TCP4 213.103.23.88 10.0.0.2 49863 8080rn

二、配置示例

下面介绍一个简单场景下的配置示例:

HAProxy(4层tcp代理) --> Nginx(7层http代理)

HAProxy配置示例

HAProxy作为sender时配置非常简单,在server段添加 send-proxy,例如:

server lb1 10.0.0.2:8080 maxconn 10000 check send-proxy

server lb1 10.0.0.2:8443 maxconn 10000 check send-proxy

Nginx配置示例

Nginx作为reciver时配置也非常简单,在listen段添加 proxy_protocol,例如:

listen 8080 proxy_protocol;

listen 8443 ssl proxy_protocol;

Nginx启用proxy_protocol后,可通过real_ip模块从proxy_protocol头中获取用户真实IP并替换remote_addr,配置如下:

set_real_ip_from 0.0.0.0/16;

real_ip_header proxy_protocol;

三、坑在最后

要使用Proxy protocol需要两个角色sender和receiver,sender在与receiver之间建立连接后,会先发送一个带有客户信息的tcp header,因为更改了tcp协议,需receiver也支持Proxy protocol,否则不能识别tcp包头,导致无法成功建立连接。

而对于Nginx来说listen段中的proxy_protocol配置是针对监听端口生效的,所以虽然是在server的listen段中配置,实际上对于端口来说算是全局配置。

所以对于同一个Nginx上如果有部分server需要代理协议,部分server不需要代理协议。他们所监听的端口一定要分开,例如:

listen 80;

listen 8080 proxy_protocol;

12

往期精彩

· 安卓Xposed框架入门

· 何为“产品力”?

· 像素艺术中的等距图形

· Lambda Expression of Java