现有代码如下:
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
目前测试服务器,没有 Nginx ,没有域名解析,直接请求服务器的 ip+端口的,实际最后都是走到 ip = request.getRemoteAddr(),然后取到的是 172 开头的 docker 内网 ip ,试了试--net=host 也不管用,访问不通了就,不太懂 docker 网络这块,求助大佬们。
1
Aliberter OP 我看百度上,大部分都是在外边加一层 nginx ,提前配置好代码里这些请求头啥的,然后后面走到代码里也就能直接取取来请求头的值,就是用户的真实 ip 了,不知道是否可行~
|
2
hopingtop 2021-11-26 09:46:36 +08:00
remoteAddr 是真正连接你服务端的 IP ,但是往往一次网络请求可能会经过几层网络代理,那么你渠道的 IP 就是最后一层代理,并不是真的 ClientIP 。
因为 Docker 他有网络模式,默认情况下( bridge )所以他其实就是相当于一层代理了。 |
3
hopingtop 2021-11-26 09:47:54 +08:00
@hopingtop 但是 HOST 网络模式应该和宿主机共享 Namespace ,如果中间没有其他代理,按理能取到 IP
|
4
hopingtop 2021-11-26 09:48:53 +08:00 1
@hopingtop ..... 按了几次 CTRL 回车,导致就没有回答完。。。狗头。。。
Docker 使用了 Linux 的 Namespaces 技术来进行资源隔离,如 PID Namespace 隔离进程,Mount Namespace 隔离文件系统,Network Namespace 隔离网络等。一个 Network Namespace 提供了一份独立的网络环境,包括网卡、路由、Iptable 规则等都与其他的 Network Namespace 隔离。 host 模式类似于 Vmware 的桥接模式,与宿主机在同一个网络中,但没有独立 IP 地址。一个 Docker 容器一般会分配一个独立的 Network Namespace 。但如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace ,而是和宿主机共用一个 Network Namespace 。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。 |
5
wolfie 2021-11-26 09:54:05 +08:00 1
一般都从 x-forwarded-for 拿,多个网关会包含多个 ip ,逗号分隔。
也有 x-real-ip 的情况。 |
6
rationa1cuzz 2021-11-26 10:06:21 +08:00 1
--net=host 按道理应该使用宿主机的 ip 端口,访问不通是不是端口被占用了?
|
8
Aliberter OP @rationa1cuzz 对,解决了,--net=host 确实管用,我重新给防火墙开了这个端口才通了,但是有个疑问就是,之前一直用端口映射的时候,我记得我加过防火墙,而且也一直是通的,能用的,改成这个模式后,又加了一遍才通,真搞不懂。
|
9
xueyuanh 2021-11-26 10:48:59 +08:00
@rationa1cuzz 用了--net=host 容器是不是就会把机器的 80 端口给占用了,之前用 docker 启一个 nginx ,一直占用 80 端口,但是 nginx 的默认监听端口已经被我换成别的了,最后去掉--net=host 才正常
|
10
rationa1cuzz 2021-11-26 11:15:27 +08:00
@xueyuanh 是的,你可以 lsof 或者 netstat 看一下就知道了,你可以看看这个 https://docs.docker.com/network/
|
11
pixiaotiao 2021-11-26 12:16:23 +08:00 via Android
一层一层传过来
|
12
yangyaofei 2021-11-26 12:16:55 +08:00
不知道这个可以不可以, 当时 https nginx 转发的时候也会遇到这个问题, 加这个配置解决的:
```yaml server: port: 8080 address: 0.0.0.0 # Enable HTTPS When Running behind a Proxy Server # https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.security.enable-https tomcat: remoteip: remote-ip-header: "x-forwarded-for" protocol-header: "x-forwarded-proto" ``` |
13
yangyaofei 2021-11-26 12:18:39 +08:00
```
server: port: 8080 address: 0.0.0.0 # Enable HTTPS When Running behind a Proxy Server tomcat: remoteip: remote-ip-header: "x-forwarded-for" protocol-header: "x-forwarded-proto" ``` |
14
yangyaofei 2021-11-26 12:19:02 +08:00
这个 markdown 不好用啊 😂😂😂
|