代理協議Proxy protocol
前言
Nginx獲取用戶真實IP是個常見的需求,基本上現在所有HTTP的項目都會使用Nginx做反向代理、負載均衡等。
但是在某些複雜的網路及架構下,Nginx獲取用戶IP就不是那麼容器了。
一般在做7層代理時,我們會通過添加XFF頭來傳遞用戶真實IP,這還比較方便。
但是如果Nginx前面還有一個做4層代理的HAProxy時,獲取用戶真實IP就不是那麼容易了。
這時用代理協議會特別的爽。
GIF
一、代理協議
代理協議(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;


TAG:點融黑幫 |