Skip to content

Debian

This activity puts into practice the concepts from the Virtualization and Virtual Machines lecture. You will install a hypervisor, configure a Debian guest, run the snapshot safety-net workflow end to end, and observe how NAT and host-only networking modes differ in practice. By the end you will have a running VM you can control, break, and recover from in seconds.


A hypervisor is the software layer that creates and manages virtual machines on your laptop. Without it, there is no way to run a second operating system alongside your host OS. We will use a Type-2 (hosted) hypervisor, meaning it runs as a regular application on top of your existing operating system. We will use VirtualBox, which runs on macOS, Windows, and Linux.

  1. Download VirtualBox from virtualbox.org and install it.
  2. Also install the VirtualBox Extension Pack from the same page (enables USB 3.0 and other features).
  3. Open VirtualBox. You do not need to create a VM yet.

An ISO file is a disk image: a single file that contains the exact contents of a bootable installation disc. The hypervisor can present this file to the VM as if it were a physical DVD drive, so the VM boots the installer without any physical media. We will use the Debian 12 (Bookworm) server netinstall ISO. Debian installs quickly, runs with a low memory footprint, and is available for both ARM and x86-64.

Download the arm64 netinstall ISO from cdimage.debian.org.

Look for a filename like debian-12.x.x-arm64-netinst.iso.

Before starting the installer, we define the VM’s virtual hardware: how many vCPUs, how much RAM, and how large a virtual disk. These choices shape the VM’s behavior for the rest of the activity. The goal is to start conservative (not generous) because it is easy to increase resources later and because over-allocating on a laptop starves your host OS.

  1. Click New.
  2. Name: debian-lab. Type: Linux. Version: Debian (64-bit) on Intel/Windows/Linux, or Debian (arm64) on Apple Silicon.
  3. Hardware:
    • Memory: 1024 MB
    • Number of CPUs: 2
    • Disk Size: 20 GB (you can use less but partitioning might be finicky for this specific activity)
    • Use EFI
  4. After the VM is created, open Settings > Network > Adapter 1 and set Adapter Type to Paravirtualized Network (virtio-net). VirtualBox defaults to an emulated Intel NIC; VirtIO gives you a paravirtualized network adapter instead.

Starting the VM boots the Debian installer from the ISO, exactly as if you had inserted a DVD into a real machine. The VM window becomes the VM’s virtual monitor: it shows only what the virtual machine is outputting. Your laptop’s own desktop continues running normally behind it.

  1. Start the VM. The Debian boot menu appears in the VM window. Select Install to use the text-mode installer.

  2. Follow the installer prompts:

    • Language: English
    • Location: United States
    • Keyboard: American English (or whatever matches your physical keyboard)
    • Hostname: debian-lab
    • Domain name: leave blank
    • Root password: set one you will remember
    • New user: create a regular account (you can use your ONID username, e.g., ulbrical) with a password
    • Timezone: Pacific (or your local timezone)
    • Partitioning: Guided - use entire disk, then All files in one partition
    • Package manager mirror: United States - debian.osuosl.com
    • Software selection: uncheck everything except SSH server and standard system utilities

    The software selection step is significant. Deselecting the desktop environment means the installed system boots to a text prompt with no graphical interface. This is a deliberate choice that reflects real server practice: a GUI consumes memory, installs more software (more attack surface), and is simply unnecessary on a machine you will manage remotely.

  3. Let the installer finish. It downloads packages from the internet during installation (5-15 minutes depending on network speed).

  4. When prompted, eject the ISO and reboot.

After reboot, the VM window shows a plain text login prompt: no desktop, no mouse cursor. This is the virtual console: the equivalent of a physical keyboard and monitor directly connected to a server. Type your username and press Enter, then enter your password (it will not echo to the screen; this is normal).

Everything in the sections below is typed into this console. The VM’s terminal behaves exactly like any Linux terminal: commands you type run inside the VM, not on your laptop. Your host OS is completely unaffected by anything you do here. This isolation is the whole point of a VM.

The hypervisor can expose virtual hardware to the guest in two ways: fully emulated (slower, universally compatible) or paravirtualized (faster, requires a cooperative driver in the guest). Here we check which type is active for storage and networking, because the difference is measurable.

  1. Check which storage devices the kernel sees:

    Terminal window
    lsblk -d -o NAME,TYPE,TRAN

    lsblk lists block devices. The -d flag shows disks only (no partitions), and -o NAME,TYPE,TRAN selects name, type, and transport. You will see something like:

    NAME TYPE TRAN
    sda disk
    sr0 rom

    The disk appears as sda because VirtualBox uses a VirtIO SCSI controller, which uses SCSI device naming. The TRAN column is empty because lsblk does not report a transport for virtio.

  2. Confirm the VirtIO controller is active by checking the PCI device list:

    Terminal window
    lspci | grep -i virtio

    You should see lines containing Virtio SCSI for storage and Virtio network for networking.

  3. Install ethtool to query the network driver. On Debian, sudo is not installed by default, so switch to root first:

    Terminal window
    su -
    apt update
    apt install ethtool
    exit
  4. Find your main network interface name:

    Terminal window
    ip link show

    You will see at least two interfaces: lo (loopback) and your main interface, named something like enp0s3, eth0, or ens3. Note the name.

  5. Check which driver is managing the network interface (substitute your interface name):

    Terminal window
    ethtool -i enp0s3 | grep driver

    Expected output: driver: virtio_net. This confirms paravirtualized networking is active. If you saw e1000 or pcnet32, it would indicate a fully-emulated NIC.

Before making any changes to a system, record what “normal” looks like. This baseline is your reference point: if something feels slow later, you can compare current numbers to these.

  1. Sample the CPU idle percentage:

    Terminal window
    top -b -n 3 | grep "Cpu(s)" | tail -1

    top -b -n 3 runs three samples in batch mode and exits. Each sample produces a Cpu(s) line showing percentages for user, system, and idle time. Taking the last sample with tail -1 avoids the startup spike. A freshly booted VM should show idle above 90%.

  2. Check memory usage:

    Terminal window
    free -h

    The key column is available: the kernel’s estimate of memory realistically free for new processes, including cache that would be released if needed. “Available” is almost always lower than “total” because the kernel uses free RAM for disk caching. This is normal; unused RAM is wasted RAM.

  3. Check disk usage on the root filesystem:

    Terminal window
    df -h /

    The Use% column is what to watch over time. On a freshly installed Debian system it should be well under 20%.

  4. Check uptime and load average:

    Terminal window
    uptime

    uptime reports three load average figures (1-minute, 5-minute, 15-minute): a rolling count of processes waiting to run. On a 2-vCPU VM, a sustained load average above 2.0 indicates the CPU is saturated.

    Record all four values. They give you a baseline to compare against after you start running services.


Before making any risky change to a running system, a snapshot gives you a guaranteed rollback path. Rather than spending time carefully reversing each change if something goes wrong, you revert the entire disk to the pre-change state in seconds. This part runs that workflow end-to-end so the steps are instinctive before you need them in a real scenario.

Log in to the VM and verify the SSH service and disk state are clean before creating the snapshot. Taking a snapshot of a broken system is not useful.

  1. Verify SSH is running and the disk has free space:

    Terminal window
    systemctl status ssh
    df -h /

    Both should show normal output: SSH active and running, root filesystem with free space. If SSH shows failed, resolve it before continuing.

  1. With the VM selected, open Snapshots, right click on “Current State” and click “Take…”.
  2. Name it pre-change-1 and click OK.

We will simulate a common real-world mistake: a typo in a configuration file that breaks a service. Here we corrupt the SSH config with an invalid port value.

  1. Append a bad config line and reload the service:

    Terminal window
    su -
    sh -c 'echo "Port INVALID_VALUE" >> /etc/ssh/sshd_config'
    systemctl reload ssh
    exit
  2. Verify the damage:

    Terminal window
    systemctl status ssh
    sshd -T

    systemctl status ssh shows the service still active (running) but with the reload marked as failed. sshd keeps the existing process alive when a reload fails so active connections are not dropped. sshd -T runs in test mode, validating the config without starting a daemon. You should see output like Badly formatted port number.

  1. Look at the end of the SSH config:

    Terminal window
    tail -10 /etc/ssh/sshd_config

    You can see the Port INVALID_VALUE line at the end. In this simple case the culprit is obvious. In a real incident the bad line might be buried in a 200-line config that was auto-generated by a deployment script, or the problem might be an interaction between two valid-looking settings. This is the decision point: keep debugging, or spend five seconds reverting to the confirmed-working state.

Shut down the VM gracefully before reverting (e.g., shutdown now), since most hypervisors require the VM to be powered off to restore a snapshot.

Revert to pre-change-1:

  1. Open the Snapshots panel for the VM.
  2. Right-click pre-change-1 and choose Restore.
  3. Uncheck Create snapshot of current state and click Restore.

Start the VM and verify recovery:

  1. Confirm everything is clean:

    Terminal window
    systemctl status ssh
    sshd -T
    tail -5 /etc/ssh/sshd_config

    All three should be clean: SSH active, no config error, no INVALID_VALUE line.

Once recovery is confirmed and you are satisfied the system is working, delete the snapshot:

  1. Open the Snapshots panel.
  2. Right-click pre-change-1 and choose Delete Snapshot.

Deleting a snapshot merges the delta file back into the base image and removes the extra layer. Snapshots are meant to be short-lived: the longer you keep one, the larger the delta grows, and the more layers the hypervisor must traverse on every disk read.


The networking mode you assign to a VM determines what it can reach and what can reach it. This matters immediately: if you configure a VM to host a service, the networking mode decides whether other machines on your network can connect. This part lets you observe the practical difference between NAT and host-only directly.

Your VM currently uses NAT. In NAT mode, the hypervisor acts like a router: the VM gets a private IP address on a virtual network, and the hypervisor forwards outbound traffic on the VM’s behalf using the host’s real IP address. This means the VM looks like the host to the outside world.

  1. Check the VM’s IP address:

    Terminal window
    ip addr show

    ip addr show lists all network interfaces with their assigned addresses. Look for an inet line on your non-loopback interface. The address is typically 10.0.2.15 on VirtualBox. Note that this is a private address in a virtual subnet managed entirely by the hypervisor.

  2. From your laptop’s terminal (not inside the VM), try to ping the VM:

    Terminal window
    ping -c 3 <vm-ip-address>

    This will time out. The VM can initiate connections outward, but nothing outside the hypervisor’s virtual network can initiate a connection to the VM. The hypervisor has no port-forwarding rule telling it where to send incoming packets addressed to the VM.

  3. Confirm the VM still has outbound internet access; run this inside the VM:

    Terminal window
    ping -c 3 debian.org

    This should succeed: the VM can reach out through the hypervisor’s NAT, even though the reverse direction is blocked.

Host-only creates a private virtual network that exists only between the host and its guests. There is no connection to the physical network or the internet; the hypervisor does not perform NAT. This mode is useful for lab setups where you want VMs to communicate with each other and with your laptop, but you do not want them reachable from outside.

  1. Power off the VM:

    Terminal window
    shutdown now
  2. Change the network adapter to host-only:

    1. In the main VirtualBox Manager window, open the Network tab (separate from the VM) and click Create to add a host-only network if none exists.
    2. Open your VM Settings > Network > Adapter 1.
    3. Change Attached to from NAT to Host-only Network and select the network you just created.
    4. Click OK and start the VM.
  3. Check the new IP address inside the VM:

    Terminal window
    ip addr show

    The address will be on a different subnet than NAT, typically 192.168.x.x for host-only.

  4. From your laptop, ping the VM:

    Terminal window
    ping -c 3 <new-vm-ip>

    This should succeed. Your laptop and the VM are on the same virtual host-only network.

  5. From inside the VM, test internet access:

    Terminal window
    ping -c 3 debian.org

    This will fail. The host-only network has no default gateway pointing to the internet; traffic has nowhere to go beyond the host. You can test the host’s IP on the host-only network to confirm the VM can still reach the host:

    Terminal window
    ping -c 3 <host-only-ip-of-host>

    That IP address is typically the gateway for the host-only network, and it should respond to pings from the VM.


Before moving on, let’s have a little fun:

  1. Install cowsay and fortune:

    Terminal window
    su -
    apt install cowsay fortune
    exit
  2. Run them together:

    Terminal window
    fortune | cowsay
  • Work through the Vagrant Quick Start to see how Vagrant defines VM configuration in code rather than through a GUI. Vagrantfiles are versionable and shareable, which solves the “works on my machine” problem for development environments.
  • Read VirtualBox networking modes in the official manual for the full picture of NAT, Host-only, Bridged, and Internal networking.
  • Try creating a second VM and connecting the two using an Internal network adapter so they can communicate without touching the host or the internet.