This is an automated email from the ASF dual-hosted git repository.

adoroszlai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 4b8156b57d2 HDDS-9894. Handle IPv4 and IPv6 addresses invalid for CSR 
consistently (#10687)
4b8156b57d2 is described below

commit 4b8156b57d23ddcba3533296ce3af26be1226574
Author: Siyao Meng <[email protected]>
AuthorDate: Wed Aug 5 01:58:03 2026 -0700

    HDDS-9894. Handle IPv4 and IPv6 addresses invalid for CSR consistently 
(#10687)
    
    Generated-by: Claude Code (Opus 4.8)
    Co-authored-by: Copilot Autofix powered by AI 
<[email protected]>
---
 .../apache/hadoop/hdds/utils/HddsServerUtil.java   | 37 ++++++++++++++--------
 .../hadoop/hdds/scm/TestHddsServerUtils.java       | 26 +++++++++++++++
 2 files changed, 50 insertions(+), 13 deletions(-)

diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
index e9050346931..49a71025c76 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
@@ -86,7 +86,6 @@
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.SystemUtils;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.commons.validator.routines.InetAddressValidator;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hdds.HddsConfigKeys;
 import org.apache.hadoop.hdds.HddsUtils;
@@ -143,10 +142,6 @@ public final class HddsServerUtil {
   public static final String OZONE_RATIS_SNAPSHOT_COMPLETE_FLAG_NAME =
       "OZONE_RATIS_SNAPSHOT_COMPLETE";
 
-  // List of ip's not recommended to be added to CSR.
-  private static final Set<String> INVALID_IPS = new HashSet<>(Arrays.asList(
-      "0.0.0.0", "127.0.0.1"));
-
   private HddsServerUtil() {
   }
 
@@ -164,8 +159,9 @@ public static void addPBProtocol(Configuration conf, 
Class<?> protocol,
   }
 
   /**
-   * Iterates through network interfaces and return all valid ip's not
-   * listed in {@link #INVALID_IPS}.
+   * Iterates through network interfaces and returns all IP addresses that are 
valid to
+   * add to a certificate's SAN extension, as determined by
+   * {@link #isValidInetForCsr(InetAddress)}.
    *
    * @return List<InetAddress>
    * @throws IOException if no network interface are found or if an error
@@ -174,7 +170,6 @@ public static void addPBProtocol(Configuration conf, 
Class<?> protocol,
   public static List<InetAddress> getValidInetsForCurrentHost()
       throws IOException {
     List<InetAddress> hostIps = new ArrayList<>();
-    InetAddressValidator ipValidator = InetAddressValidator.getInstance();
 
     Enumeration<NetworkInterface> enumNI =
         NetworkInterface.getNetworkInterfaces();
@@ -189,13 +184,11 @@ public static List<InetAddress> 
getValidInetsForCurrentHost()
         while (enumAdds.hasMoreElements()) {
           InetAddress addr = enumAdds.nextElement();
 
-          String hostAddress = addr.getHostAddress();
-          if (!INVALID_IPS.contains(hostAddress) && 
ipValidator.isValid(hostAddress)
-              && !isScopedOrMaskingIPv6Address(addr)) {
-            LOG.info("Adding ip:{},host:{}", hostAddress, addr.getHostName());
+          if (isValidInetForCsr(addr)) {
+            LOG.info("Adding ip:{},host:{}", addr.getHostAddress(), 
addr.getHostName());
             hostIps.add(addr);
           } else {
-            LOG.info("ip:{} not returned.", hostAddress);
+            LOG.info("ip:{} not returned.", addr.getHostAddress());
           }
         }
       }
@@ -204,6 +197,24 @@ public static List<InetAddress> 
getValidInetsForCurrentHost()
     return hostIps;
   }
 
+  /**
+   * Determines whether the supplied address is valid to add to a certificate's
+   * SAN extension. Wildcard/unspecified (0.0.0.0, ::) and loopback
+   * (127.0.0.0/8, ::1) addresses are excluded for both IPv4 and IPv6, along
+   * with scoped or masked IPv6 addresses (see
+   * {@link #isScopedOrMaskingIPv6Address(InetAddress)}). Using the
+   * {@link InetAddress} predicates rather than a fixed set of address strings
+   * ensures the IPv6 forms are excluded, not just their IPv4 equivalents.
+   *
+   * @param addr the InetAddress to check
+   * @return true if the address should be added to the CSR
+   */
+  public static boolean isValidInetForCsr(InetAddress addr) {
+    return !addr.isAnyLocalAddress()
+        && !addr.isLoopbackAddress()
+        && !isScopedOrMaskingIPv6Address(addr);
+  }
+
   /**
    * Determines if the supplied address is an IPv6 address, with a defined 
scope-id and/or with a defined prefix length.
    * <p>
diff --git 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestHddsServerUtils.java
 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestHddsServerUtils.java
index 3d6e94e0a87..b19b59320c7 100644
--- 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestHddsServerUtils.java
+++ 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestHddsServerUtils.java
@@ -24,12 +24,15 @@
 import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_NAMES;
 import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_STALENODE_INTERVAL;
 import static 
org.apache.hadoop.ozone.OzoneConsts.OZONE_SCM_DATANODE_ID_FILE_DEFAULT;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
 import java.util.concurrent.TimeUnit;
 import org.apache.commons.io.FileUtils;
 import org.apache.hadoop.hdds.HddsConfigKeys;
@@ -190,6 +193,29 @@ public void testNoScmDbDirConfigured() {
         () -> ServerUtils.getScmDbDir(new OzoneConfiguration()));
   }
 
+  /**
+   * Wildcard and loopback addresses must be excluded from a certificate's SAN
+   * extension for both IPv4 and IPv6. See HDDS-9894.
+   */
+  @Test
+  public void testInvalidInetsExcludedFromCsr() throws UnknownHostException {
+    // IPv4 wildcard and loopback
+    
assertThat(HddsServerUtil.isValidInetForCsr(InetAddress.getByName("0.0.0.0"))).isFalse();
+    
assertThat(HddsServerUtil.isValidInetForCsr(InetAddress.getByName("127.0.0.1"))).isFalse();
+    // IPv6 equivalents: unspecified (::) and loopback (::1)
+    
assertThat(HddsServerUtil.isValidInetForCsr(InetAddress.getByName("::"))).isFalse();
+    
assertThat(HddsServerUtil.isValidInetForCsr(InetAddress.getByName("::1"))).isFalse();
+  }
+
+  /**
+   * Regular routable addresses stay eligible for the SAN extension.
+   */
+  @Test
+  public void testValidInetsIncludedInCsr() throws UnknownHostException {
+    
assertThat(HddsServerUtil.isValidInetForCsr(InetAddress.getByName("1.2.3.4"))).isTrue();
+    
assertThat(HddsServerUtil.isValidInetForCsr(InetAddress.getByName("2001:db8::1"))).isTrue();
+  }
+
   @Test
   public void testGetStaleNodeInterval() {
     final OzoneConfiguration conf = new OzoneConfiguration();


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to