I have set up an ActiveMQ Artemis cluster (version 2.27.1) to use mutual authentication. When the second node tries to connect to the first one, I get an error
WARN [org.apache.activemq.artemis.core.server] AMQ222208: SSL handshake failed for client from /10.226.95.134:46882: java.security.cert.CertificateException: No subject alternative names matching IP address 10.226.95.134 found.
The hostname of the client is in the SAN of the certificate in the truststore. I can't figure out how to configure the acceptor to use the hostname instead of the IP address.
The broker.xml configuration is
<acceptor name="netty-master-acceptor01">
tcp://dev-artemis01:61617?sslEnabled=true;needClientAuth=true;verifyHost=true;keyStorePath=/keys/keystore.jks;keyStorePassword=123;trustStorePath=/keys/trusted_keystore.jks;trustStorePassword=password;protocols=CORE,AMQP
</acceptor>
...
<connector name="netty-master-connector02">
tcp://artemis02:61617?sslEnabled=true;keyStorePath=/keys/keystore.jks;keyStorePassword=123;trustStorePath=/keys/trusted_keystore.jks;trustStorePassword=password
</connector>
I ran openssl commands between artemis01 and artemis02 servers and they worked
openssl s_server -accept 3000 -key dev_artemis.key -cert dev-artemis.pem -CAfile dev-artemis.pem -state
openssl s_client -connect dev-artemis01:3000 -key dev_artemis.key -cert dev-artemis.pem -CAfile dev-artemis.pem -state
How can I configure the acceptor to use hostnames (which are in the SAN) instead of the raw IP addresses?
Edit:
This is what keytool shows in the certificate
keytool -list -v -storepass 123 -keystore keystore-dev-artemisrr.jks
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: dev-artemisrr
Creation date: Jul 13, 2023
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=dev-artemisrr, OU=cfrm, O="Example Technologies, Inc.", L=Portsmouth, ST=New Hampshire, C=US
Issuer: CN=dev-artemisrr, OU=cfrm, O="Example Technologies, Inc.", L=Portsmouth, ST=New Hampshire, C=US
Serial number: 88da32c
Valid from: Thu Jul 13 15:55:28 EDT 2023 until: Sun Jul 12 15:55:28 EDT 2026
Certificate fingerprints:
SHA1: 73:50:59:55:2B:18:F1:32:E2:DA:FA:C0:C1:C6:5A:F2:14:3F:91:D8
SHA256: 09:36:4C:59:63:45:5B:72:59:54:2A:83:48:74:43:F0:63:D5:A3:42:DB:35:E5:C6:E5:33:D8:2B:A4:85:37:3A
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
DNSName: dev-artemisrr01-blue
DNSName: dev-artemisrr02-blue
DNSName: dev-artemisrr03-blue
DNSName: dev-artemisrr01-green
DNSName: dev-artemisrr02-green
DNSName: dev-artemisrr03-green
]
#2: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: F8 7C 9C 65 AF FF 8F B6 BA 3E A0 26 46 C7 1C AA ...e.....>.&F...
0010: F3 C9 43 9F ..C.
]
]
*******************************************
*******************************************
I used the following script to create the certificate
#!/bin/bash
# Create Artemis Cluster Certificate.
set -e
function createSAN()
{
env=$1
num_servers=$2
server_type=$3
alias_server_type="$server_type"0
san="SAN="
for ((i=0; i < $num_servers; i++));
do
san+="DNS:$env-$alias_server_type$((i+1))-blue,"
done
for ((i=0; i < $num_servers; i++));
do
san+="DNS:$env-$alias_server_type$((i+1))-green,"
done
# truncate the last comma
san=${san%?}
echo $san
}
function createCertificate()
{
env=$1
num_servers=$2
server_type=$3
echo -e "\nCreating $server_type certificate..."
createSAN $env $num_servers $server_type
# Create the certificate
cn=$env-$server_type
keytool -keystore keystore-$env-$server_type.jks -keyalg RSA -genkey -alias $env-$server_type -ext "$san" -dname "CN=$cn,OU=engineering,O=Ajax Technologies\, Inc.,L=Portsmouth,ST=New Hampshire,C=US" -validity 1095 -storepass $password -keypass $password
# convert to pkcs12
keytool -importkeystore -srckeystore keystore-$env-$server_type.jks -destkeystore keystore-$env-$server_type.p12 -deststoretype pkcs12 -deststorepass $password -srcstorepass $password
# Extract the SSL certificate
openssl pkcs12 -nokeys -chain -in keystore-$env-$server_type.p12 -out $env-$server_type.crt -password pass:$password
# Extract the key
openssl pkcs12 -nocerts -nodes -in keystore-$env-$server_type.p12 -out $env-$server_type.key -password pass:$password
# Remove the bag attributes to be loaded into trusted keystore
openssl x509 -in $env-$server_type.crt -out $env-$server_type.pem
}
function createTrustedKeystore()
{
# keytool -import -file C:\cacerts\firstCA.cert -alias firstCA -keystore myTrustStore
for file in *.pem; do
alias="$(basename "$file" | cut -d '.' -f1)"
keytool -import -noprompt -file $alias.pem -alias $alias -keystore trusted_keystore.jks -storepass password
done
}
rm -f *.jks *.p12 *.crt *.key
password=secret
createCertificate dev 3 artemis
password=password
createTrustedKeystore
I modified the configurations a little to remove some private information and uploaded the files in the etc folder to https://gist.github.com/milindrao/935f86f30a6f921da915ed44d17e4f1a
What's making this even more difficult to debug is that setting -Djavax.net.debug=all in the artemis.profile file is not spitting out any SSL logs in the artemis.log file. In fact, modifying the log4j2.properties file to add ssl logging won't even allow the artemis service to start.
logger.handshake.name=javax.net.ssl
logger.handshake.level=DEBUG