这篇文章主要介绍“Tomcat怎么获取Nginx代理后的真实客户端IP地址”,在日常操作中,相信很多人在Tomcat怎么获取Nginx代理后的真实客户端IP地址问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Tomcat怎么获取Nginx代理后的真实客户端IP地址”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
在传统的架构中,中小型企业采用Nginx+Tomcat这种架构时,客户端请求将由Nginx转发至后端Tomcat,当有需求在Tomcat日志中也能看到客户端真实IP地址的情况下,我们就需要使用到Nginx的 proxy_set_header指令来进行协助,而且还需要修改Tomcat对于 localhost_access 的日志格式,要不然tomcat记录的访客IP全都是Nginx的, 这是因为所有的请求都是由Nginx前端服务器转发而来的。
Nginx配置日志格式
Nginx需要先获取到客户端的真实IP地址后才能将客户端真实IP地址发送到后端Tomcat,所以也需要配置Nginx的日志格式,在Nginx代理Tomcat的日志格式中最为重要的配置为 $remote_addr
来获取到真实客户端IP地址,我这里的Nginx日志格式如下:
log_format main '$remote_addr" "$remote_user" "[$time_local]" "$request"' ' "$status" "$body_bytes_sent" "$http_referer"' ' "$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio"' ' "$upstream_addr" "$request_time" "$upstream_response_time" "$http_host"';
有关更多Nginx日志格式请见:https://k8sops.cn/nginx_log_module/
Nginx配置转发IP头
proxy_set_header指令可以配置到 http, server, location 三个配置段当中,我这里配置到 location 字段中。
location ^~ /crm-newm { proxy_pass http://172.26.3.55:8086; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Port $proxy_port; proxy_set_header X-Real-IP $remote_addr; }
proxy_http_version指令解析: proxy_http_version指令用于设置代理的HTTP协议版本。默认情况下,使用的是1.0版。建议将版本1.1用于keepalive连接和NTLM身份验证
Syntax: proxy_http_version 1.0 | 1.1; Default: proxy_http_version 1.0; Context: http, server, location
proxy_set_header proxy_set_header指令用于重新定义header或将字段附加到代理服务器的请求头中。该值可以包含文本、变量、或者文本变量的组合。
proxy_set_header Host $host; Host为自定义文本,$host
变量为Nginx中的内置变量,用于获取当前主机名
proxy_set_header Port $proxy_port; Port为自定义文本,$proxy_port
变量也是为Nginx中的内置变量,用于获取nginx代理的主机端口
proxy_set_header X-Real-IP $remote_addr; X-Real-IP为自定义文本,$remote_addr
变量也是Nginx中的内置变量,用于获取真实客户端IP地址,与Nginx中的$remote_addr
一致
以上配置对于HTTP头部内容,这些变量是不区分大小写的
Tomcat日志格式讲解
在tomcat家目录下的 conf/server.xml 文件中,定位到 logs 字段来修改tomcat日志格式
vim conf/server.xml <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
prefix prefix用于指定tomcat 访问日志的前缀
suffix suffix用于指定tomcat 访问日志的后缀
pattern pattern用于指定tomcat 访问日志的输出格式
访问日志支持的格式如下:
%a - 远程IP地址 %A - 本地IP地址 %b - 发送的字节数,不包括HTTP头,或“ - ”如果没有发送字节 %B - 发送的字节数,不包括HTTP头 %h - 远程主机名 %H - 请求协议 %l - (小写的L)- 远程逻辑从identd的用户名(总是返回' - ') %m - 请求方法 %p - 本地端口 %q - 查询字符串(在前面加上一个“?”如果它存在,否则是一个空字符串 %r - 第一行的要求 %s - 响应的HTTP状态代码 %S - 用户会话ID %t - 日期和时间,在通用日志格式 %u - 远程用户身份验证 %U - 请求的URL路径 %v - 本地服务器名(访问域名) %D - 处理请求的时间(以毫秒为单位) %T - 处理请求的时间(以秒为单位) %I -(大写的i) - 当前请求的线程名称
另外,还可以将request请求的查询参数、session会话变量值、cookie值或HTTP请求/响应头内容的变量值等内容写入到日志文件。 它仿照了apache的语法:
%{XXX}i xxx代表传入的头(HTTP Request) %{XXX}o xxx代表传出的响应头(Http Resonse) %{XXX}c xxx代表特定的Cookie名 %{XXX}r xxx代表ServletRequest属性名 %{XXX}s xxx代表HttpSession中的属性名
配置Tomcat日志记录客户真实IP
此配置需要修改Tomcat的日志格式来支持记录客户端的真实IP地址,默认是不可以的。 在Nginx+Tomcat架构中使用日志格式中的 %a 是获取不到真实客户端IP地址的,如果直接访问Tomcat那么 %a 可以获取到真实客户端IP地址。 如果要在Nginx+Tomcat架构中记录真实客户端IP地址需要在日志格式中添加 %{X-Real-IP}i
配置来获取, %{X-Real-IP}i
是我们在Nginx location 配置段中指定的文本来获取 $remote_addr
变量值的,在这里将此值传送给 Tomcat。 %{Port}i
也是我们在Nginx中定义的文本来获取后端的转发端口,这里也将值转发至Tomcat。
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%t %{X-Real-IP}i %h:%p %A:%{Port}i %m %s %S %u %H %v %U %b %T %I" />
以上日志输出格式默认以空格做为分割的,以上格式我已经做了排版,tomcat输出访问日志如下:
1. %t 日期和时间 2. %{X-Real-IP}i 客户端真实IP地址 3. %h:%p 远程IP(Nginx代理IP),远程端口(客户端访问Nginx的端口) 4. %A:%{Port}i 本地IP地址及访问的本地端口 5. %m HTTP请求方法 6. %s 请求状态码 7. %S 用户会话ID 8. %u 远程用户身份验证 9. %H HTTP请求协议 10. %v 访问的域名 11. %U 访问的URL 12. %b 发送的字节数,不包括HTTP头,或“ - ”如果没有发送字节 13. %T Tomcat处理请求的时间(以秒为单位) 14. %I (大写的i)当前请求的线程名称
到此,关于“Tomcat怎么获取Nginx代理后的真实客户端IP地址”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
原创文章,作者:1402239773,如若转载,请注明出处:https://blog.ytso.com/236089.html