保持客戶端源IP
本文中含有需要您注意的重要提示信息,忽略該信息可能對您的業(yè)務(wù)造成影響,請務(wù)必仔細閱讀。
全球加速 GA(Global Accelerator)支持保持客戶端源IP功能,后端服務(wù)器可以通過該功能獲取發(fā)起訪問的客戶端源IP。本文為您介紹在不同場景中如何開啟保持客戶端源IP功能以及后端服務(wù)器如何獲取客戶端源IP。
前提條件
您已經(jīng)在全球加速實例中配置了監(jiān)聽。具體操作,請參見添加和管理智能路由類型監(jiān)聽。
背景信息
通過全球加速服務(wù)加速客戶端訪問后端服務(wù)器,默認情況下后端服務(wù)器只能獲取客戶端通過全球加速訪問后端服務(wù)器的終端節(jié)點組出公網(wǎng)IP,不能獲取客戶端的源IP。如果您需要后端服務(wù)器能獲取客戶端的源IP,您可以開啟全球加速的保持客戶端源IP功能。全球加速保持客戶端源IP功能根據(jù)監(jiān)聽協(xié)議的不同,支持的情況也不同:
HTTP和HTTPS:支持保持客戶端源IP功能。全球加速將客戶端源IP保存在HTTP請求頭的
X-Forwarded-For
字段中,后端服務(wù)器可以通過X-Forwarded-For
字段獲取客戶端源IP。UDP:不支持保持客戶端源IP功能。
TCP:支持保持客戶端源IP功能。但根據(jù)后端服務(wù)類型不同,需要后端服務(wù)器做相應(yīng)適配以獲取客戶端源IP。關(guān)于適配說明,請參見下表:
后端服務(wù)部署地
后端服務(wù)類型
是否支持獲取客戶端源IP
是否需要后端服務(wù)器適配
說明
阿里云
阿里云公網(wǎng)IP
與所綁定實例是否支持獲取客戶端源IP有關(guān):
綁定專有網(wǎng)絡(luò)類型ECS實例:支持
綁定NLB實例:支持
綁定ALB實例:不支持
綁定私網(wǎng)CLB實例:支持
綁定公網(wǎng)NAT實例:支持
警告當終端節(jié)點為阿里云公網(wǎng)IP時,如果該公網(wǎng)IP解綁原有實例并重新綁定至其他實例,可能會導致保持客戶端源IP的能力失效,并造成流量中斷。為恢復該終端節(jié)點保持客戶端源IP的能力,您可以刪除并重建相應(yīng)的終端節(jié)點,或者聯(lián)系商務(wù)經(jīng)理協(xié)助處理。
綁定ECS實例:不需要
綁定NLB實例:需要
綁定私網(wǎng)CLB實例:不需要
綁定公網(wǎng)NAT實例:
2022年10月之前創(chuàng)建的存量NAT網(wǎng)關(guān)實例:需要
2022年10月之后創(chuàng)建的NAT網(wǎng)關(guān)實例:不需要
需要:在您開啟保持客戶端源IP功能的情況下,全球加速會使用Proxy Protocol保持客戶端源IP,此時需要后端服務(wù)器支持解析Proxy Protocol,才能獲取到客戶端源IP信息。
重要如果您的后端服務(wù)器不支持解析Proxy Protocol,則會導致后端服務(wù)器無法正確解析加速流量。
不需要:在您開啟保持客戶端源IP功能后,后端服務(wù)器可直接獲取發(fā)起訪問的客戶端源IP,無需添加任何配置。
ECS
支持
但必須為專有網(wǎng)絡(luò)類型,且ECS所在安全組需放通所有客戶端源IP。
不需要
ENI
支持
但需要ENI所在安全組放通所有客戶端源IP。
OSS
不支持
交換機
默認不支持
如需保持客戶端源IP,請向商務(wù)經(jīng)理申請。
CLB
支持
但需要CLB的后端服務(wù)器所在安全組放通所有客戶端源IP。
請注意在以下情形中,后端服務(wù)器無法獲取客戶端源IP:
您的CLB實例的后端服務(wù)器為經(jīng)典網(wǎng)絡(luò)類型的ECS實例。
您的CLB實例的監(jiān)聽協(xié)議為HTTP或HTTPS。
ALB
不支持
NLB
支持
需要
非阿里云
自定義IP
支持
需要
自定義域名
支持
Proxy Protocol是一種Internet協(xié)議,通過為TCP報文添加Proxy Protocol報頭來獲取客戶端源IP。
Proxy Protocol的接收端必須在接收到完整有效的Proxy Protocol頭部后才能開始處理連接數(shù)據(jù),因此對于服務(wù)器中的同一個監(jiān)聽端口,不能同時接收攜帶Proxy Protocol和未攜帶Proxy Protocol的連接請求。如果接收到的第一個數(shù)據(jù)包不符合Proxy Protocol格式,那么服務(wù)器會直接終止連接。
通過HTTP或HTTPS監(jiān)聽協(xié)議加速訪問后端服務(wù)
如果您通過HTTP或HTTPS監(jiān)聽協(xié)議加速您后端服務(wù)的訪問,默認開啟保持客戶端源IP功能,后端服務(wù)器可直接通過HTTP請求頭的X-Forwarded-For
字段獲取客戶端源IP。
開啟保持客戶端源IP。
HTTP和HTTPS監(jiān)聽協(xié)議默認開啟保持客戶端源IP功能,并將客戶端源IP保存在HTTP請求頭的
X-Forwarded-For
字段中,您可以通過X-Forwarded-For
獲取客戶端源IP。獲取客戶端源IP。
后端服務(wù)器收到的HTTP請求頭中的
X-Forwarded-For
字段如下,其中第一個IP即為客戶端源IP。X-Forwarded-For: 客戶端源IP, 代理服務(wù)器1-IP, 代理服務(wù)器2-IP,...
通過TCP監(jiān)聽協(xié)議加速訪問阿里云后端服務(wù)
如果您通過TCP監(jiān)聽協(xié)議加速您的后端服務(wù)訪問,且您的后端服務(wù)部署在阿里云上,那么您開啟保持客戶端源IP功能后,后端服務(wù)器可直接獲取客戶端源IP信息。
開啟保持客戶端源IP。
登錄全球加速管理控制臺。
在實例列表頁面,找到目標全球加速實例,在操作列單擊配置監(jiān)聽。
在監(jiān)聽頁簽下,找到目標監(jiān)聽,在操作列單擊編輯監(jiān)聽。
在配置監(jiān)聽和協(xié)議配置向?qū)ы撁妫瑔螕?b data-tag="uicontrol" id="uicontrol-te2-m14-fl8" class="uicontrol">下一步。
在配置終端節(jié)點配置向?qū)ы撁妫?b data-tag="uicontrol" id="3a55059b3f31t" class="uicontrol">保持客戶端源IP列表中選擇保持,然后單擊下一步。
當后端服務(wù)部署在阿里云上時,獲取客戶端真實IP方式默認選擇為自動獲取。
自動獲取:IPv4客戶端訪問后端服務(wù),推薦使用此方式。此方式可以自動獲取客戶端IP,后端服務(wù)無需做任何改動。當后端服務(wù)部署在非阿里云時,不支持使用該方式。
ProxyProtocol:IPv6客戶端訪問后端服務(wù),推薦使用此方式。此方式需要后端服務(wù)器支持解析Proxy Protocol,才能獲取到客戶端源IP信息。
更多信息,請參見背景信息。
在配置審核頁面,確認無誤后,單擊提交。
獲取的客戶端源IP。
本部分以后端服務(wù)類型為阿里云Linux ECS實例為例,介紹如何查看已獲取的客戶端源IP。
登錄后端Linux ECS服務(wù)器。
執(zhí)行以下命令,抓取HTTP流量。
tcpdump tcp port [監(jiān)聽端口] -n -X -s 0
從抓取的數(shù)據(jù)包中篩選信息,查看客戶端源IP。
經(jīng)測試,開啟保持客戶端源IP功能后,可以在后端服務(wù)器查看客戶端源IP。
未開啟保持客戶端源IP功能,只能在后端服務(wù)器上查看到客戶端通過全球加速訪問后端服務(wù)器的終端節(jié)點組出公網(wǎng)IP。
通過TCP監(jiān)聽協(xié)議加速訪問非阿里云后端服務(wù)
如果您通過TCP監(jiān)聽協(xié)議加速您的后端服務(wù)訪問,且您的后端服務(wù)部署在非阿里云上,那么您的后端服務(wù)需要支持解析Proxy Protocol,才能獲取到客戶端源IP。本部分以Nginx為例,為您說明后端服務(wù)如何支持解析Proxy Protocol以及如何獲取客戶端源IP。
開啟保持客戶端源IP。
登錄全球加速管理控制臺。
在實例列表頁面,找到目標全球加速實例,在操作列單擊配置監(jiān)聽。
在監(jiān)聽頁簽下,找到目標監(jiān)聽,在操作列單擊編輯監(jiān)聽。
在配置監(jiān)聽和協(xié)議配置向?qū)ы撁妫瑔螕?b data-tag="uicontrol" id="uicontrol-te2-m14-fl8" class="uicontrol">下一步。
在配置終端節(jié)點配置向?qū)ы撁妫?b data-tag="uicontrol" id="a39329aa73cmj" class="uicontrol">保持客戶端源IP頁簽下選擇保持,然后單擊下一步。
當后端服務(wù)部署在非阿里云上時,獲取客戶端真實IP方式默認選擇為ProxyProtocol。
自動獲取:IPv4客戶端訪問后端服務(wù),推薦使用此方式。此方式可以自動獲取客戶端IP,后端服務(wù)無需做任何改動。當后端服務(wù)部署在非阿里云時,不支持使用該方式。
ProxyProtocol:IPv6客戶端訪問后端服務(wù),推薦使用此方式。此方式需要后端服務(wù)器支持解析Proxy Protocol,才能獲取到客戶端源IP信息。
更多信息,請參見背景信息。
在配置審核頁面,確認無誤后,單擊提交。
配置Nginx使其支持解析Proxy Protocol。
Nginx的
http{}
和stream{}
模塊均可以接收Proxy Protocol,在http{}
模塊或stream{}
模塊中添加相應(yīng)處理Proxy Protocol的端口即可。http { #... server { listen 8080 proxy_protocol; #在8080端口,開啟解析proxy protocol。 #... } } stream { #... server { listen 1235 proxy_protocol; #在1235端口,開啟解析proxy protocol。 #... } }
獲取客戶端源IP。
在開始解析Proxy Protocol后,Nginx會將客戶端源IP保存在變量proxy_protocol_addr中。因此,您可以通過以下兩種方式獲取客戶端源IP:
對于HTTP流量,您可以將客戶端源IP保存在HTTP請求頭字段中:
http { proxy_set_header X-Real-IP $proxy_protocol_addr; proxy_set_header X-Forwarded-For $proxy_protocol_addr; }
后端服務(wù)器通過HTTP請求頭中的
X-Forwarded-For
字段獲取源IP,其中第一個IP即為客戶端源IP。X-Forwarded-For: 客戶端源IP, 代理服務(wù)器1-IP, 代理服務(wù)器2-IP,...
對于HTTP流量或TCP流量,您也可以將客戶端源IP保存在日志中,然后通過日志信息獲取客戶端源IP。
設(shè)置
http{}
模塊和stream{}
模塊的日志格式,將客戶端源IP信息保存到日志中。http { #... log_format combined '$proxy_protocol_addr - $remote_user [$time_local] ' ##在http{}模塊的日志格式中添加保存客戶端源IP的變量proxy_protocol_addr。 '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; } #... stream { #... log_format basic '$proxy_protocol_addr - [$time_local] ' ##在stream{}模塊的日志格式中添加保存客戶端源IP的變量proxy_protocol_addr。 '$protocol $status $bytes_sent $bytes_received ' '$session_time'; }
通過以下命令查看日志信息,獲取客戶端源IP。
tail -n -5 <日志路徑>
以下內(nèi)容為您展示一個完整的配置示例:
worker_processes 4; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$proxy_protocol_addr $remote_addr - $remote_user [$time_local] "$request" '##在http{}模塊日志格式中添加保存客戶端源IP的變量proxy_protocol_addr。 '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; sendfile on; keepalive_timeout 65; upstream backend { server 192.XX.XX.36:8080; server 192.XX.XX.37:8080; keepalive 2000; } server { listen 80 proxy_protocol; ##在80端口,開啟解析proxy protocol。 server_name example.com; proxy_set_header X-Real-IP $proxy_protocol_addr; ##在發(fā)給后端服務(wù)時,將客戶端源IP信息插入到HTTP中。 proxy_set_header X-Forwarded-For $proxy_protocol_addr; access_log /var/log/nginx/access.log main; location / { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; } } } stream { log_format tcp_basic '$proxy_protocol_addr - [$time_local] ' ##在stream{}模塊的日志格式中添加保存客戶端源IP的變量proxy_protocol_addr。 '$protocol $status $bytes_sent $bytes_received ' '$session_time'; upstream stream_backend { server 192.XX.XX.36:2003; server 192.XX.XX.37:2003; } server { listen 1234 proxy_protocol; ##在1234端口,開啟解析proxy protocol。 access_log /var/log/nginx/access_tcp.log tcp_basic; proxy_pass stream_backend; } }
查看日志信息,其中日志信息中的第一個IP地址即為客戶端源IP。