Files
zertifizierung/scripts/generate-csr.sh

185 lines
5.1 KiB
Bash
Executable File

#!/bin/bash
# Script to generate a certificate request on a remote host
# Usage: ./generate-csr.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 192.168.1.100 myserver.domain.com DE berlin berlin egonetix it 4096 'firewall.domain.com,vpn.domain.com'"
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:-root}"
SSH_PASSWORD="${SSH_PASSWORD:-}"
# Setup SSH/SCP commands with password support
if [ -n "$SSH_PASSWORD" ] && command -v sshpass >/dev/null 2>&1; then
SSH_CMD="sshpass -p '$SSH_PASSWORD' ssh"
SCP_CMD="sshpass -p '$SSH_PASSWORD' scp"
else
SSH_CMD="ssh"
SCP_CMD="scp"
fi
# 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_CMD -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 "Certificate Request Generation"
echo "=========================================="
echo "Target host: $TARGET_HOST"
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..."
sleep 0.5 # Avoid SSH rate limiting
$SCP_CMD /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..."
sleep 0.5 # Avoid SSH rate limiting
$SSH_CMD ${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..."
sleep 0.5 # Avoid SSH rate limiting
$SCP_CMD ${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 "=========================================="