<>前言
我们因为安全漏洞将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; // Try to find the preferred one
//一、查看所有网卡中是否isPreferredNetworkInterface(networkInterface) 是否优先网卡
//判断是否有是优先网卡通过名字来比对的 //String preferredNetworkInterface =
System.getProperty(DUBBO_PREFERRED_NETWORK_INTERFACE); // return
Objects.equals(networkInterface.getDisplayName(), preferredNetworkInterface);
for (NetworkInterface networkInterface : validNetworkInterfaces) { if
(isPreferredNetworkInterface(networkInterface)) { result = networkInterface;
break; } } if (result == null) { // If not found, try to get the first one 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) { // ignore } } } } } 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) { // ignore } 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
同时也可以通过排除忽略网卡排除错误网卡
-Ddubbo.network.interface.ignored=docker0
yml配置优先网卡名称:
dubbo:
network:
interface:
ignored: docker0