Activemq setup
Panoramica
In questo documento si vuole documentare come installare un Apache Activemq con accesso alle code tramite passwd e uso di canale cifrato fuori da localhost.
Setup
Creare un utente activemq:
useradd -r -u 998 activemq
Scaricare e scompattare il pacchetto versione piu' recente in /opt.
Versione 5.4.0 e successive: lanciare bin/activemq setup /etc/default/activemq. Dare la proprietà di questo file all'utente activemq. Modificare il file /etc/default/activemq nelle righe:
ACTIVEMQ_USER="activemq" ACTIVEMQ_KILL_MAXSECONDS=10
La cartella $ACTIVEMQ_HOME/data deve diventare proprieta' dell'utente activemq:
sudo chown -R activemq $ACTIVEMQ_HOME/data
Si creano due soft link a $ACTIVEMQ_HOME chiamati rispettivamente apache-activemq e activemq, nella cartella che contiene $ACTIVEMQ_HOME (/opt/apache-activemq-5.4.1 ad esempio).
In $ACTIVEMQ_HOME/bin/linux-x86-32/ e in $ACTIVEMQ_HOME/bin/linux-x86-64/ c'e' lo script di startup che si chiama activemq: farne un link a /etc/init.d, inoltre creare come soft link una cartella $ACTIVEMQ_HOME/bin/linux che punta all'architettura corretta: ad esempio:
sudo ln -s $ACTIVEMQ_HOME/bin/linux-x86-32/activemq /etc/init.d/activemq sudo ln -s $ACTIVEMQ_HOME/bin/linux-x86-32/ $ACTIVEMQ_HOME/bin/linux
creare il file: /etc/insserv/overrides/activemq:
#!/bin/sh # # activemq ActiveMQ broker # # chkconfig: - 80 05 # description: Enable messaging service provided by Apache ActiveMQ # ### BEGIN INIT INFO # Provides: activemq # Required-Start: $remote_fs $network # Required-Stop: $remote_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Description: ActiveMQ broker # Short-Description: Enable messaging service provided by ActiveMQ broker ### END INIT INFO
sudo insserv activemq
(il file /etc/insserv/overrides/activemq serve per evitare l'errore 'insserv: warning: script 'activemq' missing LSB tags and overrides')
Alternativamente per gli script di avvio (sconsigliato): Rendere avviabile come servizio unix (va bene del CentOS).
Se si usa Debian provare questo script che è lo script di avvio di tomcat6 modificato a mano.
Attenzione setup solo per le versioni vecchiotte
Siccome si userà lo SSL, è necessario modificare gli script $ACTIVEMQ_HOME/bin/activemq e $ACTIVEMQ_HOME/bin/activemq-admin: si decommenta la sezione in cui si permette a JMX un accesso senza SSL e senza autenticazione:
if [ -z "$SUNJMX" ] ; then SUNJMX="-Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" #SUNJMX="-Dcom.sun.management.jmxremote" fi
Senza questa modifica, fallisce il comando /etc/init.d/activemq stop.
Può essere necessario modificare a mano anche la variabile saveddir e la porta di connessione JMX (da 1616 a 1099), se non funziona.
Inoltre si consiglia di editare $ACTIVEMQ_HOME/conf/log4j.properties e togliere i valori "stdout" o "console" dalla riga:
log4j.rootLogger=INFO, out
(altrimenti arriva troppo log sulla console).
Se allo stop si riceve un messaggio che lamenta che la porta JMX è occupata,
Stopping Apache ActiveMQ Message Broker: Errore: Eccezione dell'agente : java.rmi.server.ExportException: Port already in use: 1099; nested exception is: java.net.BindException: Address already in use
ho trovato la soluzione in questo articolo.
Se camel non sembra funzionare (activemq-5.5.1)
Nella versione 5.5.1 manca la cartella $ACTIVEMQ_HOME/webapps/camel ed il suo contenuto. Quindi camel non si avvia neanche se si include jetty.xml in activemq.xml e si crea un file camel.xml. Bisogna copiare la cartella $ACTIVEMQ_HOME/webapps/camel ed il suo contenuto da un activemq-5.5.0.
Password
Partire dal documento di riferimento. Le informazioni utili sono quelle del primo schema di autenticazione (NON quello simple).
Creare in $ACTIVEMQ_HOME/conf il file login.config (come da documento di riferimento);
in $ACTIVEMQ_HOME/conf lanciare
mkdir -p org/apache/activemq/security/
Nella directory creata copiare i due file users.properties e groups.properties, come da esempio nel documento di riferimento, dopo aver modificato la passwd dell'utente system o, ancora meglio, dopo aver creaton un altro username con una sua passwd nel gruppo users e admins.
Creare anche il file login.properties, come da esempio nel documento di riferimento.
Accertarsi che il file $ACTIVEMQ_HOME/conf/credentials.properties contenga username e passwd dell'utente system o equivalente.
Aggiungere in $ACTIVEMQ_HOME/conf/activemq.xml, dentro la sezione broker (attenzione: rispettare l'ordine alfabetico dei nodi. E' importante):
<plugins> <jaasAuthenticationPlugin configuration="activemq-domain" /> <authorizationPlugin> <map> <authorizationMap> <authorizationEntries> <authorizationEntry queue=">" read="users" write="users" admin="users" /> <authorizationEntry queue="USERS.>" read="users" write="users" admin="users" /> <authorizationEntry queue="GUEST.>" read="guests" write="guests,users" admin="guests,users" /> <authorizationEntry topic=">" read="users" write="users" admin="users" /> <authorizationEntry topic="USERS.>" read="users" write="users" admin="users" /> <authorizationEntry topic="GUEST.>" read="guests" write="guests,users" admin="guests,users" /> <authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users" admin="guests,users"/> </authorizationEntries> </authorizationMap> </map> </authorizationPlugin> </plugins>
In cui activemq-domain e' la keywork del file login.config e USERS e GUESTS sono due code di esempio da personalizzare nel proprio caso.
Mettere al sicuro la web console sulla porta 8161
Invece di configurare JAAS per usare le credenziali create nella sezione precedente, usare una proxy inversa con apache dalla porta 443 alla 8161 e poi autenticare con shibboleth o ldap.
Creare nel default host ssl una sezione:
<Location /admin> ProxyPass http://localhost:8161/admin ProxyPassReverse http://localhost:8161/admin AuthName "Amministrazione di ActiveMQ" order allow,deny allow from all AuthType Basic AuthBasicProvider ldap AuthzLDAPAuthoritative off AuthLDAPUrl "ldap://ldap2.unimore.it/ou=people,dc=unimore,dc=it?uid?sub?objectClass=*" TLS Require ldap-user malvezzi d.crecchia giova robby fabiofe irenef </Location>
Nello stesso file, all'inizio, fuori dal contesto <VirtualHost _default_:443> aggiungere:
LDAPTrustedGlobalCert CA_BASE64 /etc/ssl/certs/tcs-chain.pem LDAPTrustedMode TLS
Abilitare i seguenti moduli:
sudo a2enmod proxy_http authnz_ldap
E modificare il file /etc/apache2/mods-enables/proxy.conf e togliere il deny all, cioe' ottenere:
<Proxy *> AddDefaultCharset off Order deny,allow #Deny from all #Allow from .example.com </Proxy>
ssl
Partire dalla documentazione: è necessario creare un truststore che contiene la chiave privata ed un client store con le CA.
Per mettere una chiave privata tipo EuroPKI dentro un keystore java, non ho trovato altri sistemi che extkeytool di shibboleth1.3, che implica scaricare ed installare (ma non configurare) il pacchetto.
Poi sarà necessario aggiungere all'altezza della sezione transportConnectors (cioé alla pari, dentro la sezione broker) una sezione (rispettare l'ordine alfabetico dei nodi, altrimenti da' errore):
<sslContext> <sslContext keyStore="server.store" keyStorePassword="secret" trustStore="client.ks" trustStorePassword="password"/> </sslContext>
Se si usa come sistema di init.d la versione con il wrapper, modificare il file: ./bin/linux-x86-[32-64]/wrapper.conf e commentare le righe che fanno riferimento ai keystore:
# Java Additional Parameters # note that n is the parameter number starting from 1. wrapper.java.additional.1=-Dactivemq.home=%ACTIVEMQ_HOME% wrapper.java.additional.2=-Dactivemq.base=%ACTIVEMQ_BASE% #wrapper.java.additional.3=-Djavax.net.ssl.keyStorePassword=password #wrapper.java.additional.4=-Djavax.net.ssl.trustStorePassword=password #wrapper.java.additional.5=-Djavax.net.ssl.keyStore=%ACTIVEMQ_BASE%/conf/ahab.store #wrapper.java.additional.6=-Djavax.net.ssl.trustStore=%ACTIVEMQ_BASE%/conf/broker.ts wrapper.java.additional.3=-Dcom.sun.management.jmxremote wrapper.java.additional.4=-Dorg.apache.activemq.UseDedicatedTaskRunner=true wrapper.java.additional.5=-Djava.util.logging.config.file=logging.properties
ATTENZIONE: le righe successive a quelle commentate devono avere ordinali consecutivi.
Cambiare il logger
Per passare da jcl a logback, copiare in $ACTIVEMQ_HOME/lib:
jcl-over-slf4j-1.6.4.jar logback-access-1.0.0.jar logback-classic-1.0.0.jar logback-core-1.0.0.jar slf4j-api-1.6.4.jar
e cancellare le librerie:
jcl-over-slf4j-1.5.11.jar slf4j-api-1.5.11.jar
Poi creare un file $ACTIVEMQ_HOME/conf/logback.xml del tipo:
<configuration scan="true" scanPeriod="30 seconds"> <appender name="CAMEL" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>camel.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>camel-%d{yyyy-MM-dd}.log</FileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern>%date %msg%n</Pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>${activemq.base}/data/activemq.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>${activemq.base}/data/activemq-%d{yyyy-MM-dd}.log</FileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern>%date %msg%n</Pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender"> <SyslogHost>localhost</SyslogHost> <Facility>DAEMON</Facility> <SuffixPattern>[%logger] %msg</SuffixPattern> </appender> <logger name="it.unimore.cesia.ruby_processor" additivity="false"> <level value="DEBUG" /> <appender-ref ref="CAMEL" /> <appender-ref ref="SYSLOG" /> </logger> <logger name="it.unimore.cesia.db_processor" additivity="false"> <level value="DEBUG" /> <appender-ref ref="CAMEL" /> <appender-ref ref="SYSLOG" /> </logger> <logger name="it.unimore.cesia" additivity="false"> <level value="INFO"/> <appender-ref ref="CAMEL" /> <appender-ref ref="SYSLOG" /> </logger> <logger name="org.apache.activemq" additivity="false"> <level value="INFO"/> <appender-ref ref="FILE" /> </logger> <logger name="org.apache.camel" additivity="false"> <level value="DEBUG"/> <appender-ref ref="FILE" /> </logger> <root level="ERROR"> <appender-ref ref="SYSLOG" /> </root> </configuration>