Skip to content

Commit dcc0657

Browse files
committed
Check if interface is up for loopback devices only (#51583)
In the SQL with SSL tests, we need to find the interfaces that are up, are loopback devices, or have a loopback address. If we check if the device is up first, we can run into situations where the device is a virtual ethernet device that might have disappeared between us seeing the device, and checking if it is up. By first checking if the device is a loopback device or it has a loopback address, then we can avoid checking if the device is up except for loopback devices and therefore we can avoid the disappearing virtual ethernet device problem.
1 parent cd7ac2a commit dcc0657

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

x-pack/plugin/sql/qa/security/with-ssl/build.gradle

+25-17
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
import org.elasticsearch.gradle.BuildPlugin
21
import org.elasticsearch.gradle.LoggedExec
32
import org.elasticsearch.gradle.info.BuildParams
43

5-
import javax.net.ssl.HttpsURLConnection
6-
import javax.net.ssl.KeyManagerFactory
7-
import javax.net.ssl.SSLContext
8-
import javax.net.ssl.TrustManagerFactory
9-
import java.nio.charset.StandardCharsets
10-
import java.security.KeyStore
11-
import java.security.SecureRandom
12-
134
// Tell the tests we're running with ssl enabled
145
integTest.runner {
156
systemProperty 'tests.ssl.enabled', 'true'
@@ -213,14 +204,18 @@ class SanEvaluator {
213204
private static String getSubjectAlternativeNameString() {
214205
List<InetAddress> list = new ArrayList<>();
215206
for (NetworkInterface intf : getInterfaces()) {
216-
if (intf.isUp()) {
217-
// NOTE: some operating systems (e.g. BSD stack) assign a link local address to the loopback interface
218-
// while technically not a loopback address, some of these treat them as one (e.g. OS X "localhost") so we must too,
219-
// otherwise things just won't work out of box. So we include all addresses from loopback interfaces.
220-
for (InetAddress address : Collections.list(intf.getInetAddresses())) {
221-
if (intf.isLoopback() || address.isLoopbackAddress()) {
222-
list.add(address);
223-
}
207+
for (final InetAddress address : Collections.list(intf.getInetAddresses())) {
208+
/*
209+
* Some OS (e.g., BSD) assign a link-local address to the loopback interface. While technically not a loopback interface, some of
210+
* these OS treat them as one (e.g., localhost on macOS), so we must too. Otherwise, things just won't work out of the box. So we
211+
* include all addresses from loopback interfaces.
212+
*
213+
* By checking if the interface is a loopback interface or the address is a loopback address first, we avoid having to check if the
214+
* interface is up unless necessary. This means we can avoid checking if the interface is up for virtual ethernet devices which have
215+
* a tendency to disappear outside of our control (e.g., due to Docker).
216+
*/
217+
if ((intf.isLoopback() || address.isLoopbackAddress()) && isUp(intf, address)) {
218+
list.add(address)
224219
}
225220
}
226221
}
@@ -251,6 +246,19 @@ class SanEvaluator {
251246
return builder.toString();
252247
}
253248

249+
private static boolean isUp(final NetworkInterface intf, final InetAddress address) throws IOException {
250+
try {
251+
return intf.isUp();
252+
} catch (final SocketException e) {
253+
/*
254+
* In Elasticsearch production code (NetworkUtils) we suppress this if the device is a virtual ethernet device. That should not happen
255+
* here since the interface must be a loopback device or the address a loopback address to get here to begin with.
256+
*/
257+
assert intf.isLoopback() || address.isLoopbackAddress()
258+
throw new IOException("failed to check if interface [" + intf.getName() + "] is up", e)
259+
}
260+
}
261+
254262
private static String compressedIPV6Address(Inet6Address inet6Address) {
255263
byte[] bytes = inet6Address.getAddress();
256264
int[] hextets = new int[8];

0 commit comments

Comments
 (0)