Installing and configuring Zdkimfilter for courier-mta on Debian Buster (+ djbdns)

Download package

wget https://www.tana.it/sw/zdkimfilter/zdkimfilter-3.8.tar.gz

Install necessary packages

sudo apt install pkg-config libbsd-dev libssl-dev zlib1g-dev libunistring-dev libidn2-dev libopendbx1-dev

Compile and install

tar xfz zdkimfilter-3.8.tar.gz
cd zdkimfilter-3.8
./configure
make
sudo make install

Configure

Get superpowers :

sudo -i

Generate keys

cd /etc/courier/filters
mkdir keys
chown courier:courier keys
cd keys
/usr/local/bin/zdkimgenkey -s mydomain -d thisdomain.org

Here, the selector mydomain is just a name that I chose different from the real domain thisdomain.org for the purpose of this tutorial. You would normally use something like thisdomain.

chown courier:courier *

Setup the DNS

You have to put the public key that you just generated (the mydomain.txt file) into your DNS. It is provided in a bind-compatible format. Since I use djbdns, I have to transform the entry. I use the site https://andersbrownworth.com/projects/sysadmin/djbdnsRecordBuilder/#domainKeys to do the dirty work :

Just enter what follows p= in the TXT.

Configure

cd ..
mv zdkimfilter.conf.dist zdkimfilter.conf

Add a default domain at the end of the config file. I use thisdomain.org but you can use any domain. It is used when zdkimfilter cannot guess the real domain, that is, when the sender is something like paul (without @somedomain.tld).

It is recommended to also add the following lines :

no_signlen = Y
header_canon_relaxed = Y
body_canon_relaxed = Y
cd keys
ln -s mydomain.private thisdomain.org
filterctl start zdkimfilter

Installer Ubuntu sur Dell 15/3000

Ça devient de plus en plus compliqué d’installer une Ubuntu sur une machine pré-installée avec Windows 10, chez Dell notamment (je veux garder une petite partition Windows pour éventuellement flasher le BIOS un jour si nécessaire – le BIOS semble indiquer que c’est possible sans pour autant avoir encore un Windows mais mon expérience avec une machine HP sur laquelle c’était impossible m’a refroidi).

Pas le bon port USB

Première tentative, je mets la clé USB contenant Ubuntu dans le connecteur de droite, F12 pour accéder au “one-time-boot” et… ma clé n’est pas vue. En mettant la clé dans un autre port USB, là elle est vue.

Mode AHCI vs mode RAID

Par défaut, le contrôleur de disque est en mode VMD/RAID (je ne vois pas l’intérêt sur une machine avec un seul disque mais passons). Quand on essaye d’installer Ubuntu, ce dernier ne voit pas le disque. Il faut passer en mode AHCI. Qu’à cela ne tienne. Normalement, il suffit de booter Windows en mode sans échec, de changer de mode dans le BIOS et de ressortir du mode sans échec.

Ok, donc je boote Windows, rechercher CMD : inconnu. Pardon ? Depuis l’explorateur dans c:\windows\System\32, clic droit sur cmd, exécuter en tant qu’administrateur : “vous êtes en mode S vous ne pouvez utiliser que des logiciels fournis par Microsoft”. Mais c’est cmd ! Je me calme, et pour désactiver cette saleté de mode S, il faut télécharger un outil depuis le store de Microsoft et pour ça créer un compte. Je m’exécute et je peux enfin lancer cmd.

bcdedit/set safeboot minimal

Reboot, F2 pour accéder au BIOS, changement de VMD à AHCI, reboot et :

bcdedit/deletevalue safeboot

Réduire la taille de la partition

C’est reparti, boot sur la clé USB, installer ubuntu… et sur l’écran de partitionnement, le système est “(unknown)” (pas ntfs) donc on ne peut pas modifier la taille de la partition. Pourquoi tant de haine ? Le disque est chiffré avec Bitlocker.

Paramètres, Mise à jour et sécurité, chiffrement de l’appareil, désactiver le chiffrement. Et attendre, bien sûr.

5 minutes plus tard, l’installation d’Ubuntu est terminée et le double boot fonctionne.

Lancer un script au démarrage

Pour lancer un script au démarrage du système “proprement” (en utilisant systemd) :

1. créer un script et le placer dans /usr/local/bin.

2. créer un fichier de configuration dans /etc/systemd/system/xxx.service

3. Y placer le contenu suivant :

[Unit]
Description=Bypass Dell fan control
Before=i8kmon.service

[Service]
ExecStart=/usr/local/bin/dell-bios-fan-control enable=1
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

4. Lancer systemctl daemon-reload

5. Activer le service avec systemctl enable xxx.service

La doc : https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before=

Bullshit sites

Il y a parfois des sites qui valent le détour tant le n’importe quoi est poussé à son paroxysme. Florilège.

Okinaha – Le charlatanisme 2.0 – Ne vous contentez pas de cette page d’introduction, le site regorge d’attrape-nigauds pour personnes électrosensibles.
https://okinaha.com/collections/hygiene-electromagnetique/products/genatome-gtc-369-bouclier-electromagnetique-1

Répondeur courier-mta avec maildrop et mailbot

Il faut d’abord indiquer à courier d’utiliser un autre MDA (Mail Distribution Agent) :

/home/vmail/account/.courier :
|/usr/bin/maildrop .mailfilter

Puis indiquer les règles dans /home/vmail/account/.mailfilter :

cc "!joe@gosane.fr"
cc "| mailbot -A \"From: Account <account@gosane.fr>\" \
-N -c utf8 -T reply \
-s \"I'm on vacation\" \
-t 'vacation.txt' \
/usr/sbin/sendmail -f ''"
to "./Maildir"

Il faudra un fichier vacation.txt dans /home/vmail/account.

Raw SQL in Ruby/Rails

Everyone seems to discourage the use of raw SQL in Ruby applications and while ActiveRecord seems a good solution for general purpose CRUD operations, we have a strong expertise in SQL and we want to use it as much as possible. Here are the bits we have collected so far on the subject. We are new to Ruby/Rails so these might be obvious for some of you. We primarily write this for ourselves.

We are perfectly aware of the “limitations”. We love PostgreSQL and have no intention of being RDBMS-agnostic. At all.

find_by_sql the way we want it

We want named parameters because, despite the overhead, it’s the cleanest way to pass parameters (we don’t have to preserve a strict order which can lead to problems when enhancing the query, counting the “?”, etc). Also, when we use the same parameter several times in the same query, we don’t have to repeat it.

class ClientsController < ApplicationController

	def index
		@clients = Client.find_by_sql(
			<<-SQL
			SELECT idclient,name,email,contacts
			FROM clients 
			ORDER BY nom
			SQL
			)
	end

	def show
		@client = Client.find_by_sql(["	
			SELECT idclient,name,email,contacts 
			FROM clients 
			WHERE idclient = :idclient", 
			{ :idclient => params[:id] } 
		])[0]
	end

For the show method, we have to grab the first element in the array (thus the [0]at the end.

BorgBackup sur une storagebox Hetzner

Objectif : automatiser les sauvegardes d’une partie de mon /home

Prérequis

Créer un sous-compte (sub-account) sur l’interface Hetzner. Ici ce sera u123456-sub2.

Une clé SSH spécifique

Créer une clé SSH sans phrase de passe pour que les sauvegardes puissent être entièrement automatiques :

ssh-keygen -f .ssh/id_rsa_hetzner

Pour copier la clé publique sur la storagebox, il faut créer un dossier .ssh

Peut-être que l’on peut faire ça avec scp, comme je ne sais pas faire, j’utilise ncftp:

ncftp -u u123456-sub2@u123456.your-storagebox.de

Créer le dossier .ssh

ncftp / > mkdir .ssh

Maintenant on peut copier la clé publique qu’on vient de créer dans .ssh/authorized_keys

scp -P 23 .ssh/id_rsa_hetzner.pub u123456-sub2@u123456-sub2.your-storagebox.de:.ssh/authorized_keys

Créer le dépôt BorgBackup

On définit quelques variables d’environnement pour ne pas les répéter tout le temps :

export BORG_RSH='ssh -i ~/.ssh/id_rsa_hetzner'

export BORG_PASSPHRASE="top_secret_passphrase"

export BORG_REPO="ssh://u123456-sub2@u123456.your-storagebox.de:23/./borgrepo"

On crée le dépôt (repository) :

borg init -e repokey

Un script pour sauvegarder

…à venir…

TdxSpreadSheet creation and filling via code

Basic usage and formatting

procedure TForm1.b1Click(Sender: TObject);
Var xls:TdxSpreadSheet;
    sh: TdxSpreadSheetTableView;
begin
  xls:=TdxSpreadSheet.Create(Self);
  Try
    xls.BeginUpdate;
    xls.ClearAll;
    sh:=TdxSpreadSheetTableView(xls.AddSheet('Bénéficiaires'));

    // row,col
    if Cells[1,1]=Nil then
      CreateCell(1,1);
    Cells[Row,Col].AsString:='test';
    sh.cells[1,1].Style.Borders[bLeft].Style:=sscbsDouble;
    sh.cells[1,1].Style.Borders[bRight].Color:=clred;
    sh.Cells[1,1].Style.Brush.BackgroundColor:=clcxLightGray;
    sh.Cells[1,1].Style.AlignHorz:=ssahCenter;
    sh.Cells[1,1].Style.DataFormat.FormatCode:='dd/mm/yyyy';
    sh.Cells[1,1].Style.DataFormat.FormatCode:='# ##0.00';
    sh.Cells[1,1].Style.Font.Style:=[fsBold];

    // Formula
    CreateCell(2,1); // B3
    sh.Cells[2,1].SetText('=SUM(B2:B2)',true);

    xls.EndUpdate;
    xls.SaveToFile('C:\Users\gosane\Desktop\text.xlsx');
  Finally
    xls.Free;
  End;
end;

Helpers

function xlscolname(i:integer):string;
var a,b:integer;
begin
  if i<0 then
    result:='?'
  else if i<26 then
    result:=chr(65+i)
  else begin
    a:=i div 26;
    b:=i mod 26;
    result:=chr(64+a)+chr(65+b);
  end;
end;