- Added interactive username/password prompts to cert-manager.py - Removed requirement for SSH_USER environment variable prefix - Fixed password authentication in deploy-homeassistant.sh using SSHPASS environment variable - Added SSH rate limiting delays throughout deployment script - Improved error handling with SSH connection testing - Prioritized SSH_USER in detect-system.sh to avoid unnecessary root attempts - Added StrictHostKeyChecking=no for automated deployments Tool now works fully interactively - just run ./cert-manager.py and answer prompts
173 lines
4.7 KiB
Bash
Executable File
173 lines
4.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# Script to generate a certificate request for Home Assistant
|
|
# Usage: ./generate-csr-ha.sh <hostname> <common-name> [country] [state] [locality] [org] [ou] [key-bits] [additional-dns]
|
|
|
|
set -e
|
|
|
|
# Check arguments
|
|
if [ $# -lt 2 ]; then
|
|
echo "Usage: $0 <hostname> <common-name> [country] [state] [locality] [org] [ou] [key-bits] [additional-dns]"
|
|
echo ""
|
|
echo "Example: $0 srv-wmw-ha01 ha.egonetix.lan DE berlin berlin egonetix it 4096"
|
|
exit 1
|
|
fi
|
|
|
|
TARGET_HOST="$1"
|
|
COMMON_NAME="$2"
|
|
COUNTRY="${3:-DE}"
|
|
STATE="${4:-berlin}"
|
|
LOCALITY="${5:-berlin}"
|
|
ORG="${6:-egonetix}"
|
|
OU="${7:-it}"
|
|
KEY_BITS="${8:-4096}"
|
|
ADDITIONAL_DNS="${9:-}"
|
|
SSH_USER="${SSH_USER:-icke}"
|
|
|
|
# Extract short hostname from common name
|
|
SHORT_NAME=$(echo "$COMMON_NAME" | cut -d'.' -f1)
|
|
OUTPUT_FILE="${SHORT_NAME}.req"
|
|
|
|
# Detect if TARGET_HOST is an IP address
|
|
if [[ "$TARGET_HOST" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
TARGET_IP="$TARGET_HOST"
|
|
else
|
|
# Try to resolve hostname to IP
|
|
TARGET_IP=$(ssh -o ConnectTimeout=5 ${SSH_USER}@${TARGET_HOST} "hostname -I | awk '{print \$1}'" 2>/dev/null || echo "")
|
|
if [ -z "$TARGET_IP" ]; then
|
|
# Fallback: try local resolution
|
|
TARGET_IP=$(getent hosts "$TARGET_HOST" 2>/dev/null | awk '{print $1}' | head -1 || echo "")
|
|
fi
|
|
fi
|
|
|
|
echo "=========================================="
|
|
echo "Home Assistant Certificate Request"
|
|
echo "=========================================="
|
|
echo "Target host: $TARGET_HOST"
|
|
echo "SSH User: $SSH_USER"
|
|
echo "Target IP: ${TARGET_IP:-not detected}"
|
|
echo "Common Name: $COMMON_NAME"
|
|
echo "Country: $COUNTRY"
|
|
echo "State: $STATE"
|
|
echo "Locality: $LOCALITY"
|
|
echo "Organization: $ORG"
|
|
echo "Org Unit: $OU"
|
|
echo "Key Length: $KEY_BITS bits"
|
|
if [ -n "$ADDITIONAL_DNS" ]; then
|
|
echo "Additional DNS: $ADDITIONAL_DNS"
|
|
fi
|
|
echo "Output file: $OUTPUT_FILE"
|
|
echo "=========================================="
|
|
echo ""
|
|
|
|
# Build SAN entries
|
|
SAN_DNS="DNS.1 = $COMMON_NAME
|
|
DNS.2 = $SHORT_NAME"
|
|
|
|
DNS_COUNTER=3
|
|
|
|
# Add alternative names if common name contains domain
|
|
if [[ "$COMMON_NAME" == *.* ]]; then
|
|
SAN_DNS="$SAN_DNS
|
|
DNS.$DNS_COUNTER = ${SHORT_NAME}.${COMMON_NAME#*.}"
|
|
((DNS_COUNTER++))
|
|
fi
|
|
|
|
# Add additional DNS names if provided
|
|
if [ -n "$ADDITIONAL_DNS" ]; then
|
|
IFS=',' read -ra EXTRA_DNS <<< "$ADDITIONAL_DNS"
|
|
for dns in "${EXTRA_DNS[@]}"; do
|
|
# Trim whitespace
|
|
dns=$(echo "$dns" | xargs)
|
|
if [ -n "$dns" ]; then
|
|
SAN_DNS="$SAN_DNS
|
|
DNS.$DNS_COUNTER = $dns"
|
|
((DNS_COUNTER++))
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Add IP address if detected
|
|
SAN_IP=""
|
|
if [ -n "$TARGET_IP" ]; then
|
|
SAN_IP="IP.1 = $TARGET_IP"
|
|
fi
|
|
|
|
# Create OpenSSL config
|
|
CONFIG_CONTENT="[req]
|
|
default_bits = $KEY_BITS
|
|
prompt = no
|
|
default_md = sha256
|
|
distinguished_name = dn
|
|
req_extensions = v3_req
|
|
|
|
[dn]
|
|
C=$COUNTRY
|
|
ST=$STATE
|
|
L=$LOCALITY
|
|
O=$ORG
|
|
OU=$OU
|
|
CN=$COMMON_NAME
|
|
|
|
[v3_req]
|
|
keyUsage = digitalSignature, keyEncipherment
|
|
extendedKeyUsage = serverAuth
|
|
subjectAltName = @alt_names
|
|
|
|
[alt_names]
|
|
$SAN_DNS"
|
|
|
|
# Append IP if available
|
|
if [ -n "$SAN_IP" ]; then
|
|
CONFIG_CONTENT="$CONFIG_CONTENT
|
|
$SAN_IP"
|
|
fi
|
|
|
|
echo "[1/4] Creating OpenSSL configuration..."
|
|
echo "$CONFIG_CONTENT" > /tmp/csr_config.conf
|
|
|
|
echo "[2/4] Copying config to target host..."
|
|
scp /tmp/csr_config.conf ${SSH_USER}@${TARGET_HOST}:/tmp/csr_config.conf
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Failed to copy config to target host"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[3/4] Generating $KEY_BITS-bit RSA key and CSR on target host..."
|
|
ssh ${SSH_USER}@${TARGET_HOST} "openssl req -new -newkey rsa:$KEY_BITS -nodes -keyout /tmp/${SHORT_NAME}.key -out /tmp/${SHORT_NAME}.csr -config /tmp/csr_config.conf"
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Failed to generate CSR on target host"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[4/4] Downloading CSR..."
|
|
scp ${SSH_USER}@${TARGET_HOST}:/tmp/${SHORT_NAME}.csr "$OUTPUT_FILE"
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Failed to download CSR"
|
|
exit 1
|
|
fi
|
|
|
|
# Clean up local temp file
|
|
rm -f /tmp/csr_config.conf
|
|
|
|
echo ""
|
|
echo "=========================================="
|
|
echo "✓ CSR generated successfully!"
|
|
echo "=========================================="
|
|
echo "Certificate request saved to: $OUTPUT_FILE"
|
|
echo ""
|
|
echo "CSR details:"
|
|
openssl req -in "$OUTPUT_FILE" -noout -text | grep -A 10 "Subject:"
|
|
echo ""
|
|
echo "Subject Alternative Names:"
|
|
openssl req -in "$OUTPUT_FILE" -noout -text | grep -A 20 "Subject Alternative Name" || echo " (none found)"
|
|
echo ""
|
|
echo "Key details:"
|
|
openssl req -in "$OUTPUT_FILE" -noout -text | grep "Public-Key:"
|
|
echo ""
|
|
echo "IMPORTANT: Private key is stored on target host at:"
|
|
echo " /tmp/${SHORT_NAME}.key"
|
|
echo ""
|
|
echo "Next step: Sign this CSR with:"
|
|
echo " ./sign-cert.sh $OUTPUT_FILE $SHORT_NAME"
|
|
echo "=========================================="
|