Project

General

Profile

Support #683

Updated by Daniel Curtis over 8 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. Shared Package Cache for Arch Containers 

 *NOTE*: I found this trick to be incredibly useful by allowing me to update the host's packages, then use the downloaded packages to cut down on download time for updating the Arch containers; since many of the packages are the same between updates. Why download more than once if you don't have to, right? 

 * Edit the arch linux container config file: 
 <pre> 
 nano /var/lib/lxc/arch.example.com/config 
 </pre> 
 #* And add the following to set the containers package cache to the host's package cache directory: 
 <pre> 
 lxc.mount.entry = /var/cache/pacman/pkg var/cache/pacman/pkg none bind 0 0 
 </pre> 
 #* *NOTE*: I needed to attach to the container and refresh the pacman database list: 
 <pre> 
 lxc-attach -n arch.example.com 
 pacman -Sy 
 exit 
 </pre> 

 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/

Back