Required Information
- DietPi version |
v9.7.1
- Distro version |
bookworm
- Kernel version |
Linux pihole 6.6.44-current-rockchip64 #1 SMP PREEMPT Sat Aug 3 06:54:42 UTC 2024 aarch64 GNU/Linux
- Architecture |
arm64
- SBC model |
NanoPi R5S/R5C (aarch64)
- Power supply used | 5V 3A
- SD card used | ineternal emmc
- There is wifi/Bluetoothh card installed
AW-CB375NF Wireless NIC for Jetson Xavier NX/Orin NX/Orin Nano Board etc. 2.4G / 5GHz 300Mbps / 867Mbps Dual-Band Wi-Fi 5, RTL8822CE-CG Core, Bluetooth 5.0, M.2 A/E NGFF
Hi everyone,
I’m trying to secure my Mosquitto MQTT server running on a local network using TLS certificates. I’ve written a bash script (see below) to generate a CA, server, and client certificates. The certificates work, but I’m unsure about the best practices for setting the Common Name (CN), especially for enabling access via both hostname and IP address.
My Setup:
- Local network with devices accessing the MQTT server via hostname (e.g.,
hostname.fritz.box
) and its IP address. - MQTT server is hosted on a DietPi system.
- The script generates certificates with the CN set as
hostname.fritz.box
(default fromhostname
).
Questions:
- How should I configure the CN to support access via both hostname and IP address?
Should I use the hostname, the IP address, or something else for the server certificate’s CN? I’ve read about Subject Alternative Names (SAN), but I’m unsure how to implement it correctly in my script. - Are there additional steps needed to improve security?
For example, configuring Mosquitto or updating my script to align with best practices for certificate generation and management.
Script for Certificate Generation:
bash
Code kopieren
#!/bin/bash
# Directory to store certificates
CERT_DIR="./mosquitto_certs"
mkdir -p "$CERT_DIR"
# Certificate properties
DAYS=3650 # Validity of certificates (10 years)
COUNTRY="US"
STATE="CA"
LOCALITY="San Francisco"
ORGANIZATION="private"
ORG_UNIT="IT"
# Get the system's hostname and append .fritz.box for use as default CN
DEFAULT_CN="$(hostname).fritz.box"
# Function to generate the CA certificate
generate_ca() {
echo "Generating Certification Authority (CA)..."
openssl req -x509 -newkey rsa:2048 -days $DAYS -nodes -keyout "$CERT_DIR/ca.key" -out "$CERT_DIR/ca.crt" -subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORGANIZATION/OU=$ORG_UNIT/CN=mosquitto-ca"
echo "CA certificate and key generated: $CERT_DIR/ca.crt, $CERT_DIR/ca.key"
chmod 644 "$CERT_DIR/ca.crt" "$CERT_DIR/ca.key"
}
# Function to generate a Server certificate
generate_server() {
if [ ! -f "$CERT_DIR/ca.crt" ] || [ ! -f "$CERT_DIR/ca.key" ]; then
echo "CA certificate (ca.crt) or key (ca.key) is missing! Please create a CA first."
return
fi
echo "Generating Server certificate..."
openssl genrsa -out "$CERT_DIR/server.key" 2048
openssl req -new -key "$CERT_DIR/server.key" -out "$CERT_DIR/server.csr" -subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORGANIZATION/OU=$ORG_UNIT/CN=$DEFAULT_CN"
openssl x509 -req -in "$CERT_DIR/server.csr" -CA "$CERT_DIR/ca.crt" -CAkey "$CERT_DIR/ca.key" -CAcreateserial -out "$CERT_DIR/server.crt" -days $DAYS
echo "Server certificate and key generated: $CERT_DIR/server.crt, $CERT_DIR/server.key"
chmod 644 "$CERT_DIR/server.crt" "$CERT_DIR/server.key"
rm "$CERT_DIR/server.csr"
}
# Function to generate a Client certificate
generate_client() {
if [ ! -f "$CERT_DIR/ca.crt" ] || [ ! -f "$CERT_DIR/ca.key" ]; then
echo "CA certificate (ca.crt) or key (ca.key) is missing! Please create a CA first."
return
fi
read -p "Enter the name for the client certificate (e.g., client1): " CLIENT_NAME
if [ -z "$CLIENT_NAME" ]; then
echo "Client name cannot be empty!"
return
fi
CLIENT_CN="${CLIENT_NAME}.fritz.box"
CLIENT_KEY="$CERT_DIR/${CLIENT_NAME}.key"
CLIENT_CRT="$CERT_DIR/${CLIENT_NAME}.crt"
echo "Generating Client certificate for $CLIENT_NAME..."
openssl genrsa -out "$CLIENT_KEY" 2048
openssl req -new -key "$CLIENT_KEY" -out "$CERT_DIR/${CLIENT_NAME}.csr" -subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORGANIZATION/OU=$ORG_UNIT/CN=$CLIENT_CN"
openssl x509 -req -in "$CERT_DIR/${CLIENT_NAME}.csr" -CA "$CERT_DIR/ca.crt" -CAkey "$CERT_DIR/ca.key" -CAcreateserial -out "$CLIENT_CRT" -days $DAYS
echo "Client certificate and key generated: $CLIENT_CRT, $CLIENT_KEY"
chmod 644 "$CLIENT_CRT" "$CLIENT_KEY"
rm "$CERT_DIR/${CLIENT_NAME}.csr"
}
# Menu
while true; do
echo "Certificate Management Menu"
echo "1. Create Certification Authority (CA)"
echo "2. Create Server Certificate"
echo "3. Create Client Certificate"
echo "4. Exit"
read -p "Enter your choice: " choice
case $choice in
1) generate_ca ;;
2) generate_server ;;
3) generate_client ;;
4) echo "Exiting..."; exit ;;
*) echo "Invalid choice. Please select a valid option." ;;
esac
done
When I connect via IP I get this error
Hostname/IP does not match certificate's altnames: IP: ip of server is not in the cert's list
Any guidance, examples, or corrections would be greatly appreciated. Thank you!