docs: update Radicale guide

We now explain what Radicale even is and classify reusing the hashed
passwords of login accounts as limitation because it requires using
compatible password hashes.

This is difficult because compatible password hashes need an overlap
between libxcrypt and Radicales choice of libraries: libpass, argon2 and
bcrypt.

Extract the source code into a proper .nix file so we get source linting
and formatting for free. Pruned from bad practices of the past, like
global `with lib`.
This commit is contained in:
Martin Weinelt
2026-03-10 02:02:53 +01:00
parent 1240173034
commit cff7a27cfe
4 changed files with 85 additions and 56 deletions
-55
View File
@@ -1,55 +0,0 @@
Add Radicale
============
Configuration by @dotlambda
Starting with Radicale 3 (first introduced in NixOS 20.09) the traditional
crypt passwords are no longer supported. Instead bcrypt passwords
have to be used. These can still be generated using `mkpasswd -m bcrypt`.
.. code:: nix
{ config, pkgs, lib, ... }:
with lib;
let
mailAccounts = config.mailserver.loginAccounts;
htpasswd = pkgs.writeText "radicale.users" (concatStrings
(flip mapAttrsToList mailAccounts (mail: user:
mail + ":" + user.hashedPassword + "\n"
))
);
in {
services.radicale = {
enable = true;
settings = {
auth = {
type = "htpasswd";
htpasswd_filename = "${htpasswd}";
htpasswd_encryption = "bcrypt";
};
};
};
services.nginx = {
enable = true;
virtualHosts = {
"cal.example.com" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:5232/";
extraConfig = ''
proxy_set_header X-Script-Name /;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Authorization;
'';
};
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
}
+1 -1
View File
@@ -34,7 +34,7 @@ Welcome to NixOS Mailserver's documentation!
:caption: How-to :caption: How-to
backup-guide backup-guide
add-radicale radicale
add-roundcube add-roundcube
rspamd-tuning rspamd-tuning
flakes flakes
+55
View File
@@ -0,0 +1,55 @@
{
config,
pkgs,
lib,
...
}:
let
inherit (lib)
concatStrings
flip
mapAttrsToList
;
mailAccounts = config.mailserver.loginAccounts;
htpasswd = pkgs.writeText "radicale.users" (
concatStrings (flip mapAttrsToList mailAccounts (mail: user: "${mail}+:${user.hashedPassword}\n"))
);
in
{
services.radicale = {
enable = true;
settings = {
auth = {
type = "htpasswd";
htpasswd_filename = "${htpasswd}";
htpasswd_encryption = "bcrypt";
};
};
};
services.nginx = {
enable = true;
virtualHosts = {
"cal.example.com" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:5232/";
extraConfig = ''
proxy_set_header X-Script-Name /;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Authorization;
'';
};
};
};
};
networking.firewall.allowedTCPPorts = [
80
443
];
}
+29
View File
@@ -0,0 +1,29 @@
Radicale
========
Radicale is a lightweight open-source CalDAV/CardDAV server that stores
calendars and contacts as plain files on the filesystem, enabling simple
self-hosted synchronization with standard clients.
Limitations
^^^^^^^^^^^
Radicale since the 3.x release (introduced in NixOS 20.09) does not support
traditional crypt() password hashes any longer. To establish access for
existing :option:`mailserver.loginAccounts`, the hashing method used
for ``hashedPassword`` needs to be compatible with one of the available
`htpasswd_encryption`_ methods. Such hashes can for example be created using
.. code-block:: console
nix-shell -p mkpasswd --command "mkpasswd -m bcrypt"
.. _htpasswd_encryption: https://radicale.org/v3.html#htpasswd_encryption
Code
^^^^
Configuration contributed by Robert Schütz (@dotlambda).
.. literalinclude:: ./radicale.nix
:language: nix