<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.1">Jekyll</generator><link href="https://elou.world/feed.xml" rel="self" type="application/atom+xml" /><link href="https://elou.world/" rel="alternate" type="text/html" /><updated>2026-06-05T20:52:49+00:00</updated><id>https://elou.world/feed.xml</id><title type="html">Elouworld</title><subtitle>Exagone313 - blog</subtitle><author><name>Elouan Martinet</name></author><entry><title type="html">Alpine Linux package trigger scripts failing on CRI-O</title><link href="https://elou.world/en/kubernetes/crio-alpine-error-127" rel="alternate" type="text/html" title="Alpine Linux package trigger scripts failing on CRI-O" /><published>2020-11-11T22:30:00+00:00</published><updated>2020-11-11T22:34:37+00:00</updated><id>https://elou.world/en/kubernetes/crio-alpine-error-127</id><content type="html" xml:base="https://elou.world/en/kubernetes/crio-alpine-error-127"><![CDATA[<p>I recently created a self-managed Kubernetes cluster using the <a href="https://cri-o.io/">CRI-O</a> container runtime.
I had an issue with Alpine Linux images where package installation trigger scripts were failing for unknown reason (<code class="language-plaintext highlighter-rouge">script exited with error 127</code>).
Since I couldn’t find a resource online to fix the issue, I wanted to make a blog post to help others that would struggle with it.</p>

<h1 id="symptom">Symptom</h1>

<p>When installing packages on Alpine Linux, trigger scripts are failing, although installation seems to succeed (exit code being <code class="language-plaintext highlighter-rouge">0</code>):</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="rouge-code"><pre><span class="gp">/ #</span><span class="w"> </span>apk add curl
<span class="go">fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
(1/4) Installing ca-certificates (20191127-r4)
(2/4) Installing nghttp2-libs (1.41.0-r0)
(3/4) Installing libcurl (7.69.1-r1)
(4/4) Installing curl (7.69.1-r1)
Executing busybox-1.31.1-r19.trigger
ERROR: busybox-1.31.1-r19.trigger: script exited with error 127
Executing ca-certificates-20191127-r4.trigger
ERROR: ca-certificates-20191127-r4.trigger: script exited with error 127
OK: 7 MiB in 18 packages
</span><span class="gp">/ #</span><span class="w"> </span><span class="nb">echo</span> <span class="nv">$?</span>
<span class="go">0
</span></pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="investigation">Investigation</h1>

<p>I made a custom Alpine Linux image with <code class="language-plaintext highlighter-rouge">strace</code> installed (built locally, using Docker). This tool prints all the system calls made by a process.</p>

<div class="language-dockerfile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="k">FROM</span><span class="s"> alpine</span>
<span class="k">RUN </span>apk add <span class="nt">--no-cache</span> strace
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Then, I’ve run the <code class="language-plaintext highlighter-rouge">apk</code> command again using strace (<code class="language-plaintext highlighter-rouge">-f</code> argument tracks child processes):</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>strace <span class="nt">-f</span> apk add curl 2&gt;&amp;1 | less
</pre></td></tr></tbody></table></code></pre></div></div>

<p>I looked for a trigger script execution in the output and compared with the same command ran locally. On CRI-O, it failed to run the <code class="language-plaintext highlighter-rouge">chroot</code> system call:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="go">[pid    17] chroot(".")                 = -1 EPERM (Operation not permitted)
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>It appears that CRI-O doesn’t allow <code class="language-plaintext highlighter-rouge">chroot</code> by default.</p>

<h1 id="cure">Cure</h1>

<p>To enable <code class="language-plaintext highlighter-rouge">chroot</code> by default on CRI-O, add <code class="language-plaintext highlighter-rouge">SYS_CHROOT</code> in the <code class="language-plaintext highlighter-rouge">default_capabilities</code> array in <code class="language-plaintext highlighter-rouge">/etc/crio/crio.conf</code>:</p>

<div class="language-conf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="n">default_capabilities</span> = [
	<span class="c"># ...
</span>	<span class="s2">"SYS_CHROOT"</span>,
]
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Then, restart CRI-O:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>systemctl restart crio
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Package installations should work now:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="rouge-code"><pre><span class="gp">/ #</span><span class="w"> </span>apk add curl
<span class="go">fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
(1/4) Installing ca-certificates (20191127-r4)
(2/4) Installing nghttp2-libs (1.41.0-r0)
(3/4) Installing libcurl (7.69.1-r1)
(4/4) Installing curl (7.69.1-r1)
Executing busybox-1.31.1-r19.trigger
Executing ca-certificates-20191127-r4.trigger
OK: 7 MiB in 18 packages
</span></pre></td></tr></tbody></table></code></pre></div></div>]]></content><author><name>Elouan Martinet</name></author><category term="kubernetes" /><summary type="html"><![CDATA[I recently created a self-managed Kubernetes cluster using the CRI-O container runtime. I had an issue with Alpine Linux images where package installation trigger scripts were failing for unknown reason (script exited with error 127). Since I couldn’t find a resource online to fix the issue, I wanted to make a blog post to help others that would struggle with it.]]></summary></entry><entry><title type="html">Local boot on old Scaleway instances via kexec</title><link href="https://elou.world/en/hosting/scaleway-kexec" rel="alternate" type="text/html" title="Local boot on old Scaleway instances via kexec" /><published>2020-06-07T12:00:00+00:00</published><updated>2025-09-14T23:11:25+00:00</updated><id>https://elou.world/en/hosting/scaleway-kexec</id><content type="html" xml:base="https://elou.world/en/hosting/scaleway-kexec"><![CDATA[<p>Old instances (e.g. VC1S) don’t have the possibility to run kernel from
upstream Linux distribution (you can’t reinstall using EFI), instead they use
a kernel provided by Scaleway team, which is not regularly updated.</p>

<p>Fortunately, Scaleway has <a href="https://github.com/scaleway/initrd/tree/master/Linux#boot-options">hidden features</a>
in their boot process that allow to run <em>kexec</em> which makes it possible to run
the kernel of your choice.</p>

<p>These features are provided by setting <em>tags</em> on the instance in the Scaleway
console.</p>

<p>This guide leads you to enable <em>kexec</em> on your instance.</p>

<p><strong>Note:</strong> This tutorial is no longer applicable since Scaleway has <a href="https://www.scaleway.com/en/docs/instances/troubleshooting/bootscript-eol/">dropped support</a> for bootscripts. Also, it is now possible to reinstall servers in rescue mode with EFI, a thing that wasn’t possible at the time this article was written. This article is only kept here for educational purposes.</p>

<h1 id="install-a-kernel-on-the-server">Install a kernel on the server</h1>

<p>For Debian:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>apt <span class="nb">install </span>linux-image-amd64
</pre></td></tr></tbody></table></code></pre></div></div>

<p>For Ubuntu:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>apt <span class="nb">install </span>linux-kvm <span class="c"># or: linux-image-generic</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="check-that-symbolic-links-have-been-created">Check that symbolic links have been created</h2>

<p><em>linux-update-symlinks</em> is ran by APT to create symbolic links on <code class="language-plaintext highlighter-rouge">/vmlinuz</code>
and <code class="language-plaintext highlighter-rouge">/initrd.img</code>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="nb">ls</span> <span class="nt">-l</span> /vmlinuz /initrd.img
</pre></td></tr></tbody></table></code></pre></div></div>

<p>This should point to the kernel that has just been installed in <code class="language-plaintext highlighter-rouge">/boot</code>.</p>

<h1 id="install-a-network-daemon">Install a network daemon</h1>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>apt install ifupdown
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="configure-it">Configure it</h2>

<p>Edit <code class="language-plaintext highlighter-rouge">/etc/network/interfaces</code> and comment out lines for <code class="language-plaintext highlighter-rouge">eth0</code> interfaces,
then add:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>auto ens2
iface ens2 inet dhcp
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="edit-fstab-for-mounting-disks-on-boot">Edit fstab for mounting disks on boot</h1>

<p>Run <code class="language-plaintext highlighter-rouge">blkid</code> to get disk UUIDs.</p>

<p>Edit <code class="language-plaintext highlighter-rouge">/etc/fstab</code> so it will mount all your disks to the proper mount points
on startup:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx	/         	ext4      	rw,relatime	0 1
</pre></td></tr></tbody></table></code></pre></div></div>

<p>This step is important or it will only mount <code class="language-plaintext highlighter-rouge">/dev/vda</code> as read-only.</p>

<p>If you miss this step, you can still remount it as read-write:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>mount <span class="nt">-o</span> remount,rw /
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="check-that-setup-is-working">Check that setup is working</h1>

<p>I advise you to disable the services you don’t want to start at boot in your
tests, as these could be killed later if you restart your instance on Scaleway
console.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>systemctl status <span class="c"># check what units you want to disable</span>
systemctl disable ...
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Then install <em>kexec</em> locally:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>apt install kexec-tools
</pre></td></tr></tbody></table></code></pre></div></div>
<p>When it asks whether or not to manage boot process, choose <em>no</em>.</p>

<p>It might be useful to open now the <em>console</em> of your instance (a virtual TTY)
on the Scaleway console, to check the output of the boot process, in case of an
error. Note that it often stays blank and doesn’t work, but it is very useful
when it does.</p>

<p>Be aware that the network interface will be renamed from <code class="language-plaintext highlighter-rouge">eth0</code> to <code class="language-plaintext highlighter-rouge">ens2</code>.
You might want to update your firewall rules accordingly.</p>

<p>When you are ready, run these two commands and you’ll be logged out of SSH,
as kernel runs <em>kexec</em>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>kexec -l /vmlinuz --initrd=/initrd.img --reuse-cmdline
systemctl kexec
</pre></td></tr></tbody></table></code></pre></div></div>

<p>If server seems not responsive or failed to boot, you can <em>restart</em> the server
on Scaleway console. Note that as <em>networking</em> service has been enabled, it will
probably fail to start and blocks the boot process for 5 minutes. Check the
<em>console</em> for when it happens.</p>

<h1 id="edit-scaleway-tags">Edit Scaleway tags</h1>

<p>When you have confirmed that your setup is working, add these two tags to make
Scaleway boot process to run <em>kexec</em> by itself:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="py">KEXEC_KERNEL</span><span class="p">=</span><span class="s">/vmlinuz</span>
<span class="py">KEXEC_INITRD</span><span class="p">=</span><span class="s">/initrd.img</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Add the first tag, press <em>space</em>, then add the second tag, press <em>space</em> again.</p>

<p>Reboot your server (using <em>reboot</em> via SSH) and profit!</p>

<p>Note: if you previously disabled some services, you can restart these now:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>systemctl <span class="nb">enable</span> <span class="nt">--now</span> ...
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="references">References</h1>

<ul>
  <li><a href="https://blog.simos.info/how-to-run-the-stock-ubuntu-linux-kernel-on-scaleway-using-kexec-and-server-tags/">How to run the stock Ubuntu Linux kernel on Scaleway using KEXEC and server tags</a></li>
</ul>]]></content><author><name>Elouan Martinet</name></author><category term="hosting" /><summary type="html"><![CDATA[Old instances (e.g. VC1S) don’t have the possibility to run kernel from upstream Linux distribution (you can’t reinstall using EFI), instead they use a kernel provided by Scaleway team, which is not regularly updated.]]></summary></entry><entry><title type="html">WireGuard (via systemd-networkd)</title><link href="https://elou.world/en/tutorial/wireguard" rel="alternate" type="text/html" title="WireGuard (via systemd-networkd)" /><published>2019-10-25T18:00:00+00:00</published><updated>2025-09-14T23:11:25+00:00</updated><id>https://elou.world/en/tutorial/wireguard</id><content type="html" xml:base="https://elou.world/en/tutorial/wireguard"><![CDATA[<p><a href="https://www.wireguard.com/">WireGuard</a> is a new VPN protocol and software, using modern cryptography (ChaCha20, Ed25519…). It is simple to use and configure, similarly to OpenSSH, you just need to share public keys between peers, compared to OpenVPN where you need to manage a private certificate authority (which has different advantages). Please note though that WireGuard is not made for having <em>anonymous</em> (not logged) clients unlike how OpenVPN can be used for, since it uses static IP addresses instead of DHCP (servers need to track the connections of clients). The main implementation lives in Linux kernel (in a kernel module) but other software implementations exist.</p>

<p>Its source code has been merged in Linux 5.6 and <a href="https://www.wireguard.com/formal-verification/">formal verification</a> has been done for WireGuard protocol and implementation. The code base is way smaller than other related projects so it is easier to audit and maintain.</p>

<p>This tutorial presents an installation on a Linux-based operating system with systemd (and systemd-networkd). Other setups are also possible but I found this one simple to use, although platform-dependant. This article doesn’t cover routing Internet traffic through the private network created.</p>

<h1 id="wireguard-installation">WireGuard installation</h1>

<p>Here are instructions to install WireGuard on Debian, Ubuntu and Arch Linux. You can find other operating system instructions on the <a href="https://www.wireguard.com/install/">official website</a>.</p>

<h2 id="on-debian">On Debian</h2>

<p>Since Debian Bullseye, WireGuard support is directly available in the Linux kernel.</p>

<p>Using instructions from <a href="https://wiki.debian.org/WireGuard">Debian Wiki</a>, let’s install the <code class="language-plaintext highlighter-rouge">wireguard</code> package.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>apt update <span class="o">&amp;&amp;</span> apt <span class="nb">install </span>wireguard
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="on-ubuntu">On Ubuntu</h2>

<p>Since Ubuntu 20.04, WireGuard support has been backported in the Linux kernel (the kernel packages provide <code class="language-plaintext highlighter-rouge">wireguard-modules</code>), there is no need to build a kernel module. The instructions are the same as Debian:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>apt update <span class="o">&amp;&amp;</span> apt <span class="nb">install </span>wireguard
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="on-arch-linux">On Arch Linux</h2>

<p>Since all kernel versions are higher than 5.6 on Arch Linux, all supported kernels include the WireGuard module without any additional package.</p>

<p>Using instructions from <a href="https://wiki.archlinux.org/title/WireGuard">ArchWiki</a>, install the <code class="language-plaintext highlighter-rouge">wireguard-tools</code> package to install the WireGuard tools.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>pacman <span class="nt">-Syu</span> wireguard-tools
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="configuration">Configuration</h1>

<p>You need to enable the <code class="language-plaintext highlighter-rouge">systemd-networkd</code> service, if not done already. One advantage is that it can manage both your WireGuard setup and networking at the same time, easing the configuration. I have also used it alongside another networking daemon (like <code class="language-plaintext highlighter-rouge">networking</code> on Debian or <code class="language-plaintext highlighter-rouge">dhcpcd</code> on Arch Linux), but I recommend not doing so.</p>

<h2 id="on-both-server-and-client">On both server and client</h2>

<p>You need to create a pair of keys on both server and client. Each client will need to get server’s public key and the server will need to get each client’s public key. Also a pre-shared key will be created, known to each peer.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="rouge-code"><pre><span class="c"># go to systemd-networkd configuration directory</span>
<span class="nb">cd</span> /etc/systemd/network

<span class="c"># create files with right permissions (640) to prevent other system users to read secrets</span>
<span class="nb">umask </span>0027
<span class="nb">touch </span>wg0.netdev wg0.network wg-preshared.key wg-private.key wg-public.key
<span class="nb">umask </span>0022
<span class="nb">chown </span>root:systemd-network <span class="k">*</span>

<span class="c"># create a pair of keys</span>
wg genkey | <span class="nb">tee </span>wg-private.key | wg pubkey <span class="o">&gt;</span> wg-public.key
</pre></td></tr></tbody></table></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">wg0.netdev</code> will be used for WireGuard configuration, <code class="language-plaintext highlighter-rouge">wg0.network</code> for networking configuration.</p>

<p>On systemd versions earlier than 242, <code class="language-plaintext highlighter-rouge">wg0.netdev</code> will contain secrets, on later versions it’s possible to reference other created files. At the time of writing, Debian oldstable (<em>buster</em>) uses systemd 241, which doesn’t support that feature.</p>

<h2 id="on-server">On server</h2>

<p>On the server, you need to create the pre-shared key (or on any other peer).</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>wg genpsk <span class="o">&gt;</span> wg-preshared.key
</pre></td></tr></tbody></table></code></pre></div></div>
<p>It needs to be copied to other peers.</p>

<p>You can also use a different pre-shared key for each peer, if they are not trusted.</p>

<p>Then here are sample server configuration files. I chose to use a subnet <code class="language-plaintext highlighter-rouge">10.213.213.0/24</code>, but you can also use IPv6 or even dual-stack. For IPv6, you can create a prefix in the <code class="language-plaintext highlighter-rouge">fd00::/8</code> prefix, which is allocated for <a href="https://en.wikipedia.org/wiki/Unique_local_address">unique local addresses</a>.</p>

<p>Make sure to change <code class="language-plaintext highlighter-rouge">&lt;variable&gt;</code> to the appropriate key value. Less-than and greater-than signs (<code class="language-plaintext highlighter-rouge">&lt;&gt;</code>) must not be kept.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="rouge-code"><pre><span class="nb">cat</span> <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> &gt; wg0.netdev
[NetDev]
Name = wg0
Kind = wireguard
Description = wg server 10.213.213.0/24

[WireGuard]
# If running systemd &gt;= 242
PrivateKeyFile = /etc/systemd/network/wg-private.key
# If running systemd &lt; 242
#PrivateKey = &lt;content of local wg-private.key&gt;
ListenPort = 51820

# For any number of client:
[WireGuardPeer]
PublicKey = &lt;content of client's wg-public.key&gt;
AllowedIPs = 10.213.213.2/32
# If running systemd &gt;= 242
PresharedKeyFile = /etc/systemd/network/wg-preshared.key
# If running systemd &lt; 242
#PresharedKey = &lt;content of wg-preshared.key&gt;
</span><span class="no">EOF
</span></pre></td></tr></tbody></table></code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">AllowedIPs</code> represents here the static IP address of the client. You need to choose one per client in the subnet.</p>

<p>You can change <code class="language-plaintext highlighter-rouge">ListenPort</code> to your needs (e.g. <code class="language-plaintext highlighter-rouge">53</code> to pass through firewalls, since it uses UDP).</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="rouge-code"><pre><span class="nb">cat</span> <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> &gt; wg0.network
[Match]
Name = wg0

[Network]
Address = 10.213.213.1/32

[Route]
Gateway = 10.213.213.1
Destination = 10.213.213.0/24
</span><span class="no">EOF
</span></pre></td></tr></tbody></table></code></pre></div></div>
<p>Then restart systemd-networkd:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>systemctl restart systemd-networkd
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="on-client">On client</h2>

<p>Like on the server, here are sample configuration files. Make sure you change the private IP address on each client, according to server configuration.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="rouge-code"><pre><span class="nb">cat</span> <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> &gt; wg0.netdev
[NetDev]
Name = wg0
Kind = wireguard
Description = wg client 10.213.213.2

[WireGuard]
# If running systemd &gt;= 242
PrivateKeyFile = /etc/systemd/network/wg-private.key
# If running systemd &lt; 242
#PrivateKey = &lt;content of local wg-private.key&gt;

[WireGuardPeer]
PublicKey = &lt;server's public key&gt;
AllowedIPs = 10.213.213.0/24
Endpoint = &lt;server's public IP address&gt;:51820
# If running systemd &gt;= 242
PresharedKeyFile = /etc/systemd/network/wg-preshared.key
# If running systemd &lt; 242
#PresharedKey = &lt;content of wg-preshared.key&gt;
PersistentKeepalive = 25
</span><span class="no">EOF

</span><span class="nb">cat</span> <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> &gt; wg0.network
[Match]
Name = wg0

[Network]
Address = 10.213.213.2/32

[Route]
Gateway = 10.213.213.1
Destination = 10.213.213.0/24
GatewayOnlink = true
</span><span class="no">EOF
</span></pre></td></tr></tbody></table></code></pre></div></div>
<p>When <code class="language-plaintext highlighter-rouge">ListenPort</code> is not entered, a random port will be chosen by systemd, this is not important for clients that connect to the server specified with <code class="language-plaintext highlighter-rouge">Endpoint</code>.</p>

<p>Then restart systemd-networkd:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>systemctl restart systemd-networkd
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="check-the-connection">Check the connection</h1>

<p>You can check that systemd-networkd enabled the WireGuard network interface (wg0) with the <code class="language-plaintext highlighter-rouge">networkctl</code> command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre>$ networkctl
IDX LINK             TYPE               OPERATIONAL SETUP     
  1 lo               loopback           carrier     unmanaged 
  2 eno1             ether              routable    configured
  3 wg0              wireguard          routable    configured
</pre></td></tr></tbody></table></code></pre></div></div>

<p>You should now be able to ping server and client addresses from each other.</p>

<p>If there is any issue, check the logs with <code class="language-plaintext highlighter-rouge">journalctl -eu systemd-networkd</code>. If you have <code class="language-plaintext highlighter-rouge">Unknown lvalue</code> errors, it means you used unknown configuration directives, e.g. mistyped or from a more recent systemd version.</p>

<p>You can also get more information using the <code class="language-plaintext highlighter-rouge">wg</code> command:</p>

<p>On server:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="rouge-code"><pre>$ wg
interface: wg0
  public key: &lt;redacted&gt;
  private key: (hidden)
  listening port: 51820

peer: redacted=
  preshared key: (hidden)
  endpoint: &lt;client's public IP address&gt;:44195
  allowed ips: 10.213.213.2/32
  latest handshake: 24 seconds ago
  transfer: 968.57 KiB received, 50.94 MiB sent
</pre></td></tr></tbody></table></code></pre></div></div>

<p>On client:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="rouge-code"><pre>$ wg
interface: wg0
  public key: &lt;redacted&gt;
  private key: (hidden)
  listening port: 44195

peer: redacted=
  preshared key: (hidden)
  endpoint: &lt;server's public IP address&gt;:51820
  allowed ips: 10.213.213.0/24
  latest handshake: 49 seconds ago
  transfer: 50.94 MiB received, 971.40 KiB sent
  persistent keepalive: every 25 seconds
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="additional-configuration">Additional configuration</h1>

<ul>
  <li><code class="language-plaintext highlighter-rouge">[WireGuard]</code> and <code class="language-plaintext highlighter-rouge">[WireGuardPeer]</code> sections in <code class="language-plaintext highlighter-rouge">man 5 systemd.netdev</code> (online versions: <a href="https://manpages.debian.org/stable/systemd/systemd.netdev.5.en.html#%5BWIREGUARD%5D_SECTION_OPTIONS">Debian</a>, <a href="https://man.archlinux.org/man/core/systemd/systemd.netdev.5.en#%5BWIREGUARD%5D_SECTION_OPTIONS">Arch</a>, <a href="https://www.freedesktop.org/software/systemd/man/systemd.netdev.html#%5BWireGuard%5D%20Section%20Options">latest</a>)</li>
  <li><a href="https://www.wireguard.com/quickstart/">Quick Start</a> on official website</li>
</ul>]]></content><author><name>Elouan Martinet</name></author><category term="tutorial" /><summary type="html"><![CDATA[WireGuard is a new VPN protocol and software, using modern cryptography (ChaCha20, Ed25519…). It is simple to use and configure, similarly to OpenSSH, you just need to share public keys between peers, compared to OpenVPN where you need to manage a private certificate authority (which has different advantages). Please note though that WireGuard is not made for having anonymous (not logged) clients unlike how OpenVPN can be used for, since it uses static IP addresses instead of DHCP (servers need to track the connections of clients). The main implementation lives in Linux kernel (in a kernel module) but other software implementations exist.]]></summary></entry><entry><title type="html">La fin de l’anonymat sur l’Internet français</title><link href="https://elou.world/fr/politique/fin-anonymat-internet-francais" rel="alternate" type="text/html" title="La fin de l’anonymat sur l’Internet français" /><published>2019-02-08T02:00:00+00:00</published><updated>2025-09-14T23:11:25+00:00</updated><id>https://elou.world/fr/politique/fin-anonymat-internet-francais</id><content type="html" xml:base="https://elou.world/fr/politique/fin-anonymat-internet-francais"><![CDATA[<p>Sous couvert de protéger les français du harcèlement sur Internet, ou peut-être seulement les politiciens qui ne respectent jamais leurs promesses, le gouvernement français propose actuellement de mettre fin à “l’anonymat” des internautes sur les <a href="https://nitter.net/CNEWS/status/1093578425447694337">plateformes Internet</a>.</p>

<p>De nombreux articles discutent surtout du côté légal ou éthique vis-à-vis de l’anonymat (ou du pseudonymat) sur Internet, je vous conseille de lire par exemple <a href="https://pixellibre.net/2019/02/lettre-ouverte-deputes-afin-defendre-droit-anonymat/">la lettre ouverte aux députés</a> publiée par Numendil. J’aimerais me concentrer sur la partie technique du sujet.</p>

<p>Je ne suis pas juriste, mais il faut d’abord chercher à définir ce terme “plateforme” qui apparaît très souvent. Disons qu’il s’agit d’un service qui permet à des utilisateurs de publier du contenu sur Internet, qui sera hébergé par un tiers (on peut aussi appelé ça réseau social, je préfère d’ailleurs ce terme). Je préfère garder une définition vaste pour l’instant, je vais parler de la taille de l’hébergeur plus tard. D’ailleurs, le statut même d’hébergeur, défini par la loi <a href="https://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000000801164">LCEN</a>, est menacé notamment par les ayants droit qui veulent forcer l’utilisation du filtrage automatisé des contenus, mais ce n’est pas le sujet de cet article.</p>

<p>Aujourd’hui, n’importe qui peut créer ce genre de service, en étant particulier, association ou entreprise. Il suffit d’enregistrer un <a href="https://fr.wikipedia.org/wiki/Nom_de_domaine">nom de domaine</a> chez un registrar (comme <a href="https://www.ovhcloud.com/fr/domains/">OVH</a>), puis d’installer un logiciel dédié sur un serveur (auto-hébergé ou loué chez un prestataire). Un exemple de logiciel est <a href="https://joinmastodon.org/">Mastodon</a> qui permet non seulement d’héberger un réseau social, mais aussi d’interconnecter des instances, chacune ayant ses propres règles et thématiques, dans une fédération appelée <a href="https://fr.wikipedia.org/wiki/Fediverse">Fediverse</a>. Cela montre que plusieurs types d’acteurs avec des buts différents peuvent créer des espaces d’échange.</p>

<p>J’aimerais opposer ces acteurs aux mastodontes que sont entre autres Twitter et Facebook, deux multinationales basées aux États-Unis, qui tirent leur revenu de la publicité des annonceurs, qui est personnalisée grâce au contenu publié et aux interactions des utilisateurs de leur service. Ces acteurs sont présents sur toute la planète, or chaque pays peut avoir une vision différente sur l’anonymat sur Internet (les pays nord-européens ont en général une vision plus protectrice vis-à-vis d’Internet). Pensez-vous qu’ils vont appliquer des mesures très précises pour chaque pays ? Il y a deux possibilités : soit ils acceptent de se plier à chaque gouvernement (avec un potentiel coût en développement), en sachant que les lois peuvent changer très vite, soit ils s’y refusent en voulant harmoniser les interactions sur leur réseau social (après tout, leur réseau est mondial, et ne permet pas seulement des interactions entre utilisateurs d’un même pays).</p>

<p>Le problème est surtout de savoir ce que le gouvernement français souhaite. Soit ils veulent que chaque utilisateur ait une identité vérifiée et visible publiquement, soit ils veulent que chaque service collecte une information qui permettrait à la justice de retrouver l’identité d’un utilisateur. Dans le premier cas, je vois mal comment cela va diminuer le harcèlement : il est plus facile en connaissant l’identité d’une personne de trouver des éléments pour faciliter un tel harcèlement (qui existe aussi hors d’Internet où il est plus probable de connaître l’identité d’un individu). Dans le second cas, il existe déjà l’<a href="https://fr.wikipedia.org/wiki/Adresse_IP">adresse IP</a> qui, pour la majorité des cas, identifie précisément un utilisateur (les fournisseurs d’accès à Internet gardant l’historique de toutes les connexions, et les réseaux sociaux collectant aussi cette information). L’avantage de l’adresse IP est qu’elle fait partie du fonctionnement d’Internet et continuera d’exister. Le désavantage est qu’une adresse IP peut être partagée (par exemple avec le NAT, un <a href="https://fr.wikipedia.org/wiki/R%C3%A9seau_priv%C3%A9_virtuel">VPN</a> ou un réseau wi-fi public). De plus, en étant connecté depuis un autre pays, on peut être soumis à un traitement différent. Il peut donc être souhaitable d’avoir une identification authentifiée, où il est possible de vérifier l’identité précise d’un individu.</p>

<p>De plus, dans le premier cas, un réseau publicitaire (comme Twitter, Facebook mettant déjà en avant le fait d’utiliser son identité réelle) serait très intéressé par l’identité précise d’un utilisateur : le système des enchères publicitaires (<a href="https://fr.wikipedia.org/wiki/Real_Time_Bidding">Real Time Bidding</a>) s’appuie sur l’échange d’informations entre plusieurs services (cette pratique est incompatible avec le <a href="https://fr.wikipedia.org/wiki/R%C3%A8glement_g%C3%A9n%C3%A9ral_sur_la_protection_des_donn%C3%A9es">RGPD</a> mais malheureusement elle risque de continuer à exister).</p>

<p>Un moyen d’avoir une identification authentifiée serait d’utiliser un service d’identification tel que <a href="https://fr.wikipedia.org/wiki/FranceConnect">FranceConnect</a> (aussi cité par Numendil) qui permet de vérifier son identité via des fournisseurs d’identité (comme La Poste ou Orange). Ce service est mis en œuvre par l’État (par la <a href="https://fr.wikipedia.org/wiki/Direction_interminist%C3%A9rielle_du_num%C3%A9rique_et_du_syst%C3%A8me_d%27information_et_de_communication_de_l%27%C3%89tat">DINSIC</a>), et est actuellement utilisé pour la connexion au site des impôts ou de la sécurité sociale, mais aussi pour une mutuelle. FranceConnect pourrait fonctionner dans les deux cas : il pourrait envoyer l’identité d’un utilisateur au réseau social (c’est le fonctionnement actuel avec les services utilisant FranceConnect), ou créer un identificateur unique par service qui permettrait à l’État, en possession de cet identificateur collecté et transmis par un réseau social, de retrouver l’identité d’un utilisateur, tout en protégeant le pseudonymat de l’utilisateur. Le fait d’avoir un identificateur unique empêcherait les réseaux sociaux de pouvoir s’échanger ces identifiants pour identifier un individu sur différents services.</p>

<p>Sauf qu’il y a deux problèmes vis-à-vis de l’utilisation d’un tel service d’identification. Premièrement, comment s’assurer que tous les français sont identifiables (pour leur forcer l’utilisation du service d’identification à leur inscription) ? Deuxièmement, comment permettre à n’importe qui d’accéder à ce service (vu qu’actuellement, n’importe qui peut créer un réseau social) ?</p>

<p>Pour le premier point, il existe des listes d’adresses IP qui permettent de les localiser (par pays, par ville, par fournisseur d’accès à Internet) comme GeoIP de MaxMind (tien, on a déjà parlé des adresses IP avant) et ainsi savoir qu’un internaute se connecte depuis la France (notons que les personnes de nationalité différente ne pourront pas être différentiés). Par contre, hors de France, seul le volontariat peut fonctionner (j’implique que cette mesure ne concerne que les français évidemment). Pour le second point, il risque d’y avoir une rupture avec l’Internet actuel qui va bénéficier aux entreprises (facilement reconnues par l’État) : il faudra forcément faire une demande officielle pour pouvoir accéder au service d’identification (et donc devenir hébergeur). Ce serait aussi une rupture avec la neutralité de l’Internet, qui je l’espère ne constitue pas seulement en l’accès équitable aux différents services sur Internet, mais qui doit aussi garantir la possibilité de devenir hébergeur.</p>

<p>Je pense avoir fait le tour de la partie technique. Essayez de parler de ce sujet autour de vous pour mettre au jour les différents problèmes. Si vous avez des commentaires, vous pouvez me contacter sur Mastodon.</p>]]></content><author><name>Elouan Martinet</name></author><category term="politique" /><summary type="html"><![CDATA[Sous couvert de protéger les français du harcèlement sur Internet, ou peut-être seulement les politiciens qui ne respectent jamais leurs promesses, le gouvernement français propose actuellement de mettre fin à “l’anonymat” des internautes sur les plateformes Internet.]]></summary></entry></feed>