diff --git a/core/src/main/java/com/taobao/arthas/core/command/basic1000/AuthCommand.java b/core/src/main/java/com/taobao/arthas/core/command/basic1000/AuthCommand.java index 0ca808d0..bd99640e 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/basic1000/AuthCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/basic1000/AuthCommand.java @@ -32,7 +32,7 @@ import com.taobao.middleware.cli.annotations.Summary; @Name(ArthasConstants.AUTH) @Summary("Authenticates the current session") @Description(Constants.EXAMPLE + - " auth" + + " auth\n" + " auth \n" + " auth --username \n" + Constants.WIKI + Constants.WIKI_HOME + ArthasConstants.AUTH) diff --git a/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java b/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java index 4bc7c30b..f1e7fd53 100644 --- a/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java +++ b/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java @@ -69,6 +69,7 @@ import com.taobao.arthas.core.shell.term.impl.http.session.HttpSessionManager; import com.taobao.arthas.core.shell.term.impl.httptelnet.HttpTelnetTermServer; import com.taobao.arthas.core.util.ArthasBanner; import com.taobao.arthas.core.util.FileUtils; +import com.taobao.arthas.core.util.IPUtils; import com.taobao.arthas.core.util.InstrumentationUtils; import com.taobao.arthas.core.util.LogUtil; import com.taobao.arthas.core.util.StringUtils; @@ -393,6 +394,19 @@ public class ArthasBootstrap { } this.httpSessionManager = new HttpSessionManager(); + if (IPUtils.isAllZeroIP(configure.getIp()) && StringUtils.isBlank(configure.getPassword())) { + // 当 listen 0.0.0.0 时,强制生成密码,防止被远程连接 + String errorMsg = "Listening on 0.0.0.0 is very dangerous! External users can connect to your machine! " + + "No password is currently configured. " + "Therefore, a default password is generated, " + + "and clients need to use the password to connect!"; + AnsiLog.error(errorMsg); + configure.setPassword(StringUtils.randomString(64)); + AnsiLog.error("Generated arthas password: " + configure.getPassword()); + + logger().error(errorMsg); + logger().info("Generated arthas password: " + configure.getPassword()); + } + this.securityAuthenticator = new SecurityAuthenticatorImpl(configure.getUsername(), configure.getPassword()); shellServer = new ShellServerImpl(options); diff --git a/core/src/main/java/com/taobao/arthas/core/util/IPUtils.java b/core/src/main/java/com/taobao/arthas/core/util/IPUtils.java index 9d2b704a..00e1b2a5 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/IPUtils.java +++ b/core/src/main/java/com/taobao/arthas/core/util/IPUtils.java @@ -23,7 +23,8 @@ public class IPUtils { } /** - * get IP address, automatically distinguish the operating system.(windows or linux) + * get IP address, automatically distinguish the operating system.(windows or + * linux) * * @return String */ @@ -33,7 +34,7 @@ public class IPUtils { if (isWindowsOS()) { ip = InetAddress.getLocalHost(); } else { - //scan all NetWorkInterfaces if it's loopback address + // scan all NetWorkInterfaces if it's loopback address if (!InetAddress.getLocalHost().isLoopbackAddress()) { ip = InetAddress.getLocalHost(); } else { @@ -50,7 +51,8 @@ public class IPUtils { while (ips.hasMoreElements()) { ip = ips.nextElement(); // IP starts with 127. is loopback address - if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && !ip.getHostAddress().contains(":")) { + if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() + && !ip.getHostAddress().contains(":")) { bFindIP = true; break; } @@ -65,4 +67,19 @@ public class IPUtils { return ip == null ? null : ip.getHostAddress(); } + + public static boolean isAllZeroIP(String ipStr) { + if (ipStr == null || ipStr.isEmpty()) { + return false; + } + char[] charArray = ipStr.toCharArray(); + + for (char c : charArray) { + if (c != '0' && c != '.' && c != ':') { + return false; + } + } + + return true; + } } diff --git a/core/src/test/java/com/taobao/arthas/core/util/IPUtilsTest.java b/core/src/test/java/com/taobao/arthas/core/util/IPUtilsTest.java new file mode 100644 index 00000000..b3ba2a68 --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/util/IPUtilsTest.java @@ -0,0 +1,56 @@ +package com.taobao.arthas.core.util; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class IPUtilsTest { + + @Test + public void testZeroIPv4() { + String zero = "0.0.0.0"; + assertEquals(true, IPUtils.isAllZeroIP(zero)); + } + + @Test + public void testZeroIPv6() { + String zero = "::"; + assertEquals(true, IPUtils.isAllZeroIP(zero)); + } + + @Test + public void testNormalIPv6() { + String ipv6 = "2001:db8:85a3::8a2e:370:7334"; + assertEquals(false, IPUtils.isAllZeroIP(ipv6)); + } + + @Test + public void testLeadingZerosIPv6() { + String ipv6 = "0000::0000:0000"; + assertEquals(true, IPUtils.isAllZeroIP(ipv6)); + } + + @Test + public void testTrailingZerosIPv6() { + String ipv6 = "::0000:0000:0000"; + assertEquals(true, IPUtils.isAllZeroIP(ipv6)); + } + + @Test + public void testMixedZerosIPv6() { + String ipv6 = "0000::0000:0000:0000:0000"; + assertEquals(true, IPUtils.isAllZeroIP(ipv6)); + } + + @Test + public void testEmptyIPv6() { + String empty = ""; + assertEquals(false, IPUtils.isAllZeroIP(empty)); + } + + @Test + public void testBlankIPv6() { + String blank = " "; + assertEquals(false, IPUtils.isAllZeroIP(blank)); + } +}