Some notes on anything… Most of the stuff noted here are probably (i) not really clear, (ii) not really true and (iii) not really useful.
Samsung N150 Plus
Install Arch Linux on an old Samsung N150 Plus netbook.
Characteristics
- CPU: Intel® Atom™ N455 @ 1.66 GHz
- Memory: 2 GB DDR3 SDRAM
- Hard Drive: 250 GB Serial ATA-150
Troubleshootings
- GRUB hangs
- Hyprland crashes
Arch Linux installation
See Arch Linux
Bootloader
Install SYSLINUX since GRUB does not work:
pacman -Sy syslinux
syslinux-install_update -i -a -m
Compositor
Install weston or sway since hyprland crashes:
pacman -Sy weston sway ttf-dejavu
Enable pipewire:
systemctl --user enable --now pipewire
Let's Encrypt
Obtain or renew a certificate, but do not install it:
email=triaxx@triaxx.io
domains="triaxx_io triaxx_net"
triaxx_io_subdomains="dev mx ns0 ns1 www"
triaxx_net_subdomains="dns mail ns www"
for _domain in ${domains} ; do
eval subdomains=\$${_domain}_subdomains
domain=`echo ${_domain} | sed -e 's,_,\.,g'`
domain_args="--domain ${domain}"
for _subdomain in ${subdomains} ; do
domain_args="${domain_args} --domain ${_subdomain}.${domain}"
done
certbot certonly \
--non-interactive \
--agree-tos \
--email ${email} \
--nginx \
${domain_args} \
--expand
done
Plan the automatic (monthly) update:
crontab -e
0 0 1 * * /usr/bin/certbot renew
Restart NGINX when new certificate is deployed:
Loop device
Setup
Mount a GPT disk stored on LVM:
losetup --partscan loop0 /dev/vg0/lv-vm0
mount /dev/loop0p3 /mnt
Gentoo
Installation
Fetch an installation image and extract it in a logical volume for use with Xen)
Partitioning
fdisk /dev/xvda
Welcome to fdisk (util-linux 2.41.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS (MBR) disklabel with disk identifier 0xeada774e.
Command (m for help): o
Created a new DOS (MBR) disklabel with disk identifier 0x10aabe84.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (1-4, default 1):
First sector (2048-67108863, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-67108863, default 67108863): +1G
Created a new partition 1 of type 'Linux' and of size 1 GiB.
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (2-4, default 2):
First sector (2099200-67108863, default 2099200):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2099200-67108863, default 67108863): +4G
Created a new partition 2 of type 'Linux' and of size 4 GiB.
Command (m for help): t
Partition number (1,2, default 2):
Hex code or alias (type L to list all): 82
Changed type of partition 'Linux' to 'Linux swap / Solaris'.
Command (m for help): n
Partition type
p primary (2 primary, 0 extended, 2 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (3,4, default 3):
First sector (10487808-67108863, default 10487808):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (10487808-67108863, default 67108863):
Created a new partition 3 of type 'Linux' and of size 27 GiB.
Command (m for help): p
Disk /dev/xvda: 32 GiB, 34359738368 bytes, 67108864 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x10aabe84
Device Boot Start End Sectors Size Id Type
/dev/xvda1 2048 2099199 2097152 1G 83 Linux
/dev/xvda2 2099200 10487807 8388608 4G 82 Linux swap / Solaris
/dev/xvda3 10487808 67108863 56621056 27G 83 Linux
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Filesystem creation
mkfs.xfs -c options=/usr/share/xfsprogs/mkfs/lts_6.18.conf /dev/xvda3
mkfs.ext4 /dev/xvda1
mkswap /dev/xvda2
mkdir --parents /mnt/gentoo
mount /dev/xvda3 /mnt/gentoo
swapon /dev/xvda2
mkdir /mnt/gentoo/boot
mount /dev/xvda1 /mnt/gentoo/boot
Stage installation
wget https://distfiles.gentoo.org/releases/amd64/autobuilds/20260503T164604Z/stage3-amd64-hardened-openrc-20260503T164604Z.tar.xz
Verify files:
DNS
Configure a DNS server on OpenBSD.
nsd
# rcctl enable nsd
Create configuration file:
# cat > /var/nsd/etc/nsd.conf << EOF
remote-control:
control-enable: yes
control-interface: /var/run/nsd.sock
server:
hide-version: yes
zone:
name: "triaxx.xyz"
zonefile: "master/triaxx.io.zone"
EOF
Check that configuration is correct:
# nsd-checkconf /var/nsd/etc/nsd.conf
# echo $?
0
Create zone file:
# cat > /var/nsd/zones/master/triaxx.io.zone << EOF
$TTL 86400
$ORIGIN triaxx.io.
@ IN SOA ns0.triaxx.io. hostmaster.triaxx.io. (
2026043000 ; serial
1800 ; refresh (30 mins)
900 ; retry (15 mins)
604800 ; expire (7 days)
1200 ) ; minimum (20 mins)
@ IN NS ns0
@ IN NS ns1
@ IN MX 10 mx
@ IN A 175.52.128.39
mx IN A 175.52.128.39
ns0 IN A 175.52.128.39
ns1 IN A 105.7.42.123
EOF
Check that zone is correct:
OpenBSD
Installation
Fetch the installation image (that can be use with Xen):
# wget https://cdn.openbsd.org/pub/OpenBSD/7.8/amd64/install78.img
The installer can be used to easily install a functional system.
Packages
Install pkg_locate to find files in OpenBSD packages:
# pkg_add pkglocatedb
quirks-7.147 signed on 2025-10-10T23:15:26Z
pkglocatedb-1.5: ok
Services
Enable and start nsd:
# rcctl enable nsd
# rcctl start nsd
nftables
Netfilter configuration
Enable IP forwarding:
# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
Make it persitent:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
Connection forwarding
#!/usr/sbin/nft -f
flush ruleset
define inet_if = "enp1s0"
define inet_ip = "194.153.151.88"
define vm1_ip = "192.168.0.2"
table inet filter {
chain input {
type filter hook input priority filter;
}
chain forward {
type filter hook forward priority filter;
ct state established,related accept
}
chain output {
type filter hook output priority filter;
}
}
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat;
iifname $inet_if tcp dport 80 dnat to $vm1_ip
}
chain postrouting {
type nat hook postrouting priority srcnat;
ip saddr $vm1_ip oifname $inet_if snat to $inet_ip
}
}
ACL
Access Control List
Set read + execute permissions to /etc/fooctl for jdoe user:
setfactl --modify user:jdoe:rX /etc/fooctl
ls -adl /etc/fooctl
drwxr-x---+ 2 root root 4096 Apr 8 11:59 /etc/fooctl
Set read permission to /etc/fooctl/fooctl.conf for jdoe user:
setfactl --modify user:jdoe:r /etc/fooctl/fooctl.conf
ls -adl /etc/fooctl/fooctl.conf
-rw-rw-r--+ 1 root root 1943 Apr 8 11:59 /etc/fooctl/fooctl.conf
getfacl /etc/fooctl/fooctl.conf
getfacl: Removing leading '/' from absolute path names
# file: etc/fooctl/fooctl.conf
# owner: root
# group: root
user::rw-
user:jdoe:r--
group::rw-
mask::rw-
other::r--
Remove read permission from /etc/fooctl/fooctl.conf for jdoe user:
Netstat
Show listening TCP connections:
netstat --listening --tcp
Show programs associated to listening TCP and UDP connections (root privilege needed):
netstat --listening --tcp --udp --program
Xen
Dom0 is here Debian GNU/Linux Trixie. Install hypervisor:
apt install xen-hypervisor
systemctl reboot
OpenBSD as DomU
Add file /etc/xen/auto/obsd.cfg
type = "hvm"
name = "obsd"
memory = 4096
vcpus = 2
disk = [ '/opt/xen/install78.iso,,xvdc,cdrom', '/dev/vg0/lv-obsd,,xvda' ]
vif = [ 'mac=00:16:3e:a1:ff:01,bridge=xenbr0' ]
serial = "pty"
vnc = 1
vnclisten = 127.0.0.1
vncdisplay = 42
Create bridge interface:
cat > /etc/systemd/network/xenbr0.netdev << EOF
Name=xenbr0
Kind=bridge
EOF
cat > /etc/systemd/network/xenbr0.network << EOF
[Match]
Name=xenbr0
[Network]
Address=192.168.0.1/24
EOF
systemctl enable --now systemd-networkd
Redirect output to serial console:
xl create -c /etc/xen/auto/obsd.cfg
From the VNC viewer:
boot> set tty com0
LVM
Initialize partition sda5 for use by LVM:
pvcreate /dev/sda5
Create Volume Group vg0 on partition sda5:
vgcreate vg0 /dev/sda5
Create Logical Volume lv-data in Volum Group vg0:
lvcreate --size 64g vg0 --name lv-data
Reduce size of Logical Volume lv-data in Volum Group vg0 when lv-data does not contain filesystem:
lvreduce --size 16g vg0/lv-data
Disk encryption
LUKS
Erase table and filesystem signatures and overwrite device with random data:
wipefs --all /dev/sde
dd if=/dev/urandom of=/dev/sde bs=4M status=progress
Initialize a LUKS partition and open it:
cryptsetup luksFormat /dev/sde
WARNING!
========
This will overwrite data on /dev/sde irrevocably.
Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/sde:
Verify passphrase:
cryptsetup open /dev/sde foo
Enter passphrase for /dev/sde:
Make filesystem and mount it:
mkfs.ext4 /dev/mapper/foo
mke2fs 1.47.4 (6-Mar-2025)
Creating filesystem with 111616 1k blocks and 27888 inodes
Filesystem UUID: e4805c08-4d97-48c8-921f-91b203279131
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
mount /dev/mapper/foo /mnt
GPG
Configuration
See short key id when listing keys:
echo "keyid-format short" >> ~/.gnupg/gpg.conf
Generation
Generate a main key to sign and to certificate and a subkey to encrypt:
gpg --full-generate-key
gpg (GnuPG) 2.5.18; Copyright (C) 2025 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(14) Existing key from card
(16) ECC and Kyber
Your selection?
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(4) NIST P-384
(6) Brainpool P-256
Your selection?
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: John Doe
Email address: john@doe.net
Comment:
You selected this USER-ID:
"John Doe <john@doe.net>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: revocation certificate stored as '/home/jdoe/.gnupg/openpgp-revocs.d/4960E99609DA1753CC6798800DB4D7504AFFB5E4.rev'
public and secret key created and signed.
pub ed25519/4AFFB5E4 2026-03-25 [SC]
4960E99609DA1753CC6798800DB4D7504AFFB5E4
uid John Doe <john@doe.net>
sub cv25519/D76499B8 2026-03-25 [E]
58C2231CAEAF923DB403051E3CFD617FD76499B8
Edit key to add a signing subkey:
Restic
Use restic to backup a set of files/directories on several repositories.
Repo initialization
mkdir -p ~/.config/restic
echo "sftp:bak.triaxx.io:/srv/restic-repo" > .config/restic/repo-bak
restic --repository-file ~/.config/restic/repo-bak init
Backup
find /etc /home -print > ~/.config/restic/files
restic --repository-file ~/.config/restic/repo-bak \
backup \
--files-from-verbatim ~/.config/restic/files \
--skip-if-unchanged
Linux Automation
Create a systemd template service to execute restic backup for each repository:
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/restic-backup@.service << EOF
[Unit]
Description=Restic backup service for %i repository
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/restic backup --files-from-verbatim %E/restic/files --skip-if-unchanged
ExecStartPost=/usr/bin/restic forget --keep-last 5 --prune
Environment="RESTIC_PASSWORD_COMMAND=%E/restic/passcmd"
Environment="RESTIC_REPOSITORY_FILE=%E/restic/repo-%i"
[Install]
WantedBy=default.target
EOF
Create a target to backup on several repositories:
EFI
Efibootmgr
List UEFI entries:
efibootmgr
Delete entry 0013:
efibootmgr --delete-bootnum --bootnum 0013
Create new entry:
efibootmgr --create --label "HD001" --loader "\EFI\BOOT\BOOTX64.EFI"
Systemd-boot
Chain load FreeBSD loader:
mount -t ufs -oufstype=ufs2 /dev/sda8 /mnt/freebsd
cp /mnt/freebsd/boot/loader.efi /efi/EFI/freebsd/loader.efi
echo "rootdev=disk0p8" > /efi/EFI/freebsd/loader.env
cat > /efi/loader/entries/freebsd.conf << EOF
title FreeBSD
efi /EFI/freebsd.loader.efi
EOF
Disk check
Bad blocks
Install on NetBSD:
# pkgin install e2fsprogs
or on macOS:
# brew install e2fsprogs
Unmount device first on macOS:
# diskutil unmountDisk /dev/<device>
Start test:
# badblocks -n -s -v /dev/<device>
where <device> can be identified by executing:
# dmesg | tail
right after plugging in the USB flash storage on GNU/Linux or NetBSD and
# diskutil list
on macOS.
Smartmontools
Print health status of device /dev/sdb:
# smartctl --health /dev/sdb
smartctl 7.5 2025-04-30 r5714 [x86_64-linux-7.0.3-arch1-1] (local build)
Copyright (C) 2002-25, Bruce Allen, Christian Franke, www.smartmontools.org
=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
Start long off-line test on device /dev/sdb:
Arch Linux
Installation
Boot image
curl --output archlinux-x86_64.iso https://mirror.srv.fail/archlinux/iso/2026.03.01/archlinux-x86_64.iso
# on macOS
sudo dd if=archlinux-x86_64.iso of=/dev/disk4 bs=1m status=progress
# on NetBSD
dd if=/home/triaxx/archlinux-x86_64.iso of=/dev/sd2d bs=1m progress=100
System configuration
After booting from USB disk:
localectl list-keymaps | grep fi
loadkeys fi
timedatectl set-timezone Europe/Helsinki
Partitionning
Erase table or filesystem signatures:
wipefs --all /dev/sda
Create empty partition table:
echo 'label: gpt' | sfdisk /dev/sda
List available types for GPT:
sfdisk --label gpt --list-types
Create partitions:
echo "size=512MiB, name=efi, type=efi-system" | sfdisk /dev/sda
echo "size=512MiB, name=boot, type=linux-extended-boot" | sfdisk /dev/sda --append
echo "size=36GiB, name=linux-swap, type=linux-swap" | sfdisk /dev/sda --append
echo "size=128GiB, name=linux-root, type=linux-root-x86-64" | sfdisk /dev/sda --append
echo "size=36GiB, name=freebsd-swap, type=freebsd-swap" | sfdisk /dev/sda --append
echo "size=128GiB, name=freebsd-root, type=freebsd-ufs" | sfdisk /dev/sda --append
echo "size=+, name=data, type=freebsd-zfs" | sfdisk /dev/sda --append
Make filesystems:
Figlet
File header
figlet Makefile | sed -e "s|^|# |" > Makefile
Mercurial
Initialization
hg init
cat >> .hg/hgrc << EOF
[ui]
username = triaxx <triaxx@triaxx.io>
EOF
Usage
hg status
hg add <file>
hg forget <file>
hg commit
hg log --graph
Change the message of the last commit:
hg commit --amend
Revert to the last commit version:
hg revert
hg revert --no-backup
Extensions
Enable histedit:
cat >> .hg/hgrc << EOF
[extensions]
histedit =
Web
Add a CNAME entry for hg:
hg CNAME www
Configure a hgweb application:
Hugo
Abstract
Hugo is an open-source static website generator. It is written in Go and uses Markdown file format as input to produce static HTML website.
Initialization
Site
hugo new project <path>
cd <path>
cat > hugo.toml << EOF
baseURL = 'https://triaxx.io/'
languageCode = 'fr-FR'
title = 'Triaxx Web Log'
EOF
Theme
A theme is mandatory to build sites.
hugo new theme <name>
echo "theme = '<name>' >> hugo.toml
A example menu can be copied from themes/<name>/hugo.toml: