Jadice Server JMS-Schnittstelle mit TLS absichern
Step-by-step guide
Um die JMS-Schnittstelle von jadice server über TLS abzusichern müssen zwei Dinge angepasst werden.
Der embedded ActiveMQ-Broker, den jadice server mitbringt, muss so konfiguriert werden, dass dieser die für die Verschlüsselung benötigten Keystores kennt. Dazu in der Datei
server-config/application/embedded-activemq-broker.xml
in der Bean "broker" folgenden Eintrag ergänzen:jetty-tls.xml<amq:sslContext> <amq:sslContext keyStore="C:\path\to\your\keystore.jks" keyStorePassword="test" trustStore="C:\path\to\your\cacerts" trustStorePassword="changeit"/> </amq:sslContext>
Beachten Sie bitte, dass für den Keystore der absolute Pfad im Dateisystem angegeben werden muss.
Ebenfalls in der Datei
server-config/application/embedded-activemq-broker.xml
die Zeile<amq:transportConnector name="nio" uri="nio://0.0.0.0:${jadice.server.activemq-port}" discoveryUri="multicast://default?group=${jadice.server.activemq-group}" />
durch folgende, um das Protokoll "ssl" erweiterte, ersetzen:
<amq:transportConnector name="nio+ssl" uri="nio+ssl://0.0.0.0:${jadice.server.activemq-port}" discoveryUri="multicast://default?group=${jadice.server.activemq-group}" />
Nun kann der Server von einem Client über SSL angesprochen werden, z.B.
ssl://localhost:61616
Die komplette Datei mit Anpassungen: embedded-activemq-broker.xml
Passwörter absichern
Im obigen Beispiel stehen die Passwörter im Klartext in der Konfigurationsdatei. Dies ist natürlich für Produktionsumgebungen nicht zu empfehlen. ActiveMQ bietet die Möglichkeit Passwörter durch Verschlüsselung abzusichern (siehe ActiveMQ - Encrypted passwords).
Beispiel mit dem Verschlüsselungspasswort "activemq", dem Keystore-Passwort "test" und dem Truststore-Passwort "changeit":
Verschlüsseln der Passwörter für den KeyStore und den TrustStore.
$ apache-activemq/bin/activemq encrypt --password activemq --input test --algorithm PBEWithMD5AndDES ... Encrypted text: ZFNmPbPmkaGnqXqRl6+7KA== $ apache-activemq/bin/activemq encrypt --password activemq --input changeit --algorithm PBEWithMD5AndDES ... Encrypted text: OpGztxCdz63JkKD0mYWLDpWq/+nzR7H7
Passwörter in der Datei
server-config/application/embedded-activemq-broker.xml
durch Properties ersetzen:jetty-tls.xml<amq:sslContext> <amq:sslContext keyStore="C:\path\to\your\keystore.jks" keyStorePassword="${jadice.server.activemq.keystore.password}" trustStore="C:\path\to\your\cacerts" trustStorePassword="${jadice.server.activemq.truststore.password}"/> </amq:sslContext>
Die komplette Datei mit den Anpassungen: embedded-activemq-broker.xml
In der Datei
server-config/application/server.xml
werden die verschlüsselten Passwörter nun als Properties hinterlegt. Außerdem wird der PropertyLoader so konfiguriert, dass er die Properties mithilfe des Verschlüssellungs-Passworts aus einer Umgebungsvariablen entschlüsseln kann. Dazu werden die beiden neuen Beans "environmentVariablesConfiguration" und "configurationEncryptor" definiert, sowie die vorhandene Bean "propertyConfigurer" (mit der Klasse PropertyPlaceholderConfigurer) wie folgt angepasst:Ergänzung in server.xml<bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig"> <property name="algorithm" value="PBEWithMD5AndDES" /> <property name="passwordEnvName" value="ACTIVEMQ_ENCRYPTION_PASSWORD" /> </bean> <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor"> <property name="config" ref="environmentVariablesConfiguration" /> </bean> <bean id="propertyConfigurer" class="org.jasypt.spring4.properties.EncryptablePropertyPlaceholderConfigurer"> <constructor-arg ref="configurationEncryptor" /> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="searchSystemEnvironment" value="true" /> <property name="properties"> <props> <!-- Name of the JMS request queue for new job requests; Reference to the default queue name as defined in class JMSJobFactory --> <prop key="jadice.server.queue-name"> #{T(com.levigo.jadice.server.jms.client.JMSJobFactory).DEFAULT_QUEUE_NAME} </prop> <!-- Active MQ specific values: AMQ TCP Port and group name. These values can be dropped if another MOM is configured below. --> <prop key="jadice.server.activemq-port">61616</prop> <prop key="jadice.server.activemq-group">jadice-server.cluster</prop> <prop key="jadice.server.activemq.keystore.password">ENC(ZFNmPbPmkaGnqXqRl6+7KA==)</prop> <prop key="jadice.server.activemq.truststore.password">ENC(OpGztxCdz63JkKD0mYWLDpWq/+nzR7H7)</prop> </props> </property> </bean>
Die komplette Datei mit den Anpassungen: server.xml
Eine Umgebungsvariable für das Verschlüsselungspasswort anlegen.
# unter linux $ export ACTIVEMQ_ENCRYPTION_PASSWORD=activemq # unter Windows # z.B. über die GUI: Systemsteuerung\System und Sicherheit\System > Erweiterte Systemeinstellungen > Umgebungsvariablen > Systemvariablen "Neu"
Bouncy Castle
Um modernere Verschlüsselungsalgorithmen zu verwenden, kann z.B. ein Bouncy Castle JCE Provider verwendet werden.
<bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig"> <property name="algorithm" value="PBEWITHSHA256AND128BITAES-CBC-BC" /> <property name="passwordEnvName" value="ACTIVEMQ_ENCRYPTION_PASSWORD" /> </bean> <bean id="jceProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider"> </bean> <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor"> <property name="config" ref="environmentVariablesConfiguration" /> <property name="provider" ref="jceProvider" /> </bean>
Die Verschlüsselung in Java könnte etwa so aussehen (vgl. Using Jasypt with the Bouncy Castle JCE provider)
public static void main(String[] args) { StandardPBEStringEncryptor myFirstEncryptor = new StandardPBEStringEncryptor(); myFirstEncryptor.setProvider(new BouncyCastleProvider()); myFirstEncryptor.setAlgorithm("PBEWITHSHA256AND128BITAES-CBC-BC"); myFirstEncryptor.setPassword("activemq"); String keyStorePassword = myFirstEncryptor.encrypt("test"); String trustStorePassword = myFirstEncryptor.encrypt("changeit"); System.out.println("keyStorePassword: " + keyStorePassword); System.out.println("trustStorePassword " + trustStorePassword); }
Weitere Informationen
Informationen zu den Einstellungen können Sie der Dokumentation von ActiveMQ entnehmen:
Treten Probleme bei der Aktivierung von TLS auf, hilft die System-Property -Djavax.net.debug=all
oft weiter, um das Problem einzugrenzen. Diese Einstellung kann in der Datei wrapper/wrapper.conf
eingetragen werden. Oracle bietet einen ausführlichen Artikel zum Thema "Debugging SSL/TLS Connections" an.
Related articles