On my previous server, I had an IRC client (weechat) running in a screen
session. I recently migrated this setup to a ZNC
bouncer running on my server + weechat running on my
laptop, mainly to avoid network lags through SSH and to have a better desktop
integration (notifications, etc.).
My server hosts my e-mails, important and confidential documents (among other things) and I always thought that running an always connected IRC client on the same machine was a bad idea.
So in the same time I got rid of my weechat+screen to migrate to ZNC, I had a
look at systemd-nspawn
, also known as systemd containers. It's actually
pretty much like LXC containers, but managed with the systemd logic in mind.
Here is a quick tutorial of how I containerized ZNC into a systemd container on a Debian stretch system:
First, install systemd-container and debootstrap packages:
# apt install systemd-container debootstrap
Create directories used by
systemd-container
(which aren't create on install):# mkdir /var/lib/machines/ /etc/systemd/nspawn/
/var/lib/machines/ will host the containers' hierarchy and containers unit files will be stored into /etc/systemd/nspawn/.
Install a Debian system + znc package using
debootstrap
into /var/lib/machines/znc/:# cd /var/lib/machines/ # debootstrap --include znc stretch znc
To make the container start on boot, you have to enable the corresponding systemd-nspawn instance and the machines target (which will start all enabled instances of systemd-nspawn unit:
# systemctl enable systemd-nspawn@znc machines.target
At this stage, your container is ready. You can start your container (run its init process) with:
# systemd-nspawn -D /var/lib/machines/znc/
Or execute a command in the container:
# systemd-nspawn -D /var/lib/machines/znc/ hostname
systemd-nspawn comes with the
machinectl
command which allows you to easily manage your containers:# machinectl [list|list-images|start|stop|status|…]
See its man page for all supported sub-commands and options.
Now, let's configure some few extra stuff to run ZNC. Create a dedicated user in the container:
# systemd-nspawn -D /var/lib/machines/znc/ useradd -u 1002 -g 1002 -m znc
And customize the container's options by putting a config file into /etc/systemd/nspawn/:
[Exec] # Don't start the init process inside the container, instead execute # `znc` Boot=off Parameters=/usr/bin/znc --foreground # Drop all default capabilities: the container will run with no # capabilities, ZNC doesn't need any DropCapability=CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_FSETID CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETGID CAP_SETFCAP CAP_SETPCAP CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_TTY_CONFIG CAP_SYS_RESOURCE CAP_SYS_BOOT CAP_AUDIT_WRITE CAP_AUDIT_CONTROL # Start `znc` as znc User=znc # Those 2 options aren't supported by the version of systemd shiped # with Debian stretch. Ephemeral=on makes the container discard on # shutdown any modification made during its runtime (Docker style) and # NoNewPrivileges ensures that the code executed inside the container # won't be able to gain greater privileges (with setuid bit for instance) #Ephemeral=on #NoNewPrivileges=on # Use private user namespace (equivalent to LXC's unprivilegied mode) PrivateUsers=on [Files] # Mount my .znc configuration directory onto the container (with write # access) and the znc.pem containing the private key, certificates # chain and DH param (read-only) Bind=/home/romain/.znc/:/home/znc/.znc/ BindReadOnly=/var/lib/acme/live/irc.univers-libre.net/combined:/home/znc/.znc/znc.pem [Network] # Use the same network stack as the host VirtualEthernet=no
This file will automatically be read by
systemd-nspawn
before starting the container. All these options can be specified as commandline parameters tosystemd-nspawn
as well.
Resources: