2 title: "MCollective » Deploy » Middleware » ActiveMQ Keystores"
3 subtitle: "Setting Up Keystores For ActiveMQ"
7 [tls]: ./activemq.html#tls-credentials
9 Since ActiveMQ runs on the JVM, [configuring it to use TLS encryption/authentication][tls] requires a pair of Java keystores; it can't just use the normal PEM format certificates and keys used by Puppet and MCollective.
11 Java keystores require some non-obvious steps to set up, so this guide provides full instructions, including both a [manual method](#manually-creating-keystores) and a [Puppet method](#creating-keystores-with-puppet).
14 ## Step 0: Obtain Certificates and Keys
16 ActiveMQ needs the following credentials:
18 * A copy of the site's CA certificate
19 * A certificate signed by the site's CA
20 * A private key to match its certificate
22 These can come from anywhere, but the CA has to match the one used by MCollective.
24 The easiest approach is to re-use your site's Puppet cert infrastructure, since it's already everywhere and has tools for issuing and signing arbitrary certificates.
26 As ever, remember to **protect the private key.**
28 ### Option A: Re-Use the Node's Puppet Agent Certificate
30 On your ActiveMQ server:
32 * Locate the ssldir by running `sudo puppet agent --configprint ssldir`.
33 * Copy the following files to your working directory, making sure to give unique names to the cert and private key:
34 * `<ssldir>/certs/ca.pem`
35 * `<ssldir>/certs/<node name>.pem`
36 * `<ssldir>/private_keys/<node name>.pem`
38 ### Option B: Get a New Certificate from the Puppet CA
40 On your CA puppet master:
42 * Run `sudo puppet cert generate activemq.example.com`, substituting some name for your ActiveMQ server. Unlike with a puppet master, the cert's common name can be anything; it doesn't have to be the node's hostname or FQDN.
43 * Locate the ssldir by running `sudo puppet master --configprint ssldir`.
44 * Retrieve the following files and copy them to a working directory on your ActiveMQ server, making sure to give unique names to the cert and private key:
45 * `<ssldir>/certs/ca.pem`
46 * `<ssldir>/certs/activemq.example.com.pem`
47 * `<ssldir>/private_keys/activemq.example.com.pem`
49 ### Option C: Do Whatever You Want
51 If you have some other CA infrastructure, you can use that instead.
55 * [Manually create the keystores](#manually-creating-keystores)
56 * [Use Puppet to create the keystores](#creating-keystores-with-puppet)
58 ## Manually Creating Keystores
60 We need a **"truststore"** and a **"keystore."** We also need a **password** for each. (You can use the same password for both stores.)
62 Remember the password(s) for later, because it needs to [go in the activemq.xml file][tls].
64 ### Step 1: Truststore
66 > **Note:** The truststore is only required for CA-verified TLS. If you are using anonymous TLS, you may skip it.
68 The truststore determines which certificates are allowed to connect to ActiveMQ. If you import a CA cert into it, ActiveMQ will trust any certificate signed by that CA.
70 > You could also _not_ import a CA, and instead import every individual certificate you want to allow. If you do that, you're on your own, but the commands should be similar.
72 In the working directory with your PEM-format credentials, run the following command. Replace `ca.pem` with whatever you named your copy of the CA cert, and use the password when requested.
74 {% highlight console %}
75 $ sudo keytool -import -alias "My CA" -file ca.pem -keystore truststore.jks
76 Enter keystore password:
77 Re-enter new password:
81 Trust this certificate? [no]: y
82 Certificate was added to keystore
85 The truststore is now done.
87 If you want, you can compare fingerprints:
89 {% highlight console %}
90 $ sudo keytool -list -keystore truststore.jks
91 Enter keystore password:
94 Keystore provider: SUN
96 Your keystore contains 1 entry
98 my ca, Mar 30, 2012, trustedCertEntry,
99 Certificate fingerprint (MD5): 99:D3:28:6B:37:13:7A:A2:B8:73:75:4A:31:78:0B:68
101 $ sudo openssl x509 -in ca.pem -fingerprint -md5
102 MD5 Fingerprint=99:D3:28:6B:37:13:7A:A2:B8:73:75:4A:31:78:0B:68
108 The keystore contains the ActiveMQ broker's certificate and private key, which it uses to identify itself to the applications that connect to it.
110 In the working directory with your PEM-format credentials, run the following commands. Substitute the names of your key and certificate files where necessary, and the common name of your ActiveMQ server's certificate for `activemq.example.com`.
112 These commands use both an "export/source" password and a "destination" password. The export/source password is never used again after this series of commands.
114 {% highlight console %}
115 $ sudo cat activemq_private.pem activemq_cert.pem > temp.pem
116 $ sudo openssl pkcs12 -export -in temp.pem -out activemq.p12 -name activemq.example.com
117 Enter Export Password:
118 Verifying - Enter Export Password:
119 $sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore activemq.p12 -srcstoretype PKCS12 -alias activemq.example.com
120 Enter destination keystore password:
121 Re-enter new password:
122 Enter source keystore password:
125 The keystore is now done.
127 If you want, you can compare fingerprints:
129 {% highlight console %}
130 $ sudo keytool -list -keystore keystore.jks
131 Enter keystore password:
134 Keystore provider: SUN
136 Your keystore contains 1 entry
138 activemq.example.com, Mar 30, 2012, PrivateKeyEntry,
139 Certificate fingerprint (MD5): 7E:2A:B4:4D:1E:6D:D1:70:A9:E7:20:0D:9D:41:F3:B9
141 $ sudo openssl x509 -in activemq_cert.pem -fingerprint -md5
142 MD5 Fingerprint=7E:2A:B4:4D:1E:6D:D1:70:A9:E7:20:0D:9D:41:F3:B9
147 Move the keystore and truststore to ActiveMQ's config directory. Make sure they are owned by the ActiveMQ user and unreadable to any other users. [Configure ActiveMQ to use them in its `sslContext`.][tls] **Double-check** that you've made activemq.xml world-unreadable, since it now contains sensitive credentials.
149 ## Creating Keystores with Puppet
151 If you're managing your ActiveMQ server with Puppet anyway, you can use the [puppetlabs/java_ks module](http://forge.puppetlabs.com/puppetlabs/java_ks) to handle the format conversion.
153 This approach is more work for a single permanent ActiveMQ server, but less work if you intend to deploy multiple ActiveMQ servers or eventually change the credentials.
155 ### Step 1: Install the `java_ks` Module
157 On your puppet master, run `sudo puppet module install puppetlabs/java_ks`.
159 ### Step 2: Create a Puppet Class
161 The class to manage the keystores should do the following:
163 * Make sure the PEM cert and key files are present and protected.
164 * Declare a pair of `java_ks` resources.
165 * Manage the mode and ownership of the keystore files.
167 The code below is an example, but it will work fine if you put it in a module (example file location in the first comment) and set its parameters when you declare it. The name of the class (and its home module) can be changed as needed.
171 # /etc/puppet/modules/activemq/manifests/keystores.pp
172 class activemq::keystores (
173 $keystore_password, # required
175 # User must put these files in the module, or provide other URLs
176 $ca = 'puppet:///modules/activemq/ca.pem',
177 $cert = 'puppet:///modules/activemq/cert.pem',
178 $private_key = 'puppet:///modules/activemq/private_key.pem',
180 $activemq_confdir = '/etc/activemq',
181 $activemq_user = 'activemq',
184 # ----- Restart ActiveMQ if the SSL credentials ever change -----
185 # ----- Uncomment if you are fully managing ActiveMQ with Puppet. -----
187 # Package['activemq'] -> Class[$title]
188 # Java_ks['activemq_cert:keystore'] ~> Service['activemq']
189 # Java_ks['activemq_ca:truststore'] ~> Service['activemq']
192 # ----- Manage PEM files -----
199 file {"${activemq_confdir}/ssl_credentials":
203 file {"${activemq_confdir}/ssl_credentials/activemq_certificate.pem":
207 file {"${activemq_confdir}/ssl_credentials/activemq_private.pem":
209 source => $private_key,
211 file {"${activemq_confdir}/ssl_credentials/ca.pem":
217 # ----- Manage Keystore Contents -----
219 # Each keystore should have a dependency on the PEM files it relies on.
221 # Truststore with copy of CA cert
222 java_ks { 'activemq_ca:truststore':
224 certificate => "${activemq_confdir}/ssl_credentials/ca.pem",
225 target => "${activemq_confdir}/truststore.jks",
226 password => $keystore_password,
227 trustcacerts => true,
228 require => File["${activemq_confdir}/ssl_credentials/ca.pem"],
231 # Keystore with ActiveMQ cert and private key
232 java_ks { 'activemq_cert:keystore':
234 certificate => "${activemq_confdir}/ssl_credentials/activemq_certificate.pem",
235 private_key => "${activemq_confdir}/ssl_credentials/activemq_private.pem",
236 target => "${activemq_confdir}/keystore.jks",
237 password => $keystore_password,
239 File["${activemq_confdir}/ssl_credentials/activemq_private.pem"],
240 File["${activemq_confdir}/ssl_credentials/activemq_certificate.pem"]
245 # ----- Manage Keystore Files -----
248 # No ensure, source, or content.
250 file {"${activemq_confdir}/keystore.jks":
251 owner => $activemq_user,
252 group => $activemq_user,
254 require => Java_ks['activemq_cert:keystore'],
256 file {"${activemq_confdir}/truststore.jks":
257 owner => $activemq_user,
258 group => $activemq_user,
260 require => Java_ks['activemq_ca:truststore'],
267 ### Step 3: Assign the Class to the ActiveMQ Server
269 ...using your standard Puppet site tools.
273 [Configure ActiveMQ to use the keystores in its `sslContext`][tls], probably with the Puppet template you're using to manage activemq.xml. **Double-check** that you've made activemq.xml world-unreadable, since it now contains sensitive credentials.