背景信息
使用CDN加速服务后,用户访问链路变为:客户端 → 加速节点 → 源站。因此,源站默认获取的访问IP是CDN节点的IP,而非客户端的真实IP,这会影响访问数据的准确统计。
为解决此问题,需要在源站上进行相应配置,以获取客户端的真实IP。阿里云CDN默认通过ali-cdn-real-ip请求头将客户端IP透传至源站。
说明
ali-cdn-real-ip获取的是与CDN节点直接建立连接的客户端IP。如果客户端通过其他代理访问CDN,则该请求头获取到的是代理服务器的IP。
操作步骤
本文以Nginx源站为例,介绍如何通过修改Nginx配置,实现以下三种方式获取客户端真实IP:
在Nginx访问日志中记录客户端真实IP。
在响应头中添加包含客户端真实IP的自定义字段。
通过特定接口,在响应体中直接返回客户端真实IP。
配置自定义日志格式
通过log_format指令定义新的日志格式custom_log,在默认日志信息的基础上,增加$http_ali_cdn_real_ip变量来记录ali-cdn-real-ip请求头的值。
log_format custom_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'ali_cdn_real_ip:"$http_ali_cdn_real_ip"';配置测试接口
通过location指令配置/api/ip接口,用于直接返回客户端真实IP。
location /api/ip {
# Obtain the client's real IP address from the request header.
set $real_ip $http_ali_cdn_real_ip;
# Add the real IP address to the response header.
add_header realip $real_ip;
# Set the response content type (optional, but recommended).
add_header Content-Type text/plain;
# Return the value of the request header to the response body.
return 200 $real_ip;
}完整配置示例
以下为完整的Nginx配置文件示例,请根据实际情况替换server_name等参数。
重要
修改Nginx配置之后,需要重启Nginx该配置才能生效。
使用该配置时,需要配置CDN的默认回源HOST,并且回源HOST的值必须和
server_name保持一致。
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Customize log format by adding the ali_cdn_real_ip field.
log_format custom_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'ali_cdn_real_ip:"$http_ali_cdn_real_ip"';
sendfile on;
keepalive_timeout 65;
# Gzip Settings
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
server {
listen 80;
# Please replace it with your accelerated domain name.
server_name localhost;
# Use custom log format
access_log /var/log/nginx/access.log custom_log;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# Interface used to obtain the client's real IP address
location /api/ip {
# Obtain the client's real IP address from the request header.
set $real_ip $http_ali_cdn_real_ip;
# Add the real IP address to the response header.
add_header realip $real_ip;
# Set the response content type (optional, but recommended).
add_header Content-Type text/plain;
# Return the value of the request header to the response body.
return 200 $real_ip;
}
# Error page configuration
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# For HTTPS configuration, please refer to the following configuration.
# server {
# listen 443 ssl;
# server_name localhost; # Please replace it with your accelerated domain name.
#
# ssl_certificate /path/to/cert.pem;
# ssl_certificate_key /path/to/privkey.pem;
#
# access_log /var/log/nginx/access.log custom_log;
#
# location /api/ip {
# set $real_ip $http_ali_cdn_real_ip;
# add_header realip $real_ip;
# add_header Content-Type text/plain;
# return 200 $real_ip;
# }
# }
}结果验证
验证响应头和响应体
通过CDN加速域名访问/api/ip接口。
响应头中包含
realip字段,其值为客户端真实IP。
响应体内容为客户端真实IP。

验证访问日志
在源站服务器上查看Nginx的访问日志(默认为/var/log/nginx/access.log)。日志中已成功记录ali_cdn_real_ip字段及其值。
