Skip to content

Commit

Permalink
SMQ-1485 - Add mutual TLS support for gRPC connections (#2646)
Browse files Browse the repository at this point in the history
Signed-off-by: nyagamunene <[email protected]>
  • Loading branch information
nyagamunene authored Jan 17, 2025
1 parent fdea1a7 commit 5d75599
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 24 deletions.
4 changes: 4 additions & 0 deletions docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# SPDX-License-Identifier: Apache-2.0
# Docker: Environment variables in Compose

## Enable GRPC SSL
## If enabled run ./scripts/generate-grpc-certs.sh to generate the GRPC certs
GRPC_MTLS=

## NginX
SMQ_NGINX_HTTP_PORT=80
SMQ_NGINX_SSL_PORT=443
Expand Down
144 changes: 120 additions & 24 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,21 @@ services:
target: /auth-grpc-client-ca${SMQ_DOMAINS_GRPC_CLIENT_CA_CERTS:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_AUTH_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /auth-grpc-client${SMQ_AUTH_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_AUTH_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /auth-grpc-client${SMQ_AUTH_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_AUTH_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /auth-grpc-server-ca${SMQ_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true

invitations-db:
image: postgres:16.2-alpine
Expand Down Expand Up @@ -544,6 +559,22 @@ services:
target: /channels-grpc-server-ca${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true
# Group gRPC client certificates
- type: bind
source: ${SMQ_GROUPS_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /groups-grpc-client${SMQ_GROUPS_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_GROUPS_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /groups-grpc-client${SMQ_GROUPS_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_GROUPS_GRPC_SERVER_CERT:-ssl/certs/dummy/server_ca}
target: /groups-grpc-server-ca${SMQ_GROUPS_GRPC_SERVER_CERT:+.crt}
bind:
create_host_path: true

channels-db:
image: postgres:16.2-alpine
Expand Down Expand Up @@ -643,6 +674,66 @@ services:
target: /auth-grpc-server-ca${SMQ_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CLIENTS_AUTH_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /clients-grpc-client${SMQ_CLIENTS_AUTH_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CLIENTS_AUTH_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /clients-grpc-client${SMQ_CLIENTS_AUTH_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CLIENTS_AUTH_GRPC_SERVER_CERT:-ssl/certs/dummy/server_ca}
target: /clients-grpc-server-ca${SMQ_CLIENTS_AUTH_GRPC_SERVER_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_GROUPS_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /groups-grpc-client${SMQ_GROUPS_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_GROUPS_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /groups-grpc-client${SMQ_GROUPS_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_GROUPS_GRPC_SERVER_CERT:-ssl/certs/dummy/server_ca}
target: /groups-grpc-server-ca${SMQ_GROUPS_GRPC_SERVER_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_GRPC_SERVER_CERT:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server${SMQ_CHANNELS_GRPC_SERVER_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_GRPC_SERVER_KEY:-ssl/certs/dummy/server_key}
target: /channels-grpc-server${SMQ_CHANNELS_GRPC_SERVER_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_GRPC_CLIENT_CA_CERTS:-ssl/certs/dummy/client_ca}
target: /channels-grpc-client-ca${SMQ_CHANNELS_GRPC_CLIENT_CA_CERTS:+.crt}
bind:
create_host_path: true

users-db:
image: postgres:16.2-alpine
Expand Down Expand Up @@ -924,18 +1015,18 @@ services:
create_host_path: true
# Channels gRPC mTLS client certificates
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_AUTH_GRPC_CLIENT_CERT:+.crt}
source: ${SMQ_CHANNELS_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_AUTH_GRPC_CLIENT_KEY:+.key}
source: ${SMQ_CHANNELS_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
source: ${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true

Expand Down Expand Up @@ -995,18 +1086,18 @@ services:
create_host_path: true
# Channels gRPC mTLS client certificates
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_AUTH_GRPC_CLIENT_CERT:+.crt}
source: ${SMQ_CHANNELS_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_AUTH_GRPC_CLIENT_KEY:+.key}
source: ${SMQ_CHANNELS_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
source: ${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true
# Auth gRPC mTLS client certificates
Expand Down Expand Up @@ -1082,18 +1173,23 @@ services:
create_host_path: true
# Channels gRPC mTLS client certificates
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_AUTH_GRPC_CLIENT_CERT:+.crt}
source: ${SMQ_CHANNELS_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_AUTH_GRPC_CLIENT_KEY:+.key}
source: ${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
source: ${SMQ_CHANNELS_GRPC_CLIENT_CA_CERTS:-ssl/certs/dummy/client_ca}
target: /channels-grpc-client-ca${SMQ_CHANNELS_GRPC_CLIENT_CA_CERTS:+.crt}
bind:
create_host_path: true

Expand Down Expand Up @@ -1153,18 +1249,18 @@ services:
create_host_path: true
# Channels gRPC mTLS client certificates
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_AUTH_GRPC_CLIENT_CERT:+.crt}
source: ${SMQ_CHANNELS_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_AUTH_GRPC_CLIENT_KEY:+.key}
source: ${SMQ_CHANNELS_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /channels-grpc-client${SMQ_CHANNELS_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${SMQ_CHANNELS_AUTH_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
source: ${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /channels-grpc-server-ca${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true
# Auth gRPC mTLS client certificates
Expand Down
73 changes: 73 additions & 0 deletions scripts/generate-grpc-certs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/bin/bash
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

mkdir -p docker/ssl/certs
cd docker

if [ ! -f ssl/certs/ca.key ] || [ ! -f ssl/certs/ca.crt ]; then
echo "Generating new CA certificates..."
openssl genrsa -out ssl/certs/ca.key 4096
openssl req -new -x509 -days 365 -key ssl/certs/ca.key -out ssl/certs/ca.crt -subj "/C=FR/ST=Paris/L=Paris/O=SuperMQ/OU=SuperMQ/CN=SuperMQ Root CA"
else
echo "Using existing CA certificates..."
fi

generate_cert() {
local name=$1
local type=$2
local cn="$3"

openssl genrsa -out "ssl/certs/${name}-grpc-${type}.key" 4096

openssl req -new \
-key "ssl/certs/${name}-grpc-${type}.key" \
-out "ssl/certs/${name}-grpc-${type}.csr" \
-subj "/C=FR/ST=Paris/L=Paris/O=SuperMQ/OU=SuperMQ/CN=${cn}"

cat > "ssl/certs/${name}-grpc-${type}.ext" << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = ${name}
EOF

openssl x509 -req \
-in "ssl/certs/${name}-grpc-${type}.csr" \
-CA ssl/certs/ca.crt \
-CAkey ssl/certs/ca.key \
-CAcreateserial \
-out "ssl/certs/${name}-grpc-${type}.crt" \
-days 365 \
-extfile "ssl/certs/${name}-grpc-${type}.ext"

rm "ssl/certs/${name}-grpc-${type}.csr" "ssl/certs/${name}-grpc-${type}.ext"
}

# Generate server certificates
generate_cert "auth" "server" "auth.supermq.local"
generate_cert "groups" "server" "groups.supermq.local"
generate_cert "channels" "server" "channels.supermq.local"
generate_cert "clients" "server" "clients.supermq.local"

# Generate client certificates
generate_cert "auth" "client" "auth-client.supermq.local"
generate_cert "domains" "client" "domains-client.supermq.local"
generate_cert "groups" "client" "groups-client.supermq.local"
generate_cert "channels" "client" "channels-client.supermq.local"
generate_cert "clients" "client" "clients-client.supermq.local"

cd ssl/certs
chmod 644 *.crt
chmod 600 *.key

for service in auth groups channels clients domains; do
ln -sf ca.crt "${service}-grpc-server-ca.crt"
ln -sf ca.crt "${service}-grpc-client-ca.crt"
done

echo "Certificates generated successfully in docker/ssl/certs/"

0 comments on commit 5d75599

Please sign in to comment.