#!/bin/bash # Script to generate a certificate request on a remote host # Usage: ./generate-csr.sh [country] [state] [locality] [org] [ou] [key-bits] [additional-dns] set -e # Check arguments if [ $# -lt 2 ]; then echo "Usage: $0 [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 "=========================================="