đŸ’Ÿ Archived View for perso.pw â€ș blog â€ș rss.xml captured on 2023-05-24 at 17:44:42.

View Raw

More Information

âŹ…ïž Previous capture (2023-04-26)

âžĄïž Next capture (2023-06-14)

🚧 View Differences

-=-=-=-=-=-=-

<?xml version="1.0" encoding="UTF-8"?> 
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Solene'%</title>
    <description></description>
    <link>gemini://perso.pw/blog/</link>
    <atom:link href="gemini://perso.pw/blog/rss.xml" rel="self" type="application/rss+xml" />
    <item>
  <title>How to install Nix in a Qubes OS AppVM</title>
  <description>
    <![CDATA[
<pre># Intro

I'm still playing with Qubes OS, today I had to figure how to install Nix because I rely on it for some tasks.  It turned out to be a rather difficult task for a Qubes beginner like me when not using a fully persistent VM.

Here is how to install Nix in an AppVm (only /home/ is persistent) and some links to the documentation about `bind-dirs`, an important component of Qubes OS that I didn't know about.

=> https://www.qubes-os.org/doc/bind-dirs/ Qubes OS documentation: How to make any file persistent (bind-dirs)
=> https://nixos.org Nix project website

# bind-dirs

Behind this unfriendly name is a smart framework to customize templates or AppVM.  It allows running commands upon VM start, but also make directories explicitly persistent.

The configuration can be done at the local or template level, in our case, we want to create `/nix` and make it persistent in a single VM, so that when we install nix packages, they will be stay after a reboot.

The implementation is rather simple, the persistent directory is under the `/rw` partition in ext4, which allows mounting subdirectories.  So, if the script finds `/rw/bind-dirs/nix` it will mount this directory on `/nix` on the root filesystem, making it persistent and without having to copy at start and sync on stop.

# Setup

A limitation for this setup is that we need to install nix in single user mode, without the daemon.  I suppose it should be possible to install Nix with the daemon, but it should be done at the template level as it requires adding users, groups and systemd units (service and socket).

In your AppVM, run the following commands as root:

mkdir -p /rw/config/qubes-bind-dirs.d/

echo "binds+=( '/nix' )" > /rw/config/qubes-bind-dirs.d/50_user.conf

install -d -o user -g user /rw/bind-dirs/nix


This creates an empty directory `nix` owned by the regular Qubes user named `user`, and we tell bind-dirs that this directory is persistent.

/!\ It's not clear if it's a bug or a documentation issue, but the creation of `/rw/bind-dirs/nix` wasn't obvious.  Someone already filled a bug about this, and funny enough, they reported it using Nix installation as an example.
=> https://github.com/QubesOS/qubes-issues/issues/5862 GitHub issue: clarify bind-dirs documentation

Now, reboot your VM, you should have a `/nix` directory that is owned by your user.  This mean it's persistent, and you can confirm that by looking at `mount | grep /nix` output which should have a line.

Finally, install nix in single user mode, using the official method:

sh <(curl -L https://nixos.org/nix/install) --no-daemon


Now, we need to fix the bash code to load Nix into your environment.  The installer modified `~/.bash_profile`, but it isn't used when you start a terminal from dom0, it's only used when using a full shell login with `bash -l`, which doesn't happen on Qubes OS.

Copy the last line of `~/.bash_profile` in `~/.bashrc`, this should look like that:

if [ -e /home/user/.nix-profile/etc/profile.d/nix.sh ]; then . /home/user/.nix-profile/etc/profile.d/nix.sh; fi # added by Nix installer


Now, open a new shell, you have a working Nix in your environment \o/

You can try it using `nix-shell -p hello` and run `hello`.  If you reboot, the same command should work immediately without need to download packages again.

# Configuration

In your Qube settings, you should increase the disk space for the "Private storage" which is 2 GB by default.

# Conclusion

Installing Nix in a Qubes OS AppVM is really easy, but you need to know about some advanced features like bind-dirs.  This is a powerful feature that will allow me to make lot of fun stuff with Qubes now, and using nix is one of them!

# Going further

If you plan to use Nix like this in multiple AppVM, you may want to set up a local substituter cache in a dedicated VM, this will make your bandwidth usage a lot more efficient.

=> https://dataswamp.org/~solene/2022-06-02-nixos-local-cache.html How to make a local NixOS cache server
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/qubes-os-install-nix.gmi</guid>
  <link>gemini://perso.pw/blog//articles/qubes-os-install-nix.gmi</link>
  <pubDate>Mon, 15 May 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Create a custom application entry in Qubes OS</title>
  <description>
    <![CDATA[
<pre># Introduction

If you use Qubes OS, you already know that installed software in templates are available in your XFCE menu for each VM, and can be customized from the Qubes Settings panel.

=> https://www.qubes-os.org/doc/how-to-install-software Qubes OS documentation about How to install software

However, if you want to locally install a software, either by compiling it, or using a tarball, you won't have a application entry in the Qubes Settings, and running this program from dom0 will require using an extra terminal in the VM.  But we can actually add the icon/shortcut by creating a file at the right place.

In this example, I'll explain how I made a menu entry for the program DeltaChat, "installed" by downloading an archive containing the binary.

# Desktop files

In the VM (with a non-volatile /home) create the file `/home/user/.local/share/applications/deltachat.desktop`, or in a TemplateVM (if you need to provide this to multiple VMs) in the path `/usr/share/applications/deltachat.desktop`:

[Desktop Entry]

Encoding=UTF-8

Version=1.0

Type=Application

Terminal=False

Exec=/home/user/Downloads/deltachat-desktop-1.36.4/deltachat-desktop

Name=DeltaChat


This will create a desktop entry for the program named DeltaChat, with the path to the executable and a few other information.  You can add an `Icon=` attribute with a link toward an image file, I didn't have one for DeltaChat.

# Qubes OS integration

With the .desktop file created, open the Qubes settings and refresh the applications list, you should find an entry with the Name you used.  VoilĂ !

# Conclusion

Knowing how to create desktop entries is useful, not even on Qubes OS but for general Linux/BSD use.  Being able to install custom programs with a launcher in Qubes dom0 is better than starting yet another terminal to run a GUI program from there.

# Going further

If you want to read more about the .desktop files specifications, you can read the links below:

=> https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html Desktop entry specifications
=> https://wiki.archlinux.org/title/desktop_entries Arch Linux wiki about Desktop entries
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/qubes-os-custom-application.gmi</guid>
  <link>gemini://perso.pw/blog//articles/qubes-os-custom-application.gmi</link>
  <pubDate>Sun, 14 May 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Making Qubes OS backups more efficient</title>
  <description>
    <![CDATA[
<pre># Introduction

These days, I've been playing a lot with Qubes OS, it has an interesting concept of deploying VMs (using Xen) in a well integrated and transparent manner in order to hardly separate every tasks you need.

By default, you get default environments such as Personal, Work and an offline Vault, plus specials VMs to handle USB proxy, network and firewall.  What is cool here is that when you run a program from a VM, only the window is displayed in your window manager (xfce), and not the whole VM desktop.

The cool factor with this project is their take on the real world privacy and security need, allowing users to run what they need to run (proprietary software, random binaries), but still protect them.  Its goal is totally different from OpenBSD and Tails.  Did I say you can also route a VM network through Tor out of the box? =D

If you want to learn more, you can visit Qubes OS website (or ask if you want me to write about it):

=> https://www.qubes-os.org/ Qubes OS official website
=> https://www.qubes-os.org/news/2022/10/28/how-to-organize-your-qubes/ New user guide: How to organize your cubes (nice reading to understand Qubes OS)

# Backups

If you know me, you should know I'm really serious about backups.  This is incredibly important to have backups.

Qubes OS has a backup tool that can be used out of the box, it just dump the VMs storage into an encrypted file, it's easy but not efficient or practical enough for me.

If you want to learn more about the format used by Qubes OS (and how to open them outside of Qubes OS), they wrote some documentation:

=> https://www.qubes-os.org/doc/backup-emergency-restore-v4/ Qubes OS: backup emergency restore

Now, let's see how to store the backups in Restic or Borg in order to have proper backups.

/!\ While both software support deduplication, this doesn't work well in this case because the stored data are compressed + encrypted already, which has a very high entropy (it's hard to find duplicated patterns).

# Backup tool

Qubes OS backup tool offers compression and encryption out of the box, but when it comes to the storage location, we can actually use a command to send the backups to the command's stdin, and guess what, both restic and borg support receiving data on their standard input!

I'll demonstrate how to proceed both with restic and borg with a simple example, I recommend to build your own solution on top of it the way you need.

=> static/backup.png Screenshot of Qubes backup tool

# Create a backup VM

As we are running Qubes OS, I prefer to create a dedicated backup VM using the Fedora template, it will contain the passphrase to the repository and an SSH key for remote backup.

You need to install restic/borg in the template to make it available in that VM.

If you don't know how to install software in a template, it's well documented:

=> https://www.qubes-os.org/doc/how-to-install-software/ Qubes OS: how to install software

Generate an SSH key if you want to store your data on a remote server using SSH, and deploy it on the remote server.

# Write a backup script

In order to simplify the backup command configuration in the backup tool (it's a single input line), but don't sacrifice on features like pruning, we will write a script on the backup VM doing everything we need.

While I'm using a remote repository in the example, nothing prevents you from using a local/external drive for your backups!

The script usage will be simple enough for most tasks:



## Restic

Write a script in `/home/user/restic.sh` in the backup VM, it will allow simple customization of the backup process.

!/bin/sh

export RESTIC_PASSWORD=mysecretpass

double // is important to make the path absolute

export RESTIC_REPOSITORY=sftp://solene@10.42.42.150://var/backups/restic_qubes

KEEP_HOURLY=1

KEEP_DAYS=5

KEEP_WEEKS=1

KEEP_MONTHS=1

KEEP_YEARS=0

case "$1" in

init)

restic init

;;

list)

restic snapshots

;;

restore)

restic restore --target . $2

;;

backup)

cat | restic backup --stdin

restic forget \

--keep-hourly $KEEP_HOURLY \

--keep-daily $KEEP_DAYS \

--keep-weekly $KEEP_WEEKS \

--keep-monthly $KEEP_MONTHS \

--keep-yearly $KEEP_YEARS \

--prune

;;

esac


Obviously, you have to change the password, you can even store it in another file and use the according restic option to load the passphrase from a file (or from a command).  Although, Qubes OS backup tool enforces you to encrypt the backup (which will be store in restic), so encrypting the restic repository won't add any more security, but it can add privacy by hiding what's in the repo.

/!\ You need to run the script with the parameter "init" the first time, in order to create the repository:

$ chmod +x restic.sh

$ ./restic.sh init


## Borg

Write a script in `/home/user/borg.sh` in the backup VM, it will allow simple customisation of the backup process.

!/bin/sh

export BORG_PASSPHRASE=mysecretpass

export BORG_REPO=ssh://solene@10.42.42.150/var/solene/borg_qubes

KEEP_HOURLY=1

KEEP_DAYS=5

KEEP_WEEKS=1

KEEP_MONTHS=1

KEEP_YEARS=0

case "$1" in

init)

borg init --encryption=repokey

;;

list)

borg list

;;

restore)

borg extract ::$2

;;

backup)

cat | borg create ::{now} -

borg prune \

--keep-hourly $KEEP_HOURLY \

--keep-daily $KEEP_DAYS \

--keep-weekly $KEEP_WEEKS \

--keep-monthly $KEEP_MONTHS \

--keep-yearly $KEEP_YEARS

;;

esac


Same explanation as with restic, you can save the password elsewhere or get it from a command, but Qubes backup already encrypt the data, so the repo encryption will mostly only add privacy.

/!\ You need to run the script with the parameter "init" the first time, in order to create the repository:

$ chmod +x borg.sh

$ ./borg.sh init


## Configure Qubes backup

Now, configure the Qubes backup tool:



# Restoring a backup

While it's nice to have backups, it's important to know how to use them.  The setup doesn't add much complexity, and the helper script will ease your life.

On the backup VM, run `./borg.sh list` (or the restic version) to display available snapshots in the repository, then use `./borg.sh restore $snap` with the second parameter being a snapshot identifier listed in the earlier command.

You will obtain a file named `stdin`, this is the file to use in Qubes OS restore tool.

# Warning

If you don't always backup all the VMs, if you keep the retention policy like in the example above, you may lose data.

For example, if you have a KEEP_HOURLY=1, create a backup of all your VMs, and just after, you specifically want to backup a single VM, you will lose the previous full backup due to the retention policy.

In some cases, it may be better to not have any retention policy, or simply time based (keep snapshots which date < n days).

# Conclusion

Using this configuration, you get all the features of a industry standard backup solution such as integrity check, retention policy or remote encrypted storage.

# Troubleshoot

In case of an issue with the backup command, Qubes backup will display a popup message with the command output, this helps a lot debugging problems.

An easy way to check if the script works by hand is to run it from the backup VM:

echo test | ./restic.sh backup


This will create a new backup with the data "test" (and prune older backups, so take care!), if it doesn't work this is a simple way to trigger a new backup to solve your issue.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/qubes-os-efficient-backup.gmi</guid>
  <link>gemini://perso.pw/blog//articles/qubes-os-efficient-backup.gmi</link>
  <pubDate>Fri, 12 May 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Stream your OpenBSD desktop audio to other devices</title>
  <description>
    <![CDATA[
<pre># Introduction

Hi, back on OpenBSD desktop, I miss being able to use my bluetooth headphones (especially the Shokz ones that allow me to listen to music without anything on my ears).

Unfortunately, OpenBSD doesn't have a bluetooth stack, but I have a smartphone (and a few other computers), so why not stream my desktop sound to another device with bluetooh?  Let's see what we can do!

I'll often refer to the "monitor" input source, which is the name of an input that provides "what you hear" from your computer.

While it would be easy to just allow a remote device to play music files, I want to stream the computer's monitor input, so it could be litteraly anything, and not just music files.

This method can be used on any Linux distribution, and certainly on other BSDs, but I will only cover OpenBSD.

# The different solutions

## Icecast

One simple setup is to use icecast, the program used by most web radios, and ices, a companion program to icecast, in order to stream your monitor input to the network.

The pros:



The cons:



## Sndiod

The default sound server in OpenBSD, namely sndiod, supports network streaming!

Too bad, if you want to use Bluetooth as an output, you would have to run sndiod on Linux (which is perfectly fine), but you can't use Bluetooth with sndiod, even on Linux.

So, no sndiod.  Between two OpenBSD, or OpenBSD and Linux, it works perfectly well without latency, and it's a super simple setup, but as Bluetooth can't be used, I won't cover this setup.

The pros:



The cons:



## Pulseaudio

This sound server is available as a port on OpenBSD, and has two streaming modes: native-protocol-tcp and RTP, the former is exchanging pulseaudio internal protocol from one server to another which isn't ideal and prone to problems over a bad network, the latter being more efficient and resilient.

However, the RTP sender doesn't work on OpenBSD, and I have no interest in finding out why (the bug doesn't seem to be straightforward), but the native protocol works just fine.

The pros:



## Snapcast

Snapcast is an amazing piece of software that you can use to broadcast your audio toward multiple other client (using snapcast or a web page) with the twist that the audio will be synchronized on each client, allowing a multi room setup at no cost.

Unfortunately, I've not been able to build it on OpenBSD :(

The pros:



The cons:



# Setup

Here are the instructions to setup different solutions.

## Pulseaudio

### Client setup (OpenBSD)

On the local OpenBSD, you need to install `pulseaudio` and `ffmpeg` packages.

You also need to set sndiod flags, using `rcctl set sndiod flags -s default -m play,mon -s mon`, this will allow you to use the monitor input through the device `snd/0.mon`.

Now, when you want to stream your monitor to a remote pulseaudio, run this command in your terminal:

ffmpeg -f sndio -i snd/0.mon -ar 44100 -f s16le - | pacat -s 10.42.42.199 --raw --process-time-msec=30 --latency-msec=30


The command is composed of two parts:



## Server setup (the device with bluetooth)

The setup is easy, but note that this doesn't involve any authentication or encryption, so please use this on trusted network, or through a VPN.

On a system with pulseaudio, type:

pacmd load-module module-native-protocol-tcp auth-anonymous=1 auth-ip-acl=192.168.1.0/24


This will load the module accepting network connections, the `auth-anonymous` option is there to simplify connection to the server, otherwise you would have to share the pulseaudio cookie between computers, which I recommend doing but on a smartphone this can be really cumbersome to do, and out of scope here.

The other option is pretty obvious, just give a list of IPs you want to allow to connect to the server.

If you want the changes to be persistent, edit `/etc/pulse/default.pa` to add the line `load-module module-native-protocol-tcp auth-anonymous=1 auth-ip-acl=192.168.1.0/24`.

On Android, you can install pulseaudio using Termux (available on f-droid), using the commands:

pkg install pulseaudio

pulseaudio --start --exit-idle-time=3600

pacmd load-module module-native-protocol-tcp auth-anonymous=1 auth-ip-acl=192.168.1.0/24


There is a project named PulseDroid, the original project has been unmaintained for 13 years, but someone took it back quite recently, unfortunately no APK are provided, and I'm still trying to build it to try, it should provide an easier user experience to run pulseaudio on Android.

=> https://gitlab.com/ferreum/PulseDroid/ PulseDroid gitlab repository

## Icecast

Using icecast, you will have to setup an icecast server, and locally use ices2 client to broadcast your monitor input.  Then, any client can play the stream URL.

Install the component using:

pkg_add icecast ices--%ices2


### Server part

As suggested by the file `/usr/local/share/doc/pkg-readmes/icecast`, run the following commands to populate icecast's chroot:

cp -p /etc/{hosts,localtime,resolv.conf} /var/icecast/etc

cp -p /usr/share/misc/mime.types /var/icecast/etc


Edit `/var/icecast.xml`:



Keep in mind this is the bare minimum for a working setup, if you want to open it to the wide Internet, I'd strongly recommend reading icecast documentation before. Using a VPN may be wiser if it's only for private use.

We can start icecast and set it to start at boot:

rcctl enable icecast

rcctl start icecast


### Broadcast part

Then, to configure ices2, copy the file `/usr/local/share/examples/ices2/ices-sndio.xml` somewhere you feel comfortable for storing user configuration files. The example file is an almost working template to send sndio sources to icecast.

Edit the file, under the `<instance>` node:



Now, search for `<channels>` and set it to 2 because we want to broadcast stereo sound, and set `<downmix>` to 0 because we don't need to merge both channels into a mono output. (If those values aren't in sync, you will have funny results =D)

When you want to broadcast, run the command:

env AUDIORECDEVICE=snd/0.mon ices2 ices-sndio.xml


With any device, open the url `http://<hostname>:8000/file.ogg` with `file.ogg` being what you've put in `<mount>` earlier.  And voilĂ , you have a working local audio streaming!

# Limitations

Of course, the setup isn't ideal, you can't use your headset microphone or buttons (using MPRIS protocol).

# Conclusion

With these two setup, you have a choice for occasionnaly streaming your audio to another device, which may have bluetooth support or something making it interesting enough to go through the setup.

I'm personally happy to be able to use bluetooth headphones through my smartphone to listen to my OpenBSD desktop sound.

# Going further

If you want to directly attach bluetooth headphones to your OpenBSD, you can buy an USB dongle that will pair to the headphones and appear as a sound card to OpenBSD.

=> https://jcs.org/2020/11/18/openbsd_btaudio jcs@ article about Bluetooth audio on OpenBSD
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-sound-streaming.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-sound-streaming.gmi</link>
  <pubDate>Fri, 05 May 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Installing Alpine as a Desktop</title>
  <description>
    <![CDATA[
<pre># Introduction

While I like Alpine because it's lean and minimal, I have always struggled to install it for a desktop computer because of the lack of "meta" packages that install everything.

However, there now is a nice command that just picks your desktop environment of choice and sets everything up for you.

This article is mostly a cheat sheet to help me remember how to install Alpine using a desktop environment, NetworkManager, man pages etc...  Because Alpine is still a minimalist distribution and you need to install everything you think is useful.

=> https://www.alpinelinux.org/ Alpine Linux official project page

UPDATE 2023-05-03: I've been told that such a guide already existed in Alpine wiki 😅.

=> https://wiki.alpinelinux.org/wiki/Post_installation Alpine Wiki about Post installation

# Setup

During the installation process started by `setup`, just type `syscrypt` for full disk encryption installation.

## Installing a desktop environment

The most missing part when using Alpine for me was figuring out which packages to install and which services to run to get a working GNOME or Plasma.

But now, just run `setup-desktop` and enjoy.

## Installing man pages

A few packages are required to be able to read man pages.

apk add docs less


If a man page is missing, search for the package name with the `-doc` suffix, using `apk search $package | grep doc`.

## Internationalization

If you want your software in a language other than English, just use `apk add lang`, this will install the -lang packages for each installed package.

## NetworkManager

By default, the installer will ask you to set up networking, but if you want NetworkManager, you need to install it, enable it and disable the other services.

As I prefer to avoid duplication of documentation, please refer to the relevant Wiki page.

=> https://wiki.alpinelinux.org/wiki/NetworkManager Alpine Wiki about NetworkManager

You may want to add a few more packages:

apk add networkmanager-tui

apk add networkmanager-openvpn-lang

apk add networkmanager-openvpn

apk add networkmanager-wifi


## Bluetooth

Nothing special for Bluetooth, except NetworkManager will make it easier to use.  The wiki has setup instructions.

=> https://wiki.alpinelinux.org/wiki/Bluetooth Alpine Wiki about Bluetooth

## Use a recent kernel

By default, Alpine Linux sticks to Long Term Support (LTS) kernels, which is fine, but for newer hardware, you may want to run the latest kernel available.

Fortunately, the Alpine community repository provides the `linux-edge` package for the latest version.

## Fonts

You may want to install some extra fonts, because by default there is only the bare minimum, and your programs will look ugly.

=> https://wiki.alpinelinux.org/wiki/Fonts Alpine Wiki about Fonts

## Emojis

Having working emojis is important for me now, and Alpine only provide a default emoji font with black-and-white pictures, without the complete set.

It's a single package to add in order to get your emojis working.  The revelant Wiki page is linked below.

=> https://wiki.alpinelinux.org/wiki/Emojis Alpine Wiki about Emojis

## Keep binary packages in cache

If you want to keep all the installed packages in cache (so you could keep them for reinstalling, or share on your network), it's super easy.

Run `setup-apkcache` and choose a location (or even pass it as a parameter), you're done.  It's very handy for me because when I need to use Alpine in a VM, i just hook it to my LAN cache and I don't have to download packages again and again.

# Conclusion

Alpine Linux is becoming a serious, viable desktop Linux distribution, not just for containers or servers.  It's still very minimalist and doesn't hold your hand, so while it's not for everyone, it's becoming accessible to enthusiasts and not just hardcore users.

I suppose it's a nice choice for people who enjoy minimalism and don't like SystemD.

# Credits

Thanks to raspbeguy for the various hints about Alpine, and for making me trying it once again.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/alpine-as-desktop-cheatsheet.gmi</guid>
  <link>gemini://perso.pw/blog//articles/alpine-as-desktop-cheatsheet.gmi</link>
  <pubDate>Sun, 30 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Set up your own CalDAV and CardDAV servers on OpenBSD</title>
  <description>
    <![CDATA[
<pre># Introduction

Calendar and contacts syncing, it's something I pushed away for too long, but when I've lost data on my phone and my contacts with it, setting up a local CalDAV/CardDAV server is the first thing I did.

Today, I'll like to show you how to set up the server radicale to have your own server.

=> https://radicale.org/v3.html Radicale official project page

Basically, CalDAV (for calendars and to-do lists) and CardDAV (for contacts) are exchange protocols to sync contacs and calendars between devices.

# Setup

On OpenBSD 7.3, the latest version of radicale is radicale 2, available as a package with all the service files required for a quick and efficient setup.

You can install radicale with the following command:

pkg_add radicale


After installation, you will have to edit the file `/etc/radicale/config` in order to make a few changes.  The syntax looks like INI files with sections between brakets and then key/values on separate lines.

For my setup, I made my radicale server to listen on the IP `10.42.42.42` and port `5232`, and I chose to use htpasswd files encrypted in bcrypt to manage users.  This was accomplished with the following piece of configuration:

[server]

hosts = 10.42.42.42:5232

[auth]

type = htpasswd

htpasswd_filename = /etc/radicale/users

htpasswd_encryption = bcrypt


After saving the changes, you need to generate the file `/etc/radicale/users` to add credentials and password in it, this is done using the command `htpasswd`.

In order to add the user `solene` to the file, use the following command:

cd /etc/radicale

htpaswd users solene


Now everything is ready, you can enable radicale to run at boot, and start it now, using `rcctl` to manage the service like in:

rcctl enable radicale

rcctl start radicale


# Managing calendars and contacts

Now you should be able to reach radicale on the address it's listening, in my example it's http://10.42.42.42:5232/ and use your credentials to log in.

Then, just click on the link "Create new addressbook or calendar", and complete the form.

Back on the index, you will see each item managed by radicale and the URL to access it.  When you will configure your devices to use CalDAV and CardDAV, you will need the crendentials and the URL.

# Conclusion

Radicale is very lightweight and super easy to configure, and I finally have a proper calendar synchronization on my computers and smartphone, which turned to be very practical.

# Going further

If you want to setup HTTPS for radicale, you can either use a certificate file and configure radicale to use it, or use a reverse http proxy such as nginx and handle the certificate there.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/calendar-and-contacts-with-radicale.gmi</guid>
  <link>gemini://perso.pw/blog//articles/calendar-and-contacts-with-radicale.gmi</link>
  <pubDate>Sun, 23 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Trying some Linux distributions to free my Steam Deck</title>
  <description>
    <![CDATA[
<pre># Introduction

As the owner of a Steam Deck (a handeld PC gaming device), I wanted to explore alternatives to the pre-installed SteamOS you can find on it.  Fortunately, this machine is a plain PC with UEFI Firmware allowing you to boot whatever you want.

# What's the deck?

It's like a Nintendo Switch, but much bigger.  The "deck" is a great name because it's really what it looks like, with two touchpads and four extra buttons behind the deck.  By default, it's running SteamOS, an ArchLinux based system working in two modes:



Unfortunately for me, I don't like ArchLinux and I wanted to understand how the different modes were working, because on Steam, you just have a button menu to switch from Gaming to Desktop, and a desktop icon to switch from desktop to gaming.

=> https://www.steamdeck.com/ Steam Deck official website (with specs)

Here is a picture I took to compare a Nintendo Switch and a Steam Deck, it's really beefy and huge, but while its weight is higher than the Switch, I prefer how it holds and the buttons' placement.

=> static/deck-switch.jpg Steam Deck side by side with a Nintendo Switch

# Alternatives

And after starting my quest to free my Deck, I found there were already serious alternatives.  Let's explore them.

## HoloISO

This project purpose is to reimplement SteamOS the best it can, but only using open source components.  They also target alternative devices if you want to have a Steam Deck experience.

=> https://github.com/HoloISO/holoiso Project page

My experience wasn't great with it, once installation was done, I had to log in into Steam, and at every reboot it was asking me to log-in again.  As the project was mostly providing the same experience based on ArchLinux, I wasn't really interested to look into it further.

## ChimeraOS

This project purpose is to give Steam Deck user (or similar device owners) an OS that would fit the device, it's currently offering a similar experience, but I've read plans to offer alternative UI.  On top of that, they integrated a web server to manage emulations ROMS, or Epic Games and GOG installer, instead of having to fiddle with Lutris, minigalaxy or Heroic game launcher to install games from these store.

The project also has many side-projects such as gamescope-session, chimera or forks with custom patches.

=> https://chimeraos.org/ Project official website

My experience was very good, the web server to handle GOG/Epic is a very cool idea and worked well, the Steam GamepadUI was working as well.

## Jovian-NixOS

This project is truly amazing, it's currently what I'm running on my own devices.  Let's use NixOS with some extra patches to run your Deck, and it's just working fine!

Jovian-NixOS (in reference to Neptune, the Deck codename) is a set of configuration to use with NixOS to adapt to the Steam Deck, or any similar handeld device.  The installation isn't as smooth as the two other above because you have to install NixOS from console, write a bit of configuration, but the result is great.  It's not for everyone though.

=> https://github.com/Jovian-Experiments/Jovian-NixOS Project page

Obviously, my experience is very good.  I'm in full control of the system, thanks to NixOS declarative approach, no extra services running until I want to, it even makes a great Nix remote builder...

## Plain linux installed like a regular computer

The first attempt was to install openSUSE on the Deck like I would do on any computer.  The experience was correct, installation went well, and I got in GNOME without issues.

However, some things you must know about the Deck:



In order to switch between Desktop and Gaming mode, I found a weird setup that was working for me:



I turned out Steam GamepadUI with Gamescope button "Switch to desktop mode" is using a dbus signal to switch to desktop, distributions above handle it correctly.

Although it was mostly working, my main issues were:



But, despite these issues, performance was perfectly fine, as well as battery life.  But usability should be priority for such a device, and it didn't work very well here.

# Conclusion

If you already enjoy your Steam Deck the way it is, I recommend you to stick to SteamOS.  It does the job fine, allows you to install programs from Flatpak, and you can also root it if you really need to install system packages.

If you want to do more on your Deck (use it as a server maybe? Who knows), you may find it interesting to get everything under your control.

# Pro tip

I'm using syncthing on my Steam Deck and other devices to synchronize GOG/Epic save games, Steam cloud is neat, but with one minute per game to configure syncthing, you have something similar.

Nintendo Switch emulation works fine on Steam Deck, more about that soon :)

=> static/deck-arceus.jpg Steam Deck displaying the Switch game Pokémon Arceus Legends
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/free-the-steam-deck.gmi</guid>
  <link>gemini://perso.pw/blog//articles/free-the-steam-deck.gmi</link>
  <pubDate>Sun, 16 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Quelques Haikus pour début 2023</title>
  <description>
    <![CDATA[
<pre>Une petite sélection de haikus qui ont été publiés sur Mastodon, cela dit, il ne sont pas toujours bien fichus mais ce sont mes premiers, espérons que l'expérience m'aide à faire mieux par la suite.


Merle qui chasse

Un ciel bleu teinté de blanc

Le thym en fleurs


Plateaux enneigés

Bien au chaud et Ă  l'abri -

Violente tempĂȘte


Antarctique -

Monuments cyclopéens

Hiver ténébreux


Petit Ă©tang gris -

Tapissé de feuilles

Tout en silence


Plage au soleil

L'oiseau en laisse dans le ciel -

Son fil, cerf-volant


Idées et pensées -

Comme l'orage d'été

Tombent du ciel


Grùce matinée

Dimanche, changement d'heure -

Le chant des oiseaux


Maladie, douleur

Climat doux, bourgeons en fleurs -

Le temps, guérison


Le vent dans les feuilles -

Le ruissellement de l'eau

ForĂȘt en Ă©veil


Les rues silencieuses

L'aube qui peine Ă  se lever -

Jardin givré


Une nuit de pleine lune

Barbecue par des amis -

Vacances d'été


Des pommes de terre

Plateau de charcuterie -

Copieuse raclette


Ciel bleu printanier

fleurs, abeilles, tout se réveil -

Balade en forĂȘt

</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/haiku-2023Q1.gmi</guid>
  <link>gemini://perso.pw/blog//articles/haiku-2023Q1.gmi</link>
  <pubDate>Sun, 09 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>How to setup a local network cache for Flatpak</title>
  <description>
    <![CDATA[
<pre># Introduction

As you may have understood by now, I like efficiency on my systems, especially when it comes to network usage due to my poor slow ADSL internet connection.

Flatpak is nice, I like it for many reasons, and what's cool is that it can download only updated files instead of the whole package again.

Unfortunately, when you start using more and more packages that are updated daily, and which require subsystems like NVIDIA drivers, MESA etc... this adds up to quitea lot of daily downloads, and multiply that by a few computers and you gets a lot of network traffic.

But don't worry, you can cache it on your LAN to download updates only once.

# Setup

As usual for this kind of job, we will use Nginx on a local server on the network, and configure it to act as a reverse proxy to the flatpak repositories.

This requires modifying the URL of each flatpak repository on the machines, it's a one time operation.

Here is the configuration you need on your Nginx to proxy Flathub:

map $status $cache_header {

200 "public";

302 "public";

default "no-cache";

}

server {

listen 0.0.0.0:8080; # you may want to listen on port 80, or add TLS

server_name my-cache.local; # replace this with your hostname, or system IP

# flathub cache

set $flathub_cache https://dl.flathub.org;

location /flathub/ {

rewrite ^/flathub/(.*) /$1 break;

proxy_cache flathub;

proxy_cache_key "$request_filename";

add_header Cache-Control $cache_header always;

proxy_cache_valid 200 302 300d;

expires max;

proxy_pass $flathub_cache;

}

}

proxy_cache_path /var/cache/nginx/flathub/cache levels=1:2

keys_zone=flathub:5m

max_size=20g

inactive=60d

use_temp_path=off;


This will cause nginx to proxy requests to the flathub server, but keep files in a 20 GB cache.

You will certainly need to create the `/var/cache/nginx/flathub` directory, and make sure it has the correct ownership for your system configuration.

If you want to support another flatpak repository (like Fedora's), you need to create a new location, and new cache in your nginx config.

# Client configuration

On each client, you need to change the URL to reach flathub, in the example above, the URL is `http://my-cache.local:8080/flathub/repo/`.

You can change the URL with the following command:

flatpak remote-modify flathub --url=http://my-cache.local:8080/flathub/repo/`


Please note that if you add flathub repo, you must use the official URL to have the correct configuration, and then you can change its URL with the above command.

# Conclusion

Our dear nginx is still super useful as a local caching server, it's super fun to see some updates going at 100 MB/s from my NAS now.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/lan-cache-flatpak.gmi</guid>
  <link>gemini://perso.pw/blog//articles/lan-cache-flatpak.gmi</link>
  <pubDate>Wed, 05 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Detect left over users and groups on OpenBSD</title>
  <description>
    <![CDATA[
<pre># Introduction

If you use OpenBSD and administrate machines, you may be aware that packages can install new dedicated users and groups, and that if you remove a package doing so, the users/groups won't be deleted, instead, `pkg_delete` displays instructions about deletion.

In order to keep my OpenBSD systems clean, I wrote a script looking for users and groups that have been installed (they start by the character `_`), and check if the related package is still installed, if not, it outputs instructions that could be run in a shell to cleanup your system.

# The code

!/bin/sh

SYS_USERS=$(mktemp /tmp/system_users.txt.XXXXXXXXXXXXXXX)

PKG_USERS=$(mktemp /tmp/packages_users.txt.XXXXXXXXXXXXXXX)

awk -F ':' '/^_/ && $3 > 500 { print $1 }' /etc/passwd | sort > "$SYS_USERS"

find /var/db/pkg/ -name '+CONTENTS' -exec grep -h ^@newuser {} + | sed 's/^@newuser //' | awk -F ':' '{ print $1 }' | sort > "$PKG_USERS"

BOGUS=$(comm -1 -3 "$SYS_USERS" "$PKG_USERS")

if [ -n "$BOGUS" ]

then

echo "Bogus users/groups (missing in /etc/passwd, but a package need them)" >/dev/stderr

echo "$BOGUS" >/dev/stderr

fi

EXTRA=$(comm -2 -3 "$SYS_USERS" "$PKG_USERS")

if [ -n "$EXTRA" ]

then

echo "Extra users" >/dev/stderr

for user in $EXTRA

do

echo "userdel $user"

echo "groupdel $user"

done

fi

rm "$SYS_USERS" "$PKG_USERS"


## How to run

Write the content of the script above in a file, mark it executable, and run it from the shell, it should display a list of `userdel` and `groupdel` commands for all the extra users and groups.

# Conclusion

With this script and the package `sysclean`, it's quite easy to keep your OpenBSD system clean, as if it was just a fresh install.

# Limitations

It's not perfect in its current state because if you deleted an user, the according group that is still left won't be reported.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-delete-old-users.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-delete-old-users.gmi</link>
  <pubDate>Mon, 03 Apr 2023 00:00:00 GMT</pubDate>
</item>

  </channel>
</rss>