<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Univers Libre - systemd</title>
    <subtitle>Yet another sysadmin&#39;s personal blog</subtitle>
    <link rel="self" type="application/atom+xml" href="https://univers-libre.net/tags/systemd/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://univers-libre.net"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2019-04-20T00:00:00+00:00</updated>
    <id>https://univers-libre.net/tags/systemd/atom.xml</id>
    <entry xml:lang="en">
        <title>Containerize ZNC with systemd-nspawn</title>
        <published>2019-04-20T00:00:00+00:00</published>
        <updated>2019-04-20T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/containerize-znc-with-systemd-nspawn/"/>
        <id>https://univers-libre.net/posts/containerize-znc-with-systemd-nspawn/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/containerize-znc-with-systemd-nspawn/">&lt;p&gt;On my previous server, I had an IRC client (weechat) running in a &lt;code&gt;screen&lt;/code&gt;
session. I recently migrated this setup to a &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.znc.in/ZNC&quot;&gt;ZNC
bouncer&lt;/a&gt; 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.).&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;So in the same time I got rid of my weechat+screen to migrate to ZNC, I had a
look at &lt;code&gt;systemd-nspawn&lt;/code&gt;, also known as systemd containers. It’s actually
pretty much like LXC containers, but managed with the systemd logic in mind.&lt;/p&gt;
&lt;p&gt;Here is a quick tutorial of how I containerized ZNC into a systemd container on
a Debian stretch system:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First, install &lt;em&gt;systemd-container&lt;/em&gt; and &lt;em&gt;debootstrap&lt;/em&gt; packages:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# apt install systemd-container debootstrap&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create directories used by &lt;code&gt;systemd-container&lt;/code&gt; (which aren’t create on
install):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mkdir /var/lib/machines/ /etc/systemd/nspawn/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;/var/lib/machines/&lt;/em&gt; will host the containers’ hierarchy and containers
unit files will be stored into &lt;em&gt;/etc/systemd/nspawn/&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install a Debian system + &lt;em&gt;znc&lt;/em&gt; package using &lt;code&gt;debootstrap&lt;/code&gt; into
&lt;em&gt;/var/lib/machines/znc/&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cd /var/lib/machines/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# debootstrap --include znc stretch znc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To make the container start on boot, you have to enable the corresponding
&lt;em&gt;systemd-nspawn&lt;/em&gt; instance and the &lt;em&gt;machines&lt;/em&gt; target (which will start all
enabled instances of &lt;em&gt;systemd-nspawn&lt;/em&gt; unit:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemctl enable systemd-nspawn@znc machines.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this stage, your container is ready. You can start your container (run
its init process) with:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemd-nspawn -D /var/lib/machines/znc/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or execute a command in the container:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemd-nspawn -D /var/lib/machines/znc/ hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;systemd-nspawn comes with the &lt;code&gt;machinectl&lt;/code&gt; command which allows you to
easily manage your containers:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# machinectl [list|list-images|start|stop|status|…]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See its man page for all supported sub-commands and options.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now, let’s configure some few extra stuff to run ZNC. Create a dedicated
user in the container:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemd-nspawn -D /var/lib/machines/znc/ useradd -u 1002 -g 1002 -m znc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And customize the container’s options by putting a config file into
&lt;em&gt;/etc/systemd/nspawn/&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Exec]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Don&amp;#39;t start the init process inside the container, instead execute&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# `znc`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Boot=off&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Parameters=/usr/bin/znc --foreground&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Drop all default capabilities: the container will run with no&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# capabilities, ZNC doesn&amp;#39;t need any&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;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&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Start `znc` as znc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;User=znc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Those 2 options aren&amp;#39;t supported by the version of systemd shiped&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;with Debian stretch. Ephemeral=on makes the container discard on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shutdown any modification made during its runtime (Docker style) and&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NoNewPrivileges ensures that the code executed inside the container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;won&amp;#39;t be able to gain greater privileges (with setuid bit for instance)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#Ephemeral=on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#NoNewPrivileges=on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Use private user namespace (equivalent to LXC&amp;#39;s unprivilegied mode)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrivateUsers=on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Files] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Mount my .znc configuration directory onto the container (with write&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;access) and the znc.pem containing the private key, certificates chain&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;and DH param (read-only)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Bind=/home/romain/.znc/:/home/znc/.znc/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BindReadOnly=/var/lib/acme/live/irc.univers-libre.net/combined:/home/znc/.znc/znc.pem&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Network]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Use the same network stack as the host&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VirtualEthernet=no&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This file will automatically be read by &lt;code&gt;systemd-nspawn&lt;/code&gt; before starting
the container. All these options can be specified as commandline
parameters to &lt;code&gt;systemd-nspawn&lt;/code&gt; as well.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.archlinux.org/title/Systemd-nspawn&quot;&gt;https://wiki.archlinux.org/title/Systemd-nspawn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html&quot;&gt;https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html&quot;&gt;https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.freedesktop.org/software/systemd/man/machinectl.html&quot;&gt;https://www.freedesktop.org/software/systemd/man/machinectl.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
</feed>
