Find and use non local IPv4 address while testing IP filtering (#40234) (#41141)

For pattern "n:localhost" PatternRule#isLocalhost() matches
any local address, loopback address.
[Note: I think for "localhost" this should not consider IP address
as a match when they are bound to network interfaces. It should just
be loopback address check unless the intent is to match all local addresses.
This class is adopted from Netty3 and I am not sure if this is intended
behavior or maybe I am missing something]

For now I have fixed this assuming the PatternRule#isLocalhost check is
correct by avoiding use of local address to check address denied.

Closes #40194
This commit is contained in:
Yogesh Gaikwad 2019-04-13 04:37:25 +10:00 committed by GitHub
parent e7375368d6
commit 47ba45732d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 27 additions and 2 deletions

View File

@ -5,6 +5,7 @@
*/ */
package org.elasticsearch.xpack.security.transport.filter; package org.elasticsearch.xpack.security.transport.filter;
import org.elasticsearch.common.Numbers;
import org.elasticsearch.common.component.Lifecycle; import org.elasticsearch.common.component.Lifecycle;
import org.elasticsearch.common.network.InetAddresses; import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.network.NetworkAddress; import org.elasticsearch.common.network.NetworkAddress;
@ -26,6 +27,9 @@ import org.mockito.ArgumentCaptor;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -35,6 +39,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@ -140,7 +145,8 @@ public class IPFilterTests extends ESTestCase {
ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState);
ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses());
assertAddressIsAllowed("127.0.0.1"); assertAddressIsAllowed("127.0.0.1");
assertAddressIsDenied("192.168.0.1"); // when "localhost" is used, ES considers all local addresses see PatternRule#isLocalhost()
assertAddressIsDenied(randomNonLocalIPv4Address());
assertAddressIsAllowedForProfile("client", "192.168.0.1"); assertAddressIsAllowedForProfile("client", "192.168.0.1");
assertAddressIsDeniedForProfile("client", "192.168.0.2"); assertAddressIsDeniedForProfile("client", "192.168.0.2");
} }
@ -161,7 +167,8 @@ public class IPFilterTests extends ESTestCase {
clusterSettings.updateDynamicSettings(newSettings, updatedSettingsBuilder, Settings.builder(), "test"); clusterSettings.updateDynamicSettings(newSettings, updatedSettingsBuilder, Settings.builder(), "test");
clusterSettings.applySettings(updatedSettingsBuilder.build()); clusterSettings.applySettings(updatedSettingsBuilder.build());
assertAddressIsAllowed("127.0.0.1"); assertAddressIsAllowed("127.0.0.1");
assertAddressIsDenied("192.168.0.1"); // when "localhost" is used, ES considers all local addresses see PatternRule#isLocalhost()
assertAddressIsDenied(randomNonLocalIPv4Address());
assertAddressIsAllowedForProfile("client", "192.168.0.1", "192.168.0.2"); assertAddressIsAllowedForProfile("client", "192.168.0.1", "192.168.0.2");
assertAddressIsDeniedForProfile("client", "192.168.0.3"); assertAddressIsDeniedForProfile("client", "192.168.0.3");
} }
@ -297,4 +304,22 @@ public class IPFilterTests extends ESTestCase {
private void assertAddressIsDenied(String ... inetAddresses) { private void assertAddressIsDenied(String ... inetAddresses) {
assertAddressIsDeniedForProfile("default", inetAddresses); assertAddressIsDeniedForProfile("default", inetAddresses);
} }
private String randomNonLocalIPv4Address() throws SocketException, UnknownHostException {
String ipv4Address = null;
int noOfRetries = 0;
do {
noOfRetries++;
final InetAddress address = InetAddress.getByAddress(Numbers.intToBytes(randomInt()));
if (address.isAnyLocalAddress() || address.isLoopbackAddress() || NetworkInterface.getByInetAddress(address) != null) {
continue;
} else {
ipv4Address = NetworkAddress.format(address);
break;
}
} while (ipv4Address == null && noOfRetries < 25);
assertThat("could not generate random IPv4 address which is not local address", ipv4Address, notNullValue());
return ipv4Address;
}
} }