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, ...); 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:
@@ -1,9 +1,4 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{...}: {
|
||||
imports = [
|
||||
./networking.nix
|
||||
./users.nix
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{...}: {
|
||||
boot = {
|
||||
loader = {
|
||||
grub = {
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{...}: {
|
||||
networking = {
|
||||
hostName = "debian-4gb-fsn1-1";
|
||||
domain = "severijnse.eu";
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{pkgs, ...}: {
|
||||
users.users = {
|
||||
root = {
|
||||
openssh.authorizedKeys.keys = [
|
||||
|
||||
@@ -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,9 +1,4 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{pkgs, ...}: let
|
||||
backupScript = pkgs.writeShellScript "weekly-backup" ''
|
||||
BACKUP_DIR="/home/admin/backups"
|
||||
SRC="/home/admin"
|
||||
|
||||
@@ -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,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,
|
||||
...
|
||||
}: {
|
||||
@@ -98,8 +96,10 @@
|
||||
'';
|
||||
|
||||
# --- Gitea Actions self-hosted CI runner ---
|
||||
# Jobs install their own Nix inside the runner (official installer,
|
||||
# --no-daemon) so no system Nix daemon / nix-users group is needed.
|
||||
# The native runner only exposes `hostPackages` on PATH (see the list above),
|
||||
# which intentionally omits Nix. CI steps export the host's system Nix
|
||||
# (/run/current-system/sw/bin, i.e. Lix) onto PATH rather than installing a
|
||||
# second Nix client, so the running Lix daemon is used directly.
|
||||
# aarch64 builds run under QEMU user-emulation via boot.binfmt below.
|
||||
boot.binfmt.emulatedSystems = ["aarch64-linux"];
|
||||
}
|
||||
|
||||
@@ -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,9 +1,4 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{pkgs, ...}: {
|
||||
time.timeZone = "Europe/Amsterdam";
|
||||
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
|
||||
Reference in New Issue
Block a user