Skip to content
Snippets Groups Projects
Select Git revision
  • 238d11db14b4d5949afd163bc4dc05bfb652e477
  • live_exam_os_ubuntu default protected
2 results

secure-solution-for-nexus-infrastructure

Florent Gluck's avatar
Florent Gluck authored
- for better readability, each command's USAGE is surrounded by horizontal lines
238d11db
History
Name Last commit Last update
src
README.md

nexus-client

Introduction

nexus-client is the client component of the Nexus project, a VDI (Virtual Desktop Infrastructure) written from scratch in Go and based on Linux/KVM + QEMU.

Components

The full project, nexus_vdi, is made of three software components:

  1. nexus-server: the server program (backend) that runs on a server.
    • Exposes a REST API to manage VMs and users
  2. nexus-client: the client or end-user program to manage VMs, users and templates.
    • The client uses REST messages to communicate with nexus-server
    • The client can be run from anywhere (locally or remotely) as long as it can communicate with nexus-server
    • Two clients have been developed so far:
      • nexush: an interactive command line client, similar to a shell. It is the most user-friendly way to interact with nexus-server, but it is not suited for scripting.
      • nexus-cli: a collection of commands particularly suited to scripting and automated operations.
      • Both clients offer the same features, functionalities and syntax. A nice touch is that commands support regular expressions allowing many VMs to be created/started/stopped/destroyed/etc. at once.
    • Both clients feature an "vmattach" command which lets users interact with their VM's desktop.
  3. nexus-exam: a minimalistic graphical client used during live exams. It doesn't feature any option and only allows a student to connect to a running VM.

Access control

Access control is implemented through capabilities. Capabilities define what users can or cannot do. They are divided into two categories:

  • User capabilities: define user access control; these are stored in the user metadata
  • VM access capabilities: define access to VMs; these are stored in the VM metadata

User capabilities

USER_CREATE
USER_DESTROY
USER_SET_CAPS
USER_LIST
VM_CREATE
VM_DESTROY_ANY
VM_EDIT_ANY
VM_START_ANY
VM_STOP_ANY
VM_LIST_ANY
VM_READFS_ANY
VM_SET_ACCESS
TPL_CREATE
TPL_DESTROY
TPL_DESTROY_ANY
TPL_LIST
TPL_LIST_ANY

VM access capabilities

When a user creates a VM, she automatically gets all VM access capabilities:

VM_SET_ACCESS
VM_DESTROY
VM_EDIT
VM_START
VM_STOP
VM_LIST
VM_READFS

No other users get any access to the created VM. However, the VM owner can add any access type to any users they like.

QEMU Guest Agent

To be available, certain features require a dedicated service, QEMU Guest Agent, to be running in the VM's guest OS. This is the case of the vmshutdown command which gracefully shutdowns a VM. This command won't work otherwise.

On a Ubuntu/Debian system, the qemu-guest-agent service can be installed with:

sudo apt-get install qemu-guest-agent

Consequently, it is highly recommended to install it in all templates as it gives you more features and control over the VMs.

nexush

nexush is a nexus-client in the form of a single executable file featuring the commands listed below. Most commands support regular expressions (regex) in order to perform actions on multiple VMs and templates at once.

Welcome to nexush, the nexus shell.
Type: "help" for help on commands
      "quit" to quit the shell
nexush> help
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
refresh             Obtains a new access token.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
whoami              Displays the current user's details.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
passwd              Updates the current user's password.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
userlist            Lists users (regex).
                    Requires USER_LIST user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
useradd             Adds a user.
                    Requires USER_CREATE user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
userdel             Deletes one or more users.
                    Requires USER_DESTROY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
usersetcaps         Sets a user's capabilities.
                    Requires USER_SET_CAPS user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmlist              Lists VMs that can be listed (regex).
                    Requires VM_LIST VM access capability or VM_LIST_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmliststart         Lists VMs that can be started (regex).
                    Requires VM_START VM access capability or VM_START_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmlistattach        Lists VMs that can be attached to (regex).
                    Requires VM_LIST VM access capability or VM_LIST_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmliststop          Lists VMs that can be stopped or shutdown (regex).
                    Requires VM_STOP VM access capability or VM_STOP_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmlistedit          Lists VMs that can be edited (regex).
                    Requires VM_EDIT VM access capability or VM_EDIT_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmlisteditaccess    Lists VMs that can have their VM access edited (regex).
                    Requires VM_SET_ACCESS user capability and VM_SET_ACCESS VM access capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmlistdel           Lists VMs that can be deleted (regex).
                    Requires VM_DESTROY VM access capability or VM_DESTROY_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmlistexportdir     List VMs that can have a directory exported (regex).
                    Requires VM_READFS VM access capability or VM_READFS_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmcred2pdf          Creates a PDF with the credentials required to attach to running VMs (regex).
                    Requires VM_LIST VM access capability or VM_LIST_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmstart             Starts one or more VMs (regex).
                    Requires VM_START VM access capability or VM_START_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmstop              Stops by force one or more VMs (regex).
                    Requires VM_STOP VM access capability or VM_STOP_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmshutdown          Gracefully shutdowns one or more VMs (regex).
                    Requires VM_STOP VM access capability or VM_STOP_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmattach            Attaches to one or more VMs in order to use their desktop environment (regex).
                    Requires VM_LIST VM access capability or VM_LIST_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmcreate            Creates one or more VMs (regex).
                    Requires VM_CREATE user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmedit              Edits one or more VMs' properties: name, cpus, ram or nic (regex).
                    Requires VM_EDIT VM access capability or VM_EDIT_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmdel               Deletes one or more VMs (regex).
                    Requires VM_DESTROY VM access capability or VM_DESTROY_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmsetaccess         Sets a user's VM access in one or more VMs (regex).
                    Requires VM_SET_ACCESS user capability and VM_SET_ACCESS VM access capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmdelaccess         Deletes a user's VM access in one or more VMs (regex).
                    Requires VM_SET_ACCESS user capability and VM_SET_ACCESS VM access capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
vmexportdir         Exports one or more VMs' directory into one or more tar archives.
                    Creates one archive per VM (regex).
                    Requires VM_READFS VM access capability or VM_READFS_ANY user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
tpllist             Lists available templates (regex).
                    Requires TPL_LIST or TPL_LIST_ANY user capabilities.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
tplcreate           Creates a template from an existing VM.
                    Requires TPL_CREATE user capability.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
tpldel              Deletes one or more templates (regex).
                    Requires TPL_DESTROY or TPL_DESTROY_ANY user capabilities.

Note that when attached to a VM's desktop (vmattach command), ctrl+F12 toggles between fullscreen/non-fullscreen modes.

nexus-cli

nexus-cli is another nexus-client in the form of a single executable file featuring pretty much the exact same commands as nexush. Therefore we won't list them here.

Building nexush and nexus-cli

nexush and nexus-cli source codes must be obtained from the following git repository (using ssh key-pair authentication):

git clone ssh://git@ssh.hesge.ch:10572/flg_projects/nexus_vdi/nexus-client.git nexus-client.git

If you didn't set up a public key in your gitlab account, then you can obtain the sources through https with:

git clone https://gitedu.hesge.ch/flg_projects/nexus_vdi/nexus-client.git nexus-client.git

Building nexush

To build the nexush executable, go into nexus-client.git/src/nexush and run:

go build .

To build a statically linked, stripped and compressed version of nexush, run:

CGO_ENABLED=0 go build -a -ldflags '-w -extldflags "-static"'
strip -s nexush
upx nexush

Building nexus-cli

To build the nexus-cli executable, do exactly the same as with nexush but replace every instance of nexush with nexus-cli.

Running nexush and nexus-cli

Both nexush and nexus-cli require two environment variables:

  • NEXUS_SERVER: specifies the Nexus server to connect to along the port number.
  • NEXUS_CERT: specifies the path to the public certificate required for encrypted communication (TLS) with the Nexus server.

Example of variables initialization:

export NEXUS_SERVER=192.168.1.25:1077
export NEXUS_CERT=/home/janedoe/nexus-ca-cert.pem

nexush usage examples

Launch nexush and log in as user janedoe@nexus.org (note that you will be prompted for your password):

./nexush janedoe@nexus.org

Display available commands:

help

Display the help for the vmcreate command:

vmcreate

Display information about the currently logged-on user:

whoami

List all users:

userlist .

List users matching the "jane" pattern:

userlist jane

Add new user lukeskywalker@force.net with a list of capabilities:

useradd lukeskywalker@force.org Luke Skywalker maytheforcebewithyou USER_CREATE USER_DESTROY USER_LIST USER_SET_CAPS VM_CREATE

List all listable VMs:

vmlist .

List all listable VMs with more details ("long output"):

vmlist -l .

List listable VMs matching the "ubuntu" pattern:

vmlist ubuntu

List listable VMs matching the "ubuntu" pattern and also the VM with ID 6713ce26-941e-4d95-8e92-6b71d44bf75a:

vmlist ubuntu 6713ce26-941e-4d95-8e92-6b71d44bf75a

List all VMs that can be started:

vmliststart .

Start VM 6713ce26-941e-4d95-8e92-6b71d44bf75a:

vmstart 6713ce26-941e-4d95-8e92-6b71d44bf75a

Start VMs matching the "exam ISC_433 PCO" pattern:

vmstart "exam ISC_433 PCO"

List all VMs that can be attached to:

vmlistattach .

Attach to VM 6713ce26-941e-4d95-8e92-6b71d44bf75a and all VMs matching the pattern "zorglub":

vmattach 6713ce26-941e-4d95-8e92-6b71d44bf75a zorglub

List all VMs that can be shutdowned or stopped:

vmliststop .

Shutdown VMs matching the "exam ISC_433 PCO" pattern (for this to work, qemu-guest-agent must be running in the VM's guest OS!):

vmshutdown "exam ISC_433 PCO"

Stop by force VM 6713ce26-941e-4d95-8e92-6b71d44bf75a:

vmstop 6713ce26-941e-4d95-8e92-6b71d44bf75a

Create a VM named "Doom", based on the fbccb584-9ea6-40f7-926d-dabf3970525e (Doom) template, with 4 CPUs, 4GB RAM, and a network interface with NAT translation:

vmcreate Doom 4 4096 user fbccb584-9ea6-40f7-926d-dabf3970525e

Create 50 VMs with the base name "ISC_433 Exam" based on the 6713ce26-941e-4d95-8e92-6b71d44bf75a template, with 2 CPUs, 2GB RAM, and no network interface:

vmcreate "ISC_433 Exam" 2 2048 none 6713ce26-941e-4d95-8e92-6b71d44bf75a 50

It takes about 30 seconds and 11MB of disk space to create these 50 VMs. They will have the following names:

ISC_433 Exam [1]
ISC_433 Exam [2]
...
ISC_433 Exam [50]

List all VMs that can be edited:

vmlistedit .

Edit VM 6713ce26-941e-4d95-8e92-6b71d44bf75a by changing its name to "Tagada VM", changing it to 1 CPU and no network interface (none):

vmedit 6713ce26-941e-4d95-8e92-6b71d44bf75a name="Tagada VM" cpus=1 nic=none

Edit VMs matching the "PCO lab2" pattern by changing their CPU to 1 core and a network interface with NAT translation (user):

vmedit "PCO lab2" cpus=1 nic=user

List all VMs that can be deleted:

vmlistdel .

Delete VM 6713ce26-941e-4d95-8e92-6b71d44bf75a:

vmdel 6713ce26-941e-4d95-8e92-6b71d44bf75a

Delete VMs matching the "exam ISC_433 PCO" pattern:

vmdel "exam ISC_433 PCO"

List all VMs that can have their access edited:

vmlisteditaccess .

Set the VM access for VM 89649fe3-4940-4b77-929e-50903789cd87 with: VM_LIST and VM_DESTROY for user student@nexus.org:

vmsetaccess 89649fe3-4940-4b77-929e-50903789cd87 student@nexus.org VM_LIST VM_DESTROY

Set VM access for VMs matching the "alpine" pattern with: VM_START and VM_STOP for user student@nexus.org:

vmsetaccess alpine student@nexus.org VM_START VM_STOP

Remove VM access for student@nexus.org from VM 89649fe3-4940-4b77-929e-50903789cd87:

vmdelaccess 89649fe3-4940-4b77-929e-50903789cd87 student@nexus.org

Remove VM access for student@nexus.org from VMs matching the "lab2" pattern:

vmdelaccess lab2 student@nexus.org

Generate exam_vms.pdf with the credentials required to connect to all running VMs matching "exam prog sys":

vmcred2pdf "exam prog sys" output.pdf

Extract and download the /home directory of all VMs matching "exam prog sys" (each directory is saved in a .tar archive named after the VM's ID):

vmlistexportdir "exam prog sys" /home

List all available templates:

tpllist .

List templates matching the "ubuntu" pattern:

tpllist ubuntu

Create a new public template, named "Xubuntu 22.04 + golang toolchain" based on VM 89649fe3-4940-4b77-929e-50903789cd87 (public templates are accessible to everyone while private templates are only accessible to their creators):

tpllist 89649fe3-4940-4b77-929e-50903789cd87 "Xubuntu 22.04 + golang toolchain" public

Delete template 8ae56a30-3195-4aea-960d-abb45c47f99e:

tpldel 8ae56a30-3195-4aea-960d-abb45c47f99e

Delete all templates matching the "test" pattern:

tpldel test

Quit nexush:

quit

nexus-cli usage examples

Given nexus-cli offers the same VM, user and template commands as nexush, we only show a handful of examples here.

List available commands:

./nexus-cli

Authentify user janedoe@nexus.org and obtain an access token:

export NEXUS_TOKEN=`./nexus-cli login janedoe@nexus.org pipomolo`

Start VM 6713ce26-941e-4d95-8e92-6b71d44bf75a:

vmstart 6713ce26-941e-4d95-8e92-6b71d44bf75a

nexus-exam

Compiling nexus-exam

Get the source code with:

git clone ssh://git@ssh.hesge.ch:10572/flg_projects/nexus_vdi/nexus-client.git

To build the nexus-exam executable, run:

go build .

Unfortunately, nexus-exam cannot be built statically (on Ubuntu 20.04 and 22.04 at least) as some static libraries are missing.

Running nexus-exam

nexus-exam requires two environment variables:

  • NEXUS_SERVER: specifies the Nexus server to connect to.
  • NEXUS_CERT: specifies the path to the public certificate required for encrypted communication (TLS) with the Nexus server.

Example of variables initialization:

export NEXUS_SERVER=192.168.1.25
export NEXUS_CERT=/home/janedoe/nexus-ca-cert.pem

Below is a screenshot of nexus-exam's graphical interface:

Tutorial: creating a live exam with nexush

Let's say you want to create an exam for the class "ISC_433_PCO". Let's assume 50 students are enrolled in the class.

First, you need to create the VM that will be used by the students during the exam. Typically, this VM will contain the exam environment (compilers, editors, tools, etc.) along the description of the exam, for instance as a PDF on the desktop.

  1. First, authenticate onto the nexus server (make sure the NEXUS_SERVER and NEXUS_CERT environment variables are properly initialized):

    export NEXUS_SERVER=192.168.1.25:1077
    export NEXUS_CERT=/home/janedoe/nexus-ca-cert.pem
    
    ./nexush janedoe@nexus.org
  2. List available templates and choose the one you wish to use for your exam VM:

    tpllist .

    Let's assume template 8ae56a30-3195-4aea-960d-abb45c47f99e (Xubuntu_22.04), is the one you would like to use.

  3. Create the VM based on the chosen template. Let's say you want the VM to be named "Exam Oct2022 ISC_433_PCO" and you want it to have 2 CPUs, 4GB of RAM and access to the Internet (for now):

    vmcreate "Exam Oct2022 ISC_433_PCO" 2 4096 user 8ae56a30-3195-4aea-960d-abb45c47f99e
  4. Now that the VM is created, you need to start it, connect to it, and configure it to fit your needs. First, start it with (you can also start it by specifying its VM ID):

    vmstart "Exam Oct2022 ISC_433_PCO"
  5. Attach to the VM in order to configure it to your needs (you can also attach to it by specifying its VM ID):

    vmattach "Exam Oct2022 ISC_433_PCO"
  6. Configure the VM to your needs, by:

    • upgrading the system with sudo apt-get update && apt-get upgrade
    • installing the QEMU Guest Agent with sudo apt-get install qemu-guest-agent (so you will be able to use the vmshutdown command)
    • installing the applications, compilers, tools, editors, etc. that are required for the exam
    • copying to the desktop the file describing the exam's objectives Once done, you can shutdown the VM.
  7. Now that the VM is ready for the exam (its ID is 62856385-4797-4f0f-b840-2e050c05a0a8), you must create a template from it. This template must be private as we don't want anyone else to access it. Let's choose "Exam Oct2022 ISC_433_PCO" as the template name (template creation takes several minutes, the larger the VM, the longer):

    tplcreate 62856385-4797-4f0f-b840-2e050c05a0a8 "Exam Oct2022 ISC_433_PCO" private

    Once done, the new template ID is displayed. Let's say its ID is 540a3f8b-daa9-4ea7-9d33-e9fcaa7c9c3a

  8. You can now create the VMs for your 50 students using the freshly created template. Let's say the base name for the 50 VMs to create is "Live Exam Oct2022 ISC_433_PCO". You want the VMs to have: 2 CPUs, 4GB of RAM and no network interface to prevent any fraud. Create a CSV file, say students.csv with the names of your 50 students, one per line. The 50 VMs can be created with:

    vmcreate "Live Exam Oct2022 ISC_433_PCO" 2 4096 none 540a3f8b-daa9-4ea7-9d33-e9fcaa7c9c3a students.csv

    It should take a few seconds to generate these 50 VMs.

  9. The day of the exam, you'll have to start the 50 VMs and generate a PDF with the credentials required to connect to each VM. To start the 50 VMs, run:

    vmstart "Live Exam Oct2022"
  10. Finally, to produce the PDF containing all the credentials required to attach to each VM, run:

    vmcred2pdf "Live Exam Oct2022" creds.pdf

    creds.pdf contains a table, where each line provides access to a VM: the VM name, the port, the password and a blank cell that should be filled by the student using this VM during the exam. The students must use nexus-exam to connect to their VM using the VM's credentials (port and password).

  11. You can now print the PDF above, cut each line and give each student the strip of paper for a VM's credentials. Once a student has completed the exam, they should shutdown the VM and give you the strip of paper back. Note that you can shutdown a VM with nexus-cli vmshutdown (if the guest OS runs qemu-guest-agent). You can also force a VM to be stopped with nexus-cli vmstop although it's not clean and might corrupt the VM's filesystem.

  12. To correct the students' exams, you can either start each VM and attach to it and inspect the files. However, an easier way is to download the relevant files to your local computer with the vmlistexportdir command. For instance, the command below extracts and downloads the /home directory of all VMs matching "Live Exam Oct2022" (each directory is saved in a .tar archive named after the VM's ID):

    vmlistexportdir "Live Exam Oct2022" /home