Proxmox: Kali in a Linux Container (LXC)

In this post, I demonstrate the process of importing, installing, and configuring a Kali LXC image in Proxmox. I also discuss some of the potential challenges that may present.
Proxmox: Kali in a Linux Container (LXC)
In: Proxmox, Home Lab, Linux, Attack

Why Kali in a LXC?

To be honest... no reason at all, other than just to try it. Linux Containers do present some advantages over VMs, as they boot more quickly and can generally run on fewer resources.

Potential Pitfalls

Lack of Graphics Driver

You can install a desktop environment on your Kali LXC and use a remote desktop solution to access said environment. However, since the Linux Container does not ship with a graphics display driver, Kali will not be able to virtualize a display.

This means that your desktop sessions will be running under a temporary graphical session and if the display server crashes, is restarted, stopped, etc, then any unsaved user data running under that desktop session will be lost. This is not something you'd anticipate to happen often, so not a huge concern. It's merely something to be aware of.



Security Mitigations

Running Kali in a LXC comes with its own set of challenges as well. For security reasons, Proxmox developers recommend using unprivileged containers at all times, except extraordinary cases where privileged containers are required.

Unprivileged Containers vs. Privileged Containers


Unprivileged Containers


Unprivileged containers use a new kernel feature called user namespaces. The root UID 0 inside the container is mapped to an unprivileged user outside the container. This means that most security issues (container escape, resource abuse, etc.) in these containers will affect a random unprivileged user, and would be a generic kernel security bug rather than an LXC issue. The LXC team thinks unprivileged containers are safe by design.

Privileged Containers


The LXC team considers this kind of container as unsafe, and they will not consider new container escape exploits to be security issues worthy of a CVE and quick fix. That’s why privileged containers should only be used in trusted environments.

https://pve.proxmox.com/wiki/Linux_Container

As we can see, root in an unprivileged container does not map to root on the host. This means that you may not be able to make modifications to certain files on the host, or make specific system calls. And, this MAY yield unexpected behaviors in Kali Linux.

One such example is that you won't be able to run OpenVPN on your unprivileged container, as it won't be able to create the necessary /dev/net/tun or /dev/net/tap files without a workaround.

A potential solution? Run your Kali LXC as a privileged container, but you do so at your own risk. I am in no way advising you to do so.

The most ideal solution? If your Kali container is not running ideally, destroy it and run Kali in a VM. That will make all the aforementioned problems go away.

Create a Kali Linux VM in Proxmox
In this module, we will look at the process of creating a Kali Linux VM using the command line in Proxmox





Importing the Container Template

Now that we've got the doom and gloom out of the way, let's have some fun. 😊
In this article, I show you how to import a container image from an external source and use it to build Linux Containers in Proxmox.

Proxmox: LXC Using External Templates
In this post, I show you how to create Linux Containers using alternative container template registries.

I'll be using this container repository to pull the Kali container template:

Index of /images/kali/current/amd64/default/

And, I'll be downloading the container template accordingly:





Building the Container

The official documentation I'm referencing for the next steps can be found here:

Kali inside Proxmox (Guest VM) | Kali Linux Documentation
Due to the type of hypervisor Proxmox is we do not have a documentation page on how to install it. However, this can be found through Proxmox’s official page. Proxmox has two ways of accessing a nested environment. The first is through virtualization, using QEMU. The other is through containerizatio…
Right-click your PVE node and click 'Create CT'
Specify a password and/or SSH key, the user is 'root'
Choose the container template seen before
The folks at kali.org recommend a 20GB disk
The folks at kali.org recommend a minimum of 2 cores
Again, following recommendations, you can always add more later
Fill this out according to your network requirements
Again, fill this out according to your environment





Start and Configure the Container

Open the container console after starting it and log in. The username is root and the password and/or SSH key was set by you.



Install Required Packages

When you first boot up a LXC, there is only an extremely minimal set of core files and applications. In terms of getting the GUI (desktop environment) up and running, I'll be referencing the official documentation here:

Kali Linux LXC/LXD Images | Kali Linux Documentation
Content: Overview Command line Kali LXD container on Ubuntu host Gui Kali LXD container on Ubuntu host Privileged Kali LXC container on Kali host Unprivileged Kali LXC container on Kali host References Overview Kali Linux containers are the ideal solution to run Kali Linux within other Linux distrib…
apt clean && apt update && apt upgrade -y
apt install -y kali-linux-default
chsh -s $(which zsh)

Now, reboot your container in the Proxmox GUI.

Be patient! The kali-linux-default metapackage will install the core toolset that ships with a default Kali installation. We'll use the default selections at every prompt.

ℹ️
Ignore any error output during the installation process. Much of it is related to the fact that we're running in an unprivileged container.
Choose 'Yes', press Enter
Press Enter to proceed
Choose 'No', press Enter
Choose 'No', press Enter
Choose 'standalone', press Enter





Install the Desktop Environment

By default, Kali Linux uses the xfce desktop environment, but you can choose whichever desktop environment you prefer. To keep this experience as close to the out-of-box-experience you'd get with a default Kali Linux install, I'm going to demonstrate installing xfce.

apt install -y kali-desktop-xfce
⚠️
You're likely going to see a lot of red error output while installing this metapackage. This is due to the fact that this container is unprivileged while attempting to modify core system files that map back to the host.



If you're interested in switching from XFCE to KDE...

I wrote some brief notes on changing the desktop environment from the default XFCE to KDE Plasma. I prefer the overall functionality of KDE, especially the built-in window tiling.

💡
Also, note that KDE Plasma is going to consume a bit more of the available CPU and memory on the container. So, consider increasing the CPU cores and memory if possible.
Change to KDE Plasma D... | 0xBEN | Notes
Installing KDE Plasma Official Documentation: https://www.kali.org/docs/general-use/switching-deskt…





Networking Issue Fix

ℹ️
After installing the kali-desktop-xfce metapackage, I repeatedly noticed that this would cause the networking stack to fail to initialize. This is because this metapackage also installs the NetworkManager package, which is typically used for desktop environments.

Linux Containers are shipped with the systemd-networkd manager, as they are typically operating as headless servers without a desktop environment. NetworkManager is typically used in desktop environments, as it provides a nice GUI front end for managing network interfaces.

systemd-netword and NetworkManager can exist on the same host, so long as they're managing distinct interfaces. In the case of our container, they're both trying to manage eth0 and creating a conflict.

I'm going to opt to use systemd-networkd on my container, due to the tighter integration with Linux Containers on Proxmox.

# Remove and purge all configuration files for NetworkManager
apt remove -y --purge --auto-remove network-manager

Once finished, reboot the container.





Install Remote Desktop Server(s)

Install XRDP Server

apt install -y xorg xrdp

Install the requisite display server and RDP server packages

cat <<EOF | sudo tee /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla
[Allow Colord all Users]
Identity=unix-user:*
Action=org.freedesktop.color-manager.create-device;org.freedesktop.color-manager.create-profile;org.freedesktop.color-manager.delete-device;org.freedesktop.color-manager.delete-profile;org.freedesktop.color-manager.modify-device;org.freedesktop.color-manager.modify-profile
ResultAny=no
ResultInactive=no
ResultActive=yes
EOF

Add PolKit policy to allow controlling any color devices

systemctl enable --now xrdp
⚠️
Make sure you add the proper host and/or network firewall rules to allow the traffic to flow from your computer to your Kali LXC.



If you're running on KDE Plasma...

I have a short guide on getting up and running with XRDP server on KDE Plasma. The installation process is a bit different than what we did above with XFCE.

XRDP Server on KDE Plasma | 0xBEN | Notes
Install and Configure XRDP # Install xRDP server sudo apt update && sudo apt install -y xrdp dbus-…



Test RDP Connectivity

Windows RDP client connecting to my Kali LXC's IP address
You can safely ignore this and proceed
Enter your username and password
Success!





Install NoMachine Server

I like to use the NoMachine server on my Linux (and Windows) guests, as it will run on a huge variety of operating systems. It works very well with clipboard support, drive mapping, dynamic screen resizing, and much more.

Download NoMachine Server for Linux
We'll be using the .deb file version for 64-bit Linux.
Right-click and choose 'Copy link address'
cd /tmp
wget https://download.nomachine.com/download/8.8/Linux/nomachine_8.8.1_1_amd64.deb
dpkg -i ./nomachine_8.8.1_1_amd64.deb
systemctl enable --now nxserver

Run these commands on your LXC to install NoMachine

NoMachine Server should now be listening on TCP port 4000



Fix NoMachine Server Slow Startup

⚠️
Upon rebooting, it takes several minutes for the NoMachine server to start, likely due to some missing dependency after removing NetworkManager. Fortunately, it's a simple fix.

In my troubleshooting, I noticed that NoMachine works better with the NetworkManager service over systemd-networkd. NoMachine waits for the network to come up in a ready state before starting, and with NetworkManager, this happens much more promptly due to a cron job I had previously used.

To disable this wait for the network when using systemd-networkd, and cause NoMachine server to start up much more quickly, issue this command in the Kali container:

systemctl disable systemd-networkd-wait-online

Then, reboot the container.





Install the NoMachine Enterprise Client

I'll be using the NoMachine Enterprise Client for Windows installer. Download the correct package for your operating system and complete the installation.

Enterprise Client in the Start Menu
Click the 'Add' button
Click the 'Add' button again
⚠️
Make sure you add the proper host and/or network firewall rules to allow the traffic to flow from your computer to your Kali LXC.
Double-click the icon
Click 'OK'
Authenticate using your LXC username and password
Click 'Yes'
ℹ️
This is the part I was mentioning at the beginning of the article. Being a Linux Container, there is no display driver to make a virtual display available. So, NoMachine will use its own display driver.





Issue Workarounds

OpenVPN Workaround

As mentioned in an earlier paragraph, your unprivileged container won't be able to create the necessary /dev/net/tun or /dev/net/tap files when initializing OpenVPN tunnels. This is because the container does not have it's own kernel or drivers and needs to create those devices on the host machine and map to them internally.

The workaround in this case is to modify the container's configuration files to add the necessary permissions to create these files on the host. Open a shell on your Proxmox node and follow along.

# Stop the container
pct stop [id-number]

# Edit the configuration file
nano /etc/pve/lxc/[id-number].conf

Swap out '[id-number]' with your container's ID from Proxmox

lxc.cgroup.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net dev/net none bind,create=dir

Append these lines

# Start the container again
pct start [id-number]

Or, start the container in the GUI

Now, open a shell on your Kali LXC and connect to your VPN as you normally would.





Wrapping Up

⚠️
Again, a reminder that the desktop sessions are running in a temporary session. Please save your work often, as you run the risk of data loss if your display server crashes, or your container crashes or reboots.

The key takeaway with this exercise is that the experience of running Kali in a Linux Container is blazing fast. It boots quickly, applications start and run quickly, the UI is snappy. It's difficult to go back to a VM when things are this smooth, especially considering it's running on a fraction of the resources.

However, if you experience issues such as data loss, or things just generally aren't working as well as you think they could be, it may be time to go back to a VM. At the very least, take a snapshot, power off the container for a bit, and ponder on it.

More from 0xBEN
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.