前言
我们因为安全漏洞将dubbo 升级到2.7.15 版本,当环境中存在docker 部署的时候。dubbo 获取本机ip将会变成docker0的地址。
实践
我们查看dubbo 获取ip地址的源码org.apache.dubbo.common.utils.NetUtils#getLocalAddress0来获取本地地址。 可以看到关键在于findNetworkInterface() 获取到网卡的地址 我们将findNetworkInterface 这个方法贴出来,看到要获取networkInterface 分了三步,
public static NetworkInterface findNetworkInterface() {
List<NetworkInterface> validNetworkInterfaces = emptyList();
try {
validNetworkInterfaces = getValidNetworkInterfaces();
} catch (Throwable e) {
logger.warn(e);
}
NetworkInterface result = null;
for (NetworkInterface networkInterface : validNetworkInterfaces) {
if (isPreferredNetworkInterface(networkInterface)) {
result = networkInterface;
break;
}
}
if (result == null) {
for (NetworkInterface networkInterface : validNetworkInterfaces) {
Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
while (addresses.hasMoreElements()) {
Optional<InetAddress> addressOp = toValidAddress(addresses.nextElement());
if (addressOp.isPresent()) {
try {
if (addressOp.get().isReachable(100)) {
return networkInterface;
}
} catch (IOException e) {
}
}
}
}
}
if (result == null) {
result = first(validNetworkInterfaces);
}
return result;
}
public static String getHostName(String address) {
try {
int i = address.indexOf(':');
if (i > -1) {
address = address.substring(0, i);
}
String hostname = HOST_NAME_CACHE.get(address);
if (hostname != null && hostname.length() > 0) {
return hostname;
}
InetAddress inetAddress = InetAddress.getByName(address);
if (inetAddress != null) {
hostname = inetAddress.getHostName();
HOST_NAME_CACHE.put(address, hostname);
return hostname;
}
} catch (Throwable e) {
}
return address;
}
一、查看所有网卡中是否isPreferredNetworkInterface(networkInterface) 是否优先网卡 判断是否有是优先网卡通过名字来比对的
二、没有配置优先网卡或者配置优先网卡不存在则会 获取到当0.1s网络可达的网卡
三、如果前面条件都不成功 直接获取i存在的网卡
根据上面三个判断条件如果获取网卡不是自己想要的,可以通过配置优先网卡来获取自己想要网卡。
String preferredNetworkInterface = System.getProperty(DUBBO_PREFERRED_NETWORK_INTERFACE); return Objects.equals(networkInterface.getDisplayName(), preferredNetworkInterface);
DUBBO_PREFERRED_NETWORK_INTERFACE 的值是dubbo.network.interface.preferred 那么就可以在启动命令中或者yml配置网卡名称
-Ddubbo.network.interface.preferred=eth0 (启动命令中添加)
yml配置优先网卡名称:
dubbo: network: interface: preferred: eth0
|