From 351801b7d6ae9a98125e70d9559846b045e25823 Mon Sep 17 00:00:00 2001 From: yaohaishi Date: Tue, 5 Dec 2017 15:50:37 +0800 Subject: [PATCH 1/2] JAV-551 fix address binding logic, 0.0.0.0 should be replaced with a valid address --- .../foundation/common/net/NetUtils.java | 49 ++++++++++++++++--- .../foundation/common/net/TestNetUtils.java | 10 ++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/net/NetUtils.java b/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/net/NetUtils.java index b346f824f4a..9686137ab45 100755 --- a/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/net/NetUtils.java +++ b/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/net/NetUtils.java @@ -25,6 +25,7 @@ import java.net.SocketException; import java.net.URI; import java.net.URISyntaxException; +import java.net.UnknownHostException; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; @@ -36,6 +37,8 @@ public final class NetUtils { private static final Logger LOGGER = LoggerFactory.getLogger(NetUtils.class); + private static final String COLON = ":"; + // one interface can bind to multiple address // we only save one ip for each interface name. // eg: @@ -151,12 +154,17 @@ public static IpPort parseIpPortFromURI(String uriAddress) { } /** - * 对于配置为0.0.0.0的地址,let it go - * schema, e.g. http - * adddress, e.g 0.0.0.0:8080 - * return 实际监听的地址 + * if address is 0.0.0.0, replace it with {@link #hostAddress} + * + * @param schema e.g. http + * @param address e.g 0.0.0.0:8080 + * @return the address actually to be bound to */ public static String getRealListenAddress(String schema, String address) { + if (address == null) { + return null; + } + address = checkAddress(address); if (address == null) { return null; } @@ -164,12 +172,12 @@ public static String getRealListenAddress(String schema, String address) { URI originalURI = new URI(schema + "://" + address); IpPort ipPort = NetUtils.parseIpPort(originalURI.getAuthority()); if (ipPort == null) { - LOGGER.error("address {} is not valid.", address); + LOGGER.error("schema {} or address {} is not valid.", schema, address); return null; } return originalURI.toString(); } catch (URISyntaxException e) { - LOGGER.error("address {} is not valid.", address); + LOGGER.error("schema {} or address {} is not valid.", schema, address); return null; } } @@ -201,4 +209,33 @@ public static boolean canTcpListen(InetAddress address, int port) { return false; } } + + /** + * For security reason, 0.0.0.0 is not allowed to be bound to, + * and should be replaced with {@link #hostAddress} + * + * @param address address in configuration + * @return if host is 0.0.0.0, replace it with {@link #hostAddress}; + * otherwise, return as it is. + */ + private static String checkAddress(String address) { + if (!address.contains(COLON)) { + LOGGER.error("unexpected address format"); + return null; + } + String ip = address.substring(0, address.indexOf(COLON)); + InetAddress inetAddress = null; + try { + inetAddress = InetAddress.getByName(ip); + } catch (UnknownHostException e) { + LOGGER.error("host {} is unknown.", ip); + return null; + } + if (inetAddress.isAnyLocalAddress()) { + LOGGER.warn("address {} is not allowed to be bound to, choose {} as alternate, may not be correct.", + ip, NetUtils.getHostAddress()); + address = NetUtils.getHostAddress() + address.substring(address.indexOf(COLON)); + } + return address; + } } diff --git a/foundations/foundation-common/src/test/java/io/servicecomb/foundation/common/net/TestNetUtils.java b/foundations/foundation-common/src/test/java/io/servicecomb/foundation/common/net/TestNetUtils.java index 8b14c04de1d..e9655f614ef 100644 --- a/foundations/foundation-common/src/test/java/io/servicecomb/foundation/common/net/TestNetUtils.java +++ b/foundations/foundation-common/src/test/java/io/servicecomb/foundation/common/net/TestNetUtils.java @@ -63,6 +63,16 @@ public void testGetRealListenAddress() { Assert.assertEquals("http://1.1.1.1:8080", NetUtils.getRealListenAddress("http", "1.1.1.1:8080")); } + @Test + public void testGetRealListenAddressOnConfiguredAddressIsAll0() { + String hostAddressFieldName = "hostAddress"; + String preservedHost = Deencapsulation.getField(NetUtils.class, hostAddressFieldName); + Deencapsulation.setField(NetUtils.class, hostAddressFieldName, "12.12.12.12"); + Assert.assertEquals("http://12.12.12.12:8080", NetUtils.getRealListenAddress("http", "0.0.0.0:8080")); + + Deencapsulation.setField(NetUtils.class, hostAddressFieldName, preservedHost); + } + @Test public void testNetworkInterface() { Map org = Deencapsulation.getField(NetUtils.class, "allInterfaceAddresses"); From d872842f44a2d42081a764c2eb66dbf7db0f9d0b Mon Sep 17 00:00:00 2001 From: yaohaishi Date: Tue, 5 Dec 2017 20:19:22 +0800 Subject: [PATCH 2/2] JAV-551 fix integration test failure. --- .../demo/jaxrs/tests/JaxrsIntegrationTestBase.java | 4 ++-- .../src/test/resources/microservice.yaml | 2 +- .../demo/springmvc/tests/SpringMvcIntegrationTestBase.java | 3 ++- .../tracing-tests/src/test/resources/microservice.yaml | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/integration-tests/jaxrs-tests/src/test/java/io/servicecomb/demo/jaxrs/tests/JaxrsIntegrationTestBase.java b/integration-tests/jaxrs-tests/src/test/java/io/servicecomb/demo/jaxrs/tests/JaxrsIntegrationTestBase.java index a90bfd09749..e538bb9c8ab 100644 --- a/integration-tests/jaxrs-tests/src/test/java/io/servicecomb/demo/jaxrs/tests/JaxrsIntegrationTestBase.java +++ b/integration-tests/jaxrs-tests/src/test/java/io/servicecomb/demo/jaxrs/tests/JaxrsIntegrationTestBase.java @@ -50,11 +50,11 @@ import io.servicecomb.common.rest.codec.RestObjectMapper; import io.servicecomb.demo.compute.Person; import io.servicecomb.demo.server.User; +import io.servicecomb.foundation.common.net.NetUtils; @Ignore public class JaxrsIntegrationTestBase { - - private final String baseUrl = "http://127.0.0.1:8080/"; + private final String baseUrl = "http://" + NetUtils.getHostAddress() + ":8080/"; private final RestTemplate restTemplate = new RestTemplate(); diff --git a/integration-tests/spring-zuul-tracing-tests/src/test/resources/microservice.yaml b/integration-tests/spring-zuul-tracing-tests/src/test/resources/microservice.yaml index 9e5f87387b2..30acddc71a3 100644 --- a/integration-tests/spring-zuul-tracing-tests/src/test/resources/microservice.yaml +++ b/integration-tests/spring-zuul-tracing-tests/src/test/resources/microservice.yaml @@ -7,7 +7,7 @@ cse: registry: address: http://127.0.0.1:30100 rest: - address: 0.0.0.0:8080 + address: 127.0.0.1:8080 handler: chain: Provider: diff --git a/integration-tests/springmvc-tests/src/test/java/io/servicecomb/demo/springmvc/tests/SpringMvcIntegrationTestBase.java b/integration-tests/springmvc-tests/src/test/java/io/servicecomb/demo/springmvc/tests/SpringMvcIntegrationTestBase.java index db5e6d125e5..f239aabaacb 100644 --- a/integration-tests/springmvc-tests/src/test/java/io/servicecomb/demo/springmvc/tests/SpringMvcIntegrationTestBase.java +++ b/integration-tests/springmvc-tests/src/test/java/io/servicecomb/demo/springmvc/tests/SpringMvcIntegrationTestBase.java @@ -56,11 +56,12 @@ import io.servicecomb.common.rest.codec.RestObjectMapper; import io.servicecomb.demo.compute.Person; import io.servicecomb.demo.server.User; +import io.servicecomb.foundation.common.net.NetUtils; @Ignore public class SpringMvcIntegrationTestBase { - private final String baseUrl = "http://127.0.0.1:8080/"; + private final String baseUrl = "http://" + NetUtils.getHostAddress() + ":8080/"; private final RestTemplate restTemplate = new RestTemplate(); diff --git a/integration-tests/tracing-tests/src/test/resources/microservice.yaml b/integration-tests/tracing-tests/src/test/resources/microservice.yaml index 76d78be55c2..b3beb8b6e53 100644 --- a/integration-tests/tracing-tests/src/test/resources/microservice.yaml +++ b/integration-tests/tracing-tests/src/test/resources/microservice.yaml @@ -7,9 +7,9 @@ cse: registry: address: http://127.0.0.1:30100 rest: - address: 0.0.0.0:8080?sslEnabled=false + address: 127.0.0.1:8080?sslEnabled=false highway: - address: 0.0.0.0:7070 + address: 127.0.0.1:7070 handler: chain: Provider: