User:Ams

From ArchWiki
Jump to: navigation, search

LXC

I'm coming from Ubuntu, and I want to be able to use LXC in the same sort of way.

LXC issues with Arch

Can't create Ubuntu guests due to a bug with the Ubuntu template. I reported it on github

Here's the workaround:

$ sudo env PATH=/usr/sbin:/sbin:/bin:$PATH lxc-create -n precise -t ubuntu -- -r precise

LXC with DHCP

This config uses the DHCP server built into dnsmasq to give addresses to LXC containers. It doesn't use the primary dnsmasq config so I can use that for other purposes. It might be possible to use a full bridge and have the container get an address from my real LAN, but this config uses NAT. This is a little more travel-friendly, but the main reason is that it means my containers can share my VPN connection.

Set up files:

/etc/netctl/lxcbr0
escription="Bridge connection"
Interface=lxcbr0
Connection=bridge
BindsToInterfaces=()
IP=static
Address=('10.0.3.1/24')
/etc/lxc/default.conf
lxc.network.type = veth
lxc.network.ipv4 = 0.0.0.0
lxc.network.link = lxcbr0
/etc/dnsmasq-lxcbr0.conf
interface=lxcbr0
except-interface=lo
bind-interfaces

domain=lxc
dhcp-range=10.0.3.2,10.0.3.100,12h

host-record=lxchost.lxc,10.0.3.1
local=/lxc/

Install dnsmasq and iptables, and set up the networking.

$ netctl start lxcbr0
$ dnsmasq -C /etc/dnsmasq-lxcbr0.conf
$ iptables -t nat -A POSTROUTING -j MASQUERADE

The iptables command allows NAT from anywhere to anywhere, so something more restrictive might be appropriate?

Now create, and start the new container (install lxc and debootstrap):

$ PATH=/usr/sbin:/sbin:/bin:$PATH lxc-create -n lxc1 -t ubuntu -- -r precise
$ lxc-start -n lxc1

Find the address of a container (install dnsutils):

$ host lxc1 10.0.3.1

You can connect to the running container like this:

$ ssh $(host lxc1 | awk '/has address 10\.0\.3\./ {print $NF}')

See dnsmasq setup below for an easier way.

From inside the container, you can connect to the host using the name lxchost.

Everything should now work, but you'll have to rerun the netctl, dnsmasq, and iptables commands after every reboot.

Make Network Setup Persistent

First the NAT bridge:

$ netctl enable lxcbr0

Next, for the DHCP server, create a file:

/etc/systemd/system/dnsmasq-lxcbr0.service
[Unit]
Description=DHCP server for LXC containers.
Requires=netctl@lxcbr0.service
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/dnsmasq -C /etc/dnsmasq-lxcbr0.conf --pid-file=/var/run/dnsmasq-lxcbr0.pid -u dnsmasq
PIDFile=/var/run/dnsmasq-lxcbr0.pid
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

And enable it:

$ systemctl enable dnsmasq-lxcbr0

Finally, for the NAT routing rule:

$ iptables-save > /etc/iptables/iptables.rules
$ systemctl enable iptables

DNSmasq

dnsmasq is a DNS proxy that can be used to choose which DNS queries to send where. In it's most basic setup is does nothing resolvconf can't do on its own.

Basic Setup

Install dnsmasq and resolvconf.

Set up files:

/etc/resolvconf.conf
resolv_conf=/etc/resolv.conf

name_servers=127.0.0.1

dnsmasq_conf=/etc/dnsmasq.d/resolvconv
dnsmasq_resolv=/var/run/dnsmasq/resolv.conf
dnsmasq_restart="systemctl restart dnsmasq"
dnsmasq_reload="systemctl reload dnsmasq"

# (optional) to prevent the VPN trying to resolve unqualified names
domain_blacklist=*.vpn.example.com
/etc/dnsmasq.conf
resolv-file=/var/run/dnsmasq/resolv.conf
interface=lo
bind-interfaces
conf-dir=/etc/dnsmasq.d
/etc/systemd/system/resolvconf-permissions.service
[Unit]
Description=Ensure that /var/run/dnsmasq/resolv.conf is readable.
Before=netctl.service

[Service]
Type=oneshot
ExecStart=/usr/bin/mkdir -p /var/run/dnsmasq
ExecStart=/usr/bin/touch /var/run/dnsmasq/resolv.conf
ExecStart=/usr/bin/chmod +r /var/run/dnsmasq/resolv.conf

[Install]
WantedBy=multi-user.target

Create the directories /var/run/dnsmasq and /etc/dnsmasq.d

Make sure the new resolvconf file would be readable to the "dnsmasq" user:

$ systemctl start resolvconf-permissions

Reload resolvconf, which should start dnsmasq automatically:

$ resolvconf -u

You should now be able to do DNS lookups exactly the same as before.

Finally, set dnsmasq to start at boot:

$ systemctl enable resolvconf-permissions
$ systemctl enable dnsmasq

Setup with Openconnect VPN

The goal is to use dnsmasq and resolvconf to do most DNS lookups via the local DNS server, and only the use the VPN DNS servers where absolutely necessary. This equally for efficiency, geo-correctness, and privacy. This will also sit nicely with the LXC dnsmasq setup.

Install openconnect.

In /etc/vpnc/vpnc-script find the resolvconf -a $TUNDEV line, and add the -p option to the end (private mode), thusly:

/etc/vpnc/vpnc-script (extract)
echo "$NEW_RESOLVCONF" | /usr/sbin/resolvconf -a $TUNDEV -p

And set everything running by connecting to the VPN:

$ openconnect ...............

That should cause resolvconf to reread its config file, and that, in turn, should restart the dnsmasq service.

Check the end of the log:

$ journalctl -xn

The dnsmasq service should be started, and should list its lookup settings like this:

reading /var/run/dnsmasq/resolv.conf
using nameserver XXX.XXX.XXX.XXX#53
using nameserver YYY.YYY.YYY.YYY#53
using nameserver MMM.MMM.MMM.MMM#53 for domain vpn.example.com
using nameserver NNN.NNN.NNN.NNN#53 for domain vpn.example.com

If that's not sufficient (either there are domains outside the one given by the VPN DHCP that should also use the VPN, or domains inside that should not), then set up another dnsmasq config file:

/etc/dnsmasq.d/my_vpn_extras
server=/example.com/MMM.MMM.MMM.MMM
server=/example.com/NNN.NNN.NNN.NNN
server=/exception.example.com/#

And reload the config:

$ systemctl restart dnsmasq

Allow lookup of LXC Containers

In this scenario there are two dnsmasq instances running. One on interface lxcbr0 configured to provide both DHCP and DNS, and one on interface lo configured for DNS only. The config files above have the interface settings deliberately configured so they can coexist. They trick here is to pass DNS lookups from the .lxc domain from one to the other.

Create a new file:

/etc/dnsmasq.d/lxc
server=/lxc/10.0.3.1

and restart dnsmasq:

$ systemctl restart dnsmasq

It should now be possible to do the lookup like this:

$ host lxc1.lxc

And connecting is as simple as this:

$ ssh lxc1.lxc

Hardware Specific Tweaks

My Dell M4600 laptop does not reset when I use reboot. The solution is to tweak the kernel parameters:

Inser this into /etc/default/grub
GRUB_CMDLINE_LINUX="reboot=pci"


BTRFS For Root

mkiniticpio gives an error (non-fatal):

ERROR: file not found: `fsck.btrfs'

Solution: remove the "fsck" hook from /etc/mkinitcpio.conf: it's not needed for btrfs.