💾 Archived View for perso.pw › blog › rss.xml captured on 2022-04-28 at 18:20:41.

View Raw

More Information

⬅️ Previous capture (2022-03-01)

➡️ Next capture (2022-06-03)

🚧 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>Writing my first OpenBSD game using Godot</title>
  <description>
    <![CDATA[
<pre># Introduction

I'm a huge fan of video games but never really thought about writing one.  Well, this crossed my mind a few times, but I don't know anything about writing a GUI software or using OpenGL, but a few days ago I discovered the open source game engine Godot.

This game engine is a full-featured tool allowing to easily write 2D or 3D games that are portables on Android, Mac, Windows, Linux, HTML5 (using WebASM) and operating systems where the Godot engine is available, like OpenBSD.

=> https://godotengine.org/ Godot engine project website

# Learning

Godot offers a GUI to write games, the GUI itself being a Godot game, it's full featured and come with a code editor, documentation, 2D/3D views, animation, tile set management, and much more.

The documentation is well written and gives introduction to the concepts, and then will just teach you how to write a simple 2D game!  It only took me a couple of hours to be able to start creating my very own first game and getting the grasps.

=> https://docs.godotengine.org/en/stable/ Godot documentation

I had no experience into writing games but only programming experience.  The documentation is excellent and give simple examples that can be easily reused thanks to the way Godot is designed.  The forums are also a good way to find a solution for common problems.

# Demo

I wrote a simple game, OpenBSD themed, especially themed against its 6.8 version for which the artwork is dedicated to the movie "Hackers".  It took me like 8 hours I think to write it, it's long, but I didn't see time passing at all, and I learned a lot.  I have a very interesting game in my mind, but I need to learn a lot more to be able to do it, so starting with simple games is a nice training for me.

It's easy to play and fun (I hope so), give it a try!

=> https://perso.pw/hack_planet/puffy-bubble.html Play it on the web browser
=> https://perso.pw/hack_planet/puffy-bubble.x86_64 Play it on Linux
=> https://perso.pw/hack_planet/puffy-bubble.exe Play it on Windows

If you wish to play on OpenBSD or any other operating system having Godot, download the Linux binary and run "godot --main-pack puffy-bubble.x86_64" and enjoy.

I chose a neon style to fit to the theme, it's certainly not everyone's taste :)

=> static/puffy-bubble.png A screenshot of the game, displaying a simple maze in the neon style, a Puffy mascot, the text "Hack the planet" and a bubble on the top of the maze.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/writing-a-game-with-godot.gmi</guid>
  <link>gemini://perso.pw/blog//articles/writing-a-game-with-godot.gmi</link>
  <pubDate>Thu, 28 Apr 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Routing a specific user on a specific network interface on Linux</title>
  <description>
    <![CDATA[
<pre># Introduction

I have a special network need on Linux, I must have a single user going through specific VPN tunnel.  This can't be done using a different metric for the VPN or by telling the program to bind on a specific interface.

# How does it work

The setup is easy once you find how to proceed on Linux: we define a new routing table named 42 and add a rule assigning user with uid 1002 to this routing table.  It's important to declare the VPN default route on the exact same table to make it work.

!/bin/sh

REMOTEGW=YOUR_VPN_REMOTE_GATEWAY_IP

LOCALIP=YOUR_VPN_LOCAL_IP

INTERFACE=tun0

ip route add table 42 $REMOTEGW dev tun0

ip route add table 42 default via $REMOTEGW dev tun0 src $LOCALIP

ip rule add pref 500 uidrange 1002-1002 lookup 42

ip rule add from $LOCALIP table 42


# Conclusion

It's quite complicated to achieve this on Linux because there are many ways to proceed like netns (network namespace), iptables or vrf but the routing solution is quite elegant, and the documentation are never obvious for this use case.

I'd like to thank @loweel@bbs.keinpfusch.net from the Fediverse for giving me the first bits about ip rules and using a different route table.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/linux-user-on-specific-interface.gmi</guid>
  <link>gemini://perso.pw/blog//articles/linux-user-on-specific-interface.gmi</link>
  <pubDate>Sat, 23 Apr 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Video guide to install OpenBSD 7.1 with the GNOME desktop</title>
  <description>
    <![CDATA[
<pre># Introduction

I asked the community recently if they would like to have a video tutorial about installing OpenBSD, many people answered yes so here it is!  I hope you will enjoy it, I'm quite happy of the result while I'm not myself fan of watching video tutorials.

# The links

The videos are published on Peertube, but you are free to reupload them on YouTube if you want to, the licence permits it.  I won't publish on YouTube because I don't want to feed this platform.

The English video has Italian subtitles that have been provided by a fellow reader.

=> https://videos.pair2jeux.tube/w/rAfEsfT7goA4yps4HQMmt5 [English] Guide to install OpenBSD 7.1 with the GNOME desktop
=> https://videos.pair2jeux.tube/w/hmjvVdN8vDnJWwp8Czd866 [French] Guide vidéo d'installation d'OpenBSD de A à Z avec l'environnement GNOME

# Why not having used a VM?

I really wanted to use a real hardware (an IBM ThinkPad T400 with an old Core 2 Duo) instead of a virtual machine because it feels a lot more real (WoW :D) and has real world quirks like firmwares that would be avoided in a VM.

# Youtube Links

If you prefer YouTube, someone republished the video on this Google proprietary platform.

=> https://youtu.be/_ntBSbbsQT4 [YOUTUBE] [English] Guide to install OpenBSD 7.1 with the GNOME desktop
=> https://youtu.be/js9suODs8A0 [YOUTUBE] [French] Guide vidéo d'installation d'OpenBSD de A à Z avec l'environnement GNOME

# Making-off

I rarely make videos, and it was a first time for me to create this, so I wanted to share about how I made it because it was very amateurish and weird :D

My first setup trying to record the screen of a laptop using another laptop and an USB camera, it didn't work well
=> static/setup_0.jpg My first setup trying to record the screen of a laptop using another laptop and an USB camera, it didn't work well

My second setup, with a GoPro camera more or less correctly aligned with the laptop screen
=> static/setup_1.jpg My second setup, with a GoPro camera more or less correctly aligned with the laptop screen

The first part on Linux was recorded locally with ffmpeg from the T400 computer, the rest is recorded with the GoPro camera, I applied a few filters with the shotcut video editing software to flatten the picture (the lens is crazy on the GoPro).

I spent like 8 hours to create the video, most of the time was editing, blurring my Wi-Fi password, adjusting the speed of the sequences, and once the video was done I recorded my audio comment (using a USB Rode microphone) while watching it, I did it in English and in French, and used shotcut again to sync the audio with the video and merge them together.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-video-tutorial-installation.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-video-tutorial-installation.gmi</link>
  <pubDate>Sat, 23 Apr 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Reduce httpd web server bandwidth usage by serving compressed files</title>
  <description>
    <![CDATA[
<pre># Introduction

When reaching a website, most web browsers will send a header (some metadata about the requestion) informing the web server that you supported compressed content.  In OpenBSD 7.1, the httpd web server received a new feature allowing it to serves a pre-compressed file of a requested file if the web browser supports compression.  The benefits are a bandwidth usage reduced by 2x to 10x depending on the file content, this is particularly interesting for people who self-host and for high traffic websites.

# Configuration

In your httpd.conf, in a server block add the "gzip-static" keyword, save the file and reload the httpd service.

A simple server block would look like this:

server "perso.pw" {

root "/htdocs/solene"

listen on * port 80

gzip-static

}


# Creating the files

In addition to this change, I added a new flag to the gzip command to easily compress files while keeping the original files.  Run "gzip -k" on the files you want to serve compressed when the clients support the feature.

It's best to compress text files, such as HTML, JS or CSS for the most commons.  Compressing binary files like archives, pictures, audio or videos files won't provide any benefit.

# How does it work?

When the client connects to the httpd server requesting "foobar.html", if gzip-static is used for this location/server, httpd will look for a file named "foobar.html.gz" that is not older than "foobar.html". When found, "foobar.html.gz" is transparently transferred to the client requesting "foobar.html".

Take care to regenerate the gz files when you update the original files, remember that the gz files must be newer to be used.

# Conclusion

This is for me a major milestone for using httpd in self-hosting and with static websites.  We battle tested this change with the webzine server often hitting big news websites leading to many people visiting the website in a short time span, this drastically reduced the bandwidth usage of the server, allowing it to support more clients per second.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-httpd-gzip.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-httpd-gzip.gmi</link>
  <pubDate>Fri, 22 Apr 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>OpenBSD 7.1: fan noise and high temperature solution</title>
  <description>
    <![CDATA[
<pre># Introduction

OpenBSD 7.1 has been released with a change that will set the CPU to max speed when plugged to the wall.  This brings better performance and entirely let the CPU and mainboard do the frequency throttling.

However, it may doesn't throttle well for some users, resulting in huge power usage even when idle, heat from the CPU and also fan noise.

As the usual "automatic" frequency scheduling mode is no longer available when connected to powergrid, I wrote a simple utility to manage the frequency when the system is plugged to the wall, I took the opportunity to improve it, giving better performance than the previous automatic mode, but also giving more battery life when using on a laptop on battery.

=> https://tildegit.org/solene/obsdfreqd obsdfreqd project page

# Installation

The project README or man page explains how to install, but here are the instructions to proceed.  It's important to remove the automatic mode from apmd which would kill obsdfreqd, apmd can be kept to have its ability to run commands on resume/suspend etc...

doas pkg_add git

cd /tmp/ && git clone https://tildegit.org/solene/obsdfreqd.git

cd obsdfreqd

make

doas make install

rcctl ls on | grep ^apmd && doas rcctl set apmd flags -L && doas rcctl restart apmd

doas rcctl enable obsdfreqd

doas rcctl start obsdfreqd


# Configuration

No configuration are required, it works out of the box with a battery saving profile when on battery and a performance profile when connected to power.

If you feel adventurous, obsdfreqd man page will give you information about all the parameters available if you want to tailor yourself a specific profile.

Note that obsdfreqd can target a specific temperature limit using -T parameter, see the man page for explanations.

# FAQ

Using hw.perfpolicy="auto" sysctl won't help, the kernel code entirely bypass the frequency management if the system is not running on battery.

=> https://github.com/openbsd/src/blob/0294e0be5821991219b454f4fdc27f570d30a6fd/sys/kern/sched_bsd.c#L547 sched_bsd.c line shipped in OpenBSD 7.1

Using apmd -A doesn't solve the issue because apmd was simply setting the sysctl hw.perfpolicy to auto, which as explained above set the frequency to full speed when not on battery.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-71-fan-noise-temperature.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-71-fan-noise-temperature.gmi</link>
  <pubDate>Thu, 21 Apr 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Operating systems battle: OpenBSD vs NixOS</title>
  <description>
    <![CDATA[
<pre># Introduction

While I'm an OpenBSD contributor, I also enjoy using Linux especially the NixOS distribution which I consider a system apart from the other Linux distributions because of how different it is.  Because I use both, I have two SSDs in my laptop with each system installed and I can jump from one to another depending on the task I'm doing or which I want to use.

My main system, the one with all my data, is OpenBSD, unfortunately the lack of an interoperable and good file system between NixOS and OpenBSD make it difficult to share data between them without using a network storage offering a protocol they have in common.

# OpenBSD and NixOS

Let me quickly introduce the two operating systems if you don't know them.

OpenBSD is a 25+ years old fork of NetBSD, it's full of history and a solid system, it's also the place where OpenSSH or tmux are developed.  It's a BSD system with its own kernel and own drivers, it's not related to Linux but will share most of well known open source programs you can have on Linux, they are provided as packages (programs such as GIMP, Libreoffice, Firefox, Chromium etc...).  The whole OpenBSD system (kernel, drivers, userland and packages) is managed by a team of approximately 150 persons (without counting people sending updates and who don't have a commit access).

=> https://www.openbsd.org/ The OpenBSD project website

NixOS will be soon a 20 years old Linux distribution based on the nix package manager.  It's offering a new approach to system management, based on reproducible builds and declarative configurations, basically you define how your computer should be configured (packages, services, name, users etc..) in a configuration file and "build" the system to configure itself, if you share this configuration file on another computer, you should be able to reproduce the exact same system.  Packages are not installed in a standard file hierarchy but each package files are stored into a dedicated directory and the users profiles are made of symbolic links and many environment variables to permit programs to find libraries or dependencies, for example the path to Firefox may look like something like /nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1/bin/firefox.

=> https://nixos.org/ The NixOS project website
=> https://nixos.org/guides/how-nix-works.html NixOS wiki: How Nix works

## Performance

OpenBSD is lacking hardware acceleration for encoding/decoding video, this make it a lot slower when working with videos.

Interactive desktop usage and I/O also feel slower on OpenBSD, on the other hand the Linux kernel used in NixOS benefits from many people working full time at improving its performance, we have to admit the efforts pay off.

Although OpenBSD is slower than Linux, it's actually usable for most tasks one may need to achieve.

## Hardware support

OpenBSD doesn't support as many devices as NixOS and its Linux kernel.  On NixOS I can use an external NVIDIA card using a thunderbolt case, OpenBSD doesn't have support for this case nor has it a driver for NVIDIA cards (which is mostly NVIDIA's fault for not providing documentation).

However, OpenBSD barely requires any configuration to work, if the hardware is supported, it will work.

Finally, OpenBSD can be used on old computers from various architectures, like i386, old Apple powerpc, risc, arm, while NixOS is only focusing on modern hardware such as Amd64 and Arm64.

## Software choice

Both systems provide a huge packages set, but the one from Nix has more choice.  It's not that bad on the OpenBSD side though, most common packages are available and often with a recent version, I also found many times a package available in OpenBSD but not in Nix.

Most notably, I feel the quality of OpenBSD packages is slightly higher than on Nix, they have less issues (Nix packages sometimes have issues that may be related to nix unusual file hierarchy) and are sometimes patched to have better defaults (for instance I'm thinking of disabling network accesses opened by default in some GUI applications).

Both of them make a new release every six months, but while OpenBSD only backport packages security fixes for its latest release, NixOS provides a lot more updates to its packages for the release users.

Updating packages is painless on OpenBSD and NixOS, but it's easier to find which version you are currently using on OpenBSD.  This may be because I don't know enough the nix shell but I find it very hard to know if I'm actually using a program that has been updated (after a CVE I often check that) or if it's not.

=> https://openports.pl/ OpenBSD packages list
=> https://search.nixos.org/packages NixOS packages list

## Network

Network is certainly the area where OpenBSD is the most well-known, its firewall Packet Filter is easy to use/configure and efficient.  OpenBSD provides mechanisms such as routing tables/domains to assign a network interface to an entire separated network, allowing to expose a program/user to a specific interface reliably, I didn't find how to achieve this on Linux yet.  OpenBSD comes with all the required daemons to manage a network (dhcp, slaacd, rpki, email, http, NAT, ftp, tftp etc...) within its base system.

The performance when dealing with network throughput may be sub-par on OpenBSD compared to Linux but for the average user or server it's fine, it will mostly depend on the network card used and its driver support.

I don't really enjoy playing with network on Linux as I find it very complicated, I never found how to aggregate wifi and Ethernet interfaces to transparently switch from one to the other when I (un)plug the rj45 cable on my laptop, doing this is easy to achieve on OpenBSD (I don't enjoy losing all my TCP connections when moving the laptop around).

## Maintenance

The maintenance topic will be very personal, for a personal workstation/server case and not a farm of hundreds of servers.

OpenBSD doesn't change much, it has a new release every six months but the upgrades are always easy to handle, most corner cases are documented in the upgrade guide and I'm ALWAYS confident when I have to update an OpenBSD system.

NixOS is also easy to update and keep clean, I never had any issue when upgrading yet and it would still be possible to rollback to the previous version in case something is going wrong.

I can say they have both a different approach but they both work well.

## Documentation

I have to say the NixOS documentation is rather huge but yet not always useful.  There is a nice man page named "configuration.nix" giving all the options to parameter a system, but it's generated from the Nix code and is often lacking explanations in addition to describe an API.  There are also a few guides and manual available on NixOS website but they are either redundant or not really describing how to solve real world problems.

=> https://nixos.org/learn.html NixOS documentation

On the OpenBSD side, the website provides a simple "Frequently Asked Questions" section for some use case, and then all the system and its internal are detailed in very well written man pages, it may feel unfriendly or complicated at first but once you taste the OpenBSD man pages you easily get sad when looking at another documentation.  If you had to setup an OpenBSD system for some task relying on components from the base system (= not packages), I'm confident to say you could do it offline with only the man pages.  OpenBSD is not a system that you find its documentation on various forums or github gists, while I often feel this with NixOS :(

=> https://www.openbsd.org/faq/index.html OpenBSD FAQ
=> https://man.openbsd.org/ OpenBSD man pages

## Contributing

I would say NixOS have a modern contribution system, it relies on github and a bot automatically do many checks to the contributions, helping contributors to check their work quickly without "wasting" the time of someone who would have to read every submitted code.

OpenBSD is doing exactly that, changes to the code are done on a mailing list, only between humans.  It doesn't scale very well but the human contact will give better explanations than a bot, but this is when your work is interesting someone who want to spend time on it, sometimes you will never get any feedback and it's a bit sad we are losing updates and contributors because of this.

# Conclusion

I can't say one is better to the other nor that one is doing absolutely better at one task.

My love for OpenBSD may come from its small community, made of humans that like working on something different.  I know how OpenBSD works, when something is wrong it's easy to debug because the system has been kept relatively simple.  It's painless, when your hardware is supported, it just works fine.  The default configuration is good and I don't have to worry about it.

But I also love NixOS, it's adventurous, it offers a new experience (transactional updates, reproducibility) that I feel are the future of computing, but it also make the whole very complicated to understand and debug.  It's a huge piece of software that could be bend to many forms given you are a good Nix arcanist.

I'd be happy to hear about your experiences with regards to OpenBSD and NixOS, feel free to write me (mastodon or email) about this!
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-vs-nixos.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-vs-nixos.gmi</link>
  <pubDate>Mon, 18 Apr 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Keep your OpenBSD system cool with obsdfreqd</title>
  <description>
    <![CDATA[
<pre># Introduction

Last week I wrote a system daemon to manage the CPU frequency from userland, entirely bypassing the kernel automatic mode.  While this was more of a toy at first because I only implemented the same automatic mode used in the kernel but with all the variables being easily changed, I found it valuable for many use case to improve battery life or even temperature.

The coolest feature I added today is to support a maximum temperature and let the program do its best to keep the CPU temperature below the limit.

=> https://tildegit.org/solene/obsdfreqd obsdfreqd project page

# Installation

As said in the "Too Long Didn't Read" section of the project README, a simple `make install` as root and starting the service is enough.

# Results

A nice benchmark to run was to start the compilation of the rust package with all the four cores of my T470 laptop and run obsdfreqd with various temperature limits and see how it goes.  The program did a good job at reducing the CPU frequency to keep the temperature around the threshold.

=> static/bench_freq_temp.png Diagram of benchmark results of various temperature limitation

# Conclusion

While this is ultimately not a replacement for the in-kernel frequency scheduler, it can be used to keep a computer a lot cooler or make a system comply with some specific requirements (performance for given battery life or maximum temperature).

The customization is so that you can have various settings depending if the system is running on battery or not, which can be tailored to suit every kind of user.  The defaults are made to provide good performance when on AC, and provide a balanced performance/battery life mode when on battery.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-cool-frequency.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-cool-frequency.gmi</link>
  <pubDate>Mon, 21 Mar 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Reproducible clean $HOME in OpenBSD using impermanence</title>
  <description>
    <![CDATA[
<pre># Introduction

Let me present you my latest project: home-impermanence, under this name is a reference to the NixOS community project impermanence.  The name may not be obvious about what it is doing, let me explain.

=> https://nixos.wiki/wiki/Impermanence NixOS wiki about Impermanence, a community module
=> https://tildegit.org/solene/home-impermanence home-impermanence for OpenBSD

The original goal of impermanence in NixOS is to have a fully reproducible system mounted on tmpfs where only user-defined files and directories are hooked into the temporary file system to be persistent (such as /var/lib, /var/lib and some /etc files for instance).  Why this is something achievable on NixOS, on OpenBSD side we are far from having the tooling to go that deep so I wrote home-impermanence that allows an user to just do that at their $HOME level.

What does it mean exactly? When you start your system, your $HOME directory will be mounted with an empty memory based file system (using mfs) and symbolic links to files and directories listed in the configuration file will be done in your $HOME.  Every time you reboot, you will have the exact same set of files, extra files created meanwhile will be lost.  When you hold a $HOME directory for long, you know you get many directories and files created in various ~/.config or ~/.local or directly as dotfiles in the top level of the home directory, with impermanence you can get ride of all the noise.

A benefit is that you can run software as if it was their first run, in some software upgrade you will avoid old settings that would create troubles, or settings that would disturb a whole class of applications (like a gtk setting affecting all gtk programs), with impermanence the user can decide exactly what should remain across reboots or disappear.

# Implementation

My implementation is a Perl script relying on some libraries packaged on OpenBSD, it will run as root from a rc service and the settings done in rc.conf.local.  It will read the configuration file from the persistent directory holding the user data and create symlinks in the target directory to the files and directories, doing some sanitizing in the process to prevent listed files to be included in listed directories which would nest symlinks incorrectly.

I chose Perl because it's a stable language, OpenBSD ships with Perl and the very few dependencies required were already available in the ports tree.

The program could easily be ported to Linux, FreeBSD and maybe NetBSD, the mount_mfs calls could be replaced by a mount_tmpfs and the directories symlinks could be done with a mount_bind or mount_nullfs which we don't have on OpenBSD, if someone wants to port my project to another system I could help adding the required logic.

# How to use

I wrote a complete README file explaining the installation and configuration process, for full instructions refer to this document and the man page that ships with home-impermanence.

=> https://tildegit.org/solene/home-impermanence/src/branch/main/README.md home-impermanence README

## Installation

Quick method:

git clone https://tildegit.org/solene/home-impermanence/

cd home-impermanence

doas make install

doas rcctl enable impermanence

doas rcctl set impermanence flags -u user -d /home/persist/

doas install -d /home/persist/


From now, you may want to make things quickly, logout from your user and run these commands, this will move your user directory and prepare the mountpoint.

mv /home/user /home/persist/user

install -d -o user -g wheel /home/user


Now, it's time to configure impermanence before running it.

## Configuration

Reusing the paths from the installation example, the configuration file should be in /home/persist/user/impermanence.yml , the file must be using YAML formatting.  Here is my personal configuration file that you can use as a base.

size: 500m

files:

- .Xdefaults

- .Xresources

- .bashrc

- .gitconfig

- .kshrc

- .profile

- .xsession

- .tmux.conf

- .config/kwalletrc

directories:

- .claws-mail

- .config/Thunar

- .config/asciinema

- .config/gajim

- .config/kak

- .config/keepassxc

- .config/lagrange

- .config/mpv

- .config/musikcube

- .config/openttd

- .config/xfce4

- .config/zim

- .local/share/cozy

- .local/share/gajim

- .local/share/ibus-typing-booster

- .local/share/kwalletd

- .mozilla

- .ssh

- Documents

- Downloads

- Music

- bin

- dev

- notes

- tmp


When you think you are done, start the impermanence rc service with rcctl start impermanence and log-in.  You should see all the symlinks you defined in your configuration file.

## Result

Here is the content of my $HOME directory when I use impermanence.

solene@daru ~> ls -la

total 104

drwxr-xr-x 8 solene wheel 1024 Mar 15 12:10 .

drwxr-xr-x 17 root wheel 512 Mar 14 15:36 ..

-rw------- 1 solene wheel 165 Mar 15 09:08 .ICEauthority

-rw------- 1 solene solene 53 Mar 15 09:08 .Xauthority

lrwxr-xr-x 1 root wheel 34 Mar 15 09:08 .Xdefaults -> /home/permanent//solene/.Xdefaults

lrwxr-xr-x 1 root wheel 35 Mar 15 09:08 .Xresources -> /home/permanent//solene/.Xresources

-rw-r--r-- 1 solene wheel 48 Mar 15 12:07 .aspell.en.prepl

-rw-r--r-- 1 solene wheel 42 Mar 15 12:07 .aspell.en.pws

lrwxr-xr-x 1 root wheel 31 Mar 15 09:08 .bashrc -> /home/permanent//solene/.bashrc

drwxr-xr-x 9 solene wheel 512 Mar 15 12:10 .cache

lrwxr-xr-x 1 root wheel 35 Mar 15 09:08 .claws-mail -> /home/permanent//solene/.claws-mail

drwx------ 8 solene wheel 512 Mar 15 12:27 .config

drwx------ 3 solene wheel 512 Mar 15 09:08 .dbus

lrwxr-xr-x 1 root wheel 34 Mar 15 09:08 .gitconfig -> /home/permanent//solene/.gitconfig

drwx------ 3 solene wheel 512 Mar 15 12:32 .gnupg

lrwxr-xr-x 1 root wheel 30 Mar 15 09:08 .kshrc -> /home/permanent//solene/.kshrc

drwx------ 3 solene wheel 512 Mar 15 09:08 .local

lrwxr-xr-x 1 root wheel 32 Mar 15 09:08 .mozilla -> /home/permanent//solene/.mozilla

lrwxr-xr-x 1 root wheel 32 Mar 15 09:08 .profile -> /home/permanent//solene/.profile

lrwxr-xr-x 1 solene wheel 30 Mar 15 12:10 .sbclrc -> /home/permanent/solene/.sbclrc

drwxr-xr-x 2 solene wheel 512 Mar 15 09:08 .sndio

lrwxr-xr-x 1 root wheel 28 Mar 15 09:08 .ssh -> /home/permanent//solene/.ssh

lrwxr-xr-x 1 root wheel 34 Mar 15 09:08 .tmux.conf -> /home/permanent//solene/.tmux.conf

lrwxr-xr-x 1 root wheel 33 Mar 15 09:08 .xsession -> /home/permanent//solene/.xsession

-rw------- 1 solene wheel 25273 Mar 15 13:26 .xsession-errors

lrwxr-xr-x 1 root wheel 33 Mar 15 09:08 Documents -> /home/permanent//solene/Documents

lrwxr-xr-x 1 root wheel 33 Mar 15 09:08 Downloads -> /home/permanent//solene/Downloads

lrwxr-xr-x 1 root wheel 30 Mar 15 09:08 HANGAR -> /home/permanent//solene/HANGAR

lrwxr-xr-x 1 root wheel 27 Mar 15 09:08 dev -> /home/permanent//solene/dev

lrwxr-xr-x 1 root wheel 29 Mar 15 09:08 notes -> /home/permanent//solene/notes

lrwxr-xr-x 1 root wheel 33 Mar 15 09:08 quicklisp -> /home/permanent//solene/quicklisp

lrwxr-xr-x 1 root wheel 27 Mar 15 09:08 tmp -> /home/permanent//solene/tmp


## Rollback

If you want to rollback it's easy, disable impermanence, move /home/persist/user to /home/user and you are done.

# Conclusion

I really don't want to go back to not using impermanence since I tried it on NixOS.  I thought implementing it only for $HOME would be good enough as a start and started thinking about it, made a proof of concept to see if the symbolic links method was enough to make it work, and it was!

I hope you will enjoy this as much as I do, feel free to contact me if you need some help understanding the setup.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-impermanence.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-impermanence.gmi</link>
  <pubDate>Tue, 15 Mar 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Reed-alert: five years later</title>
  <description>
    <![CDATA[
<pre># Introduction

I wrote the program reed-alert five years ago, I've been using it since its first days, here is some feed back about it.

The software reed-alert is meant to be used by system administrators who want to monitor their infrastructures and get alerts when things go wrong.  I got a lot more experience in the monitoring field over time and I wanted to share some thoughts about this project.

=> https://tildegit.org/solene/reed-alert reed-alert source code

# Reed-alert

## The name

The software name is a pun I found in a Star Trek Enterprise episode.

=> https://memory-alpha.fandom.com/wiki/Red_alert#Notable_uses Reed alert pun origins

## Project finished

The code didn't receive many commits over the last years, I consider the program to be complete with regard to features, but new probes could be added, or bug fixes could be done.  But the core of the software itself is perfect to me.

The probes are small parts of code allowing to monitor extra states, like http return code, working ping, service started etc...  It's already easy to extend reed-alert using a shell command returning 0 or not 0 to define a custom probe.

## Reliability

I don't remember having a single issue with reed-alert since I've set it up on my server.  It's run by a cron job every 10 minutes, this mean a common lisp interpreter is loading the code, evaluating the configuration file, running the check commands and alerts commands if required, and stops.  I chose a serviceless paradigm for reed-alert as it make the code and usage a lot simpler.  With a running service, it could fail, leak memory, be exploited and certainly many other bugs I can't think of.

Reed-alert is simple as it only need a common lisp interpreter, the most notable sbcl and ecl interpreters are absolutely reliable and change very little over time.  Some unix standard commands are required for some checks or default alerts, such as ping, service, mail or curl but this defers all the work to well established binaries.

The source code is minimal with 179 lines for reed-alert core and 159 lines for the probes, a total of 338 lines of code (including empty lines and comments), hacking on reed-alert is super easy and always a lot of fun for me.  For whatever reason, my common lisp software often work at first try when I add new features, so it's always pleasant to work on them.

## Awesome features

One aspect of reed-alert that may disturb users at first is the choice of common lisp code as a configuration file, this may look complicated at first, but a simple configuration doesn't require more common lisp knowledge than what is explained in reed-alert documentation.  But it gives all its power when you need to loop over a data entry to run checks, allowing to make reed-alert dynamic instead of handwriting all the configuration.

The use of common lisp as configuration has other advantages, it's possible to chain checks to easily prevent some checks to be done in case a condition is failing.  Let me give a few examples for this:



All the previous conditions can be done with reed-alert thanks to the code-as-configuration choice.

## Scalability

I've been asked a few times if reed-alert could be used in a professional context.  Depending on what you call a professional environment, I will reply it depends.

Reed-alert is dumb, it needs to be run from a scheduling software (such as cron) and will sequentially run the checks.  It won't guarantee a perfect timing between checks.

If you need multiples machines to run a set of checks, reed-alert is not able to share the states to continue to work reliably in a high availability environment.

In regard to resources usage, while reed-alert is small it needs to run the command lisp interpreter every time, if you want to run reed-alert every minute or multiple time per minute, I'd recommend using something else.

# A real life example

Here is a chunk of the configuration I've been running for years, it checks the system itself and some remote servers.

(=> mail disk-usage :path "/" :limit 60 :desc "partition /")

(=> mail disk-usage :path "/var" :limit 70 :desc "partition /var")

(=> mail disk-usage :path "/home" :limit 95 :desc "partition /home")

(=> mail service :name "dovecot")

(=> mail service :name "spamd")

(=> mail service :name "dkimproxy_out")

(=> mail service :name "smtpd")

(=> mail service :name "ntpd")

(=> mail number-of-processes :limit 140)

;; check dataswamp server is working

(=> mail ping :host "dataswamp.org" :desc "Dataswamp")

;; check webzine related web servers

(and

(=> mail ping :host "openports.pl" :desc "Liaison Grifon.fr")

(=> mail curl-http-status :url "https://webzine.puffy.cafe" :desc "Webzine Puffy.cafe" :timeout 10)

(=> mail curl-http-status :url "https://puffy.cafe" :desc "Puffy.cafe" :timeout 10)

(=> mail ssl-expiration :host "webzine.puffy.cafe" :seconds (* 7 24 60 60))

(=> mail ssl-expiration :host "puffy.cafe" :seconds (* 7 24 60 60)))

;; check openports.pl is working

(and

(=> mail ping :host "46.23.90.152" :desc "Openports.pl ping")

(=> mail curl-http-status :url "http://46.23.90.152" :desc "Packages OpenBSD http" :timeout 10))

;; check www.openbsd.org website is replying under 10 seconds

(=> mail curl-http-status :url "https://www.openbsd.org" :desc "OpenBSD.org" :timeout 10)

;; check if a XML file is created regularly and valid

(=> mail file-updated :path "/var/www/htdocs/solene/openbsd-current.xml" :limit 1440)

(=> mail command :command (format nil "xmllint /var/www/htdocs/solene/openbsd-current.xml") :desc "XML openbsd-current.xml is not valid")

;; monitoring multiple gopher servers

(loop for host in '("grifon.fr" "dataswamp.org" "gopherproject.org")

do

(=> mail command

:try 6

:command (format nil "echo '/is-alive?done-by-solene-at-libera' | nc -w 3 ~a 70" host)

:desc (concatenate 'string "Gopher " host)))

(quit)


# Conclusion

I wrote a simple software using an old programming language (Common LISP ANSI is from 1994), the result is that it's reliable over time, require no code maintenance and is fun to code on.

=> https://en.wikipedia.org/wiki/Common_Lisp Common Lisp on Wikipedia
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/five-years-of-reed-alert.gmi</guid>
  <link>gemini://perso.pw/blog//articles/five-years-of-reed-alert.gmi</link>
  <pubDate>Thu, 10 Feb 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Harden your NixOS workstation</title>
  <description>
    <![CDATA[
<pre># Introduction

Coming from an OpenBSD background, I wanted to harden my NixOS system for better security.  As you may know (or not), security mitigations must be thought against a security threat model.  My model here is to prevent web browsers to leak data, prevent services to be exploitable remotely and prevent programs from being exploited to run malicious code.

NixOS comes with a few settings to improve in these areas, I'll share a sample of configuration to increase the default security.  Unrelated to security defense itself, but you  should absolutely encrypt your filesystem, so in case of physical access to your computer no data could be extracted.

# Use the hardened profile

There are a few profiles available by default in NixOS which are files with a set of definitions and one of them is named "hardened" because it enables many security measures.

=> https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/hardened.nix Link to the hardened profile definition

Here is a simplified list of important changes:



Of course, using this mode will slightly reduce the system performance and may trigger some runtime problems due to the memory management being less permissive.  On one hand, it's good because it allows to catch programming errors, but on the other hand it's not fun to have your programs crashing when you need them.

With the scudo memory allocator, I have troubles running Firefox, it will only start after 2 or 3 crashes and then will work fine.  There is a less permissive allocator named graphene-hardened, but I had too much troubles running programs with it.

# Use firewall

One simple rule is to block any incoming traffic that would connect to listening services.  It's way more secure to block everything and then allow the services you know must be open to the outside than relying on the service's configuration to not listen on public interfaces.

# Use Clamav

Clamav is an antivirus, and yes it can be useful on Linux.  If it can prevent you at least once to run a hostile binary, then it's worth running it.

# Firejail

I featured firejail previously on my blog, I'm convinced of its usefulnes.  You can run a program using firejail, and it will restrict its permissions and rights so in case of security breach, the program will be restricted.
This is rather important to run web browsers with it because it will prevent them any access to the filesystem except ~/Downloads/ and a few required directories (local profile, /etc/resolv.conf, font cache etc...).

# Enable this on NixOS

Because NixOS is declarative, it's easy to share the configuration.  My configuration supports both Firefox and Chromium, you can remove the related lines you don't need.
Be careful about the import declaration, you certainly already have one for the ./hardware-configuration.nix file.

imports =

[

./hardware-configuration.nix

<nixpkgs/nixos/modules/profiles/hardened.nix>

];

# enable firewall and block all ports

networking.firewall.enable = true;

networking.firewall.allowedTCPPorts = [];

networking.firewall.allowedUDPPorts = [];

# disable coredump that could be exploited later

# and also slow down the system when something crash

systemd.coredump.enable = false;

# required to run chromium

security.chromiumSuidSandbox.enable = true;

# enable firejail

programs.firejail.enable = true;

# create system-wide executables firefox and chromium

# that will wrap the real binaries so everything

# work out of the box.

programs.firejail.wrappedBinaries = {

firefox = {

executable = "${pkgs.lib.getBin pkgs.firefox}/bin/firefox";

profile = "${pkgs.firejail}/etc/firejail/firefox.profile";

};

chromium = {

executable = "${pkgs.lib.getBin pkgs.chromium}/bin/chromium";

profile = "${pkgs.firejail}/etc/firejail/chromium.profile";

};

};

# enable antivirus clamav and

# keep the signatures' database updated

services.clamav.daemon.enable = true;

services.clamav.updater.enable = true;


Rebuild the system, reboot and enjoy your new secure system.

# Going further: network filtering

If you want to absolutely control your network connections, I'd absolutely recommend the service OpenSnitch.  This is a daemon that will listen to all the network done on the system and allow you to allow/block connections per executable/source/destination/protocol/many parameters.

OpenSnitch comes with a GUI app called opensnitch-ui which is mandatory, if the ui is not running, no filtering is done.  When the ui is running, every time a new connection is not matching an existing rule, you will be prompted with information telling you what executable is trying to do on which protocol with which host, then you can decide how long you allow this (or block).

Just use `services.opensnitch.enable = true;` in the system configuration and run opensnitch-ui program in your graphical session.  To have persistent rules, open opensnitch-ui, go in the Preferences menu and tab Database, choose "Database type: File" and pick a path to save it (it's a sqlite database).

From this point, you will have to allow / block all network done on your system, it can be time-consuming at first, but it's user-friendly enough and rules can be done like "allow this entire executable" so you don't have to allow every website visited by your web browser (but you could!). You may be surprised by the amount of traffic done by non networking programs.  After some time, the rule set should be able to cope with most of your needs without needing to add new entries.

=> https://github.com/evilsocket/opensnitch/wiki/Getting-started OpenSnitch wiki: getting started
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/nixos-hardened.gmi</guid>
  <link>gemini://perso.pw/blog//articles/nixos-hardened.gmi</link>
  <pubDate>Thu, 13 Jan 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>How to pin a nix-shell environment using niv</title>
  <description>
    <![CDATA[
<pre># Introduction

In the past I shared a bit about Nix nix-shell tool, allowing to have a "temporary" environment with a specific set of tools available.  I'm using it on my blog to get all the dependencies required to rebuild it without having to remember what programs to install.

But while this method was practical, as I'm running NixOS development version (called unstable channel), I have to download the new versions of the dependencies every time I use the nix shell.  This is long on my DSL line, and also a waste of bandwidth.

There is a way to pin the version of the packages, so I always use the exact same environment, whatever the version of my nix.

# Use niv tool

Let's introduce you to niv, a program to manage nix dependencies, for this how-to I will only use a fraction of its features.  We just want it to init a directory with a default configuration pinning the nixpkgs repository to a branch / commit ID, and we will tell the shell to use this version.

=> https://github.com/nmattia/niv niv project GitHub homepage

Let's start by running niv (you can get niv from nix package manager) in your directory:

niv init


It will create a nix/ directory with two files: sources.json and sources.nix, looking at the content is not fascinating here (you can take a look if you are curious though).  The default is to use the latest nixpkgs release.

# Create a shell.nix file

My previous shell.nix file looked like this:

with (import <nixpkgs> {});

mkShell {

buildInputs = [

gnumake sbcl multimarkdown python3Full emacs-nox toot nawk mandoc libxml2

];

}


Yes, I need all of this for my blog to work because I have texts in org-mode/markdown/mandoc/gemtext/custom.  The blog also requires toot (for mastodon), sbcl (for the generator), make (for building and publishing).

Now, I will make a few changes to use the nix/sources.nix file to tell it where to get the nixpkgs information, instead of <nixpkgs> which is the system global.

let

sources = import ./nix/sources.nix;

pkgs = import sources.nixpkgs {};

in

with pkgs;

pkgs.mkShell {

buildInputs = [

gnumake sbcl multimarkdown python3Full emacs-nox

toot nawk mandoc libxml2

];

}


That's all!  Now, when I run nix-shell in the directory, I always get the exact same shell and set of packages every day.

# How to update?

Because it's important to update from time to time, you can easily manage this using niv, it will bump the latest commit id of the branch of the nixpkgs repository:

niv update nixpkgs -b master


When a new release is out, you can switch to the new branch using:

niv modify nixpkgs -a branch=release-21.11


# Using niv with configuration.nix

It's possible to use niv to pin the git revision you want to use to build your system, it's very practical for many reasons like following the development version on multiple machines with the exact same revision.  The snippet to use sources.nix for rebuilding the system is a bit different.

Replace "{ pkgs, config, ... }:" with:

{

sources ? import ./nix/sources.nix,

pkgs ? import sources.nixpkgs {},

config, ...

}:


Of course, you need to run "niv init" in /etc/nixos/ before if you want to manage your system with niv.

# Extra tip: automatically run nix-shell with direnv

It's particularly comfortable to have your shell to automatically load the environment when you cd into a project requiring a nix-shell, this is doable with the direnv program.

=> https://nixos.org/guides/declarative-and-reproducible-developer-environments.html#declarative-reproducible-envs nixos documentation about direnv usage
=> https://direnv.net/ direnv project homepage

This can be done in 3 steps after you installed direnv in your profile:

1. create a file .envrc in the directory with the content "use nix" (without double quotes of course)
2. execute "direnv allow"
3. create the hook in your shell, so it knows how to do with direnv (do this only once)

=> https://direnv.net/docs/hook.html How to hook direnv in your shell

Everytime you will cd into the directory, nix-shell will be automatically started.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/nix-niv-shell.gmi</guid>
  <link>gemini://perso.pw/blog//articles/nix-niv-shell.gmi</link>
  <pubDate>Wed, 12 Jan 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>My plans for 2022</title>
  <description>
    <![CDATA[
<pre>Greetings dear readers, I wish you a happy new year and all the best.  Like I did previously at the new year time, although it's not a yearly exercise, I would like to talk about the blog and my plan for the next twelve months.

# About me

Let's talk about me first, it will make sense for the blog part after.  I plan to find a new job, maybe switch into the cybersecurity field or work in some position allowing me to contribute to an open source project, it's not that easy to find, but I have hope.

This year, I will work at getting new skills, this should help me find jobs, but I also think I've been a resting  a bit about learning over the last two years.  My plan is to dedicate 45 minutes every day to learn about a topic.  I already started doing so with some security and D language readings.

# About the blog

With regular learning time, I'm not sure yet if I will have much desire to write here as often as I did in 2021.  I'm absolutely sure the publication rate will drop, but I will try to maintain a minimum, because I'm learning I will want to share some ideas, experiences or knowledge hopefuly.

I'm thanksful to readers community I have, I often get feedback by email or IRC or mastodon about my posts, so I can fix them, extend them or rework them if I was wrong.  This is invaluable to me, it helps me to make connections to other people, and it's what make life interesting.

# Podcast

In December 2021, I had the chance to be interviewed by the people of the BSDNow podcast, I'm talking about how I got into open source, about my blog but also about the old laptop challenge I made last year.

=> https://www.bsdnow.tv/435 Access to the podcast link on BSDNow


Thanks everyone! Let's have fun with computers!</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/2022-new-year.gmi</guid>
  <link>gemini://perso.pw/blog//articles/2022-new-year.gmi</link>
  <pubDate>Sat, 08 Jan 2022 00:00:00 GMT</pubDate>
</item>
<item>
  <title>My NixOS configuration</title>
  <description>
    <![CDATA[
<pre># Introduction

Let me share my NixOS configuration file, the one in /etc/nixos/configuration.nix that describe what is installed on my Lenovo T470 laptop.

The base of NixOS is that you declare every user, services, network and system settings in a file, and finally it configures itself to match your expectations.  You can also install global packages and per-user packages.  It makes a system environment reproducible and reliable.

# The file

{ config, pkgs, ... }:

{

imports =

[ # Include the results of the hardware scan.

./hardware-configuration.nix

];

# run garbage collector at 19h00 everyday

# and remove stuff older than 60 days

nix.gc.automatic = true;

nix.gc.dates = "19:00";

nix.gc.persistent = true;

nix.gc.options = "--delete-older-than 60d";

# clean /tmp at boot

boot.cleanTmpDir = true;

# latest kernel

boot.kernelPackages = pkgs.linuxPackages_latest;

# sync disk when buffer reach 6% of memory

boot.kernel.sysctl = {

"vm.dirty_ratio" = 6;

};

# allow non free stuff

nixpkgs.config.allowUnfree = true;

# Use the systemd-boot EFI boot loader.

boot.loader.systemd-boot.enable = true;

boot.loader.efi.canTouchEfiVariables = true;

networking.hostName = "t470";

time.timeZone = "Europe/Paris";

networking.networkmanager.enable = true;

# wireguard VPN

networking.wireguard.interfaces = {

wg0 = {

ips = [ "192.168.5.1/24" ];

listenPort = 1234;

privateKeyFile = "/root/wg-private";

peers = [

{ # server

publicKey = "MY PUB KEY";

endpoint = "SERVER:PORT";

allowedIPs = [ "192.168.5.0/24" ];

}];

};

};

# firejail firefox by default

programs.firejail.wrappedBinaries = {

firefox = {

executable = "${pkgs.lib.getBin pkgs.firefox}/bin/firefox";

profile = "${pkgs.firejail}/etc/firejail/firefox.profile";

};

};

# azerty keyboard <3

i18n.defaultLocale = "fr_FR.UTF-8";

console = {

# font = "Lat2-Terminus16";

keyMap = "fr";

};

# clean logs older than 2d

services.cron.systemCronJobs = [

"0 20 * * * root journalctl --vacuum-time=2d"

];

# nvidia prime offload rendering for eGPU

hardware.nvidia.modesetting.enable = true;

hardware.nvidia.prime.sync.allowExternalGpu = true;

hardware.nvidia.prime.offload.enable = true;

hardware.nvidia.prime.nvidiaBusId = "PCI:10:0:0";

hardware.nvidia.prime.intelBusId = "PCI:0:2:0";

services.xserver.videoDrivers = ["nvidia" ];

# programs

programs.steam.enable = true;

programs.firejail.enable = true;

programs.fish.enable = true;

programs.gamemode.enable = true;

programs.ssh.startAgent = true;

# services

services.acpid.enable = true;

services.thermald.enable = true;

services.fwupd.enable = true;

services.vnstat.enable = true;

# Enable the X11 windowing system.

services.xserver.enable = true;

services.xserver.displayManager.sddm.enable = true;

services.xserver.desktopManager.plasma5.enable = true;

services.xserver.desktopManager.xfce.enable = false;

services.xserver.desktopManager.gnome.enable = false;

# Configure keymap in X11

services.xserver.layout = "fr";

services.xserver.xkbOptions = "eurosign:e";

# Enable sound.

sound.enable = true;

hardware.pulseaudio.enable = true;

# Enable touchpad support

services.xserver.libinput.enable = true;

users.users.solene = {

isNormalUser = true;

shell = pkgs.fish;

packages = with pkgs; [

gajim audacity chromium dmd dtools

kate kdeltachat pavucontrol rclone rclone-browser

zim claws-mail mpv musikcube git-annex

];

extraGroups = [ "wheel" "sudo" "networkmanager" ];

};

# my gaming users running steam/lutris/emulators

users.users.gaming = {

isNormalUser = true;

shell = pkgs.fish;

extraGroups = [ "networkmanager" "video" ];

packages = with pkgs; [ lutris firefox ];

};

users.users.aria = {

isNormalUser = true;

shell = pkgs.fish;

packages = with pkgs; [ aria2 ];

};

# global packages

environment.systemPackages = with pkgs; [

ncdu kakoune git rsync restic tmux fzf

];

# Enable the OpenSSH daemon.

services.openssh.enable = true;

# Open ports in the firewall.

networking.firewall.enable = true;

networking.firewall.allowedTCPPorts = [ 22 ];

networking.firewall.allowedUDPPorts = [ ];

# user aria can only use tun0

networking.firewall.extraCommands = "

iptables -A OUTPUT -o lo -m owner --uid-owner 1002 -j ACCEPT

iptables -A OUTPUT -o tun0 -m owner --uid-owner 1002 -j ACCEPT

iptables -A OUTPUT -m owner --uid-owner 1002 -j REJECT

";

# This value determines the NixOS release from which the default

# settings for stateful data, like file locations and database versions

# on your system were taken. It‘s perfectly fine and recommended to leave

# this value at the release version of the first install of this system.

# Before changing this value read the documentation for this option

# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).

system.stateVersion = "21.11"; # Did you read the comment?

}

</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/my-nixos.gmi</guid>
  <link>gemini://perso.pw/blog//articles/my-nixos.gmi</link>
  <pubDate>Tue, 21 Dec 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Restrict users to a network interface on Linux</title>
  <description>
    <![CDATA[
<pre># Introduction

If for some reasons you want to prevent a system user to use network interfaces except one, it's doable with a couple of iptables commands.

The use case would be to force your user to go through a VPN and make sure it can't reach the Internet if the VPN is not available.

=> https://linux.die.net/man/8/iptables iptables man page

# Iptables

We can use simple rules using the "owner" module, basically, we will allow traffic through tun0 interface (the VPN) for the user, and reject traffic for any other interface.

Iptables is applying first matching rule, so if traffic is going through tun0, it's allowed and otherwise rejected.  This is quite simple and reliable.

We will need the user id (uid) of the user we want to restrict, this can be found as third field of /etc/passwd or by running "id the_user".

iptables -A OUTPUT -o lo -m owner --uid-owner 1002 -j ACCEPT

iptables -A OUTPUT -o tun0 -m owner --uid-owner 1002 -j ACCEPT

iptables -A OUTPUT -m owner --uid-owner 1002 -j REJECT


Note that instead of --uid-owner it's possible to use --gid-owner with a group ID if you want to make this rule for a whole group.

To make the rules persistent across reboots, please check your Linux distribution documentation.

# Going further

I trust firewall rules to do what we expect from them.  Some userland programs may be able to restrict the traffic, but we can't know for sure if it's truly blocking or not.  With iptables, once you made sure the rules are persistent, you have a guarantee that the traffic will be blocked.

There may be better ways to achieve the same restrictions, if you know one that is NOT complex, please share!
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/linux-forbid-user-except-vpn.gmi</guid>
  <link>gemini://perso.pw/blog//articles/linux-forbid-user-except-vpn.gmi</link>
  <pubDate>Mon, 20 Dec 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Playing video games on Linux</title>
  <description>
    <![CDATA[
<pre># Introduction

While I mostly make posts about playing on OpenBSD, I also do play video games on Linux.  There is a lot more choice, but it comes with the price that the choice comes from various sources with pros and cons.

# Commercial stores

There are a few websites where you can get games:

## itch.io

Itch.io is dedicated to indie games, you can find many games running on Linux, most games there are free.  Most games could be considered "amateurish" but it's a nice pool from which some gems get out like Celeste, Among Us or Noita.

=> https://itch.io/ itch.io website

## Steam

It is certainly the biggest commercial platform, it requires the steam desktop Client and an account to be useful.  You can find many free-to-play video games, (including some open source games like OpenTTD or Wesnoth who are now available on Steam for free) but also paid games.  Steam is working hard on their tool to make Windows games running on Linux (based on Wine + many improvements on the graphic stack).  The library manager allows Linux games filtering if you want to search native games.  Steam is really a big DRM platform, but it also works well.

=> https://store.steampowered.com/ Steam website

## GOG

GOG is a webstore selling video games (many old games from people's childhood but not only), they only require you to have an account.  When you buy a game in their store, you have to download the installer, so you can keep/save it, without any DRM beyond the account registration on their website to buy games.

=> https://www.gog.com/ GOG website

## Your packager manager / flatpak

There are many open source video games around, they may be available in your package manager, allowing a painless installation and maintenance.

Flatpak package manager also provides video games, some are recent and complex games that are not found in many package managers because of the huge work required.

=> https://flathub.org/apps/collection/editors-choice-games flathub flatpak repository, games page

## Developer's website

Sometimes, when you want to buy a game, you can buy it directly on the developer's website, it usually comes without any DRM and doesn't rely on a third party vendor.  I know I did it for Rimworld, but some other developers offer this "service", it's quite rare though.

## Epic game store

They do not care about Linux.

# Streaming services

It's now possible to play remotely through "cloud computing", using a company's computer with a good graphic card.  There are solutions like Nvidia with Geforce Now or Stadia from Google, both should work in a web browser like Chromium.

They require a very decent Internet access with at least 15 MB/s of download speed for a 1080p stream but will work almost anywhere.

# How to manage games

Let me describe a few programs that can be used to manage games libraries.

## Steam

As said earlier, Steam has its own mandatory desktop client to buy/install/manage games.

## Lutris

Lutris is an ambitious open source project, it aims to be a game library manager allowing to mix any kind of game: emulation / Steam / GOG / Itch.io / Epic game Store (through Wine) / Native linux games etc...

Its website is a place where people can send recipes for installing some games that could be complicated, allowing to automate and distribute in the community ways to install some games.  But it makes very easy to install games from GOG.  There is a recent feature to handle the Epic game store, but it's currently not really enjoyable and the launcher itself running through wine draw for CPU like madness.

It has nice features such as activating a HUD for displaying FPS, automatically run "gamemode" (disabling screen effects, doing some optimization), easy offloading rendering to graphic card, set locale or switch to qwerty per game etc...

It's really a nice project that I follow closely, it's very useful as a Linux gamer.

=> https://lutris.net/ lutris project website

## Minigalaxy

Minigalaxy is a GUI to manage GOG games, installing them locally with one click, keeping them updated or installing DLC with one click too.  It's really simplistic compared to Lutris, but it's made as a simple client to manage GOG games which is perfectly fine.

Minigalaxy can update games while Lutris can't, both can be used on the same installed video games.  I find these two are complementary.

=> https://sharkwouter.github.io/minigalaxy/ Minigalaxy project website

## play.it

This tool is a set of script to help you install native Linux video games in your system, depending on their running method (open source engine, installer, emulator etc...).

=> https://www.dotslashplay.it/en/start play.it official website

# Conclusion

It has never been so easy to play video games on Linux.  Of course, you have to decide if you want to run closed sources programs or not.  Even if some games are closed sources, some fans may have developed a compatible open source engine from scratch to play it again natively given you have access to the "assets" (sets of files required for the game which are not part of the engine, like textures, sounds, databases).

=> https://en.wikipedia.org/wiki/List_of_game_engine_recreations List of game engine recreation (Wikipedia EN)
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/playing-on-linux.gmi</guid>
  <link>gemini://perso.pw/blog//articles/playing-on-linux.gmi</link>
  <pubDate>Sun, 19 Dec 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>OpenVPN on OpenBSD in its own rdomain to prevent data leak</title>
  <description>
    <![CDATA[
<pre># Introduction

Today I will explain how to establish an OpenVPN tunnel through a dedicated rdomain to only expose the VPN tunnel as an available interface, preventing data leak outside the VPN (and may induce privacy issues).  I did the same recently for WireGuard tunnels, but it had an integrated mechanism for this.

Let's reuse the network diagram from the WireGuard text to explain:

+-------------+

| server | tun0 remote peer

| |---------------+

+-------------+ |

| public IP |

| 1.2.3.4 |

| |

| |

/\/\/\/\/\/\/\ |OpenVPN

| internet | |VPN

\/\/\/\/\/\/\/ |

| |

| |

|rdomain 1 |

+-------------+ |

| computer |---------------+

+-------------+ tun0

rdomain 0 (default)


We have our computer and have been provided an OpenVPN configuration file, we want to establish the OpenVPN toward the server 1.2.3.4 using rdomain 1.  We will set our network interfaces into rdomain 1 so when the VPN is NOT up, we won't be able to connect to the Internet (without the VPN).

# Network configuration

Add "rdomain 1" to your network interfaces configuration file like "/etc/hostname.trunk0" if you use a trunk interface to aggregate Ethernet/Wi-Fi interfaces into an automatic fail over trunk, or in each interface you are supposed to use regularly.  I suppose this setup is mostly interesting for wireless users.

Create a "/etc/hostname.tun0" file that will be used to prepare the tun0 interface for OpenVPN, add "rdomain 0" to the file, this will be enough to create the tun0 interface at startup. (Note that the keyword "up" would work too, but if you edit your files I find it easier to understand the rdomains of each interface).

Run "sh /etc/netstart" as root to apply changes done to the files, you should have your network interfaces in rdomain 1 now.

# OpenVPN configuration

From here, I assume your OpenVPN configuration works.  The OpenVPN client/server setup is out of the scope of this text.

We will use rcctl to ensure openvpn service is enabled (if it's already enabled this is not an issue), then we will configure it to use rtable 1 to run, this mean it will connect through the interfaces in the rdomain 1.

If your OpenVPN configuration runs a script to set up the route(s) (through "up /etc/something..." directive in the configuration file), you will have to by add parameter -T0 to the command route in the script.  This is important because openvpn will run in rdomain 1 so calls to "route" will apply to routing table 1, so you must change the route command to apply the changes in routing table 0.

rcctl enable openvpn

rcctl set openvpn rtable 1

rcctl restart openvpn


Now, you should have your tun0 interface in rdomain 0, being the default route and the other interfaces in rdomain 1.

If you run any network program it will go through the VPN, if the VPN is down, the programs won't connect to the Internet (which is the wanted behavior here).

# Conclusion

The rdomain and routing tables concepts are powerful tools, but they are not always easy to grasp, especially in a context of a VPN mixing both (one for connectivity and one for the tunnel).  People using VPN certainly want to prevent their programs to not go through the VPN and this setup is absolutely effective in that task.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-openvpn-exit.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-openvpn-exit.gmi</link>
  <pubDate>Thu, 16 Dec 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Persistency management of memory based filesystem on OpenBSD</title>
  <description>
    <![CDATA[
<pre># Introduction

For saving my SSD and also speeding up my system, I store some cache files into memory using the mfs filesystem on OpenBSD.  But that would be nice to save the content upon shutdown and restore it at start, wouldn't it?

I found that storing the web browser cache in a memory filesystem drastically improve its responsiveness, but it's hard to make measurements of it.

Let's do that with a simple rc.d script.

# Configuration

First, I use a mfs filesystem for my Firefox cache, here is the line in /etc/fstab

/dev/sd3b /home/solene/.cache/mozilla mfs rw,-s400M,noatime,nosuid,nodev 1 0


This mean I have a 400 MB partition using system memory, it's super fast but limited.  tmpfs is disabled in the default kernel because it may have issues and is not well enough maintained, so I stick with mfs which is available out of the box. (tmpfs is faster and only use memory when storing file, while mfs reserves the memory chunk at first).

# The script

We will write /etc/rc.d/persistency with the following content, this is a simple script that will store as a tgz file under /var/persistency every mfs mountpoint found in /etc/fstab when it receives the "stop" command.  It will also restore the files at the right place when receiving the "start" command.


!/bin/ksh

STORAGE=/var/persistency/

if [[ "$1" == "start" ]]

then

install -d -m 700 $STORAGE

for mountpoint in $(awk '/ mfs / { print $2 }' /etc/fstab)

do

tar_name="$(echo ${mountpoint#/} | sed 's,/,_,g').tgz"

tar_path="${STORAGE}/${tar_name}"

test -f ${tar_path}

if [ $? -eq 0 ]

then

cd $mountpoint

if [ $? -eq 0 ]

then

tar xzfp ${tar_path} && rm ${tar_path}

fi

fi

done

fi

if [[ "$1" == "stop" ]]

then

install -d -m 700 $STORAGE

for mountpoint in $(awk '/ mfs / { print $2 }' /etc/fstab)

do

tar_name="$(echo ${mountpoint#/} | sed 's,/,_,g').tgz"

cd $mountpoint

if [ $? -eq 0 ]

then

tar czf ${STORAGE}/${tar_name} .

fi

done

fi


All we need to do now is to use "rcctl enable persistency" so it will be run with start/stop at boot/shutdown times.

# Conclusion

Now I'll be able to carry my Firefox cache across reboots while keeping it in mfs.


</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-mfs-persistency.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-mfs-persistency.gmi</link>
  <pubDate>Wed, 15 Dec 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>What are the VPN available on OpenBSD</title>
  <description>
    <![CDATA[
<pre># Introduction

I wanted to write this text for some time, a list of VPN with encryption that can be used on OpenBSD.  I really don't plan to write about all of them but I thought it was important to show the choices available when you want to create a VPN between two peers/sites.

# VPN

VPN is an acronym for Virtual Private Network, is the concept of creating a network relying on a virtual layer like IP to connect computers, while regular network use physical network layer like Ethernet cable, wifi or light.

There are different VPN implementation existing, some are old, some are new.  They have pros and cons because they were done for various purpose.  This is a list of VPN protocols supported by OpenBSD (using base or packages).

## OpenVPN

Certainly the most known, it's free and open source and is widespread.

Pros:


Cons:


## WireGuard

A recent VPN protocol joined the party with an interesting approach.  It's supported by OpenBSD base system using ifconfig.

Pros:


Cons:


=> https://man.openbsd.org/ifconfig#WIREGUARD OpenBSD ifconfig man page anchored to WireGuard section
=> https://man.openbsd.org/wg#EXAMPLES Examples of wg interfaces setup

## SSH

SSH is known for being a secure way to access a remote shell but it can also be used to create a VPN with a tun interface.  This is not the best VPN solution available but at least it doesn't require much software and could be enough for some users.

Pros:


Cons:


## mlvpn

mlvpn is a software to aggregate links through VPN technology

Pros:


Cons:


## IPsec

IPSec is handled with iked in base system or using strongswan from ports.  This is the most used VPN protocol, it's reliable.

Pros:


Cons:


=> https://www.openbsd.org/faq/faq17.html OpenBSD FAQ about VPN

## Tinc

Meshed VPN that works without a central server, this is meant to be robust and reliable even if some peers are down.

Pros:


Cons:


Note that Tailscale is a solution to create something similar using WireGuard.

## Dsvpn

Pros:


Cons:


## Openconnect

I never heard of it before, I found it in the ports tree while writing this text.  There is openconnect package to act as a client and ocserv to act as a server.

Pros:


Cons:


## gre

gre is a special device on OpenBSD to create VPN without encryption, it's recommended to use it over IPSec.  I don't cover it more because I was emphasing on VPN with encryption.

=> https://man.openbsd.org/gre gre interface man page

# Conclusion

If you never used a VPN, I'd say OpenVPN is a good choice, it's versatile and it can easily bypass restrictions if you run it on port TCP/443.

I personnaly use WireGuard on my phone to reach my emails, because of WireGuard stateless protocol the VPN doesn't draw battery to maintain the connection and doesn't have to renogicate every time the phone gets Internet access.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/openbsd-vpn.gmi</guid>
  <link>gemini://perso.pw/blog//articles/openbsd-vpn.gmi</link>
  <pubDate>Sat, 11 Dec 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Port of the week: cozy</title>
  <description>
    <![CDATA[
<pre># Introduction

The Port of the week of this end of 2021 is Cozy a GTK audio book player.  There are currently not much alternative outside of audio players if you want to listen to audio books.

=> https://cozy.sh/ Cozy project website

# How to install

On OpenBSD I imported cozy in December 2021 so it will be available from OpenBSD 7.1 or now in -current, a simple "pkg_add cozy" is required to install.

On Linux, there is a flatpak package if your distribution doesn't provide a package.

# Features

Cozy provides a few features making it more interesting than a regular music player:



=> static/potw-cozy.png Screenshot of Cozy ready to play an audio book
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/potw-cozy.gmi</guid>
  <link>gemini://perso.pw/blog//articles/potw-cozy.gmi</link>
  <pubDate>Thu, 09 Dec 2021 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Nvidia card in eGPU and NixOS</title>
  <description>
    <![CDATA[
<pre># Updates



# Introduction

I previously wrote about using an eGPU on Gentoo Linux.  It was working when using the eGPU display but I never got it to work for accelerating games using the laptop display.

Now, I'm back on NixOS and I got it to work!

# What is it about?

My laptop has a thunderbolt connector and I'm using a Razer Core X external GPU case that is connected to the laptop using a thunderbolt cable.  This allows to use an external "real" GPU on a laptop but it has performance trade off and on Linux also compatibility issues.

There are three ways to use the nvidia eGPU:

- run the nvidia driver and use it as a normal card with its own display connected to the GPU, not always practical with a laptop
- use optirun / primerun to run programs within a virtual X server on that GPU and then display it on the X server (very clunky, originally created for Nvidia Optimus laptop)
- use Nvidia offloading module (it seems recent and I learned about it very recently)

The first case is easy, just install nvidia driver and use the right card, it should work on any setup.  This is the setup giving best performance.

The most complicated setup is to use the eGPU to render what's displayed on the laptop, meaning the video signal has to come back from the thunderbolt cable, reducing the bandwidth.

# Nvidia offloading

Nvidia made work in their proprietary driver to allow a program to have its OpenGL/Vulkan calls to be done in a GPU that is not the one used for the display.  This allows to throw optirun/primerun for this use case, which is good because they added performance penalty, complicated setup and many problems.

=> https://download.nvidia.com/XFree86/Linux-x86_64/435.17/README/primerenderoffload.html Official documentation about offloading with nvidia driver


# NixOS

I really love NixOS and for writing articles it's so awesome, because instead of a set of instructions depending on conditions, I only have to share the piece of config required.

This is the bits to add to your /etc/nixos/configuration.nix file and then rebuild system:

hardware.nvidia.modesetting.enable = true;

hardware.nvidia.prime.sync.allowExternalGpu = true;

hardware.nvidia.prime.offload.enable = true;

hardware.nvidia.prime.nvidiaBusId = "PCI:10:0:0";

hardware.nvidia.prime.intelBusId = "PCI:0:2:0";

services.xserver.videoDrivers = ["nvidia" ];


A few notes about the previous chunk of config:
- only add nvidia to the list of video drivers, at first I was adding modesetting but this was creating troubles
- the PCI bus ID can be found with lspci, it has to be translated in decimal, here my nvidia id is 10:0:0 but in lspci it's 0a:00:00 with 0a being 10 in hexadecimal

=> https://nixos.wiki/wiki/Nvidia#offload_mode NixOS wiki about nvidia offload mode

# How to use it

The use of offloading is controlled by environment variables.  What's pretty cool is that if you didn't connect the eGPU, it will still work (with integrated GPU).

## Running a command

We can use glxinfo to be sure it's working, add the environment as a prefix:

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo


## In Steam

Modify the command line of each game you want to run with the eGPU (it's tedious), by:

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia %command%


## In Lutris

Lutris has a per-game or per-runner setting named "Enable Nvidia offloading", you just have to enable it.

# Advanced usage / boot specialisation

Previously I only explained how to use the laptop screen and the eGPU as a discrete GPU (not doing display).  For some reasons, I've struggled a LOT to be able to use the eGPU display (which gives more performance because it's hitting less thunderbolt limitations).

I've discovered NixOS "specialisation" feature, allowing to add an alternative boot entry to start the system with slight changes, in this case, this will create a new "external-display" entry for using the eGPU as the primary display device:

hardware.nvidia.modesetting.enable = true;

hardware.nvidia.prime.sync.allowExternalGpu = true;

hardware.nvidia.prime.offload.enable = true;

hardware.nvidia.prime.nvidiaBusId = "PCI:10:0:0";

hardware.nvidia.prime.intelBusId = "PCI:0:2:0";

services.xserver.videoDrivers = ["nvidia" ];

# external display on the eGPU card

# otherwise it's discrete mode using laptop screen

specialisation = {

external-display.configuration = {

system.nixos.tags = [ "external-display" ];

hardware.nvidia.modesetting.enable = pkgs.lib.mkForce false;

hardware.nvidia.prime.offload.enable = pkgs.lib.mkForce false;

hardware.nvidia.powerManagement.enable = pkgs.lib.mkForce false;

services.xserver.config = pkgs.lib.mkOverride 0

''

Section "Module"

Load "modesetting"

EndSection

Section "Device"

Identifier "Device0"

Driver "nvidia"

BusID "10:0:0"

Option "AllowEmptyInitialConfiguration"

Option "AllowExternalGpus" "True"

EndSection

'';

};

};


With this setup, the default boot is the offloading mode but I can choose "external-display" to use my nvidia card and the screen attached to it, it's very convenient.

I had to force the xserver configuration file because the one built by NixOS was not working for me.
</pre>
    ]]>
  </description>
  <guid>gemini://perso.pw/blog//articles/nixos-egpu.gmi</guid>
  <link>gemini://perso.pw/blog//articles/nixos-egpu.gmi</link>
  <pubDate>Sun, 05 Dec 2021 00:00:00 GMT</pubDate>
</item>

  </channel>
</rss>