Harden server and add Nix-native CI + self-hosted Gitea Actions
- caddy: security headers (X-Content-Type-Options/X-XSS-Protection/ X-Frame-Options) on all vhosts + baseline CSP; strip SnappyMail upstream copies via header_down on mail.severijnse.eu - tlsa-updater: compute TLSA 3 1 1 from cert SPKI (SHA-256), sync _25/_465/_993, fail-safe placeholders; coredns zone updated - pre-commit: wire cachix/git-hooks.nix (alejandra, statix, actionlint, deadnix); CI pre-commit job over x86_64 + aarch64 matrix - gitea: enable Gitea Actions + self-hosted runner (native:host, aarch64 via binfmt); add .gitea/workflows/ci.yml and local hook - fix statix warnings (merge repeated systemd/database/configFile keys) + disable empty_pattern via statix.toml (nixpkgs standard) - Clean up unused lambda patterns across 38 .nix files via deadnix - Format whole repo with alejandra (27 files) - Remove .github/workflows/ci.yml (Gitea shadows .github; runner labels differ) - Fix CI nix-not-found: export /run/current-system/sw/bin in PATH - Trim aarch64 from pre-commit matrix (no QEMU binfmt deployed yet)
This commit is contained in:
@@ -1,9 +1,4 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{pkgs, ...}: let
|
||||
# Caddy's canonical certificate storage (XDG data dir). Renewals land here,
|
||||
# owned caddy:caddy 0600 — the mail server's non-root Postfix/Dovecot cannot
|
||||
# read it directly, so we copy it into a world-readable distribution dir.
|
||||
@@ -58,42 +53,44 @@
|
||||
echo "tlsa-update: TLSA set to $HEX"
|
||||
'';
|
||||
in {
|
||||
# Ensure the distribution dir exists (Caddy does not write here).
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${distCertDir} 0755 root root - -"
|
||||
];
|
||||
systemd = {
|
||||
# Ensure the distribution dir exists (Caddy does not write here).
|
||||
tmpfiles.rules = [
|
||||
"d ${distCertDir} 0755 root root - -"
|
||||
];
|
||||
|
||||
systemd.services.tlsa-update = {
|
||||
description = "Sync Caddy TLS certificate to mail server and update DANE/TLSA records";
|
||||
after = ["caddy.service" "coredns.service"];
|
||||
partOf = ["coredns.service"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
path = with pkgs; [openssl coreutils gnused podman systemd];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${syncScript}";
|
||||
User = "root";
|
||||
Group = "root";
|
||||
services.tlsa-update = {
|
||||
description = "Sync Caddy TLS certificate to mail server and update DANE/TLSA records";
|
||||
after = ["caddy.service" "coredns.service"];
|
||||
partOf = ["coredns.service"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
path = with pkgs; [openssl coreutils gnused podman systemd];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${syncScript}";
|
||||
User = "root";
|
||||
Group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Fire as soon as Caddy rewrites the certificate on renewal (the atomic rewrite
|
||||
# changes the directory mtime), eliminating the up-to-24h DANE drift window.
|
||||
systemd.paths.tlsa-update = {
|
||||
description = "Watch Caddy certificate directory for renewal";
|
||||
wantedBy = ["paths.target"];
|
||||
pathConfig = {
|
||||
PathModified = [caddyCertDir];
|
||||
Unit = "tlsa-update.service";
|
||||
# Fire as soon as Caddy rewrites the certificate on renewal (the atomic rewrite
|
||||
# changes the directory mtime), eliminating the up-to-24h DANE drift window.
|
||||
paths.tlsa-update = {
|
||||
description = "Watch Caddy certificate directory for renewal";
|
||||
wantedBy = ["paths.target"];
|
||||
pathConfig = {
|
||||
PathModified = [caddyCertDir];
|
||||
Unit = "tlsa-update.service";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Fallback in case a renewal event is missed (e.g. inotify overflow).
|
||||
systemd.timers.tlsa-update = {
|
||||
wantedBy = ["timers.target"];
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = true;
|
||||
# Fallback in case a renewal event is missed (e.g. inotify overflow).
|
||||
timers.tlsa-update = {
|
||||
wantedBy = ["timers.target"];
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user