diff --git a/tools/ubuntu_vm_start.sh b/tools/ubuntu_vm_start.sh index 085fd6b..69345b4 100755 --- a/tools/ubuntu_vm_start.sh +++ b/tools/ubuntu_vm_start.sh @@ -27,15 +27,15 @@ BRIDGE_IP="192.168.100.1/24" NETWORK="192.168.100.0/24" log() { - echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" + echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" >&2 } warn() { - echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" + echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" >&2 } error() { - echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" + echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" >&2 # If VM_NUMBER is set and we're in VM creation phase, clean up if [ -n "$VM_NUMBER" ] && [ -n "$VM_PID" ]; then @@ -46,7 +46,7 @@ error() { } info() { - echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $1${NC}" + echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $1${NC}" >&2 } # Test functions @@ -200,9 +200,10 @@ test_ssh_connection() { while [ $attempt -le $max_attempts ]; do info "SSH attempt $attempt/$max_attempts" - # Test SSH connection with timeout - if timeout 10 sshpass -p 'ubuntu' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 ubuntu@"$vm_ip" 'echo "SSH connection successful"' 2>/dev/null; then - log "✓ SSH connection successful to ubuntu@$vm_ip" + # Test SSH connection with timeout, using key-based auth, with verbose output for diagnostics + info "Attempting SSH with key: timeout 10 ssh -i \"$SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH\" -v -o StrictHostKeyChecking=no -o ConnectTimeout=5 ubuntu@\"$vm_ip\" 'echo \"SSH connection successful\"'" >&2 + if timeout 10 ssh -i "$SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH" -v -o StrictHostKeyChecking=no -o ConnectTimeout=5 ubuntu@"$vm_ip" 'echo "SSH connection successful"'; then + log "✓ SSH connection successful to ubuntu@$vm_ip with key $SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH" >&2 return 0 fi @@ -253,8 +254,52 @@ fi # Calculate static IP address based on VM number VM_STATIC_IP="192.168.100.$VM_NUMBER" -log "Starting VM: $VM_NAME (number $VM_NUMBER) with ${MEMORY_MB}MB RAM and $CPU_CORES CPU cores" -log "VM will be assigned static IP: $VM_STATIC_IP" +log "Starting VM: $VM_NAME (number $VM_NUMBER) with ${MEMORY_MB}MB RAM and $CPU_CORES CPU cores" >&2 +log "VM will be assigned static IP: $VM_STATIC_IP" >&2 + +# SSH Key Configuration for Host Root to VM Ubuntu User +HOST_ROOT_SSH_DIR="/root/.ssh" +HOST_ROOT_SSH_PUB_KEY_PATH_ED25519="$HOST_ROOT_SSH_DIR/id_ed25519.pub" +HOST_ROOT_SSH_PRIV_KEY_PATH_ED25519="$HOST_ROOT_SSH_DIR/id_ed25519" +HOST_ROOT_SSH_PUB_KEY_PATH_RSA="$HOST_ROOT_SSH_DIR/id_rsa.pub" +HOST_ROOT_SSH_PRIV_KEY_PATH_RSA="$HOST_ROOT_SSH_DIR/id_rsa" + +SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH="" +SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH="" + +mkdir -p "$HOST_ROOT_SSH_DIR" +chmod 700 "$HOST_ROOT_SSH_DIR" + +if [ -f "$HOST_ROOT_SSH_PUB_KEY_PATH_ED25519" ]; then + SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH="$HOST_ROOT_SSH_PUB_KEY_PATH_ED25519" + SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH="$HOST_ROOT_SSH_PRIV_KEY_PATH_ED25519" + log "Using existing ED25519 SSH key: $SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH" >&2 +elif [ -f "$HOST_ROOT_SSH_PUB_KEY_PATH_RSA" ]; then + SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH="$HOST_ROOT_SSH_PUB_KEY_PATH_RSA" + SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH="$HOST_ROOT_SSH_PRIV_KEY_PATH_RSA" + log "Using existing RSA SSH key: $SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH" >&2 +else + log "No existing SSH key found for root. Generating ED25519 key..." >&2 + ssh-keygen -t ed25519 -N "" -f "$HOST_ROOT_SSH_PRIV_KEY_PATH_ED25519" -q + if [ $? -eq 0 ] && [ -f "$HOST_ROOT_SSH_PUB_KEY_PATH_ED25519" ]; then + SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH="$HOST_ROOT_SSH_PUB_KEY_PATH_ED25519" + SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH="$HOST_ROOT_SSH_PRIV_KEY_PATH_ED25519" + log "Generated ED25519 SSH key: $SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH" >&2 + chmod 600 "$HOST_ROOT_SSH_PRIV_KEY_PATH_ED25519" + chmod 644 "$HOST_ROOT_SSH_PUB_KEY_PATH_ED25519" + else + error "Failed to generate ED25519 SSH key." + fi +fi + +if [ -z "$SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH" ]; then + error "Could not find or generate an SSH public key for root user." +fi + +HOST_ROOT_SSH_PUB_KEY_CONTENT=$(cat "$SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH") +if [ -z "$HOST_ROOT_SSH_PUB_KEY_CONTENT" ]; then + error "SSH public key content is empty at $SELECTED_HOST_ROOT_SSH_PUB_KEY_PATH" +fi # Comprehensive prerequisite checks log "Performing prerequisite checks..." @@ -453,8 +498,8 @@ VM_MAC="52:54:00:$(printf '%02x:%02x:%02x' $((RANDOM%256)) $((RANDOM%256)) $((RA log "Generated MAC address for VM: $VM_MAC" # Generate proper password hash for 'ubuntu' -PASSWORD_HASH=$(generate_password_hash) -test_step "Password hash generation" "[ -n '$PASSWORD_HASH' ]" +# PASSWORD_HASH=$(generate_password_hash) # No longer needed for ubuntu user +# test_step "Password hash generation" "[ -n '$PASSWORD_HASH' ]" cat > "/tmp/user-data" << EOF #cloud-config @@ -462,23 +507,24 @@ users: - name: ubuntu sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash - lock_passwd: false - passwd: $PASSWORD_HASH + # lock_passwd: false # Not needed with key auth + # passwd: $PASSWORD_HASH # Using SSH key instead groups: sudo home: /home/ubuntu + ssh_authorized_keys: + - ${HOST_ROOT_SSH_PUB_KEY_CONTENT} -# Enable SSH with password authentication -ssh_pwauth: true -disable_root: false -chpasswd: +# ssh_pwauth: true # Disabling password auth for ubuntu user by not setting a password +disable_root: false # Keep root disabled for direct login, sudo is available +chpasswd: # This section might be irrelevant now for ubuntu user expire: false # SSH configuration -ssh_authorized_keys: [] +# ssh_authorized_keys: [] # This was a global setting, moved to user-specific # Network configuration with static IP network: - config: disabled + config: disabled # This disables cloud-init's direct network config, relying on write_files + runcmd write_files: - path: /etc/netplan/50-cloud-init.yaml @@ -790,22 +836,22 @@ fi # Test SSH connectivity if test_ssh_connection "$VM_IP"; then - log "🎉 SUCCESS: VM $VM_NAME is fully operational!" - log "✓ VM is running with PID $VM_PID" - log "✓ VM has IP address: $VM_IP" - log "✓ SSH is working: ssh ubuntu@$VM_IP (password: ubuntu)" - log "✓ VM info saved to: $VM_INFO_FILE" + log "🎉 SUCCESS: VM $VM_NAME is fully operational!" >&2 + log "✓ VM is running with PID $VM_PID" >&2 + log "✓ VM has IP address: $VM_IP" >&2 + log "✓ SSH is working with key: ssh -i \"$SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH\" ubuntu@$VM_IP" >&2 + log "✓ VM info saved to: $VM_INFO_FILE" >&2 # Display relevant IP configuration lines from VM log if [ -f "$VM_LOG_FILE" ]; then - info "Relevant IP configuration from VM log ($VM_LOG_FILE):" - grep -E "inet .*ens3|default via" "$VM_LOG_FILE" | tail -n 5 || true + info "Relevant IP configuration from VM log ($VM_LOG_FILE):" >&2 + grep -E "inet .*ens3|default via" "$VM_LOG_FILE" | tail -n 5 || true # Output of grep goes to stdout, which is fine here fi - echo "" - info "VM $VM_NAME is ready for use!" - info "Connect via SSH: ssh ubuntu@$VM_IP" - info "Default password: ubuntu (please change after first login)" + echo "" >&2 # Direct echo to stderr + info "VM $VM_NAME is ready for use!" >&2 + info "Connect via SSH: ssh -i \"$SELECTED_HOST_ROOT_SSH_PRIV_KEY_PATH\" ubuntu@$VM_IP" >&2 + # info "Default password: ubuntu (please change after first login)" # No longer relevant info "To stop the VM: sudo $(dirname "$0")/ubuntu_vm_delete.sh $VM_NUMBER" echo ""