activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From clebertsuco...@apache.org
Subject [1/2] activemq-artemis git commit: More on ARTEMIS-594: support HTTPS access to hawtio Remove the keystore.jks in distribution Add documentation Add cli options
Date Thu, 30 Jun 2016 14:43:04 GMT
Repository: activemq-artemis
Updated Branches:
  refs/heads/master 880539a96 -> 77cc6407c


More on ARTEMIS-594: support HTTPS access to hawtio
  Remove the keystore.jks in distribution
  Add documentation
  Add cli options


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/3522979b
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/3522979b
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/3522979b

Branch: refs/heads/master
Commit: 3522979bda95e9be57f31739b22101feffbb21a2
Parents: 880539a
Author: Howard Gao <howard.gao@gmail.com>
Authored: Thu Jun 30 09:56:04 2016 +0800
Committer: Howard Gao <howard.gao@gmail.com>
Committed: Thu Jun 30 09:56:58 2016 +0800

----------------------------------------------------------------------
 .../activemq/artemis/cli/commands/Create.java   |  57 ++++++++++--
 .../cli/commands/etc/bootstrap-web-settings.txt |   2 +-
 .../artemis/cli/commands/etc/keystore.jks       | Bin 2236 -> 0 bytes
 .../apache/activemq/cli/test/ArtemisTest.java   |  88 +++++++++++++++++++
 docs/user-manual/en/security.md                 |  32 +++++++
 5 files changed, 173 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3522979b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
index 991bd69..c99bc78 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
@@ -58,7 +58,7 @@ public class Create extends InputAbstract {
 
    private static final Integer HQ_PORT = 5445;
 
-   private static final Integer HTTP_PORT = 8161;
+   public static final Integer HTTP_PORT = 8161;
 
    private static final Integer MQTT_PORT = 1883;
 
@@ -72,7 +72,6 @@ public class Create extends InputAbstract {
    public static final String ETC_LOGGING_PROPERTIES = "etc/logging.properties";
    public static final String ETC_BOOTSTRAP_XML = "etc/bootstrap.xml";
    public static final String ETC_BROKER_XML = "etc/broker.xml";
-   public static final String ETC_WEB_KEYSTORE = "etc/keystore.jks";
 
    public static final String ETC_ARTEMIS_ROLES_PROPERTIES = "etc/artemis-roles.properties";
    public static final String ETC_ARTEMIS_USERS_PROPERTIES = "etc/artemis-users.properties";
@@ -103,6 +102,21 @@ public class Create extends InputAbstract {
    @Option(name = "--http-port", description = "The port number to use for embedded web server
(Default: 8161)")
    int httpPort = HTTP_PORT;
 
+   @Option(name = "--ssl-key", description = "The key store path for embedded web server")
+   String sslKey;
+
+   @Option(name = "--ssl-key-password", description = "The key store password")
+   String sslKeyPassword;
+
+   @Option(name = "--use-client-auth", description = "If the embedded server requires client
authentication")
+   boolean useClientAuth;
+
+   @Option(name = "--ssl-trust", description = "The trust store path in case of client authentication")
+   String sslTrust;
+
+   @Option(name = "--ssl-trust-password", description = "The trust store password")
+   String sslTrustPassword;
+
    @Option(name = "--name", description = "The name of the broker (Default: same as host)")
    String name;
 
@@ -347,6 +361,27 @@ public class Create extends InputAbstract {
       return clusterPassword;
    }
 
+   public String getSslKeyPassword() {
+      if (sslKeyPassword == null) {
+         sslKeyPassword = inputPassword("--ssl-key-password", "Please enter the keystore
password:", "password");
+      }
+      return sslKeyPassword;
+   }
+
+   public String getSslTrust() {
+      if (sslTrust == null) {
+         sslTrust = input("--ssl-trust", "Please enter the trust store path:", "/etc/truststore.jks");
+      }
+      return sslTrust;
+   }
+
+   public String getSslTrustPassword() {
+      if (sslTrustPassword == null) {
+         sslTrustPassword = inputPassword("--ssl-key-password", "Please enter the keystore
password:", "password");
+      }
+      return sslTrustPassword;
+   }
+
    public void setClusterPassword(String clusterPassword) {
       this.clusterPassword = clusterPassword;
    }
@@ -522,6 +557,21 @@ public class Create extends InputAbstract {
          filters.put("${journal.settings}", "ASYNCIO");
       }
 
+      if (sslKey != null) {
+         filters.put("${web.protocol}", "https");
+         getSslKeyPassword();
+         String extraWebAttr = " keyStorePath=\"" + sslKey + "\" keyStorePassword=\"" + sslKeyPassword
+ "\"";
+         if (useClientAuth) {
+            getSslTrust();
+            getSslTrustPassword();
+            extraWebAttr += " clientAuth=\"true\" trustStorePath=\"" + sslTrust + "\" trustStorePassword=\""
+ sslTrustPassword + "\"";
+         }
+         filters.put("${extra.web.attributes}", extraWebAttr);
+      }
+      else {
+         filters.put("${web.protocol}", "http");
+         filters.put("${extra.web.attributes}", "");
+      }
       filters.put("${user}", System.getProperty("user.name", ""));
       filters.put("${default.port}", String.valueOf(defaultPort + portOffset));
       filters.put("${amqp.port}", String.valueOf(AMQP_PORT + portOffset));
@@ -625,9 +675,6 @@ public class Create extends InputAbstract {
          filters.put("${bootstrap-web-settings}", applyFilters(readTextFile(ETC_BOOTSTRAP_WEB_SETTINGS_TXT),
filters));
       }
 
-      //keystore
-      write(ETC_WEB_KEYSTORE);
-
       if (noAmqpAcceptor) {
          filters.put("${amqp-acceptor}", "");
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3522979b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt
b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt
index 5612269..49c5e37 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt
@@ -1,4 +1,4 @@
    <!-- The web server is only bound to loalhost by default -->
-   <web bind="http://localhost:${http.port}" path="web">
+   <web bind="${web.protocol}://localhost:${http.port}" path="web"${extra.web.attributes}>
        <app url="jolokia" war="jolokia-war-1.3.3.war"/>
    </web>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3522979b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/keystore.jks
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/keystore.jks
b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/keystore.jks
deleted file mode 100644
index f5a6760..0000000
Binary files a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/keystore.jks
and /dev/null differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3522979b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
index b3a9e29..969138f 100644
--- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
+++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
@@ -20,7 +20,12 @@ import javax.jms.Connection;
 import javax.jms.MessageProducer;
 import javax.jms.Session;
 import javax.jms.TextMessage;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.activemq.artemis.api.core.SimpleString;
@@ -43,6 +48,9 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
 
 /**
  * Test to validate that the CLI doesn't throw improper exceptions when invoked.
@@ -116,6 +124,81 @@ public class ArtemisTest {
    }
 
    @Test
+   public void testWebConfig() throws Exception {
+      Run.setEmbedded(true);
+      //instance1: default using http
+      File instance1 = new File(temporaryFolder.getRoot(), "instance1");
+      Artemis.main("create", instance1.getAbsolutePath(), "--silent");
+      File bootstrapFile = new File(new File(instance1, "etc"), "bootstrap.xml");
+      Assert.assertTrue(bootstrapFile.exists());
+      Document config = parseXml(bootstrapFile);
+      Element webElem = (Element)config.getElementsByTagName("web").item(0);
+
+      String bindAttr = webElem.getAttribute("bind");
+      String bindStr = "http://localhost:" + Create.HTTP_PORT;
+
+      Assert.assertEquals(bindAttr, bindStr);
+      //no any of those
+      Assert.assertFalse(webElem.hasAttribute("keyStorePath"));
+      Assert.assertFalse(webElem.hasAttribute("keyStorePassword"));
+      Assert.assertFalse(webElem.hasAttribute("clientAuth"));
+      Assert.assertFalse(webElem.hasAttribute("trustStorePath"));
+      Assert.assertFalse(webElem.hasAttribute("trustStorePassword"));
+
+      //instance2: https
+      File instance2 = new File(temporaryFolder.getRoot(), "instance2");
+      Artemis.main("create", instance2.getAbsolutePath(), "--silent", "--ssl-key", "etc/keystore",
"--ssl-key-password", "password1");
+      bootstrapFile = new File(new File(instance2, "etc"), "bootstrap.xml");
+      Assert.assertTrue(bootstrapFile.exists());
+      config = parseXml(bootstrapFile);
+      webElem = (Element)config.getElementsByTagName("web").item(0);
+
+      bindAttr = webElem.getAttribute("bind");
+      bindStr = "https://localhost:" + Create.HTTP_PORT;
+      Assert.assertEquals(bindAttr, bindStr);
+
+      String keyStr = webElem.getAttribute("keyStorePath");
+      Assert.assertEquals("etc/keystore", keyStr);
+      String keyPass = webElem.getAttribute("keyStorePassword");
+      Assert.assertEquals("password1", keyPass);
+
+      Assert.assertFalse(webElem.hasAttribute("clientAuth"));
+      Assert.assertFalse(webElem.hasAttribute("trustStorePath"));
+      Assert.assertFalse(webElem.hasAttribute("trustStorePassword"));
+
+      //instance3: https with clientAuth
+      File instance3 = new File(temporaryFolder.getRoot(), "instance3");
+      Artemis.main("create", instance3.getAbsolutePath(), "--silent", "--ssl-key", "etc/keystore",
+              "--ssl-key-password", "password1",
+              "--use-client-auth", "--ssl-trust", "etc/truststore", "--ssl-trust-password",
"password2");
+      bootstrapFile = new File(new File(instance3, "etc"), "bootstrap.xml");
+      Assert.assertTrue(bootstrapFile.exists());
+
+      byte[] contents = Files.readAllBytes(bootstrapFile.toPath());
+      String cfgText = new String(contents);
+      System.out.println("confg: " + cfgText);
+
+      config = parseXml(bootstrapFile);
+      webElem = (Element)config.getElementsByTagName("web").item(0);
+
+      bindAttr = webElem.getAttribute("bind");
+      bindStr = "https://localhost:" + Create.HTTP_PORT;
+      Assert.assertEquals(bindAttr, bindStr);
+
+      keyStr = webElem.getAttribute("keyStorePath");
+      Assert.assertEquals("etc/keystore", keyStr);
+      keyPass = webElem.getAttribute("keyStorePassword");
+      Assert.assertEquals("password1", keyPass);
+
+      String clientAuthAttr = webElem.getAttribute("clientAuth");
+      Assert.assertEquals("true", clientAuthAttr);
+      String trustPathAttr = webElem.getAttribute("trustStorePath");
+      Assert.assertEquals("etc/truststore", trustPathAttr);
+      String trustPass = webElem.getAttribute("trustStorePassword");
+      Assert.assertEquals("password2", trustPass);
+   }
+
+   @Test
    public void testSimpleRun() throws Exception {
       String queues = "q1,t2";
       String topics = "t1,t2";
@@ -230,5 +313,10 @@ public class ArtemisTest {
       Assert.assertEquals(0, LibaioContext.getTotalMaxIO());
    }
 
+   private static Document parseXml(File xmlFile) throws ParserConfigurationException, IOException,
SAXException {
+      DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+      DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
+      return domBuilder.parse(xmlFile);
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3522979b/docs/user-manual/en/security.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/security.md b/docs/user-manual/en/security.md
index 53a6efb..6c0d078 100644
--- a/docs/user-manual/en/security.md
+++ b/docs/user-manual/en/security.md
@@ -648,3 +648,35 @@ they use for this should always be changed from the installation default
 to prevent a security risk.
 
 Please see [Management](management.md) for instructions on how to do this.
+
+
+## Securing the console
+
+Artemis comes with a web console that allows user to browse Artemis documentation via an
embedded server. By default the
+web access is plain HTTP. It is configured in `bootstrap.xml`:
+
+    <web bind="http://localhost:8161" path="web">
+        <app url="jolokia" war="jolokia-war-1.3.3.war"/>
+    </web>
+
+Alternatively you can edit the above configuration to enable secure access using HTTPS protocol.
e.g.:
+
+    <web bind="https://localhost:8443"
+        path="web"
+        keyStorePath="${artemis.instance}/etc/keystore.jks"
+        keyStorePassword="password">
+        <app url="jolokia" war="jolokia-war-1.3.3.war"/>
+    </web>
+
+As shown in the example, to enable https the first thing to do is config the `bind` to be
an `https` url. In addition,
+You will have to configure a few extra properties desribed as below.
+
+-   `keyStorePath` - The path of the key store file.
+
+-   `keyStorePassword` - The key store's password.
+
+-   `clientAuth` - The boolean flag indicates whether or not client authentication is required.
Default is `false`.
+
+-   `trustStorePath` - The path of the trust store file. This is needed only if `clientAuth`
is `true`.
+
+-   `trustStorePassword` - The trust store's password.


Mime
View raw message