CDN环境下Nginx访问日志记录请求源IP

由于大部分内容分发网络(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
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注