As my first noteworthy venture in containerization I decided to jump on the hype train and run a Pi-hole instance on my NAS to block ads and the-like in my local network.
The NAS runs Arch Linux and I opted for LXC as it seemed to be the leaner approach compared to Docker. Here's how I did it.
Install LXC
On Arch all you need to do for being able to run (privileged) LXC containers is installing it:
$ pacman -S lxc
I want containers to look like proper network clients instead of having them
NAT'ed and routed by their host (the NAS) so I changed the default config to
use macvlan
in bridge mode for container networking:
# /etc/lxc/default.conf
lxc.net.0.type = macvlan
lxc.net.0.macvlan.mode = bridge
lxc.net.0.link = eth0
lxc.net.0.flags = up
lxc.net.0.name = eth0
Note: the last line sets the name of the virtual interface that appears
inside the container to eth0
. This is not required, but many images seem to
have issues dealing with generated interface names.
Create the Container
I chose to go with the current Debian release for my Pi-hole container, which is Buster.
$ lxc-create -t download -n pi-hole -- -d debian -r buster -a amd64
This sets up a (refreshingly minimal) Debian image.
The only thing that I changed inside the container is switching to static addressing for IPv4 as I did not want the container to query my router for DHCP:
# /etc/network/interfaces
auto eth0
eth0 inet static
address 10.0.0.3
netmask 255.255.255.0
gateway 10.0.0.1
(Urr, feels so ancient when you're used to systemd-networkd...)
Install Pi-hole
There are some requirements to install first:
$ apt-get install wget curl
Then the official Pi-hole install script can be used.
I really hate the attitude behind curl
'ing install scripts and directly
piping them to Bash as root user which seems en vogue these days. In my head
this rings all alarm bells in terms of security. But I guess that's what comes
with the nature of containers: they're isolated and volatile, so they're a
disposable object that is cared less about.
I still refuse to do so and instead download them, give them at least a quick scroll and fire them up afterwards. Thus with the Pi-hole installer:
$ curl -sSL https://install.pi-hole.net -o pi-hole.sh
$ less $_
$ bash $_
The installer then took care of the rest.
Final Touches
Don't forget to make the container autorun at boot using
$ systemctl enable lxc@pi-hole
A highly considerable improvement to my setup will be switching to unprivileged containers for increased degree of isolation.