Linux containers

Linux containers (LXC) is the Linux implementation of FreeBSD Jails.

Within a Linux container we can run a self-contained installation of Linux which will utilise the system's kernel.

This is more lightweight method of virtualisation than than offered by Xen, for example.

Install

apt-get install lxc lxc-templates bridge-utils cgroupfs-mount conntrack iptables debootstrap
/etc/init.d/cgroupfs-mount start

Setup

Disable lxc services, we will do this stuff manually.

init.d
/etc/init.d/lxc-net stop
update-rc.d lxc-net disable
/etc/init.d/lxc stop
update-rc.d lxc disable
killall dnsmasq
systemd
systemctl disable lxc-net.service
systemctl disable lxc.service
defaults
sed -i 's/LXC_AUTO="true"/LXC_AUTO="false"/g' /etc/default/lxc
sed -i 's/USE_LXC_BRIDGE="true"/USE_LXC_BRIDGE="false"/g' /etc/default/lxc-net

Networking

Bridge

Virtual interfaces are bridged on to the primary network interface.

auto eth0
iface eth0 inet manual

auto lxcbr0
iface lxcbr0 inet static
 bridge_ports eth0
 address 10.10.44.10
 netmask 255.255.255.0
 gateway 10.10.44.1
Subnet

Virtual interfaces are contained on the their own private subnet.

auto lxcbr0
iface lxcbr0 inet static
 pre-up brctl addbr lxcbr0
 address 10.10.10.1
 netmask 255.255.255.0
 post-down brctl delbr lxcbr0
iptables

Example NAT tables for containers on private subnet.

#! /bin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin

iptables -t filter -F
iptables -t filter -X
iptables -t raw -F
iptables -t nat -F
conntrack -F

# raw:PREROUTING
iptables -t raw -A PREROUTING -i lo -j NOTRACK

# raw:OUTPUT
iptables -t raw -A OUTPUT -o lo -j NOTRACK

# filter:INPUT
iptables -t filter -P INPUT ACCEPT

# filter:FORWARD
iptables -t filter -P FORWARD ACCEPT

# filter:OUTPUT
iptables -t filter -P OUTPUT ACCEPT

# nat:POSTROUTING
iptables -t nat -A POSTROUTING -o eth0 -s 10.10.10.0/24 -d 0/0 -j MASQUERADE

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.proxy_arp=1

sysctl -w net.netfilter.nf_conntrack_max=524288
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=7440

echo 65536 > /sys/module/nf_conntrack/parameters/hashsize
echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range

exit 0

Initialise

Wheezy on IBM PC platform
lxc-create -n HOSTNAME -t debian -- -r wheezy -a amd64
Stretch on Raspberry Pi
lxc-create -n cracker -t debian -- -r stretch -a armhf
Buster/Bullseye on Raspberry Pi

Install keys

mkdir -p /var/cache/lxc/debian
wget "https://ftp-master.debian.org/keys/release-10.asc"
gpg --no-default-keyring --keyring /var/cache/lxc/debian/archive-key.gpg --import release-10.asc
wget "https://ftp-master.debian.org/keys/release-11.asc"
gpg --no-default-keyring --keyring /var/cache/lxc/debian/archive-key.gpg --import release-11.asc

Install buster

lxc-create -n cracker -t debian -- -r buster -a armhf

Install bullseye

lxc-create -n terminator -t debian -- -r bullseye -a armhf

Configure

/var/lib/lxc/HOSTNAME/config
# Template used to create this container: /usr/share/lxc/templates/lxc-debian
# Parameters passed to the template: -r stretch
# Template script checksum (SHA-1): 5a35ad98c578f5487dc5712a1c7d38af399be813
# For additional config options, please look at lxc.container.conf(5)

# Uncomment the following line to support nesting containers:
#lxc.include = /usr/share/lxc/config/nesting.conf
# (Be aware this has security implications)

#lxc.net.0.type = veth
#lxc.net.0.hwaddr = 00:XX:XX:XX:XX:XX
#lxc.net.0.link = lxcbr0
#lxc.net.0.flags = up
lxc.apparmor.profile = generated
lxc.apparmor.allow_nesting = 1
lxc.rootfs.path = dir:/var/lib/lxc/cheese/rootfs

# Common configuration
lxc.include = /usr/share/lxc/config/debian.common.conf

# Container specific configuration
lxc.tty.max = 4
lxc.uts.name = cheese
lxc.arch = armhf
lxc.pty.max = 1024

# Local network configuration

lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = lxcbr0
lxc.net.0.name = lxcnet0
lxc.net.0.hwaddr = XX:XX:XX:XX:XX:XX
lxc.net.0.veth.pair = veth0
lxc.net.0.ipv4.address = ?/24
lxc.net.0.ipv4.gateway = ?
#lxc.net.0.ipv6.address = ?
#lxc.net.0.ipv6.gateway = ?

# You may need the following for initial boot
#
# You can replace systemd by changing the lxc.init.cmd before rebooting
#
lxc.cgroup.devices.allow =
lxc.cgroup.devices.deny =
lxc.init.cmd = /lib/systemd/systemd systemd.unified_cgroup_hierarchy=1
#lxc.init.cmd = /sbin/init

Run

Run in background (now the default)

lxc-start -d -n HOSTNAME

Run in foreground (was the default)

lxc-start -F -n HOSTNAME

Attach

Attach to container and change root password.

lxc-attach -n HOSTNAME
passwd root

Stop

lxc-stop -n HOSTNAME

Unprivileged containers

Root can run containers with lower privileges. First we set aside some user ids to map to the container then configure it.

This has been tested to work Ubuntu vivid and nothing else since.

When assigning a range of ids to the root user. Choose what is available, here i chose 200000 because this was free.

usermod --add-subuids 200000-265535 root
usermod --add-subgids 200000-265535 root

The host configuration now needs to map the ids in its config.

lxc.id_map = u 0 200000 65536
lxc.id_map = g 0 200000 65536

The container root will be system uid 200000, and nobody in the container will be 265534, for example..

Before starting, the lcx directory needs the execute permission.

chmod +x /var/lib/lxc

Now we can start and stop the container, attach to it, etc.

Runit

Start container and login as root

lxc-start -F -n container

Install runit. It will ask you to enter a phrase and after installation reboot.

apt install runit-init
reboot

Login to tidy up.

lxc-attach -n container
cd /etc/service
rm getty-tty*
This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information