场景介绍: 有的时候nginx后续需要安装新的模块 比如服务器的nginx日志需要记录clb(负载均衡)转发过来的真实客户端ip,而不是clb的内网ip,此时需要有安装--with-http_realip_module
模块的检测安装
检测版本
nginx -V
(注意是大写的V) 查看对应的nginx版本 以及当时的 configure arguments:
即当时编译安装的nginx参数项 是否有你要的 --with-http_realip_module 配置,如果有了就直接后续改配置,如果没有那就先安装对应的模块
[root@xxx local]# nginx -V
nginx version: nginx/1.10.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-ipv6 --with-http_sub_module
模块安装
#下载对应版本的nginx
cd /usr/local/src/
wget http://nginx.org/download/nginx-x.x.x.tar.gz
#解压进入对应版本的nginx源码包
tar zxf nginx-x.x.x.tar.gz
cd /usr/local/src/nginx-x.x.x
#在原配置的基础上加上你想要补充安装的模块 --with-http_realip_module
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-ipv6 --with-http_sub_module --with-http_realip_module
#检测配置并编译(切记不需要make install)
echo $?
0
make
#编译完成后会在当前目录下生成一个 objs/nginx 二进制文件
备份源文件并替换nginx的二进制文件
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
cp objs/nginx /usr/local/nginx/sbin/nginx
再次验证模块是否安装
[root@xxx local]# nginx -V
nginx version: nginx/1.10.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-ipv6 --with-http_sub_module --with-http_realip_module
配置nginx记录负载均衡代理的真实客户端IP
查看原clb的内网ip段
#查看项目对应配置的access_log 文件
100.122.17.53 - - [03/Aug/2023:16:49:15 +0800] "GET / HTTP/1.1" 200 332 "-" "curl/7.68.0"
100.122.17.39 - - [03/Aug/2023:16:49:16 +0800] "GET / HTTP/1.1" 200 332 "-" "curl/7.68.0"
100.122.17.34 - - [03/Aug/2023:16:49:35 +0800] "GET / HTTP/1.1" 200 257 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
100.122.17.32 - - [03/Aug/2023:16:49:37 +0800] "GET /favicon.ico HTTP/1.1" 200 16958 "https://ht.xckeji1.cn/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
100.122.17.112 - - [03/Aug/2023:16:50:59 +0800] "GET / HTTP/1.1" 200 332 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:47.0) Gecko/20100101 Firefox/47.0"
100.122.17.35 - - [03/Aug/2023:16:51:15 +0800] "GET / HTTP/1.1" 200 257 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
...
#得知上面的clb内网ip段是 100.122.17.xx
修改配置获取真实IP
nginx.conf 中的 http 块配置日志格式
http
{
...
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
...
}
对应项目的 www.xxx.com.conf 中的 最后一个 location /
入口块配置set_real_ip_from,因为我的所有项目的配置最后都有加 include php.conf;
且有最后的 location 入口配置,所以我的配置写在了php.conf 中
location ~ [^/]\.php(/|$)
{
...
set_real_ip_from 100.122.0.0/16;
real_ip_header X-Forwarded-For;
...
}
注意:阿里云的CLB真实的客户端源IP默认存放在HTTP头部的X-Forwarded-For字段,格式类似于 X-Forwarded-For: <用户真实IP, 代理服务器1-IP, 代理服务器2-IP,...> 如果是自建的负载均衡需要自行配置转发客户端的ip到 X-Forwarded-For 的header头中
检测真实ip获取
nginx -t
,nginx -s reload
检测配置并重启,而后访问你的站点再次查看对应的日志文件的ip是否是你的客户端真实ip,正常情况下此时的 $remote_addr 应该获取的就是真实ip,"$http_x_forwarded_for" 一般还是为空 这个是客户端使用了代理的情况下才记录
参考地址:
nginx添加未被编译的模块
保留客户端真实源地址