From 2a4538c8d3ef4d9a070cf1f20609544931ea3151 Mon Sep 17 00:00:00 2001 From: Drew Bednar Date: Mon, 16 Sep 2024 21:45:12 -0400 Subject: [PATCH] Prepare to use TLS in local dev --- .gitignore | 4 ++ .mosquitto/.gitignore | 5 ++- .mosquitto/certs/.gitkeep | 0 Makefile | 12 ++++++ README.md | 2 +- scripts/gen-local-tls-certs.sh | 68 ++++++++++++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 .mosquitto/certs/.gitkeep create mode 100755 scripts/gen-local-tls-certs.sh diff --git a/.gitignore b/.gitignore index adf8f72..ae254c8 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ # Go workspace file go.work +# Certs +*.crt +*.key +*.csr \ No newline at end of file diff --git a/.mosquitto/.gitignore b/.mosquitto/.gitignore index 748a50e..70c90d9 100644 --- a/.mosquitto/.gitignore +++ b/.mosquitto/.gitignore @@ -1 +1,4 @@ -passwd \ No newline at end of file +passwd +*.crt +*.key +*.csr \ No newline at end of file diff --git a/.mosquitto/certs/.gitkeep b/.mosquitto/certs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Makefile b/Makefile index eac9505..53ccffd 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,15 @@ +check-deps: + @echo "Checking system dependencies..." + @command -v openssl > /dev/null || (echo "OpenSSL cli is not installed."; exit 1) + @echo "System dependencies met." +.PHONEY: check-deps + +# https://mosquitto.org/man/mosquitto-tls-7.html +# FOR LOCAL DEV ONLY! These certs do not use encryption. Use let's encrypt or a real cert. +gen-local-tls: + ./scripts/gen-local-tls-certs.sh +.PHONEY: gen-local-tls + start-dev: docker compose up -d .PHONEY: start-dev diff --git a/README.md b/README.md index d6a96ea..db20d4d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Learning MQTT with Golang by doing. This repo is a simple example of using a Gol ## Development -Start the local development environment with: +For local development we use [Mosquitto](https://mosquitto.org/). Start the local development environment with: ``` make start-dev diff --git a/scripts/gen-local-tls-certs.sh b/scripts/gen-local-tls-certs.sh new file mode 100755 index 0000000..ac3c755 --- /dev/null +++ b/scripts/gen-local-tls-certs.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +# https://mosquitto.org/man/mosquitto-tls-7.html +set -euo pipefail + +# Set working directory to project root +cd "$(dirname "$0")/../" +CDIR=$(pwd -P) +export CDIR + +MOSQUITTO_CERTS_DIR="${CDIR}/.mosquitto/certs" +TLS_CERT_DURATION="${TLS_CERT_DURATION:-365}" +CA_COMMON_NAME="${CA_COMMON_NAME:-runcible.io}" +HOSTNAME=$(hostname) + +warn(){ + echo -e "\nFOR LOCAL DEVELOPMENT ONLY!!! These certs do not follow best practices.\n\ +Keys are not encypted! Seriously, don't use this for anything other than local development.\n" +} + +generate_ca_cert(){ + echo "Generating CA key in ${MOSQUITTO_CERTS_DIR}..." + openssl genpkey -algorithm RSA -out "${MOSQUITTO_CERTS_DIR}/ca.key" + + echo "Generating CA cert..." + openssl req -x509 -new -nodes -key "${MOSQUITTO_CERTS_DIR}/ca.key" -sha256 -days "${TLS_CERT_DURATION}" \ + -extensions v3_ca -out "${MOSQUITTO_CERTS_DIR}/ca.crt" -subj "/C=US/O=Runcible/CN=${CA_COMMON_NAME}" + + echo "CA cert generation complete." +} + +generate_server_cert(){ + echo "Generating server key..." + openssl genrsa -out "${MOSQUITTO_CERTS_DIR}/server.key" 2048 + + echo "Generating cert signing request for CA..." + openssl req -out "${MOSQUITTO_CERTS_DIR}/server.csr" -key "${MOSQUITTO_CERTS_DIR}/server.key" -new \ + -subj "/C=US/O=Runcible/CN=${HOSTNAME}" + + echo "Sending server CSR to CA..." + openssl x509 -req -in "${MOSQUITTO_CERTS_DIR}/server.csr" -CA "${MOSQUITTO_CERTS_DIR}/ca.crt" \ + -CAkey "${MOSQUITTO_CERTS_DIR}/ca.key" -CAcreateserial -out "${MOSQUITTO_CERTS_DIR}/server.crt" \ + -days "${TLS_CERT_DURATION}" + + echo "Server cert generation complete." +} + +generate_client_cert(){ + echo "Creating client cert in $CDIR" + echo "Generating client key..." + openssl genrsa -out "${CDIR}/client.key" 2048 + + echo "Generating client CSR for CA..." + openssl req -out "${CDIR}/client.csr" -key "${CDIR}/client.key" -new -subj "/C=US/O=Runcible/CN=localhost" + + echo "Sending client CSR to CA..." + openssl x509 -req -in "${CDIR}/client.csr" -CA "${MOSQUITTO_CERTS_DIR}/ca.crt" -CAkey "${MOSQUITTO_CERTS_DIR}/ca.key" \ + -CAcreateserial -out "${CDIR}/client.crt" -days "${TLS_CERT_DURATION}" + + echo "Client cert generation complete." +} + + +warn +generate_ca_cert +generate_server_cert +generate_client_cert +warn \ No newline at end of file