网站建设教程菜鸟教程,做的网站怎么卖出去,宝石网站建设,温州文成县高端网站设计现象
领导反馈生产环境的用户ip有问题。登陆到这个页面#xff0c;发现是所有的用户ip都是172.30.94.97#xff0c;这是个内部网络ip.
排查过程
1 登陆到应用前端nginx#xff0c; 查看nginx的请求日志
172.30.94.97 - - [17/Jul/2024:02:02:54 0000] POST /***/n…现象
领导反馈生产环境的用户ip有问题。登陆到这个页面发现是所有的用户ip都是172.30.94.97这是个内部网络ip.
排查过程
1 登陆到应用前端nginx 查看nginx的请求日志
172.30.94.97 - - [17/Jul/2024:02:02:54 0000] POST /***/notify/my-page HTTP/1.1 200 182 /report/home?type2id2612langzh_CN Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 10.72.44.200
172.30.94.97 - - [17/Jul/2024:02:02:54 0000] POST /***/notify/my-page HTTP/1.1 200 182 /home?langzh_CN Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 10.49.140.102
172.30.94.97 - - [17/Jul/2024:02:02:56 0000] POST /***/msg/notify/my-page HTTP/1.1 200 59 /user/message/info?langzh_CN Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 10.13.52.192
发现第一列展示的ip正好是我们的Java应用代码拿到的iP而真实的ip展示在最后一列
2 查看nginx的日志输出格式。第一列取的是remote_addr变量说明这个变量是有问题的 。我们要取的是最后一列http_x_forwarded_for变量
log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for;3 查看Java代码获取客户ip的逻辑。Java代码从6个Header变量中依次找可以用的ip。 public static String getClientIP(HttpServletRequest request, String... otherHeaderNames) {String[] headers new String[]{X-Forwarded-For, X-Real-IP, Proxy-Client-IP, WL-Proxy-Client-IP, HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR};if (ArrayUtil.isNotEmpty(otherHeaderNames)) {headers (String[])ArrayUtil.addAll(new String[][]{headers, otherHeaderNames});}return getClientIPByHeader(request, headers);} 4 查看nginx传递过来了哪些Header变量。nginx传递过来了X-Real-IP和X-Forwarded-For其中X-Real-IP取的是有问题的remote_addr正好我们Java代码取到的是这个变量。X-Forwarded-For没有值。
location ~ ^/(admin-api|rpc-api)/ {client_max_body_size 32m;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://***:30001;
}
5 根据第二步的分析将remote_addr修改为http_x_forwarded_for 6 重启nginx问题解决
K8S网络拓扑 所有的外部流量一定会通过一个ingress controller进入到K8S的内部。ingress controller的一个常见实现是Nginx正好我们的k8s选择的就是Nginx。也就是说我们的业务前端nginx前面还有一个nginx。所以我们的前端nginx的remote_addr拿到的是k8s入口ingress的内部ip地址。
总结
用户请求经过两层nginx转发才到达后端java业务应用。remote_addr仅存储上一个转发节点的ip所以我们的业务应用一直拿的是ingress的ip。http_x_forwarded_for存储的是原始用户的请求ip。