Safe Development with LXC

Jul 2022

As a developer, how many times have you run unknown scripts (from the internet) in your system? Many times, the developers are limited by time or motivation to read through the scripts they find online. And sometimes, it's not even practical to go through every package and script that we run or install. What if one of those scripts you run contains malware? This is especially alarming since most of us use the same laptop in our developer and personal lives.

Two popular choices that can solve this issue are virtual machines and Docker containers. You can develop in a virtual machine or a docker container to isolate your developer life from your personal life. But virtual machines are resource-heavy and Docker containers might not be suitable for a long-term development plan. What you need is a container that is easy to manage and lightweight. And that's why you need LXC!

Containerizing is not a complete preventive measure against malware. This article only focuses on the safeguarding of your personal files from the direct reach of the potentially malicious scripts you run during your dev works.

So, what is LXC? Well, another article on LXC/LXD will be redundant. So, instead of reinventing the wheel, I will point you to the right resources to get you started.

LXC containers are often considered as something in the middle between a chroot and a full fledged virtual machine. The goal of LXC is to create an environment as close as possible to a standard Linux installation but without the need for a separate kernel.
~ Linux Containers Docs

LXD is a next generation system container and virtual machine manager. It offers a unified user experience around full Linux systems running inside containers or virtual machines.
~ Linux Containers Docs

To summarize, imagine LXD to be something like your VM Manager, which helps you create and manage containers by using LXC under the hood. Since the underlying runtime is LXC, you will see most people say LXC instead of LXD.

To get comfortable with LXC, I recommend you start at this video by LearnLinuxTV.

Once you watch the above video, you know how to create, start, and stop LXC containers.

General Commands for Command-line Usage

Here are a few useful commands for your reference.

# start a container
lxc start {container-name}

# stop a container
lxc stop {container-name}

# execute commands in a container
lxc exec {container-name} -- {command}

# get shell in a container
lxc exec {container-name} -- bash

GUI Applications in LXC

To run GUI applications within LXC, follow this blog:

Application Launch Icons for LXC

Now you can start GUI applications within the container from a command line. However, we can do better. Let's create launch icons for applications within the container so that they can be launched just like an application on the host system. For demo purposes, we will create a launcher for file explorer. You can use the same technique to create launchers for other programs as well.

Creating a Launcher for File Explorer

1) In your container:

First, make sure nautilus (GNOME file manager) is installed by running nautilus from a shell within the container. If not installed, install nautilus using the following command:

(container)$ sudo apt-get install -y nautilus

2) In your host system

  1. Go to ~/.local/share/applications in your host system.
  2. Create a file with .desktop extension.
  3. The contents of this file should be as follows:
    #!/usr/bin/env xdg-open
    [Desktop Entry]
    Name=LXC Files
    Exec=lxc exec {container-name} -- sudo --user {user-name} --login nautilus
  4. Replace {container-name}, {user-name} and {icon's-absolute-path} appropriately.
    • Both the {container-name} and {user-name} will be ubuntu if you followed the LearnLinuxTV tutorial above.
    • The icon for the application should be available in the host system.
    • I have created a few icons combining various application icons with LXC logo. This helps avoid confusion when the application is installed in the host as well as the container. You can find them below.
  5. Go to applications and search for lxc. You will find the launch icon appearing.
    Note: Launch configurations might take a few minutes to sync. Try restarting your system if it is taking a long time.
When you launch a GUI application within the container, the title bar will indicate the container in which the application is running. The following screenshot shows Firefox running in a container named "ubuntu".

Now you can launch applications within the container just like the native GUI applications. Note that now the container runtime has no access to any of the files in your host system. However, sometimes you might want to share a few files between the host and the container. The following section explains how you can share a folder between the container and the host.

Mounting Folders

You can mount folders from your host system to your container so that you can access the files from both systems. This will be helpful in various scenarios. For example, let's say you want to push your code to GitHub. But you don't want to expose your GitHub (SSH) keys to the container since the container is considered unsafe. In that case, you mount a folder to make it accessible to both the host as well as the container. Now you develop (write and run) the code in this folder from your container. And you push this code to GitHub from your host system.

The following tutorial by Vivek Gite will help you mount directories.

Don't mount your entire home folder to the container. Instead, mount only the essential folders used for development. Do not mount any folder containing your personal files.
By now, your container should serve most of your development requirements. But let's improve the experience further.

LXC Audio

Let's enable audio in your container. To enable audio, we expose the host's PulseAudio socket to the container. Toby63 has provided detailed steps for doing this in the LXC forum:

Emulators within LXC

If you are an android developer, you might want to run AVD emulators inside your container.

AVD emulators are based on QEMU. You can use the following tutorial to set up QEMU for LXC.

Once your setup is complete, you can use the command virt-host-validate to validate your setup.

Install Android Studio and AVD in your container and you can start your Android development within your container.

Closing Remarks

You can do almost everything you need within the container. Some requirements might want you to expose a few necessary unix sockets, ports, and folders to the container. However, a limitation of the container is when you need to modify the kernel or load kernel modules. Such developments will still require a VM as the container shares the kernel of the host system. Your containers cannot modify your kernel.

The end
Other Articles