| CARVIEW |
Select Language
HTTP/2 200
server: GitHub.com
content-type: application/xml
last-modified: Mon, 15 Dec 2025 06:48:27 GMT
access-control-allow-origin: *
etag: W/"693faf3b-1738e"
expires: Fri, 26 Dec 2025 14:28:56 GMT
cache-control: max-age=600
content-encoding: gzip
x-proxy-cache: MISS
x-github-request-id: 63BB:234FE9:572118:60F683:694E9950
accept-ranges: bytes
age: 0
date: Fri, 26 Dec 2025 14:18:56 GMT
via: 1.1 varnish
x-served-by: cache-bom-vanm7210065-BOM
x-cache: MISS
x-cache-hits: 0
x-timer: S1766758737.706098,VS0,VE211
vary: Accept-Encoding
x-fastly-request-id: aa0c368395951fcfc35136101f875666ed6f3919
content-length: 19825
Samuel Henrique (samueloph)
My personal website
Zola
2025-08-28T17:30:00+00:00
https://samueloph.dev/atom.xml
Debian 13: My list of exciting new features
2025-08-28T17:30:00+00:00
2025-08-28T17:30:00+00:00
Unknown
https://samueloph.dev/blog/debian-13-my-list-of-exciting-new-features/
<img src="debian-13-my-list-of-exciting-new-features.webp" alt="A bunch of
screenshots overlaid on top of each other showing different tools: lazygit,
gnome settings, gnome system monitor, powerline-go, and the wcurl logo, the
text at the top says 'Debian 13: My list of exciting new features', and there's
a Debian logo in the middle of image" width="1200" height="630" loading="lazy" />
<h1 id="beyond-debian-useful-for-other-distros-too">Beyond Debian: Useful for other distros too</h1>
<p>Every two years Debian releases a new major version of its Stable series,
meaning the differences between consecutive Debian Stable releases represent
two years of new developments both in Debian as an organization and its native
packages, but also in all other packages which are also shipped by other
distributions (which are getting into this new Stable release).</p>
<p>If you're not paying close attention to everything that's going on all the time
in the Linux world, you miss a lot of the nice new features and tools. It's
common for people to only realize there's a cool new trick available only years
after it was first introduced.</p>
<p>Given these considerations, the tips that I'm describing will eventually be
available in whatever other distribution you use, be it because it's a Debian
derivative or because it just got the same feature from the upstream project.</p>
<p>I'm not going to list "passive" features (as good as they can be), the focus
here is on new features that might change how you configure and use your
machine, with a mix between productivity and performance.</p>
<h1 id="debian-13-trixie">Debian 13 - Trixie</h1>
<p>I have been a Debian Testing user for longer than 10 years now (and I recommend
it for non-server users), so I'm not usually keeping track of all the cool
features arriving in the new Stable releases because I'm continuously receiving
them through the Debian Testing rolling release.</p>
<p>Nonetheless, as a Debian Developer I'm in a good position to point out the ones
I can remember. I would also like other Debian Developers to do the same as I'm
sure I would learn something new.</p>
<p>The Debian 13 release notes contain a <a rel="noopener" target="_blank" href="https://www.debian.org/releases/trixie/release-notes/whats-new.en.html">"What's new" section
</a>, which
lists the first two items here and a few other things, in other words, take my
list as an addition to the release notes.</p>
<p>Debian 13 was released on 2025-08-09, and these are nice things you shouldn't
miss in the new release, with a bonus one not tied to the Debian 13 release.</p>
<h2 id="1-wcurl">1) wcurl</h2>
<img src="wcurl-logo.svg" alt="wcurl logo" width="998" height="250" loading="lazy" />
<p>Have you ever had to download a file from your terminal using curl and didn't
remember the parameters needed? I did.</p>
<p>Nowadays you can use <code>wcurl</code>; "a command line tool which lets you download URLs
without having to remember any parameters."</p>
<p>Simply call <code>wcurl</code> with one or more URLs as parameters and it will download
all of them in parallel, performing retries, choosing the correct output file
name, following redirects, and more.</p>
<p>Try it out:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">wcurl</span></span><span class="z-meta z-function-call z-arguments z-shell"> example.com</span>
</span></code></pre>
<p><code>wcurl</code> comes installed as part of the curl package on Debian 13 and in any other
distribution you can imagine, starting with curl 8.14.0.</p>
<p>I've written more about wcurl in its <a rel="noopener" target="_blank" href="https://samueloph.dev/blog/announcing-wcurl-a-curl-wrapper-to-download-files/">release
announcement</a>
and I've done a lightning talk presentation in DebConf24, which is linked in
the release announcement.</p>
<h2 id="2-http-3-support-in-curl">2) HTTP/3 support in curl</h2>
<p>Debian has become the first stable Linux distribution to ship curl with support
for HTTP/3. <a rel="noopener" target="_blank" href="https://samueloph.dev/blog/debian-curl-now-supports-http3/">I've written about this in July
2024</a>, when we
first enabled it. Note that we first switched the curl CLI to GnuTLS, but then
ended up releasing the curl CLI linked with OpenSSL (as support arrived later).</p>
<p>Debian was the first stable Linux distro to enable it, and within
rolling-release-based distros; Gentoo enabled it first in their non-default
flavor of the package and Arch Linux did it three months before we pushed it to
Debian Unstable/Testing/Stable-backports, kudos to them!</p>
<p>HTTP/3 is not used by default by the curl CLI, you have to enable it with
<code>--http3</code> or <code>--http3-only</code>.</p>
<p>Try it out:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">curl</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>http3</span> https://www.example.org</span>
</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">curl</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>http3-only</span> https://www.example.org</span>
</span></code></pre>
<h2 id="3-systemd-soft-reboot">3) systemd soft-reboot</h2>
<p>Starting with systemd v254, there's a new <code>soft-reboot</code> option, it's an
userspace-only reboot, much faster than a full reboot if you don't need to
reboot the kernel.</p>
<p>You can read the announcement from the <a rel="noopener" target="_blank" href="https://github.com/systemd/systemd/releases/tag/v254">systemd v254 GitHub
release</a></p>
<p>Try it out:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> This will reboot your machine!</span><span class="z-comment z-line z-number-sign z-shell">
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">systemctl</span></span><span class="z-meta z-function-call z-arguments z-shell"> soft-reboot</span>
</span></code></pre>
<h2 id="4-apt-update">4) apt --update</h2>
<p>Are you tired of being required to run <code>sudo apt update</code> just before <code>sudo apt upgrade</code> or <code>sudo apt install $PACKAGE</code>? So am I!</p>
<p>The new <code>--update</code> option lets you do both things in a single command:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> apt<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>update</span> upgrade</span>
</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> apt<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>update</span> install <span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">PACKAGE</span></span></span>
</span></code></pre>
<p>I love this, but it's still not yet where it should be, fingers crossed for a
simple <code>apt upgrade</code> to behave like other package managers by updating its
cache as part of the task, maybe in Debian 14?</p>
<p>Try it out:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> apt upgrade<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>update</span></span>
</span><span class="z-source z-shell z-bash"><span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> The order doesn't matter</span><span class="z-comment z-line z-number-sign z-shell">
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> apt<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>update</span> upgrade</span>
</span></code></pre>
<p>This is especially handy for container usage, where you have to update the apt
cache before installing anything, for example:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">podman</span></span><span class="z-meta z-function-call z-arguments z-shell"> run debian:stable bin/bash<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>c</span> <span class="z-string z-quoted z-single z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">'</span>apt install --update -y curl<span class="z-punctuation z-definition z-string z-end z-shell">'</span></span></span>
</span></code></pre>
<h2 id="5-powerline-go">5) powerline-go</h2>
<p><code>powerline-go</code> is a powerline-style prompt written in Golang, so it's much more
performant than its Python alternative <code>powerline</code>.</p>
<p>powerline-style prompts are quite useful to show things like the current status
of the git repo in your working directory, exit code of the previous command,
presence of jobs in the background, whether or not you're in an ssh session,
and more.</p>
<img src="powerline-go.webp" alt="A screenshot of a terminal with
powerline-go enabled, showing how the PS1 changes inside a git repository and
when the last command fails" width="1929" height="618" loading="lazy" />
<p>Try it out:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> apt install powerline-go</span>
</span></code></pre>
<p>Then add this to your <code>.bashrc</code>:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"><span class="z-storage z-type z-function z-shell">function</span> <span class="z-entity z-name z-function z-shell">_update_ps1</span><span class="z-punctuation z-section z-parens z-begin z-shell">(</span><span class="z-punctuation z-section z-parens z-end z-shell">)</span> <span class="z-punctuation z-section z-braces z-begin z-shell">{</span>
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-variable z-other z-readwrite z-assignment z-shell">PS1</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">"</span><span class="z-meta z-group z-expansion z-command z-parens z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-parens z-begin z-shell">(</span><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">/usr/bin/powerline-go</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>error</span> <span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-language z-shell">?</span></span><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>jobs</span> <span class="z-meta z-group z-expansion z-command z-parens z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-parens z-begin z-shell">(</span><span class="z-meta z-function-call z-shell"><span class="z-support z-function z-jobs z-shell">jobs</span></span><span class="z-meta z-function-call z-arguments z-shell"> -p</span> <span class="z-keyword z-operator z-logical z-pipe z-shell">|</span> <span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">wc</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>l</span></span><span class="z-punctuation z-section z-parens z-end z-shell">)</span></span></span><span class="z-punctuation z-section z-parens z-end z-shell">)</span></span><span class="z-punctuation z-definition z-string z-end z-shell">"</span></span></span>
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell">
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> Uncomment the following line to automatically clear errors after showing</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> them once. This not only clears the error for powerline-go, but also for</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> everything else you run in that shell. Don't enable this if you're not</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> sure this is what you want.</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell">
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell">set "?"</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"><span class="z-punctuation z-section z-braces z-end z-shell">}</span></span>
</span><span class="z-source z-shell z-bash">
</span><span class="z-source z-shell z-bash"><span class="z-keyword z-control z-conditional z-if z-shell">if</span> <span class="z-support z-function z-test z-begin z-shell">[</span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">"</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">TERM</span></span><span class="z-punctuation z-definition z-string z-end z-shell">"</span></span> <span class="z-keyword z-operator z-logical z-shell">!=</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">"</span>linux<span class="z-punctuation z-definition z-string z-end z-shell">"</span></span> <span class="z-support z-function z-test z-end z-shell">]</span></span> <span class="z-keyword z-operator z-logical z-and z-shell">&&</span> <span class="z-support z-function z-test z-begin z-shell">[</span><span class="z-meta z-function-call z-arguments z-shell"> <span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell">-</span>f</span> <span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">"</span>/usr/bin/powerline-go<span class="z-punctuation z-definition z-string z-end z-shell">"</span></span> <span class="z-support z-function z-test z-end z-shell">]</span></span><span class="z-keyword z-operator z-logical z-continue z-shell">;</span> <span class="z-keyword z-control z-conditional z-then z-shell">then</span>
</span><span class="z-source z-shell z-bash"> <span class="z-variable z-other z-readwrite z-assignment z-shell">PROMPT_COMMAND</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">"</span>_update_ps1; <span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-other z-readwrite z-shell">PROMPT_COMMAND</span></span><span class="z-punctuation z-definition z-string z-end z-shell">"</span></span></span>
</span><span class="z-source z-shell z-bash"><span class="z-keyword z-control z-conditional z-end z-shell">fi</span>
</span></code></pre>
<p>Or this to <code>.zshrc</code>:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"><span class="z-storage z-type z-function z-shell">function</span> <span class="z-entity z-name z-function z-shell">powerline_precmd</span><span class="z-punctuation z-section z-parens z-begin z-shell">(</span><span class="z-punctuation z-section z-parens z-end z-shell">)</span> <span class="z-punctuation z-section z-braces z-begin z-shell">{</span>
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-variable z-other z-readwrite z-assignment z-shell">PS1</span><span class="z-keyword z-operator z-assignment z-shell">=</span><span class="z-string z-unquoted z-shell"><span class="z-string z-quoted z-double z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">"</span><span class="z-meta z-group z-expansion z-command z-parens z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-parens z-begin z-shell">(</span><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">/usr/bin/powerline-go</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>error</span> <span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-variable z-language z-shell">?</span></span><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>jobs</span> <span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-expansion z-parameter z-begin z-shell">{</span></span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-variable z-other z-readwrite z-shell"><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-definition z-variable z-shell">$</span><span class="z-punctuation z-section z-expansion z-parameter z-begin z-shell">{</span></span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-variable z-other z-readwrite z-shell">(<span class="z-keyword z-operator z-expansion z-shell">%</span></span></span><span class="z-meta z-group z-expansion z-parameter z-shell">):%j</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-section z-expansion z-parameter z-end z-shell">}</span></span></span></span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-keyword z-operator z-assignment z-shell">:-</span></span><span class="z-meta z-group z-expansion z-parameter z-shell">0</span><span class="z-meta z-group z-expansion z-parameter z-shell"><span class="z-punctuation z-section z-expansion z-parameter z-end z-shell">}</span></span></span><span class="z-punctuation z-section z-parens z-end z-shell">)</span></span><span class="z-punctuation z-definition z-string z-end z-shell">"</span></span></span>
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell">
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> Uncomment the following line to automatically clear errors after showing</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> them once. This not only clears the error for powerline-go, but also for</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> everything else you run in that shell. Don't enable this if you're not</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell"> sure this is what you want.</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell">
</span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"> <span class="z-comment z-line z-number-sign z-shell"><span class="z-punctuation z-definition z-comment z-begin z-shell">#</span></span><span class="z-comment z-line z-number-sign z-shell">set "?"</span><span class="z-comment z-line z-number-sign z-shell">
</span></span></span><span class="z-source z-shell z-bash"><span class="z-meta z-function z-shell"><span class="z-punctuation z-section z-braces z-end z-shell">}</span></span>
</span></code></pre>
<p>If you'd like to have your prompt start in a newline, like I have in the
screenshot above, you just need to set <code>-newline</code> in the powerline-go
invocation in your <code>.bashrc</code>/<code>.zshrc</code>.</p>
<h2 id="6-gnome-system-monitor-extension">6) Gnome System Monitor Extension</h2>
<p>Tips number 6 and 7 are for Gnome users.</p>
<p>Gnome is now shipping a system monitor extension which lets you get a glance of
the current load of your machine from the top bar.</p>
<img src="gnome_system_monitor_extension.webp" alt="Screenshot of the top
bar of Gnome with the system monitor extension enabled, showing the load of:
CPU, memory, network and disk" width="1537" height="59" loading="lazy" />
<p>I've found this quite useful for machines where I'm required to install
third-party monitoring software that tends to randomly consume more resources
than it should. If I feel like my machine is struggling, I can quickly glance
at its load to verify if it's getting overloaded by some process.</p>
<p>The extension is not as complete as
<a rel="noopener" target="_blank" href="https://extensions.gnome.org/extension/3010/system-monitor-next/">system-monitor-next</a>,
not showing temperatures or histograms, but at least it's officially part of
Gnome, easy to install and supported by them.</p>
<p>Try it out:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> apt install gnome-system-monitor gnome-shell-extension-manager</span>
</span></code></pre>
<p>And then enable the extension from the "Extension Manager" application.</p>
<h2 id="7-gnome-setting-for-battery-charging-profile">7) Gnome setting for battery charging profile</h2>
<p>After having to learn more about batteries in order to get into FPV drones,
I've come to have a bigger appreciation for solutions that minimize the
inevitable loss of capacity that accrues over time.</p>
<p>There's now a "Battery Charging" setting (under the "Power") section which lets
you choose between two different profiles: "Maximize Charge" and "Preserve
Battery Health".</p>
<img src="gnome_battery_charging.png" alt="A screenshot of the Gnome
settings for Power showing the options for Battery Charging" width="1648" height="1104" loading="lazy" />
<p>On supported laptops, this setting is an easy way to set thresholds for when
charging should start and stop, just like you could do it with the <code>tlp</code> package,
but now from the Gnome settings.</p>
<p>To increase the longevity of my laptop battery, I always keep it at "Preserve
Battery Health" unless I'm traveling.</p>
<p>What I would like to see next is support for choosing different "Power Modes"
based on whether the laptop is plugged-in, and based on the battery
charge percentage.</p>
<p>There's a <a rel="noopener" target="_blank" href="https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/715">GNOME
issue</a>
tracking this feature, but there's some pushback on whether this is the right
thing to expose to users.</p>
<p>In the meantime, there are some workarounds mentioned in that issue which
people who really want this feature can follow.</p>
<p>If you would like to learn more about batteries; <a rel="noopener" target="_blank" href="https://batteryuniversity.com">Battery
University</a> is a great starting point, besides
getting into FPV drones and being forced to handle batteries without a Battery
Management System (BMS).</p>
<p>And if by any chance this sparks your interest in FPV drones, Joshua Bardwell's
YouTube channel is a great resource:
<a rel="noopener" target="_blank" href="https://www.youtube.com/@JoshuaBardwell">@JoshuaBardwell</a>.</p>
<h2 id="8-lazygit">8) Lazygit</h2>
<p>Emacs users are already familiar with the legendary <code>magit</code>; a terminal-based
UI for git.</p>
<p>Lazygit is an alternative for non-emacs users, you can integrate it with neovim
or just use it directly.</p>
<p>I'm still playing with <code>lazygit</code> and haven't integrated it into my workflows,
but so far it has been a pleasant experience.</p>
<img src="lazygit.webp" alt="Screenshot of lazygit from the Debian curl
repository, showing a selected commit and its diff, besides the other things
from the lazygit UI" width="1000" height="634" loading="lazy" />
<p>You should check out the demos from the <a rel="noopener" target="_blank" href="https://github.com/jesseduffield/lazygit">lazygit GitHub
page</a>.</p>
<p>Try it out:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> apt install lazygit</span>
</span></code></pre>
<p>And then call <code>lazygit</code> from within a git repository.</p>
<h2 id="9-neovim">9) neovim</h2>
<p>neovim has been shipped in Debian since 2016, but upstream has been doing a lot of
work to improve the experience out-of-the-box in the last couple of years.</p>
<p>If you're a neovim poweruser, you're likely not installing it from the official
repositories, but for those that are, Debian 13 comes with version 0.10.4,
which brings the following improvements compared to the version in Debian 12:</p>
<ul>
<li>
<p>Treesitter support for C, Lua, Markdown, with the possibility of adding any
other languages as needed;</p>
</li>
<li>
<p>Better spellchecking due to treesitter integration (spellsitter);</p>
</li>
<li>
<p>Mouse support enabled by default;</p>
</li>
<li>
<p>Commenting support out-of-the-box;</p>
<p>Check <code>:h commenting</code> for details, but the
tl;dr is that you can use <code>gcc</code> to comment the current line and <code>gc</code> to comment
the current selection.</p>
</li>
<li>
<p>OSC52 support.</p>
<p>Especially handy for those using neovim over an ssh
connection, this protocol lets you copy something from within the neovim
process into the clipboard of the machine you're using to connect through ssh.
In other words, you can copy from neovim running in a host over ssh and paste
it in the "outside" machine.</p>
</li>
</ul>
<h2 id="10-bonus-running-old-debian-releases">10) [Bonus] Running old Debian releases</h2>
<p>The bonus tip is not specific to the Debian 13 release, but something I've
recently learned in the <code>#debian-devel</code> IRC channel.</p>
<p>Did you know there are usable container images for all past Debian releases?
I'm not talking "past" as in "some of the older releases", I'm talking past as
in "literally every Debian release, including the very first one".</p>
<p>Tianon Gravi "tianon" is the Debian Developer responsible for making this
happen, kudos to him!</p>
<p>There's a small gotcha that the releases Buzz (1.1) and Rex (1.2) require a
32-bit host, otherwise you will get the error <code>Out of virtual memory!</code>, but
starting with Bo (1.3) all should work in amd64/arm64.</p>
<p>Try it out:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> apt install podman</span>
</span><span class="z-source z-shell z-bash">
</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">podman</span></span><span class="z-meta z-function-call z-arguments z-shell"> run<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>it</span> docker.io/debian/eol:bo</span>
</span></code></pre>
<p>Don't be surprised when noticing that <code>apt/apt-get</code> is not available inside the
container, that's because <code>apt</code> first appeared in Debian Slink (2.1).</p>
<h1 id="changes-since-publication">Changes since publication</h1>
<h2 id="2025-08-30">2025-08-30</h2>
<ul>
<li>Mention that Arch also enabled HTTP/3.</li>
</ul>
DebConf24 was fun! Security, curl, wcurl, Debian's quality
2024-09-04T00:00:00+00:00
2024-09-04T00:00:00+00:00
Unknown
https://samueloph.dev/blog/debconf24-was-fun/
<img src="debconf24_was_fun.webp" alt="A picture of a badger2040w with
Samuel's badge and the curl manpage PCB on the side" width="1200" height="630" loading="lazy" />
<h4 id="tl-dr">tl;dr</h4>
<p><a rel="noopener" target="_blank" href="https://debconf24.debconf.org/">DebConf24</a> was fun!</p>
<p>A playlist of all of my talks, with subtitles (en, pt-br) and chapters is
available on <a rel="noopener" target="_blank" href="https://youtube.com/playlist?list=PLKGG29PjeLnYeao03jWWH0eaRC5htIg1E&si=3Hwrl5WHFFM2IaSO">YouTube</a>.</p>
<h1 id="overview">Overview</h1>
<p>DebConf24 was held in Busan, South Korea, between Sunday July 28th to Sunday August 4th 2024.</p>
<p>As usual for DebConfs, I had a great time meeting my friends, but also met new
people and got to learn a bit about the interesting things they're working on.</p>
<p>I ended up getting too excited during the talk submission stage of the
conference and as a result I presented 5 different activities (3 talks, 1 BoF
and 1 lightning talk).</p>
<p>Since I was too busy with the presentations, I did not have a lot of time to
actually hang out with folks, or even to go out in the city, I guess I've
learned my lesson for next time.</p>
<p>The main purpose of this post is to write about all of the things I presented
at the conference. I did want to list some of the interesting talks I've
watched, but that I would not be able to be fair as I'm sure I would miss some.</p>
<p>You can get the schedule and the recordings of any talks from the conference's website:
<a rel="noopener" target="_blank" href="https://debconf24.debconf.org/schedule/">https://debconf24.debconf.org/schedule/</a></p>
<h1 id="wcurl-lightning-talk">wcurl Lightning Talk</h1>
<p>The most fun of my presentations, during the second-to-last day of the
conference, I've asked for help from Sergio Durigan Junior <sergiodj> to
setup an URL containing a whitespace and redirecting that to <a rel="noopener" target="_blank" href="https://curl.se/wcurl/">wcurl</a>'s
manpage.</p>
<p>I then did a little demo to showcase why me (and a lot others) struggle
with downloading things with curl, and how <a rel="noopener" target="_blank" href="https://curl.se/wcurl/">wcurl</a> solves that.</p>
<p><a rel="noopener" target="_blank" href="https://www.youtube.com/watch?v=eM8M5qa4pPM">https://www.youtube.com/watch?v=eM8M5qa4pPM</a>
<div class="yv">
<iframe src="https://www.youtube-nocookie.com/embed/eM8M5qa4pPM" title="Youtube" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
</p>
<h1 id="fixing-cves-on-debian-everything-you-probably-know-already">Fixing CVEs on Debian: Everything you probably know already</h1>
<p>I've always felt like DebConf was missing security-related talks, so I decided
to do something about it and presented a few of the things I've learned when
fixing CVEs for Debian.</p>
<p>This is an area where we don't get a lot of new contributors, I'm trying to
change that, and this talk can be used to introduce newcomers to it.</p>
<p><a rel="noopener" target="_blank" href="https://www.youtube.com/watch?v=XzNVVILVyUM">https://www.youtube.com/watch?v=XzNVVILVyUM</a>
<div class="yv">
<iframe src="https://www.youtube-nocookie.com/embed/XzNVVILVyUM" title="Youtube" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
</p>
<h1 id="the-secret-sauce-of-debian">The secret sauce of Debian</h1>
<p>Debian is not very vocal about all of the nice things it has regarding
quality-assurance, testing, or CI, even though it's at the state-of-the-art for
a lot of things.</p>
<p>This talk is an initial step towards making people aware of the cool
things happening behind the scenes. Ideally we should have it
well-documented somewhere.</p>
<p><a rel="noopener" target="_blank" href="https://www.youtube.com/watch?v=x_X2IBnpjic">https://www.youtube.com/watch?v=x_X2IBnpjic</a>
<div class="yv">
<iframe src="https://www.youtube-nocookie.com/embed/x_X2IBnpjic" title="Youtube" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
</p>
<h1 id="i-use-debian-btw-fzf-tmux-zoxide-and-friends">"I use Debian BTW": fzf, tmux, zoxide and friends</h1>
<p>One of my earliest good memories of Debian was when it started coming with a
colored PS1 by default, I still remember the feeling of relief whenever I
jumped into a Debian server and didn't have to deal with a black and white PS1.</p>
<p>There's still a lot of room for Debian to ship better defaults, and I think
some of them can actually happen.</p>
<p>This talk is a bit of a silly one where I'm just making people aware of the
existence of a few Golang/Rust CLI tools, and also some dotfiles configurations
that should probably be the default.</p>
<p><a rel="noopener" target="_blank" href="https://www.youtube.com/watch?v=tfto3Seokn4">https://www.youtube.com/watch?v=tfto3Seokn4</a>
<div class="yv">
<iframe src="https://www.youtube-nocookie.com/embed/tfto3Seokn4" title="Youtube" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
</p>
<h1 id="curl">curl</h1>
<p>The curl project does such a great job with their security advisories that it
will likely never receive the amount of praise it deserves, but I did my best
at mentioning it throughout my <a rel="noopener" target="_blank" href="https://www.youtube.com/watch?v=XzNVVILVyUM">CVEs talk</a>.</p>
<p><strong>Maybe I will write more extensively about this someday, but in case I don't:</strong></p>
<hr />
<p>There's no other project which always consistently mentions the exact range of
commits that are affected by a given CVE.</p>
<p>Forget about whether the versions are EOL, curl doesn't have LTS releases, yet
they do such a great job at clearly documenting their CVEs that I would take
that over having LTS releases anytime (that's for curl at least, I
acknowledge some types of projects have a different need for LTS
releases).</p>
<p>Not only that, but they are also always careful about explaining alternative
mitigations such as configuration changes, build flags that defuse the
exploitation, or parameters that you should not use.</p>
<hr />
<p>Just like we tend to do every time we meet, me and the other Debian curl
maintainers spent the first 2 or 3 days of the conference talking about how we
wanted to eventually meet up to discuss the package.</p>
<p>It was going to be informal, maybe during the <a rel="noopener" target="_blank" href="https://debconf24.debconf.org/about/cheese-and-wine-party/">Cheese and Wine
party</a>, but then
I've realized we should make it part of the official schedule, which would
also give us the recordings for later.</p>
<p>And so the "curl maintainers BoF" happened, where we spoke about HTTP3,
GnutTLS, <a rel="noopener" target="_blank" href="https://curl.se/wcurl/">wcurl</a> and other things.</p>
<p><a rel="noopener" target="_blank" href="https://www.youtube.com/watch?v=fL7hSypUTdM">https://www.youtube.com/watch?v=fL7hSypUTdM</a>
<div class="yv">
<iframe src="https://www.youtube-nocookie.com/embed/fL7hSypUTdM" title="Youtube" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
</p>
<h1 id="wcurl">wcurl</h1>
<p>Right after that BoF, Daniel Stenberg
<a rel="noopener" target="_blank" href="https://curl.se/mail/archive-2024-08/0000.html">asked</a> if we were interested
in having <a rel="noopener" target="_blank" href="https://curl.se/wcurl/">wcurl</a> adopted into curl, which we
definitely were, so <a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2024/08/08/curl-welcomes-wcurl-to-the-team/">wcurl is now part of the curl
project</a>.</p>
<p>Daniel was also kind enough to design a logo for the project, which makes me
especially happy because I can stop with my own approach at a logo (which I had
to redo every few days):</p>
<img src="wcurl_draft_logo.webp" alt="A laptop with a curl and a GoHorse
sticker, there's a 'w' handwritten with a marker on the right side of the curl
sticker, making it 'wcurl'" width="700" height="699" loading="lazy" />
<p>And here is the new logo:</p>
<img src="wcurl_logo.svg" alt="'wcurl' written with the same font and
colors as the curl logo, with the 'w' being green instead of blue, and a
download icon at the end" width="998" height="250" loading="lazy" />
<p>Much better, I would say :)</p>
<h1 id="curl-swag">curl Swag</h1>
<p>DebConf24 was my chance at forwarding some curl swag items to the other
curl maintainers, so both Sergio Durigan Junior <sergiodj> and Carlos
Henrique Lima Melara <charles> got the <a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2024/05/06/i-survived-curl-up-2024">curl-up
t-shirt</a>
and the very cool <a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2023/11/03/curl-coasters/">curl PCB
coaster</a>, both gifted
by Daniel Stenberg.</p>
<p>Unfortunately I didn't have any of that for DebConf attendees, but I did drop
loads of curl stickers at the stickers table, they were gone very quickly.</p>
<img src="debconf24_curl_stickers.webp" alt="A table full of different
stickers, curl stickers can be seen over the whole table" width="450" height="800" loading="lazy" />
<h1 id="for-the-future">For the future</h1>
<p>I used to think the most humbling experience you could have as someone who presented
a talk was to have to watch it yourself, you notice a lot of mistakes and
you instantly think about things that should be done differently.</p>
<p>It turns out the most humbling thing to do is actually to write subtitles for
your talks, I noticed every single mistake, often multiple times.</p>
<p>So after spending more than 30 hours writing the subtitles for both English and
Brazilian Portuguese for my talks, I feel like it's going to be much easier to
avoid committing the same mistakes again. After some time you stop feeling shame
about those mistakes and you're just left with feelings of annoyance, and at
that point it becomes easier to consciously avoid them.</p>
<p>I am collecting a list of things I wish I had done differently on all of those
talks, so if I end up presenting any one of them again, it will be an improved
version.</p>
<p> <img src="debconf24_group_photo.webp" alt="A picture from the top of a
group of conference attendees, there's about 150 people in the picture" width="1484" height="1024" loading="lazy" />
Photography: Aigars Mahinovs <aigaruius@debian.org><br />
License: CC-BYv3+ or GPLv2+</p>
Debian's curl now supports HTTP3
2024-07-04T00:00:00+00:00
2024-07-04T00:00:00+00:00
Unknown
https://samueloph.dev/blog/debian-curl-now-supports-http3/
<h4 id="tl-dr">tl;dr</h4>
<p>Starting with <strong>curl 8.0.0-2</strong>, you can now use HTTP3.</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">curl</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> --</span>http3-only</span> https://example.com</span>
</span></code></pre>
<p>Or, if you would like to try it out in a container:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">podman</span></span><span class="z-meta z-function-call z-arguments z-shell"> run debian:testing /bin/bash<span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>c</span> <span class="z-string z-quoted z-single z-shell"><span class="z-punctuation z-definition z-string z-begin z-shell">'</span>apt install --update -y curl && curl --http3-only https://example.com<span class="z-punctuation z-definition z-string z-end z-shell">'</span></span></span>
</span></code></pre>
<p><em>(in case you haven't noticed, apt now has the <code>--update</code> option for the
<code>upgrade</code> and <code>install</code> commands, although not available on stable yet)</em></p>
<h5 id="availability">Availability</h5>
<ul>
<li>Debian unstable - Since 2024-07-02</li>
<li>Debian testing - Since 2024-07-18</li>
<li>Debian 12/bookworm-backports - Since 2024-08-25</li>
<li>Debian 12/bookworm - Due to the mechanisms we have in place to make sure
Debian stable is in fact stable, we will never be able to ship this in the
regular repository. Users can make use of the
<a rel="noopener" target="_blank" href="https://backports.debian.org/">backports</a> repositories instead.</li>
<li>Debian derivatives - Rolling releases will get it by the time it's on Debian
testing (e.g.: Kali Linux). Stable derivatives only in their next major release.</li>
</ul>
<h1 id="the-challenge">The challenge</h1>
<p>HTTP3 is fresh new, well... not really, but at least fresh enough that I'm not
aware of any other Linux distribution supporting it on curl, the reason is
likely two-fold:</p>
<ol>
<li><h3 id="openssl-is-not-there-yet">OpenSSL is not there yet</h3>
<p>OpenSSL still doesn't have proper HTTP3 support, and given that OpenSSL is so
widely used, almost every curl distributor/packager will build curl with it
and thus changing the TLS backend to something else is risky.</p>
<p>Unfortunately, proper support for the OpenSSL libcurl is unlikely to come anytime
before the end of this year, the OpenSSL performance is <a rel="noopener" target="_blank" href="https://curl.se/mail/distros-2024-04/0001.html">not good enough
yet as of version 3.3</a>.</p>
<p>Daniel Stenberg has written about the state of this multiple times, most
recently at <a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2024/06/10/http-3-in-curl-mid-2024/">HTTP/3 in curl mid
2024</a>, if
you're interested, I suggest reading through his other posts as well.</p>
<p>Some might have noticed that nginx <a rel="noopener" target="_blank" href="http://nginx.org/en/docs/quic.html">does support HTTP3 through OpenSSL</a>,
although when you look closely, it's not exactly perfect:</p>
<blockquote>
<p>An SSL library that provides QUIC support is recommended to build nginx, such as BoringSSL, LibreSSL, or QuicTLS. Otherwise, the OpenSSL compatibility layer will be used that does not support early data.</p>
</blockquote>
<p>As you can see, they don't recommend using OpenSSL, and when doing so, you don't get complete support.</p>
</li>
<li><h3 id="http3-support-for-gnutls-nghttp3-ngtcp2-is-recent">HTTP3 support for GnuTLS/nghttp3/ngtcp2 is recent</h3>
<p>The non-experimental support arrived <a rel="noopener" target="_blank" href="https://github.com/curl/curl/commit/5f78cf503c786a1d48d13528dde038bccfa6c67c">back in October
2023</a>,
and so that's when I started seriously planning for this.</p>
<p>curl has been working on HTTP3 support for years, and so it did support other
TLS backends before that, but out of them, the one most feasible for a
distribution to ship would be GnuTLS, which gets HTTP3 support <a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2024/06/10/http-3-in-curl-mid-2024/">through ngctp2 and
nghttp3</a>.</p>
</li>
</ol>
<h1 id="how-it-was-done">How it was done</h1>
<p>The Debian curl package has historically shipped at least two variants of libcurl, an
OpenSSL and a GnuTLS one.</p>
<p>The OpenSSL libcurl can't support HTTP3 for the reasons explained above, but
the GnuTLS libcurl can (with ngtcp2 and nghtp3).</p>
<p>Debian packages can choose which version of libcurl to link against (without
having to modify any upstream source code). Debian's "git" package being a famous
example of a package that links against the GnuTLS libcurl.</p>
<p>Enabling HTTP3 on curl was done in three steps:</p>
<ol>
<li>Make sure all required dependencies fulfill the minimum requirements.</li>
<li>Enable HTTP3 for GnuTLS libcurl.</li>
<li>Change the libcurl used by the curl CLI, from OpenSSL to GnuTLS.</li>
</ol>
<p>curl's HTTP3 support requires a somewhat recent version of nghttp3 and
updating that required a <a rel="noopener" target="_blank" href="https://wiki.debian.org/Teams/ReleaseTeam/Transitions">transition</a> (due to the SONAME bump), while we've also
had months of freeze for transitions due to the <a rel="noopener" target="_blank" href="https://lists.debian.org/debian-devel-announce/2024/02/msg00000.html">time_t
transition</a>.</p>
<p>After the dependencies were in place, enabling HTTP3 for the GnuTLS libcurl was
<a rel="noopener" target="_blank" href="https://salsa.debian.org/debian/curl/-/commit/51df321b0165e5164a0d898d23a64ca3bbd553c0">straightforward</a>.</p>
<p>Then, for the last part, we had to switch the TLS backend used by the curl CLI.
Doing the swap is also <a rel="noopener" target="_blank" href="https://salsa.debian.org/debian/curl/-/commit/37820dad3612d1b13a9fb9550b1726b998c80cfc">quite
easy</a>
on the packaging level, but we have to consider the chances of this change
breaking our users' environments.</p>
<h1 id="ensuring-there-are-no-breakages">Ensuring there are no breakages</h1>
<p>The first thing to consider regarding breakages is that this change is not
going to be pushed directly to the current Debian stable releases, it will be
present in the next stable release (13/trixie) but the current one will stick to the
version that's already shipped.</p>
<p>Secondly, we have to consider the risk of losing the ability to use certain
parameters from the curl CLI which could be limited to the OpenSSL backend.
During <a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2024/05/06/i-survived-curl-up-2024/">curl-up 2024</a>, the curl developers pointed out the existence of a page
that lists the <a rel="noopener" target="_blank" href="https://curl.se/libcurl/c/tls-options.html">TLS related options and the backends they work
with</a>.</p>
<p>Analysing that page, ignoring all of the options that are suffixed with "BLOB"
(only pertinent to the library, not the CLI), the only one left which is
attention worthy is <a rel="noopener" target="_blank" href="https://curl.se/libcurl/c/CURLOPT_ECH.html">CURLOPT_ECH</a>.</p>
<blockquote>
<p>This experimental feature requires a special build of OpenSSL, as ECH is not
yet supported in OpenSSL releases. In contrast ECH is supported by the latest
BoringSSL and wolfSSL releases.</p>
</blockquote>
<p>As it turns out, <code>Encrypted Client Hello</code> is experimental and it's not
supported by the vanilla OpenSSL.</p>
<p>This was enough of an investigation for me to go ahead with the change. Noting
that even in the worst case scenario (we find a horrible regression), we can
rollback without having affected a single stable release.</p>
<p>Now that the package is on Debian unstable, the CI tests (autopkgtest) of every
package that depends on curl is currently running, the results are compared
against the migration-reference (in this case, the curl CLI with OpenSSL,
before the change).</p>
<p>If everything goes right, curl with HTTP3 support will migrate to Debian
testing in around 5 days. If we spot any issues, we'll have to solve them
first and it's going to be hard to predict how long it takes, although it's
fair to expect less than a month.</p>
<h1 id="feedback">Feedback</h1>
<p>Feel free to join the Matrix room for the Debian curl maintainers:<br />
<a rel="noopener" target="_blank" href="https://matrix.to/#/#debian-curl-maintainers:matrix.org">https://matrix.to/#/#debian-curl-maintainers:matrix.org</a></p>
<h1 id="acknowledgements">Acknowledgements</h1>
<p>It took us a bit longer than expected to be able to enable HTTP3, nonetheless it's
still early enough to be excited about.</p>
<p>A lot of people were crucial to make this happen.</p>
<p>I should recognize in the first place, obviously, the curl developers and the
developers of the supporting libraries: GnuTLS, nghttp3, ngtcp2. Participating
in the <a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2024/05/06/i-survived-curl-up-2024/">curl-up
2024</a>
conference helped me get motivated to push this through, besides becoming aware
of the right documentation to research for impact.</p>
<p>On the Debian side, Sakirnth Nagarasa <sakirnth> was responsible for updating
and taking care of the transition for nghttp3 and ngtcp2.</p>
<p>Also on the Debian side, I've got loads of help and support from the
co-maintainers of the curl package: Sergio Durigan Junior <sergiodj> and Carlos
Henrique Lima Melara <charles>.</p>
<h1 id="changes-since-publication">Changes since publication</h1>
<h2 id="2025-03-08">2025-03-08</h2>
<ul>
<li>Fix podman command, the previous one was not running all commands inside the container.</li>
<li>Change the podman command to use Debian testing instead of unstable.</li>
</ul>
<h2 id="2024-08-28">2024-08-28</h2>
<ul>
<li>Mention availability in bookworm-backports.</li>
</ul>
<h2 id="2024-07-18">2024-07-18</h2>
<ul>
<li>Update date of availability for Debian testing and expected date for bookworm-backports.</li>
<li>Remove mention of language spoken in the Matrix room, we are using English now.</li>
</ul>
Announcing wcurl: a curl wrapper to download files
2024-07-03T00:00:00+00:00
2024-07-03T00:00:00+00:00
Unknown
https://samueloph.dev/blog/announcing-wcurl-a-curl-wrapper-to-download-files/
<div class="yv">
<iframe src="https://www.youtube-nocookie.com/embed/eM8M5qa4pPM" title="Youtube" class="yvi" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<h4 id="tl-dr">tl;dr</h4>
<p>Whenever you need to download files through the terminal and don't feel like using wget:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">wcurl</span></span><span class="z-meta z-function-call z-arguments z-shell"> example.com/filename.txt</span>
</span></code></pre>
<p>Manpage:<br />
<a rel="noopener" target="_blank" href="https://curl.se/wcurl/manual.html">https://curl.se/wcurl/manual.html</a></p>
<h5 id="availability-comes-installed-with-the-curl-package">Availability (comes installed with the curl package):</h5>
<ul>
<li>Debian unstable - Since 2024-07-02</li>
<li>Debian testing - Since 2024-07-18</li>
<li>Debian 12/bookworm-backports - Since 2024-08-25</li>
<li>Debian 12/bookworm - Due to the way changes are planned for Debian Stable,
wcurl will not be present in bookworm. Users are recommended to either manually
download wcurl or use the bookworm-backports repository. wcurl will be present
in Debian 13/trixie.</li>
<li>Debian derivatives - Rolling releases will get it by the time it's on Debian
testing (e.g.: Kali Linux). Stable derivatives only in their next major release.</li>
</ul>
<p>If you don't want to wait for the package update to arrive, you can always copy
the script and place it in your <code>/usr/bin</code>:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">curl</span></span><span class="z-meta z-function-call z-arguments z-shell"><span class="z-variable z-parameter z-option z-shell"><span class="z-punctuation z-definition z-parameter z-shell"> -</span>fLO</span> https://github.com/curl/wcurl/releases/latest/download/wcurl</span>
</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">chmod</span></span><span class="z-meta z-function-call z-arguments z-shell"> +x wcurl</span>
</span><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">sudo</span></span><span class="z-meta z-function-call z-arguments z-shell"> mv wcurl /usr/bin/wcurl</span>
</span></code></pre>
<p>After this announcement, wcurl has joined the curl organization:<br />
<a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2024/08/08/curl-welcomes-wcurl-to-the-team/">https://daniel.haxx.se/blog/2024/08/08/curl-welcomes-wcurl-to-the-team/</a></p>
<p>Project homepage:<br />
<a rel="noopener" target="_blank" href="https://curl.se/wcurl/">https://curl.se/wcurl/</a></p>
<h1 id="smoother-cli-experience">Smoother CLI experience</h1>
<p>Starting with <strong>curl version 8.8.0-2</strong>, the Debian's curl package now ships a wcurl
executable.</p>
<p>wcurl is the solution for those who just need to download files without having
to remember curl's parameters for things like automatically naming the files.</p>
<p>Some people, myself included, would fall back to using wget whenever there was a
need to download a file. Sometimes even installing wget just for that usecase.
After all, it's easier to remember "apt install wget" rather than "curl -L -O -C - ...".</p>
<p>wcurl consists of a simple shell script that provides sane defaults for the curl
invocation, for when the use case is to just download files.</p>
<p>By default, wcurl will:</p>
<blockquote>
<ul>
<li>Percent-encode whitespaces in URLs;</li>
<li>Download multiple URLs in parallel if the installed curl's version is >= 7.66.0;</li>
<li>Follow redirects;</li>
<li>Automatically choose a filename as output;</li>
<li>Avoid overwriting files if the installed curl's version is >= 7.83.0 (--no-clobber);</li>
<li>Perform retries;</li>
<li>Set the downloaded file timestamp to the value provided by the server, if available;</li>
<li>Disable curl's URL globbing parser so {} and [] characters in URLs are not treated specially;</li>
<li>Percent-decode the resulting filename;</li>
<li>Use "index.html" as default filename if there's none in the URL.</li>
</ul>
</blockquote>
<p>Example to download a single file:</p>
<pre data-lang="bash" class="language-bash z-code"><code class="language-bash" data-lang="bash"><span class="z-source z-shell z-bash"><span class="z-meta z-function-call z-shell"><span class="z-variable z-function z-shell">wcurl</span></span><span class="z-meta z-function-call z-arguments z-shell"> example.com/filename.txt</span>
</span></code></pre>
<p>If you ever need to set a custom flag, you can make use of the <code>--curl-options</code>
wcurl option, anything set there will be passed to the curl invocation.
Just beware that if you need to set any custom flags, it's likely you will be
better served by calling curl directly. The <code>--curl-options</code> option is there to
allow for some flexibility in unforeseen circumstances.</p>
<h1 id="the-need-for-wcurl">The need for wcurl</h1>
<p>I've always felt a bit ashamed of not remembering curl's parameters for
downloading a file and automatically naming it, having resorted to wget most of
the times this was needed (even installing wget when it wasn't there, just for
this). I've spoken to a few other experienced people I know and confirmed what
could be obvious to others: a lot of people struggle with this.</p>
<p>Recently, the curl project released the results of <a rel="noopener" target="_blank" href="https://daniel.haxx.se/media/curl-user-survey-2024-analysis.pdf">2024's curl
survey</a>, which
also showed this is as a much needed feature, just look at some of the answers:</p>
<h4 id="q-which-curl-command-line-option-do-you-think-needs-improvement-and-how">Q: Which curl command line option do you think needs improvement and how?</h4>
<blockquote>
<p>-O, I really want wget like functionality where I don't have to specify the name</p>
</blockquote>
<blockquote>
<p>Downloading a file (like wget) could be improved - with automatic naming of the file</p>
</blockquote>
<blockquote>
<p>downloading files - wget is much cleaner</p>
</blockquote>
<blockquote>
<p>I wish the default behaviour when GETting a binary was to drop it on disk. That's the only
reason 'wget foo.tgz" is still ingrained in my muscle memory .</p>
</blockquote>
<blockquote>
<p>Maybe have a way to download without specifying something in -o (the only reason i used wget
still)</p>
</blockquote>
<blockquote>
<p>--remote-time should be default</p>
</blockquote>
<blockquote>
<p>--remote-name-all could really use a short flag</p>
</blockquote>
<h4 id="q-if-you-miss-support-for-something-tell-us-what">Q: If you miss support for something, tell us what!</h4>
<blockquote>
<p>"Write the data to the file named in the URL (or in redirects if I'm feeling daring), and
timestamp the file to the last-modified-date". This is the main reason I'm still using wget.</p>
</blockquote>
<p>I can finally feel less bad about falling back to wget due to not remembering the
parameters I want.</p>
<h1 id="idealization-vs-reality">Idealization vs. reality</h1>
<p>I don't believe curl will ever change its default behavior in such a way that
would accommodate this need, as that would have a side-effect of breaking things
which expect the current behavior (the blast radius is literally the
<a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2021/12/03/why-curl-is-used-everywhere-even-on-mars/">solar system</a>).</p>
<p>This means a new executable needs to be shipped side-by-side with curl, an
opportunity to start fresh and work with a more focused use case (to download
files).</p>
<p>Ideally, this new executable would be maintained by the curl project, make use
of libcurl under-the-hood, and be available everywhere. Nobody wants to worry
if their systems have the tool or not, it should always be there.</p>
<p>Given I'm just a Debian Developer, with not as much free time as I wish, I've
decided to write a simple shell script wrapper calling the curl CLI
under-the-hood.</p>
<p>wcurl will come installed with the curl package from now on, and I will check
with the release team about shipping it on the current Debian stable as well.
Shipping wcurl in other distros will be up to them (Debian-derivatives should
pick it up automatically, though).</p>
<p>We've tried to make it easy for anyone to ship this by using the curl license,
keeping the script POSIX-compliant, and shipping a <a rel="noopener" target="_blank" href="https://manpages.debian.org/unstable/curl/wcurl.1.en.html">manpage</a>.</p>
<p>Maybe if there's enough interest across distributions, someone might sign up
for implementing this in upstream curl and increase its reach. I would be happy
with the curl project reusing the wcurl name when that happens. It's unlikely
that wcurl would be shipped by curl upstream as it is, assuming they would
prefer a solution that uses libcurl direclty (more similar to curl the CLI, to
maintain).</p>
<p>In the worst case, wcurl becomes a Debian-specific tool that only a few people
are aware of, in the best case, it becomes the new go-to CLI tool for simply
downloading files. I would be happy if at least someone other than me finds
it useful.</p>
<h1 id="naming-is-hard">Naming is hard</h1>
<p>When I started working on it, I was calling the new executable "curld"
(stands for "curl download"), but then when discussing this in one of our
weekly calls in the Debian BrasÃlia community, it was mentioned that this could
be confused for a daemon.</p>
<p>We then settled for the name "wcurl", suggested by Carlos Henrique Lima
Melara <charles>. It doesn't really stand for anything,
but it's very easy to remember.</p>
<p>You know... "it's that wget alternative for when you want to use curl instead"
:)</p>
<h1 id="feedback">Feedback</h1>
<p>The code is hosted in GitHub, feel free to open an issue to provide feedback.<br />
<a rel="noopener" target="_blank" href="https://github.com/curl/wcurl">https://github.com/curl/wcurl</a></p>
<p>We also have a Matrix room for the Debian curl maintainers:<br />
<a rel="noopener" target="_blank" href="https://matrix.to/#/#debian-curl-maintainers:matrix.org">https://matrix.to/#/#debian-curl-maintainers:matrix.org</a></p>
<h1 id="acknowledgments">Acknowledgments</h1>
<p>The idea for wcurl came a few days before the <a rel="noopener" target="_blank" href="https://daniel.haxx.se/blog/2024/05/06/i-survived-curl-up-2024/">curl-up conference
2024</a>.
I've been thinking a lot about developer productivity in the terminal lately,
different tools and better defaults. Before curl-up, I was also thinking about
packaging improvements for the curl package. I don't remember what exactly
happened, but I likely had to download something and felt a bit ashamed of
maintaining curl and not remembering the parameters to download files the way I
wanted.</p>
<p>I first discussed this idea in the conference, where I asked the
participants about it and there were no concerns raised, and some people said I should give it a go.
Participating in curl-up was a really great experience and I'm thankful for the
interactions I've had there.</p>
<p>On the Debian side, I've got reviews of the code and manpage by Sergio Durigan
Junior <sergiodj>, Guilherme Puida Moreira <puida> and Carlos Henrique Lima
Melara <charles>. Sergio ended up rewriting the tool to be POSIX-compliant (my
version was written in bash), so he takes all the credit for the portability.</p>
<h1 id="changes-since-publication">Changes since publication</h1>
<h2 id="2025-01-19">2025-01-19</h2>
<ul>
<li>Mention that wcurl will not be added to Debian 12/bookworm, it will be
present in Debian 13/trixie.</li>
</ul>
<h2 id="2024-12-14">2024-12-14</h2>
<ul>
<li>Update list of wcurl features.</li>
<li>Point out to wcurl homepage and mention that it's now part of curl.</li>
<li>Reorder this changelog to have latest changes on top.</li>
</ul>
<h2 id="2024-08-28">2024-08-28</h2>
<ul>
<li>Mention availability in bookworm-backports.</li>
<li>Link to wcurl lightning talk from DebConf24.</li>
</ul>
<h2 id="2024-07-18">2024-07-18</h2>
<ul>
<li>Update date of availability for Debian testing and expected date for bookworm backports.</li>
<li>Mention charles as the person who suggested "wcurl" as a name.</li>
<li>Update wcurl's -o/--opts options, it's now just --curl-options.</li>
<li>Remove mention of language spoken in the Matrix room, we are using English now.</li>
<li>Update list of features of wcurl.</li>
</ul>
Hello World
2024-04-18T00:00:00+00:00
2024-04-18T00:00:00+00:00
Unknown
https://samueloph.dev/blog/hello-world/
<p>This is my very first post, just to make sure everything is working as expected.</p>
<p>Made with <a rel="noopener" target="_blank" href="https://www.getzola.org/">Zola</a> and the <a rel="noopener" target="_blank" href="https://github.com/jieiku/abridge/">Abridge theme</a>.</p>