From da08840645849aeb970237f93cf7caf1a6086c14 Mon Sep 17 00:00:00 2001 From: rdhaese Date: Sat, 4 May 2024 11:50:57 +0200 Subject: [PATCH 1/4] safe logging: hide password if peer url uses basic auth in url --- .../eureka/cluster/PeerEurekaNodes.java | 75 ++++++++++++------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java b/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java index 0f221ec747..81232c3092 100644 --- a/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java +++ b/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java @@ -1,19 +1,5 @@ package com.netflix.eureka.cluster; -import javax.inject.Inject; -import javax.inject.Singleton; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.InstanceInfo; import com.netflix.discovery.EurekaClientConfig; @@ -25,6 +11,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + /** * Helper class to manage lifecycle of a collection of {@link PeerEurekaNode}s. * @@ -67,7 +64,7 @@ public List getPeerNodesView() { public List getPeerEurekaNodes() { return peerEurekaNodes; } - + public int getMinNumberOfAvailablePeers() { return serverConfig.getHealthStatusMinNumberOfAvailablePeers(); } @@ -169,7 +166,10 @@ protected void updatePeerEurekaNodes(List newPeerUrls) { List newNodeList = new ArrayList<>(peerEurekaNodes); if (!toShutdown.isEmpty()) { - logger.info("Removing no longer available peer nodes {}", toShutdown); + logger.info( + "Removing no longer available peer nodes {}", + toShutdown.stream().map(this::removePasswordFromPeerUrl).collect(Collectors.toSet()) + ); int i = 0; while (i < newNodeList.size()) { PeerEurekaNode eurekaNode = newNodeList.get(i); @@ -184,7 +184,10 @@ protected void updatePeerEurekaNodes(List newPeerUrls) { // Add new peers if (!toAdd.isEmpty()) { - logger.info("Adding new peer nodes {}", toAdd); + logger.info( + "Adding new peer nodes {}", + toAdd.stream().map(this::removePasswordFromPeerUrl).collect(Collectors.toSet()) + ); for (String peerUrl : toAdd) { newNodeList.add(createPeerEurekaNode(peerUrl)); } @@ -194,6 +197,29 @@ protected void updatePeerEurekaNodes(List newPeerUrls) { this.peerEurekaNodeUrls = new HashSet<>(newPeerUrls); } + /** + * If basic http authorization is used in the url, replace the password with 'PASSWORD', making it safe to log. + */ + private String removePasswordFromPeerUrl(String url) { + URI uri; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + logger.warn("Cannot parse peer URI {}", url, e); + return null; + } + + String userInfo = uri.getUserInfo(); + if (userInfo != null && userInfo.contains(":")) { + String[] userInfoParts = userInfo.split(":"); + if (userInfoParts.length == 2) { + String sanitizedUserInfo = userInfoParts[0] + ":PASSWORD"; + return url.replace(userInfo, sanitizedUserInfo); + } + } + return url; + } + protected PeerEurekaNode createPeerEurekaNode(String peerEurekaNodeUrl) { HttpReplicationClient replicationClient = JerseyReplicationClient.createReplicationClient(serverConfig, serverCodecs, peerEurekaNodeUrl); String targetHost = hostFromUrl(peerEurekaNodeUrl); @@ -204,16 +230,15 @@ protected PeerEurekaNode createPeerEurekaNode(String peerEurekaNodeUrl) { } /** + * @param url the service url of the replica node that the check is made. + * @return true, if the url represents the current node which is trying to + * replicate, false otherwise. * @deprecated 2016-06-27 use instance version of {@link #isThisMyUrl(String)} - * + *

* Checks if the given service url contains the current host which is trying * to replicate. Only after the EIP binding is done the host has a chance to * identify itself in the list of replica nodes and needs to take itself out * of replication traffic. - * - * @param url the service url of the replica node that the check is made. - * @return true, if the url represents the current node which is trying to - * replicate, false otherwise. */ public static boolean isThisMe(String url) { InstanceInfo myInfo = ApplicationInfoManager.getInstance().getInfo(); @@ -229,7 +254,7 @@ public static boolean isThisMe(String url) { * * @param url the service url of the replica node that the check is made. * @return true, if the url represents the current node which is trying to - * replicate, false otherwise. + * replicate, false otherwise. */ public boolean isThisMyUrl(String url) { final String myUrlConfigured = serverConfig.getMyUrl(); @@ -238,11 +263,11 @@ public boolean isThisMyUrl(String url) { } return isInstanceURL(url, applicationInfoManager.getInfo()); } - + /** * Checks if the given service url matches the supplied instance * - * @param url the service url of the replica node that the check is made. + * @param url the service url of the replica node that the check is made. * @param instance the instance to check the service url against * @return true, if the url represents the supplied instance, false otherwise. */ From 2830652da923353ba897843473cf3798634d4f01 Mon Sep 17 00:00:00 2001 From: rdhaese Date: Sat, 4 May 2024 11:52:56 +0200 Subject: [PATCH 2/4] code inspection suggestions --- .../eureka/cluster/PeerEurekaNodes.java | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java b/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java index 81232c3092..dec2d4551b 100644 --- a/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java +++ b/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java @@ -71,27 +71,21 @@ public int getMinNumberOfAvailablePeers() { public void start() { taskExecutor = Executors.newSingleThreadScheduledExecutor( - new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r, "Eureka-PeerNodesUpdater"); - thread.setDaemon(true); - return thread; - } + r -> { + Thread thread = new Thread(r, "Eureka-PeerNodesUpdater"); + thread.setDaemon(true); + return thread; } ); try { updatePeerEurekaNodes(resolvePeerUrls()); - Runnable peersUpdateTask = new Runnable() { - @Override - public void run() { - try { - updatePeerEurekaNodes(resolvePeerUrls()); - } catch (Throwable e) { - logger.error("Cannot update the replica Nodes", e); - } - + Runnable peersUpdateTask = () -> { + try { + updatePeerEurekaNodes(resolvePeerUrls()); + } catch (Throwable e) { + logger.error("Cannot update the replica Nodes", e); } + }; taskExecutor.scheduleWithFixedDelay( peersUpdateTask, @@ -154,7 +148,7 @@ protected void updatePeerEurekaNodes(List newPeerUrls) { } Set toShutdown = new HashSet<>(peerEurekaNodeUrls); - toShutdown.removeAll(newPeerUrls); + newPeerUrls.forEach(toShutdown::remove); Set toAdd = new HashSet<>(newPeerUrls); toAdd.removeAll(peerEurekaNodeUrls); From a29695c7108180f126791625d1a6ddce6e97d649 Mon Sep 17 00:00:00 2001 From: rdhaese Date: Sat, 4 May 2024 11:53:17 +0200 Subject: [PATCH 3/4] code inspection suggestions --- .../main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java | 1 - 1 file changed, 1 deletion(-) diff --git a/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java b/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java index dec2d4551b..df7c25b1f7 100644 --- a/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java +++ b/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java @@ -18,7 +18,6 @@ import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; From ba5ff9b80dce454a81e3879b9c1c9471ece12447 Mon Sep 17 00:00:00 2001 From: rdhaese Date: Sat, 4 May 2024 12:00:20 +0200 Subject: [PATCH 4/4] consistency --- .../com/netflix/eureka/cluster/PeerEurekaNodes.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java b/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java index df7c25b1f7..577b086abc 100644 --- a/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java +++ b/eureka-core/src/main/java/com/netflix/eureka/cluster/PeerEurekaNodes.java @@ -107,9 +107,7 @@ public void shutdown() { this.peerEurekaNodes = Collections.emptyList(); this.peerEurekaNodeUrls = Collections.emptySet(); - for (PeerEurekaNode node : toRemove) { - node.shutDown(); - } + toRemove.forEach(PeerEurekaNode::shutDown); } /** @@ -149,7 +147,7 @@ protected void updatePeerEurekaNodes(List newPeerUrls) { Set toShutdown = new HashSet<>(peerEurekaNodeUrls); newPeerUrls.forEach(toShutdown::remove); Set toAdd = new HashSet<>(newPeerUrls); - toAdd.removeAll(peerEurekaNodeUrls); + peerEurekaNodeUrls.forEach(toAdd::remove); if (toShutdown.isEmpty() && toAdd.isEmpty()) { // No change return; @@ -181,9 +179,7 @@ protected void updatePeerEurekaNodes(List newPeerUrls) { "Adding new peer nodes {}", toAdd.stream().map(this::removePasswordFromPeerUrl).collect(Collectors.toSet()) ); - for (String peerUrl : toAdd) { - newNodeList.add(createPeerEurekaNode(peerUrl)); - } + toAdd.stream().map(this::createPeerEurekaNode).forEach(newNodeList::add); } this.peerEurekaNodes = newNodeList;