Browse Source

Bind the readiness service to the wildcard address (#91329)

This change changes the host binding on the readiness service to all from localhost.
Nikola Grcevski 2 years ago
parent
commit
3fd338ffd1

+ 2 - 1
distribution/src/config/elasticsearch.yml

@@ -77,7 +77,8 @@
 #
 # --------------------------------- Readiness ----------------------------------
 #
-# Enable an unauthenticated TCP readiness endpoint on localhost
+# Enable an unauthenticated TCP readiness endpoint. The readiness service binds to all
+# host addresses.
 #
 #readiness.port: 9399
 #

+ 6 - 0
docs/changelog/91329.yaml

@@ -0,0 +1,6 @@
+pr: 91329
+summary: Bind the readiness service to the wildcard address
+area: Infra/Core
+type: enhancement
+issues:
+ - 90997

+ 2 - 4
docs/reference/setup/advanced-configuration.asciidoc

@@ -166,10 +166,8 @@ If configured, a node can open a TCP port when the node is in a ready state. A n
 ready when it has successfully joined a cluster. In a single node configuration, the node is
 said to be ready, when it's able to accept requests.
 
-To enable the readiness TCP port, use the `readiness.port` setting. The port is
-always bound to the loopback address, which defaults to the IPv4 loopback address `127.0.0.1`.
-To bind the readiness port to the IPv6 loopback address `::1`,
-add `-Djava.net.preferIPv6Addresses=true` to the <<set-jvm-options,JVM options>>.
+To enable the readiness TCP port, use the `readiness.port` setting. The readiness service will bind to
+all host addresses.
 
 If the node leaves the cluster, or the <<put-shutdown,Shutdown API>> is used to mark the node
 for shutdown, the readiness port is immediately closed.

+ 13 - 5
server/src/main/java/org/elasticsearch/readiness/ReadinessService.java

@@ -102,18 +102,26 @@ public class ReadinessService extends AbstractLifecycleComponent implements Clus
 
     // package private for testing
     ServerSocketChannel setupSocket() {
-        InetAddress localhost = InetAddress.getLoopbackAddress();
-        int portNumber = PORT.get(environment.settings());
+        var settings = environment.settings();
+        int portNumber = PORT.get(settings);
         assert portNumber >= 0;
 
+        var socketAddress = AccessController.doPrivileged((PrivilegedAction<InetSocketAddress>) () -> {
+            try {
+                return socketAddress(InetAddress.getByName("0"), portNumber);
+            } catch (IOException e) {
+                throw new IllegalArgumentException("Failed to resolve readiness host address", e);
+            }
+        });
+
         try {
             serverChannel = ServerSocketChannel.open();
 
             AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                 try {
-                    serverChannel.bind(socketAddress(localhost, portNumber));
+                    serverChannel.bind(socketAddress);
                 } catch (IOException e) {
-                    throw new BindTransportException("Failed to bind to " + NetworkAddress.format(localhost, portNumber), e);
+                    throw new BindTransportException("Failed to bind to " + NetworkAddress.format(socketAddress), e);
                 }
                 return null;
             });
@@ -129,7 +137,7 @@ public class ReadinessService extends AbstractLifecycleComponent implements Clus
                 }
             }
         } catch (Exception e) {
-            throw new BindTransportException("Failed to open socket channel " + NetworkAddress.format(localhost, portNumber), e);
+            throw new BindTransportException("Failed to open socket channel " + NetworkAddress.format(socketAddress), e);
         }
 
         return serverChannel;

+ 1 - 3
server/src/main/resources/org/elasticsearch/bootstrap/security.policy

@@ -23,9 +23,7 @@ grant codeBase "${codebase.elasticsearch}" {
   // needed for loading plugins which may expect the context class loader to be set
   permission java.lang.RuntimePermission "setContextClassLoader";
   // needed for the readiness service
-  permission java.net.SocketPermission "127.0.0.1", "listen, accept";
-  // required if started with -Djava.net.preferIPv6Addresses=true
-  permission java.net.SocketPermission "0:0:0:0:0:0:0:1", "listen, accept";
+  permission java.net.SocketPermission "*", "listen, accept";
 
   // for module layer
   permission java.lang.RuntimePermission "createClassLoader";

+ 1 - 1
x-pack/plugin/shutdown/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownIT.java

@@ -122,7 +122,7 @@ public class NodeShutdownIT extends ESRestTestCase implements ReadinessClientPro
         String[] readinessAddresses = readinessPorts.split(",");
         String readinessAddress = readinessAddresses[nodeIndex];
 
-        String portStr = readinessAddress.split(":")[1];
+        String portStr = readinessAddress.substring(readinessAddress.lastIndexOf(':') + 1);
         Integer port = Integer.parseInt(portStr);
 
         // Once we have the right port, check to see if it's ready, has to be for a properly started cluster