Support #683
Updated by Daniel Curtis about 9 years ago
{{>toc}}
This is a simple guide for setting up and using Linux Containers on Arch Linux.
h2. Prepare the Environment
* Make sure the system is up to date:
<pre>
pacman -Syu
</pre>
* Install the base-devel and wget packages:
<pre>
pacman -S base-devel wget rsync
</pre>
* Download the packages for yaourt:
<pre>
cd /tmp
wget https://aur.archlinux.org/cgit/aur.git/snapshot/package-query.tar.gz && wget https://aur.archlinux.org/cgit/aur.git/snapshot/yaourt.tar.gz
tar xzf package-query.tar.gz
tar xzf yaourt.tar.gz
</pre>
#* Install package-query:
<pre>
cd package-query
makepkg -csi
</pre>
#* Install yaourt
<pre>
cd ../yaourt
makepkg -csi
</pre>
h2. Set Up The Network
* Install netctl:
<pre>
pacman -S netctl
</pre>
h3. Bridged Wired Connection
* Bridge Internet-shared - This example will bridge network interface eth0 and configure a static IP for the bridge:
<pre>
nano /etc/netctl/lxcbridge
</pre>
#* And add/modify the following:
<pre>
Description="LXC Bridge"
Interface=br0
Connection=bridge
BindsToInterfaces=(eth0)
IP=dhcp
SkipForwardingDelay=yes
</pre>
* After changes are made, make sure to re-enable and restart the bridge:
<pre>
netctl enable lxcbridge
netctl start lxcbridge
</pre>
* Enable IP Forwarding persist at boot:
<pre>
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/40-ip-forward.conf
</pre>
* And also apply this iptables rule:
<pre>
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
</pre>
#* To make changes persist upon reboot:
<pre>
iptables-save > /etc/iptables/iptables.rules
systemctl enable iptables
systemctl start iptables
</pre>
h3. NAT Wireless Connection (Optional)
* Make sure that forwarding is turned on to support NAT:
<pre>
echo 1 > /proc/sys/net/ipv4/ip_forward
</pre>
* Make the previous change persistent after a reboot:
<pre>
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/30-ipforward.conf
echo 'net.ipv6.conf.default.forwarding=1' >> /etc/sysctl.d/30-ipforward.conf
echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.d/30-ipforward.conf
</pre>
* NAT Internet-shared - This example will bridge network interface eth0 and configure a static IP for the bridge:
<pre>
nano /etc/netctl/lxcnatbridge
</pre>
#* And add/modify the following:
<pre>
Description="LXC NAT Bridge"
Interface=natbr0
Connection=bridge
IP=static
Address=192.168.10.200/24
DNS=192.168.1.1
SkipForwardingDelay=yes
ExecUpPost="/usr/local/bin/natbr0-up"
</pre>
* Create the nat script:
<pre>
nano /usr/local/bin/natbr0-up
</pre>
#* And add the following:
<pre>
#!/bin/sh
# Script to setup NAT iptables masquerade rules; and dnsmasq for DHCP and DNS.
# This is the address assigned to the bridge at boot
BRADDR=192.168.10.200
# DHCP IP address range for containers
BRRANGE=192.168.10.201,192.168.10.250
# Configure iptables rules for NAT
iptables -A FORWARD -i natbr0 -s ${BRADDR}/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE
# (Optional) Forward port 2222 to host behind NAT bridge
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to 192.168.10.200:22
# Start dnsmasq DNS/DHCP server for the network attached to the NAT interface.
dnsmasq --bind-interfaces --conf-file= --listen-address $BRADDR --except-interface lo --dhcp-range $BRRANGE --dhcp-lease-max=253 --dhcp-no-override
</pre>
* Make sure it is executable by doing
<pre>
chmod +x /usr/local/bin/natbr0-up
</pre>
* Start and enable the NAT bridge at boot:
<pre>
netctl enable lxcnatbridge
netctl start lxcnatbridge
</pre>
* Now a container lxc.conf should read:
<pre>
lxc.network.type=veth
lxc.network.link=natbr0
lxc.network.flags=up
</pre>
h2. Install LXC
* Install lxc, bridge-utils, and arch-install-scripts:
<pre>
pacman -S lxc bridge-utils arch-install-scripts dnsmasq
</pre>
#* (_Optional_) Install extra packages for lxc:
<pre>
pacman -S lua lua-filesystem lua-alt-getopt
</pre>
* Test that the system is correctly configured
<pre>
lxc-checkconfig
</pre>
#* The output should be similar to:
<pre>
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: missing
Network namespace: enabled
Multiple /dev/pts instances: enabled
--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled
</pre>
h3. Arch Container
* Create the container:
<pre>
lxc-create -n arch.example.com -t archlinux
</pre>
#* *NOTE*: If using btrfs, lxc can take advantage of the subvoluming btrfs provides. To use btrfs, create the container with the following command:
<pre>
lxc-create -n arch.example.com -t archlinux -B btrfs
</pre>
* Edit the Arch Linux container config file:
<pre>
nano /var/lib/lxc/arch.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
#lxc.network.hwaddr =
lxc.network.ipv4 = 192.168.1.10
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.kmsg = 0
lxc.rootfs = /var/lib/lxc/arch.example.com/rootfs
lxc.utsname = arch.example.com
lxc.arch = armv7l
</pre>
* Start the Arch container:
<pre>
lxc-start -n arch.example.com
</pre>
* Open a console:
<pre>
lxc-attach -n arch.example.com
</pre>
#* And change the password:
<pre>
passwd
</pre>
* Create a wired connection:
<pre>
cp /etc/netctl/examples/ethernet-static /etc/netctl/wired
</pre>
* Edit the /etc/netctl/wired to match your needs.
<pre>
nano /etc/netctl/wired
</pre>
#* Add/modify the following:
<pre>
Description='Ethernet Connection'
Interface=eth0
Connection=ethernet
IP=static
Address=('192.168.1.20/24')
Gateway=('192.168.1.1')
DNS=('192.168.1.1')
# Required to start a network connection in a container
ForceConnection=yes
</pre>
* Start and enable the wired connection at boot:
<pre>
netctl enable wired
</pre>
* *NOTE*: I needed to edit /etc/systemd/system/netctl\@wired.service and comment out the following in order for the netctl command to start:
<pre>
#BindsTo=sys-subsystem-net-devices-eth0.device
#After=sys-subsystem-net-devices-eth0.device
</pre>
#* Then reload the systemd units:
<pre>
systemctl daemon-reload
</pre>
* While the console to the container is open, install openssh
<pre>
pacman -S openssh
</pre>
#* Start and enable openssh at boot:
<pre>
systemctl enable sshd.service
systemctl start sshd.service
</pre>
h3. Debian Container
* Install debootstrap from AUR:
<pre>
yaourt debootstrap
</pre>
#* Install gnupg1 for keyring verification; make sure to +edit the PKGBUILD+ and add *armv7h* to the arch parameter:
<pre>
gpg --keyserver pgpkeys.mit.edu --recv-keys 2071B08A33BD3F06
yaourt gnupg1
</pre>
#* Install debian-archive-keyring:
<pre>
yaourt debian-archive-keyring
</pre>
* Create the container:
<pre>
lxc-create -n debian.example.com -t debian -- --release jessie --packages=apt-utils,wget,debian-keyring
</pre>
#* *NOTE*: If using btrfs, lxc can take advantage of the subvoluming btrfs provides. To use btrfs, create the container with the following command:
<pre>
lxc-create -n debian.example.com -t debian -B btrfs -- --release jessie --packages=apt-utils,wget,debian-keyring
</pre>
* Edit the Debian container config file:
<pre>
nano /var/lib/lxc/debian.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.53
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.rootfs = /var/lib/lxc/debian.example.com/rootfs
lxc.utsname = debian.example.com
lxc.arch = armvhf
</pre>
* Start the containter:
<pre>
lxc-start -n debian.example.com
</pre>
#* (Optional) Attach to the container to execute commands:
<pre>
lxc-attach -n debian.example.com
</pre>
* _(Optional)_ Add the Raspbian repository on top of stock Debian repos:
<pre>
echo 'deb http://archive.raspbian.org/raspbian jessie main contrib non-free rpi' >> /etc/apt/sources.list.d/raspbian.list
echo 'deb-src http://archive.raspbian.org/raspbian jessie main contrib non-free rpi' >> /etc/apt/sources.list.d/raspbian.list
</pre>
#* And add the Raspbian public signing key:
<pre>
wget https://archive.raspbian.org/raspbian.public.key -O - | sudo apt-key add -
</pre>
#* Update the apt repository cache and upgrade any necessary files:
<pre>
apt-get update && apt-get upgrade
</pre>
* _(Optional)_ Add the Wolfram Alpha repository:
<pre>
echo 'deb http://repository.wolfram.com/raspbian/ stable non-free' >> /etc/apt/sources.list.d/wolfram.list
</pre>
#* And add the Wolfram public signing key:
<pre>
apt-key adv —keyserver http://repository.wolfram.com/raspbian/raspbian@wolfram.com.gpg.pub-key —recv-keys 574FA74E5CBB4222
</pre>
#* Update the apt repository cache and upgrade any necessary files:
<pre>
apt-get update && apt-get upgrade
</pre>
#* Install wolfram:
<pre>
apt-get install wolfram-engine mathelxc-create -n kali.example.com -t kali-arm -- --release sana --mirror=http://archive.kali.org/kali --security=http://security.kali.org/kali-security --packages=apt-utils,wget,debian-keyring,e2fsprogs,kali-defaults,kali-menu,parted,sudo,usbutilsmatica-fonts
</pre>
h3. Ubuntu Container
* Install debootstrap from AUR:
<pre>
yaourt debootstrap
</pre>
#* Install ubuntu-keyring:
<pre>
yaourt ubuntu-keyring
</pre>
* Create the container:
<pre>
lxc-create -n ubuntu.example.com -t ubuntu -- -r trusty
</pre>
#* *NOTE*: If using btrfs, lxc can take advantage of the subvoluming btrfs provides. To use btrfs, create the container with the following command:
<pre>
lxc-create -n ubuntu.example.com -t ubuntu -B btrfs -- --r trusty
</pre>
* Edit the Ubuntu container config file:
<pre>
nano /var/lib/lxc/ubuntu.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.54
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.rootfs = /var/lib/lxc/ubuntu.example.com/rootfs
lxc.utsname = ubuntu.example.com
lxc.arch = armvhf
</pre>
* Start the containter:
<pre>
lxc-start -n ubuntu.example.com
</pre>
h3. Fedora Container
* Create the container:
<pre>
lxc-create -n fedora.example.com -t fedora -- -R 23
</pre>
* Edit the Fedora container config file:
<pre>
nano /var/lib/lxc/fedora.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.55
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.rootfs = /var/lib/lxc/fedora.example.com/rootfs
lxc.utsname = fedora.example.com
lxc.arch = armvhf
</pre>
* Start the containter:
<pre>
lxc-start -n fedora.example.com
</pre>
h3. Kali Container
* Install debootstrap from AUR:
<pre>
yaourt debootstrap
</pre>
#* Install gnupg1 for keyring verification; make sure to +edit the PKGBUILD+ and add *armv7h* to the arch parameter:
<pre>
gpg --keyserver pgpkeys.mit.edu --recv-keys 2071B08A33BD3F06
yaourt gnupg1
</pre>
#* Install debian-archive-keyring:
<pre>
yaourt debian-archive-keyring
</pre>
* Create a sana debootstrap script from the debian jessie script:
<pre>
cp /usr/share/debootstrap/scripts/jessie /usr/share/debootstrap/scripts/sana
</pre>
* Create a kali-arm lxc template script from the debian jessie template:
<pre>
cp /usr/share/lxc/templates/lxc-debian /usr/share/lxc/templates/lxc-kali-arm
</pre>
* Edit the kali-arm lxc template:
<pre>
nano /usr/share/lxc/templates/lxc-kali-arm
</pre>
#* And modify the following:
<pre>
valid_releases=('squeeze' 'wheezy' 'jessie' 'stretch' 'sid' 'sana')
#...
packages=\
ifupdown,\
locales,\
libui-dialog-perl,\
dialog,\
isc-dhcp-client,\
netbase,\
net-tools,\
iproute,\
kali-archive-keyring,\
kali-defaults,\
kali-menu,\
openssh-server
#...
debootstrap --verbose --variant=minbase --arch=$arch --keyring=/usr/share/keyrings/kali-archive-keyring.gpg
</pre>
* Create the container:
<pre>
lxc-create -n kali.example.com -t kali-arm -- --release sana --mirror=http://archive.kali.org/kali --security=http://security.kali.org/kali-security --packages=apt-utils,wget,e2fsprogs,parted,sudo,usbutils
</pre>
#* *NOTE*: If using btrfs, lxc can take advantage of the subvoluming btrfs provides. To use btrfs, create the container with the following command:
<pre>
lxc-create -n kali.example.com -t kali-arm -B btrfs -- --release sana --mirror=http://archive.kali.org/kali --security=http://security.kali.org/kali-security --packages=apt-utils,wget,e2fsprogs,parted,sudo,usbutils
</pre>
* Edit the Kali container config file:
<pre>
nano /var/lib/lxc/kali.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.56
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.rootfs = /var/lib/lxc/kali.example.com/rootfs
lxc.utsname = kali.example.com
lxc.arch = armvhf
</pre>
* Copy over the resolv config from the host:
<pre>
cp /etc/resolv.conf /var/lib/lxc/kali.example.com/rootfs/etc/
</pre>
* Start the containter:
<pre>
lxc-start -n kali.example.com
</pre>
* Enable ssh at boot up:
<pre>
arch-chroot /var/lib/lxc/kali.example.com/rootfs /bin/bash
/bin/systemctl enable ssh
exit
</pre>
#* _(Optional)_ Add bob the administrative user:
<pre>
arch-chroot /var/lib/lxc/kali.example.com/rootfs /bin/bash
/usr/sbin/adduser bob
/usr/sbin/usermod -aG sudo bob
exit
</pre>
#* Restart the container for the service to take effect:
<pre>
lxc-stop -n kali.example.com
lxc-start -n kali.example.com
</pre>
* Now connect to the kali contain via ssh:
<pre>
ssh kali.example.com
</pre>
#* _(Optional)_ Install the desktop packages:
<pre>
apt-get install fonts-croscore fonts-crosextra-caladea fonts-crosextra-carlito gnome-theme-kali gtk3-engines-xfce kali-desktop-xfce kali-root-login lightdm network-manager network-manager-gnome xfce4 xserver-xorg-video-fbdev
</pre>
#* _(Optional)_ Install a few commomly used tools:
<pre>
apt-get install aircrack-ng ethtool hydra john libnfc-bin mfoc nmap passing-the-hash sqlmap usbutils winexe wireshark
</pre>
#* _(Optional)_ Install a Kali Top10 meta-package:
<pre>
apt-get install kali-linux-top10
</pre>
#* *NOTE*: If installing the kali-linux-all, kali-linux-wireless, or kali-linux-sdr meta packages, make sure to create a modified uhd-usrp2 sysctl file before installing the packages. If this is not done, the installation process +will fail while installing+ the uhd-host package:
<pre>
echo '# USRP2 gigabit ethernet transport tuning' >> /etc/sysctl.d/uhd-usrp2.conf
echo '#net.core.rmem_max=50000000' >> /etc/sysctl.d/uhd-usrp2.conf
echo '#net.core.wmem_max=1048576' >> /etc/sysctl.d/uhd-usrp2.conf
apt-get install kali-linux-sdr
</pre>
h2. Autostart Containers
* Enable the lxc service at boot:
<pre>
systemctl enable lxc.service
</pre>
* Then add the autostart line to the containers config file:
<pre>
echo 'lxc.start.auto = 1' >> /var/lib/lxc/arch.example.com/config
</pre>
* Start the lxc service:
<pre>
systemctl start lxc.service
</pre>
h2. Device Passthru
One of my use cases involves passing a serial device to a specific container. LXC makes this task simple with the @lxc-device@ command.
* Pass @/dev/ttyACM0@ to the arch.example.com containers @/dev/ttyACM0@:
<pre>
lxc-device -n arch.example.com /dev/ttyACM0 /dev/ttyACM0
</pre>
h2. Graphical Management
* Install virt-manager:
<pre>
pacman -S virt-manager
</pre>
# Open virt-manager, then *Create a New Connection*.
# Set the _connection type_ to *LXC*, and set the _container type_ to *Operating system container*.
# Set the _OS root directory_ to *@/var/lib/lxc/arch.example.com/rootfs@*.
# Set a desired CPU and RAM amount.
# Set a name for the container.
After the container is configured it will automatically start.
h2. Resources
* https://s3hh.wordpress.com/2011/05/17/lxc-containers-on-a-host-with-wireless/
* https://wiki.archlinux.org/index.php?title=Linux_Containers&redirect=no
* https://www.raspbian.org/RaspbianFAQ#Can_I_mix_packages_from_the_Debian_repositories_with_Raspbian.3F
* https://www.raspbian.org/RaspbianRepository
* https://www.raspberrypi.org/forums/viewtopic.php?f=94&t=61509
* https://github.com/andrius/build-raspbian-image/issues/1
* http://docs.kali.org/kali-on-arm/install-kali-linux-arm-raspberry-pi
* http://docs.kali.org/development/kali-linux-arm-chroot
* http://docs.kali.org/general-use/kali-linux-sources-list-repositories
* https://forums.kali.org/showthread.php?18079-Public-key-error
* https://github.com/offensive-security/kali-arm-build-scripts/blob/master/rpi2.sh
* http://www.kali.org/new/kali-linux-metapackages/