Skip to content

Commit 7824d1e

Browse files
authored
Example: mTLS between RabbitMQ nodes (#469)
Example: mTLS between RabbitMQ nodes
1 parent 4b2e9d9 commit 7824d1e

File tree

6 files changed

+163
-0
lines changed

6 files changed

+163
-0
lines changed
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# mtls-inter-node Example
2+
3+
This example shows how to [secure the Erlang Distribution with TLS](https://www.rabbitmq.com/clustering-ssl.html) so that RabbitMQ cluster nodes communicate over secure channels.
4+
In the future, the RabbitMQ Cluster Operator may make this easier to configure but it is already possible with the [`envConfig`](https://www.rabbitmq.com/kubernetes/operator/using-operator.html#env-config) and [`override`](https://www.rabbitmq.com/kubernetes/operator/using-operator.html#override) properties.
5+
6+
The most important parts of this example are:
7+
8+
* `rabbitmq.yaml` - `RabbitmqCluster` definition with all the necessary configuration
9+
* `inter_node_tls.config` - Erlang Distribution configuration file that will be mounted as a volume
10+
11+
The other files serve as an example for setting up certificates with [Cert Manager](https://cert-manager.io/docs/).
12+
13+
* `rabbitmq-ca.yaml` - defines an `Issuer` (CA)
14+
* `rabbitmq-certificate.yaml` - defines a certificate that will be provisioned by Cert Manager and then mounted as a volume
15+
16+
`setup.sh` should perform all the necessary steps but may need to be adjusted to work on your system.
17+
18+
```shell
19+
# install Cert Manager
20+
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.4/cert-manager.yaml
21+
# deploy the example
22+
./setup.sh
23+
```
24+
25+
To validate that RabbitMQ nodes connect over TLS you can run the following checks:
26+
27+
```shell
28+
# check that the distribution port has TLS enabled (this command should return `Verification: OK`)
29+
kubectl exec -it mtls-inter-node-server-0 -- bash -c 'openssl s_client -connect ${HOSTNAME}${K8S_HOSTNAME_SUFFIX}:25672 -state -cert /etc/rabbitmq/certs/tls.crt -key /etc/rabbitmq/certs/tls.key -CAfile /etc/rabbitmq/certs/ca.crt 2>&1 | grep Verification'
30+
31+
# check that distribution uses TLS (this command should return `{ok,[["inet_tls"]]}`)
32+
kubectl exec -it mtls-inter-node-server-0 -- rabbitmqctl eval 'init:get_argument(proto_dist).'
33+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[
2+
{server, [
3+
{cacertfile, "/etc/rabbitmq/certs/ca.crt"},
4+
{certfile, "/etc/rabbitmq/certs/tls.crt"},
5+
{keyfile, "/etc/rabbitmq/certs/tls.key"},
6+
{secure_renegotiate, true},
7+
{fail_if_no_peer_cert, true},
8+
{verify, verify_peer},
9+
{customize_hostname_check, [
10+
{match_fun, public_key:pkix_verify_hostname_match_fun(https)}
11+
]}
12+
]},
13+
{client, [
14+
{cacertfile, "/etc/rabbitmq/certs/ca.crt"},
15+
{certfile, "/etc/rabbitmq/certs/tls.crt"},
16+
{keyfile, "/etc/rabbitmq/certs/tls.key"},
17+
{secure_renegotiate, true},
18+
{fail_if_no_peer_cert, true},
19+
{verify, verify_peer},
20+
{customize_hostname_check, [
21+
{match_fun, public_key:pkix_verify_hostname_match_fun(https)}
22+
]}
23+
]}
24+
].
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: cert-manager.io/v1
2+
kind: Issuer
3+
metadata:
4+
name: rabbitmq-ca
5+
spec:
6+
ca:
7+
secretName: rabbitmq-ca
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
apiVersion: cert-manager.io/v1
2+
kind: Certificate
3+
metadata:
4+
name: mtls-inter-node-nodes-tls
5+
spec:
6+
secretName: mtls-inter-node-nodes-tls
7+
duration: 2160h # 90d
8+
renewBefore: 360h # 15d
9+
subject:
10+
organizations:
11+
- RabbitMQ
12+
commonName: mtls-inter-node
13+
isCA: false
14+
privateKey:
15+
algorithm: RSA
16+
encoding: PKCS1
17+
size: 2048
18+
usages:
19+
- server auth
20+
- client auth
21+
dnsNames:
22+
- mtls-inter-node-server-0.mtls-inter-node-nodes.default
23+
- mtls-inter-node-server-1.mtls-inter-node-nodes.default
24+
- mtls-inter-node-server-2.mtls-inter-node-nodes.default
25+
issuerRef:
26+
name: rabbitmq-ca
27+
kind: Issuer
28+
group: cert-manager.io
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
apiVersion: rabbitmq.com/v1beta1
2+
kind: RabbitmqCluster
3+
metadata:
4+
name: mtls-inter-node
5+
spec:
6+
rabbitmq:
7+
envConfig: |
8+
SERVER_ADDITIONAL_ERL_ARGS="-pa /usr/local/lib/erlang/lib/ssl-10.1/ebin -proto_dist inet_tls -ssl_dist_optfile /etc/rabbitmq/inter-node-tls.config"
9+
RABBITMQ_CTL_ERL_ARGS="-pa /usr/local/lib/erlang/lib/ssl-10.1/ebin -proto_dist inet_tls -ssl_dist_optfile /etc/rabbitmq/inter-node-tls.config"
10+
replicas: 3
11+
override:
12+
statefulSet:
13+
spec:
14+
template:
15+
spec:
16+
containers:
17+
- name: rabbitmq
18+
volumeMounts:
19+
- mountPath: /etc/rabbitmq/certs
20+
name: mtls-inter-node-nodes-tls
21+
- mountPath: /etc/rabbitmq/inter-node-tls.config
22+
name: inter-node-config
23+
subPath: inter_node_tls.config
24+
volumes:
25+
- configMap:
26+
defaultMode: 420
27+
name: mtls-inter-node-tls-config
28+
name: inter-node-config
29+
- name: mtls-inter-node-nodes-tls
30+
secret:
31+
secretName: mtls-inter-node-nodes-tls
32+
items:
33+
- key: ca.crt
34+
mode: 416
35+
path: ca.crt
36+
- key: tls.crt
37+
mode: 416
38+
path: tls.crt
39+
- key: tls.key
40+
mode: 416
41+
path: tls.key
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/bash
2+
3+
OPENSSL=${OPENSSL:-openssl}
4+
5+
# Generate CA certificate and key
6+
#
7+
# These commands do not work with LibreSSL which is shipped with MacOS. Please use openssl
8+
#
9+
if $OPENSSL version | grep -q LibreSSL; then
10+
echo "Please do not use LibreSSL. Set OPENSSL variable to actual OpenSSL binary."
11+
exit 1
12+
fi
13+
14+
$OPENSSL genrsa -out rabbitmq-ca-key.pem 2048
15+
$OPENSSL req -x509 -new -nodes -key rabbitmq-ca-key.pem -subj "/CN=mtls-inter-node" -days 3650 -reqexts v3_req -extensions v3_ca -out rabbitmq-ca.pem
16+
17+
# Create a CA secret
18+
kubectl create secret tls rabbitmq-ca --cert=rabbitmq-ca.pem --key=rabbitmq-ca-key.pem
19+
20+
# Create an Issuer (Cert Manager CA)
21+
kubectl apply -f rabbitmq-ca.yaml
22+
23+
# Create a certificate for the cluster
24+
kubectl apply -f rabbitmq-certificate.yaml
25+
26+
# Create a configuration file for Erlang Distribution
27+
kubectl create configmap mtls-inter-node-tls-config --from-file=inter_node_tls.config
28+
29+
# Deploy a RabbitMQ cluster
30+
kubectl apply -f rabbitmq.yaml

0 commit comments

Comments
 (0)