RabbitMQ SSL
$ make [HOSTNAME=`hostname`] export
# See http://www.rabbitmq.com/ssl.html | |
# | |
# (c) Stan Angeloff / http://www.gnu.org/licenses/agpl-3.0.html | |
SHELL := /bin/bash | |
HOSTNAME ?= $(shell hostname) | |
PASSPHRASE ?= $(shell cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) | |
PASSPHRASE_FILE = $(HOSTNAME)/.passphrase | |
CLIENT_NAME ?= client-1 | |
# --------------------------------------------------------------------------------------------------------------------- | |
.PHONY: $(HOSTNAME) | |
$(HOSTNAME): $(HOSTNAME)/ca | |
$(PASSPHRASE_FILE): | |
@mkdir -p $(@D) | |
@echo '$(PASSPHRASE)' > $@ | |
$(HOSTNAME)/ca: $(HOSTNAME)/ca/cacert.pem $(HOSTNAME)/ca/cacert.cer $(HOSTNAME)/server/cert.pem $(HOSTNAME)/server/keycert.p12 $(HOSTNAME)/$(CLIENT_NAME)/cert.pem $(HOSTNAME)/$(CLIENT_NAME)/keycert.p12 | |
$(HOSTNAME)/ca/certs: | |
mkdir -p $@ | |
$(HOSTNAME)/ca/private: | |
mkdir -p $@ | |
chmod 0750 $@ | |
$(HOSTNAME)/ca/serial: | |
echo 01 > $@ | |
$(HOSTNAME)/ca/index.txt: | |
touch $@ | |
$(HOSTNAME)/ca/openssl.cnf: $(HOSTNAME)/ca/certs $(HOSTNAME)/ca/private $(HOSTNAME)/ca/serial $(HOSTNAME)/ca/index.txt openssl.cnf.template | |
cat $(lastword $^) | sed -e 's/$$HOSTNAME/$(HOSTNAME)/g' -e 's/$$CLIENT_NAME/$(CLIENT_NAME)/g' > $@ | |
$(HOSTNAME)/ca/cacert.pem: $(HOSTNAME)/ca/openssl.cnf | |
openssl req -x509 -config $< -newkey rsa:2048 -days 3650 -out $@ -outform PEM -subj /CN=$(HOSTNAME)/ -nodes | |
$(HOSTNAME)/ca/cacert.cer: $(HOSTNAME)/ca/cacert.pem | |
openssl x509 -in $< -out $@ -outform DER | |
$(HOSTNAME)/server $(HOSTNAME)/$(CLIENT_NAME): | |
mkdir $@ | |
.SECONDARY: $(HOSTNAME)/server/key.pem $(HOSTNAME)/$(CLIENT_NAME)/key.pem | |
$(HOSTNAME)/%/key.pem: $(HOSTNAME)/% | |
openssl genrsa -out $@ 2048 | |
.SECONDARY: $(HOSTNAME)/server/req.pem $(HOSTNAME)/$(CLIENT_NAME)/req.pem | |
$(HOSTNAME)/%/req.pem: $(HOSTNAME)/%/key.pem | |
openssl req -new -key $< -out $@ -outform PEM -subj /CN=$(HOSTNAME)/O=$(shell basename $(@D))/ -nodes | |
$(HOSTNAME)/%/cert.pem: $(HOSTNAME)/ca/openssl.cnf $(HOSTNAME)/%/req.pem | |
openssl ca -config $(firstword $^) -in $(lastword $^) -out $@ -notext -batch -extensions $(shell basename $(@D))_ca_extensions | |
$(HOSTNAME)/%/keycert.p12: $(HOSTNAME)/%/key.pem $(PASSPHRASE_FILE) $(HOSTNAME)/%/cert.pem | |
openssl pkcs12 -export -out $@ -in $(lastword $^) -inkey $(firstword $^) -passout file:$(PASSPHRASE_FILE) | |
# --------------------------------------------------------------------------------------------------------------------- | |
.PHONY: export | |
export: $(HOSTNAME) | |
mkdir $(HOSTNAME)/export | |
mkdir $(HOSTNAME)/export/ca | |
mkdir $(HOSTNAME)/export/ca/private | |
mkdir $(HOSTNAME)/export/server | |
mkdir $(HOSTNAME)/export/$(CLIENT_NAME) | |
cp $(HOSTNAME)/ca/cacert.pem $(HOSTNAME)/export/ca/ | |
cp $(HOSTNAME)/ca/private/cakey.pem $(HOSTNAME)/export/ca/private/ | |
cp $(HOSTNAME)/server/key.pem $(HOSTNAME)/server/cert.pem $(HOSTNAME)/export/server/ | |
cp $(HOSTNAME)/$(CLIENT_NAME)/key.pem $(HOSTNAME)/$(CLIENT_NAME)/cert.pem $(HOSTNAME)/export/$(CLIENT_NAME)/ | |
cat $(HOSTNAME)/ca/openssl.cnf | sed -e 's!$(HOSTNAME)/ca!ca!g' > $(HOSTNAME)/export/ca/openssl.cnf |
[ ca ] | |
default_ca = $HOSTNAME | |
[ $HOSTNAME ] | |
dir = $HOSTNAME/ca | |
certificate = $dir/cacert.pem | |
database = $dir/index.txt | |
new_certs_dir = $dir/certs | |
private_key = $dir/private/cakey.pem | |
serial = $dir/serial | |
default_crl_days = 7 | |
default_days = 3650 | |
default_md = sha256 | |
policy = $HOSTNAME_policy | |
x509_extensions = certificate_extensions | |
[ $HOSTNAME_policy ] | |
commonName = supplied | |
stateOrProvinceName = optional | |
countryName = optional | |
emailAddress = optional | |
organizationName = optional | |
organizationalUnitName = optional | |
domainComponent = optional | |
[ certificate_extensions ] | |
basicConstraints = CA:false | |
[ req ] | |
default_bits = 2048 | |
default_keyfile = $HOSTNAME/ca/private/cakey.pem | |
default_md = sha256 | |
prompt = yes | |
distinguished_name = root_ca_distinguished_name | |
x509_extensions = root_ca_extensions | |
[ root_ca_distinguished_name ] | |
commonName = $HOSTNAME | |
[ root_ca_extensions ] | |
basicConstraints = CA:true | |
keyUsage = keyCertSign, cRLSign | |
[ $CLIENT_NAME_ca_extensions ] | |
basicConstraints = CA:false | |
keyUsage = digitalSignature | |
extendedKeyUsage = 1.3.6.1.5.5.7.3.2 | |
[ server_ca_extensions ] | |
basicConstraints = CA:false | |
keyUsage = keyEncipherment | |
extendedKeyUsage = 1.3.6.1.5.5.7.3.1 |
Maybe you could share a template file of openssl.cnf ? :)
Done.
RabbitMQ's own test suites use tls-gen, as do several client libraries. On behalf of the RabbitMQ core team I'd recommend using that instead of a yet another DIY version.
This example uses a shorter key extension list which can affect cipher suite negotiation.
tls-gen
produces certificates that include all extensions known to be relevant to RabbitMQ (or, well, Erlang's TLS implementation).
Maybe you could share a template file of openssl.cnf ? :)