Skip to content

Commit

Permalink
ARTEMIS-3042 simple properties based, extensible broker image
Browse files Browse the repository at this point in the history
  • Loading branch information
gtully committed May 15, 2023
1 parent c9c819a commit e59f954
Show file tree
Hide file tree
Showing 20 changed files with 766 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,15 @@ public static void main(String... args) throws Exception {
public static void verifyManagementDTO(File etc) {
if (etc != null) {
File management = new File(etc, "management.xml");

try {
ManagementContextDTO managementContextDTO = XmlUtil.decode(ManagementContextDTO.class, management);
if (managementContextDTO != null && managementContextDTO.getAuthorisation() != null) {
System.setProperty("javax.management.builder.initial", "org.apache.activemq.artemis.core.server.management.ArtemisMBeanServerBuilder");
if (management.exists()) {
try {
ManagementContextDTO managementContextDTO = XmlUtil.decode(ManagementContextDTO.class, management);
if (managementContextDTO != null && managementContextDTO.getAuthorisation() != null) {
System.setProperty("javax.management.builder.initial", "org.apache.activemq.artemis.core.server.management.ArtemisMBeanServerBuilder");
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
Expand Down Expand Up @@ -2143,7 +2144,7 @@ public void testRunPropertiesDudArgument() throws Exception {

// verify error
Object ret = Artemis.internalExecute("run", "--properties", "https://www.apache.org");
assertTrue(ret instanceof IllegalStateException);
assertTrue(ret instanceof FileNotFoundException);
}

@Test
Expand Down
51 changes: 51 additions & 0 deletions artemis-image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
###What is in the image

An _empty_, _open_ broker with a default acceptor on port 61616

- by empty: has no addresses or queues but will auto create on demand
- by open: has no security; authentication or authorization, users or roles

###How will the image behave

1) the image will use or create `/app/data` for persistence of data

2) the image will use any [.properties files](https://activemq.apache.org/components/artemis/documentation/latest/configuration-index.html#broker_properties) from `/app/etc` to augment broker configuration

3) the image will use `/app/etc/broker.xml` if present, to bootstrap configuration, the 'bring your own config' use case

###Build and Use

First build an OCI image tar file from this artemis project using mvn:

 `$> mvn compile jib:buildTar@now`

An OCI image is created as a tar file.

> *Note that any OCI compatible container runtime and registry can be used for the next steps, eg: docker, podman... I have used podman.*
To load the image tar into the local container registry, use:

 `$> sudo podman image load --input target/jib-image.tar`

To run the image detached with port 61616 bridged to the local host by podman, use:

 `$> sudo podman run --name=artemis -dp 61616:61616 localhost/target/activemq-artemis-image:<...>`

To determine the IP of the bridged pod by inspecting the container by its name, use:
`$> export BRIDGE_IP=`sudo podman inspect --format='{{.NetworkSettings.IPAddress}}' artemis`

Execute the artemis producer/consumer command line tools to interact with the broker.

 `$> ./bin/artemis producer --url tcp://$BRIDGE_IP:61616`

 `$> ./bin/artemis consumer --url tcp://$BRIDGE_IP:61616`

###Intent

The intent is that this image is useful as is. If one can trust users, having no access control or limits can work fine.

If not, then this image can be configured by mounting an `/app/etc` directory with property files that augment default broker configuration.
This image could also be the base for a derived jib image, by simply adding more property files to the `src/main/jib/config` directory.

see examples/README.md for some more detail.

7 changes: 7 additions & 0 deletions artemis-image/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
TODO:
- replace @classpath_file with cp from libs/*.jar directory - more extensible for folks that want extra jars/plugins in derived images
- or figure out a mount point for extra jars
- currently running as root!
- maybe we need a base image with an 'app' or 'java' user preconfigured with rw permissions on /app
- or do that in a launch.sh
- this is a known and reasonable limitation of jib https://github.com/GoogleContainerTools/jib/issues/1029
61 changes: 61 additions & 0 deletions artemis-image/examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
###Examples

This directory contains examples of customising the image for particular use cases

####amqp_sasl_scram_test__etc
In this example, you can run the image with configuration that locks the broker down to a single user on a single predefined
queue called `TEST`. The necessary configuration overrides:
- restricting the acceptor to AMQP/SASL-SCRAM
- providing RBAC for queue TEST

are in:`./amqp_sasl_scram_test__etc/amqp_sasl_scram.properties`

To exercise this example, you need to choose a password for the pre-configured user 'A'.
With SASL_SCRAM the broker retains a salted representation of that value, but not the plain text value.

Register your chosen password by creating `./amqp_sasl_scram_test__etc/user` using mvn as follows:

 `$> mvn exec:exec -Dexample.pwd=<some value>`

To see the result, cat the generated user file to see the stored representation:

 `$> cat ./amqp_sasl_scram_test__etc/user`

You can then mount the `./amqp_sasl_scram_test__etc directory` as `/app/etc` for the container and initialize JAAS
via the `java.security.auth.login.config` system property, which is passed to the JVM via the ENV `JDK_JAVA_OPTIONS` as follows:

 `$> sudo podman run --name=artemis-amqp -dp 61616:61616 --env JDK_JAVA_OPTIONS=-Djava.security.auth.login.config=/app/etc/login.config --privileged -v ./amqp_sasl_scram_test__etc:/app/etc localhost/target/activemq-artemis-image:<version>`

To determine the IP of the bridged pod by inspecting the container by its name, use:
`$> export BRIDGE_IP=`sudo podman inspect --format='{{.NetworkSettings.IPAddress}}' artemis-amqp`

Execute the artemis producer/consumer command line tools to validate secure access to the TEST queue using AMQP
SASL-SCRAM with your chosen password via:

 `$> ./bin/artemis producer --protocol amqp --url amqp://$BRIDGE_IP:61616 --user A --password <some value>`

 `$> ./bin/artemis consumer --protocol amqp --url amqp://$BRIDGE_IP:61616 --user A --password <some value>`

####byoc__etc
This is an example of "Bring Your Own Config" or BYOC. The image will look for `/app/etc/broker.xml`. If that file exists
it will be treated as the broker xml configuration for the embedded broker. If your existing configuration is nicely
locked down or if you want to provide some custom defaults for your image, referencing an existing broker.xml makes sense.
Property files can still be used to augment the defaults or be used solely for more dynamic parts of configuration.

To exercise the example, `./byoc__etc directory` as `/app/etc` for the container as follows:

 `$> sudo podman run --name=artemis-byoc -dp 61616:61616 --privileged -v ./byoc__etc:/app/etc localhost/target/activemq-artemis-image:<version>`

Peek at the broker logs to note the broker name 'byoc' configured from the broker.xml file

`$> sudo podman logs artemis-byoc

To determine the IP of the bridged pod by inspecting the container by its name, use:
`$> export BRIDGE_IP=`sudo podman inspect --format='{{.NetworkSettings.IPAddress}}' artemis-byoc`

Execute the artemis producer/consumer command line tools to validate, it behaves like the bare image:

 `$> ./bin/artemis producer --url tcp://$BRIDGE_IP:61616`

 `$> ./bin/artemis consumer --url tcp://$BRIDGE_IP:61616`

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------

## reset to default
securityEnabled=true

## reference user role files with login.config, -Djava.security.auth.login.config=jaas/login.config
## the broker JAAS domain in login.config
acceptorConfigurations.tcp.params.securityDomain=broker

## lock down broker acceptor
## to SCRAM AMQP
acceptorConfigurations.tcp.params.saslMechanisms=SCRAM-SHA-512
acceptorConfigurations.tcp.params.protocols=AMQP
acceptorConfigurations.tcp.params.saslLoginConfigScope=amqp-sasl-scram

## if over TLS, configure acceptor key and trust store
# acceptorConfigurations.tcp.params.sslEnabled=true
# acceptorConfigurations.tcp.params.keyStorePath=/app/etc/<keystore>.keystore
# acceptorConfigurations.tcp.params.keyStorePassword=<password>


## create TEST address and ANYCAST queue b/c we won't have createX permissions
## TEST is the default queue for ./bin/artemis producer
addressConfigurations.TEST.queueConfigs.TEST.routingType=ANYCAST

## grant users role read/write
securityRoles.TEST.users.send=true
securityRoles.TEST.users.consume=true

26 changes: 26 additions & 0 deletions artemis-image/examples/amqp_sasl_scram_test__etc/login.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

amqp-sasl-scram {
org.apache.activemq.artemis.spi.core.security.jaas.SCRAMPropertiesLoginModule required
;
};

broker {
org.apache.activemq.artemis.spi.core.security.jaas.SCRAMLoginModule required
;
};
18 changes: 18 additions & 0 deletions artemis-image/examples/amqp_sasl_scram_test__etc/role
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------

users=A
46 changes: 46 additions & 0 deletions artemis-image/examples/byoc__etc/broker.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version='1.0'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:activemq"
xsi:schemaLocation="urn:activemq:core schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core">

<!--
Configure an image in the traditional way.
Providing boilerplate xml can form the well known configuration for an organisational base image that can be further extended with properties
-->

<!-- set an example specific name, it appears in the started/stopped logging messages -->
<name>byoc</name>
<security-enabled>false</security-enabled>

<!-- broker properties in the image are still in play so there will be an acceptor
configured from src/main/resources/acceptors.properties -->

<addresses>
<address name="TEST">
<anycast>
<queue name="TEST"/>
</anycast>
</address>
</addresses>
</core>
</configuration>
77 changes: 77 additions & 0 deletions artemis-image/examples/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-pom</artifactId>
<version>2.29.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

<artifactId>artemis-image-examples</artifactId>
<name>Apache ActiveMQ Artemis Image Examples</name>
<packaging>pom</packaging>

<properties>
<!-- for checkstyle plugin -->
<activemq.basedir>${project.basedir}/../..</activemq.basedir>

<!-- for the locked down example user A is referenced in the amqp_sasl_scram_test__etc/role file,
so don't just change it here! -->
<example.user>A</example.user>
<!-- a password must be provided to generate the user credential data.
use: mvn exec:exec -Dexample.pwd=xyz on the command line to register your value in the example.user.file -->
<example.pwd></example.pwd>
<example.user.file>amqp_sasl_scram_test__etc/user</example.user.file>
</properties>

<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-server</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>


<build>
<plugins>
<!-- to easily create a single salted credential for our ${example.user.file}-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec-maven-plugin.version}</version>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath/>
<argument>org.apache.activemq.artemis.spi.core.security.jaas.SCRAMPropertiesLoginModule</argument>
<argument>${example.user}</argument>
<argument>${example.pwd}</argument>
</arguments>
<outputFile>${example.user.file}</outputFile>
</configuration>
</plugin>
</plugins>
</build>

</project>
Loading

0 comments on commit e59f954

Please sign in to comment.