由于大部分内容分发网络(Content Delivery Network)都是使用反向代理的原理进行网站加速,这就产生了一个令人非常困惑的问题。CDN不仅隐藏了服务器/源站的IP,与此同时分布式CDN节点还代理了用户请求IP。以至于造成客户端认为CDN IP是服务器IP,服务器获取到的请求IP则全部来源于分布式CDN节点(理应如此,CDN实现了客户端对源站访问的透明)。上述问题在Nginx中可以通过自定义access_log日志来解决。
Nginx 日志两条主要的指令:
- log_format:用来设置日志格式;
- access_log:用来指定日志文件的存放路径、格式(把定义的log_format
跟在后面)和缓存大小;如果不想启用日志则access_log off ;
log_format 日志格式
- 语法:
log_format name(格式名字) 格式样式(即想要得到什么样的日志内容)log_format cdn '$http_x_forwarded_for - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';
-
参数 说明 示例 $remote_addr 客户端地址 123.45.67.89 $remote_user 客户端用户名称 --- $time_local 访问时间和时区 13/Jul/2018:22:23:59 +0800 $time_iso8601 ISO标准格式下的本地时间 $request 请求的URL和HTTP协议 "GET /article.html HTTP/1.1" $http_host 请求地址,及输入的IP/域名 www.google.com $status HTTP请求状态 200 $upstream_status upstream请求状态 200 $body_bytes_sent 发给客户端文件内容大小 1547 $http_referer url跳转来源 $https_user_agent 用户终端浏览器等信息 "Mozilla/4.0 ........" $request_time 整个请求的总时间 0.350 $ssl_protocol SSL协议版本 TLSv1
- x_forwarded_for:通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_addr拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
首先,将下列代码添加到nginx.conf文件的http模块后面,并让日志重置:
#自定义一个日志格式
#局限性:通过CDN的访问是用$http_x_forwarded_for来记录IP,倘若未使用CDN访问,则无法获取访问者IP。
log_format cdn '$http_x_forwarded_for - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
然后,修改nginx站点conf配置文件中的日志输出格式,修改access_log /home/wwwlogs/***.log; 为access_log /home/wwwlogs/***.log cdn; 即可。输入下列指令以检测Nginx配置是否正确,而后重启Nginx。
nginx -t
service nginx reload
#该方法适用于关闭CDN后,Nginx不需要变更获取IP的方法,兼容性较好。
#修改Nginx配置文件 /usr/local/nginx/conf/nginx.conf 文件,添加在 http 字段中:
map $HTTP_CF_CONNECTING_IP $clientRealIp
{
"" $remote_addr;
~^(?P[a-z0-9.:]+),?.*$ $firstAddr;
}
log_format access '$clientRealIp [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'$http_user_agent $remote_addr $request_time';
#然后再修改当前站点/usr/local/nginx/conf/vhost/*****.conf 日志记录后加上 access
access_log /www/wwwlogs/*****.log access;
#重启Nginx
service nginx reload
Nginx的$http_x_forwarded_for属性起了至关重要的作用~