Harden server and add Nix-native CI + self-hosted Gitea Actions
CI / Flake check (aarch64-linux) (push) Failing after 8s
CI / Flake check (x86_64-linux) (push) Failing after 2s
CI / Pre-commit checks (aarch64-linux) (push) Failing after 2s
CI / Pre-commit checks (x86_64-linux) (push) Failing after 2s

- 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,
  ...); 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,
  inherit, bool-compare guards); add missing trailing newlines
This commit is contained in:
2026-07-12 01:45:33 +02:00
parent 7ed54e51a2
commit e0453b0123
41 changed files with 91 additions and 294 deletions
+1 -6
View File
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
# NOTE: Caddy handles all TLS natively via its ACME integration.
# This module is kept as a fallback for non-Caddy services.
# Currently NOT imported in default.nix — uncomment there to activate.
+1 -6
View File
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: let
{pkgs, ...}: let
backupScript = pkgs.writeShellScript "weekly-backup" ''
BACKUP_DIR="/home/admin/backups"
SRC="/home/admin"
+1 -7
View File
@@ -1,10 +1,4 @@
{
config,
pkgs,
lib,
...
}: let
domain = "severijnse.eu";
{...}: let
antiScrape = ''
@bad_bot {
header_regexp User-Agent "(?i)(scrapy|cpython-requests|python-requests|curl|wget|go-http-client|ltx71|petalbot|bytespider|dotbot|ahrefsbot|semrushbot|mj12bot|dataforseo|facebookexternalhit|claudebot|anthropic-ai|perplexity|gptbot|chatgpt-user|omnisci|imgproxy|ccbot|exabot|360spider|baiduspider|sogou|duckduckgo|amazonbot|cohere-ai|diffbot|imagesiftbot).*"
+1 -6
View File
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: let
{pkgs, ...}: let
zoneFile = pkgs.writeText "severijnse.eu.db" ''
$ORIGIN severijnse.eu.
$TTL 3600
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
# Keep fail2ban as OCI container to preserve the web UI
virtualisation.oci-containers.containers.fail2ban = {
image = "crazymax/fail2ban:latest";
@@ -1,7 +1,5 @@
{
config,
pkgs,
lib,
unstablePkgs,
...
}: {
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
virtualisation.oci-containers.containers.mailserver = {
image = "ghcr.io/docker-mailserver/docker-mailserver:latest";
autoStart = true;
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
virtualisation.oci-containers.containers = {
hbbr = {
image = "rustdesk/rustdesk-server:latest";
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
virtualisation.oci-containers.containers.shkeeper = {
image = "vsyshost/shkeeper:2.5.29";
autoStart = true;
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
virtualisation.oci-containers.containers.snappymail = {
image = "djmaze/snappymail:latest";
autoStart = true;
@@ -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.
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
virtualisation.oci-containers.containers.vaultwarden = {
image = "vaultwarden/server:latest";
autoStart = true;
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
virtualisation.oci-containers.containers.watchtower = {
image = "ghcr.io/nicholas-fedor/watchtower:latest";
autoStart = true;
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
virtualisation.oci-containers.containers.wg-easy = {
image = "ghcr.io/wg-easy/wg-easy:latest";
autoStart = true;
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{...}: {
virtualisation.oci-containers.containers.wrxproxy = {
image = "localhost/wrxproxy:latest";
autoStart = false;
+1 -6
View File
@@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}: {
{pkgs, ...}: {
time.timeZone = "Europe/Amsterdam";
i18n.defaultLocale = "en_US.UTF-8";