From b5f39c4e8cf4d699f963c0abc7f4038f3851fd58 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 25 May 2026 13:43:26 +0900 Subject: [PATCH] WIP: temmie/userweb: use bro to proxy sendmail requests out of sandbox --- flake.lock | 54 ++++++++++- flake.nix | 12 ++- hosts/temmie/services/userweb/default.nix | 17 +--- hosts/temmie/services/userweb/mail.nix | 109 +++++++++++++++++++++- 4 files changed, 169 insertions(+), 23 deletions(-) diff --git a/flake.lock b/flake.lock index 05fe645..cafea3e 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,27 @@ { "nodes": { + "bro": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1779629827, + "narHash": "sha256-nrlB50/oelB8oFx9DhOoXI5z0VoTZGEA6XxYvkvpqDA=", + "ref": "main", + "rev": "7d0f35e12e4dec39f981c08fc33515589f41f4a5", + "revCount": 3, + "type": "git", + "url": "https://git.pvv.ntnu.no/Projects/bro.git" + }, + "original": { + "ref": "main", + "type": "git", + "url": "https://git.pvv.ntnu.no/Projects/bro.git" + } + }, "crane": { "locked": { "lastModified": 1776635034, @@ -101,7 +123,7 @@ "nixpkgs": [ "nixpkgs-unstable" ], - "rust-overlay": "rust-overlay" + "rust-overlay": "rust-overlay_2" }, "locked": { "lastModified": 1777019032, @@ -165,7 +187,7 @@ "nixpkgs": [ "nixpkgs" ], - "rust-overlay": "rust-overlay_2" + "rust-overlay": "rust-overlay_3" }, "locked": { "lastModified": 1767906976, @@ -352,6 +374,7 @@ }, "root": { "inputs": { + "bro": "bro", "dibbler": "dibbler", "disko": "disko", "gergle": "gergle", @@ -377,7 +400,7 @@ "nixpkgs": [ "nixpkgs" ], - "rust-overlay": "rust-overlay_3" + "rust-overlay": "rust-overlay_4" }, "locked": { "lastModified": 1778600367, @@ -396,6 +419,27 @@ } }, "rust-overlay": { + "inputs": { + "nixpkgs": [ + "bro", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779419951, + "narHash": "sha256-dMX0PUslUHPajP6o8FEoRdFv9afq/dec4POR0vVfjK4=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "5b5c521d6cae9ef4aa32f888eb2c0ce595c9be52", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_2": { "inputs": { "nixpkgs": [ "greg-ng", @@ -416,7 +460,7 @@ "type": "github" } }, - "rust-overlay_2": { + "rust-overlay_3": { "inputs": { "nixpkgs": [ "minecraft-heatmap", @@ -437,7 +481,7 @@ "type": "github" } }, - "rust-overlay_3": { + "rust-overlay_4": { "inputs": { "nixpkgs": [ "roowho2", diff --git a/flake.nix b/flake.nix index 148fcd0..84285e3 100644 --- a/flake.nix +++ b/flake.nix @@ -47,6 +47,9 @@ qotd.url = "git+https://git.pvv.ntnu.no/Projects/qotd.git?ref=main"; qotd.inputs.nixpkgs.follows = "nixpkgs"; + + bro.url = "git+https://git.pvv.ntnu.no/Projects/bro.git?ref=main"; + bro.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { @@ -214,7 +217,14 @@ }; shark = stableNixosConfig "shark" {}; wenche = stableNixosConfig "wenche" {}; - temmie = stableNixosConfig "temmie" {}; + temmie = stableNixosConfig "temmie" { + overlays = [ + inputs.bro.overlays.default + ]; + modules = [ + inputs.bro.nixosModules.default + ]; + }; gluttony = stableNixosConfig "gluttony" { overlays = [ (final: prev: { bluemap = final.callPackage ./packages/bluemap.nix {}; }) diff --git a/hosts/temmie/services/userweb/default.nix b/hosts/temmie/services/userweb/default.nix index edf98dd..a905021 100644 --- a/hosts/temmie/services/userweb/default.nix +++ b/hosts/temmie/services/userweb/default.nix @@ -67,21 +67,6 @@ let ignoreCollisions = true; }; - sendmailWrapper = pkgs.writeShellApplication { - name = "sendmail"; - runtimeInputs = [ ]; - text = '' - args=("$@") - - if [[ -z "$USERDIR_USER" ]] && [[ "$USERDIR_USER" != "pvv" ]]; then - # Prepend -fusername to the argument list, so bounces go to the user - args=("-f$USERDIR_USER" "''${args[@]}") - fi - - exec '${lib.getExe pkgs.system-sendmail}' "''${args[@]}" - ''; - }; - # https://nixos.org/manual/nixpkgs/stable/#sec-building-environment fhsEnv = pkgs.buildEnv { name = "userweb-env"; @@ -89,7 +74,7 @@ let paths = with pkgs; [ bash - sendmailWrapper + config.services.bro.instances.userweb-sendmail.client.package perlEnv pythonEnv diff --git a/hosts/temmie/services/userweb/mail.nix b/hosts/temmie/services/userweb/mail.nix index 203cddf..6389b61 100644 --- a/hosts/temmie/services/userweb/mail.nix +++ b/hosts/temmie/services/userweb/mail.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: { services.postfix.enable = lib.mkForce false; @@ -9,4 +9,111 @@ remotes = "mail.pvv.ntnu.no smtp --port=25"; }; }; + + services.bro = { + enable = true; + + instances.userweb-sendmail = { + enable = true; + + client = { + settings.BRO_FILE_FLAGS = [ + "-C" + ]; + }; + + server = { + settings = { + executable = let + sendmailWrapper = pkgs.writeShellApplication { + name = "sendmail"; + runtimeInputs = [ ]; + bashOptions = [ + "errexit" + "pipefail" + ]; + text = '' + args=("$@") + + if [[ -z "$USERDIR_USER" ]] && [[ "$USERDIR_USER" != "pvv" ]]; then + # Prepend -fusername to the argument list, so bounces go to the user + args=("-f$USERDIR_USER" "''${args[@]}") + fi + + exec '${lib.getExe pkgs.system-sendmail}' "''${args[@]}" + ''; + }; + in lib.getExe sendmailWrapper; + allowed-env = [ "USERDIR_USER" ]; + }; + }; + }; + }; + + environment.systemPackages = [ + (config.services.bro.instances.userweb-sendmail.client.package.overrideAttrs (prev: { + buildCommand = prev.buildCommand + '' + mv "$out/bin/sendmail" "$out/bin/bro-sendmail" + ''; + })) + ]; + + users.users.nullmailer-user = { + enable = true; + isSystemUser = true; + group = "nullmailer-user"; + }; + + users.groups.nullmailer-user = { }; + + systemd.services.bro-userweb-sendmail = { + serviceConfig = { + User = "nullmailer-user"; + Group = "nullmailer-user"; + + ReadWritePaths = [ + "/var/spool/nullmailer" + ]; + + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + NoNewPrivileges = false; + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + PrivateUsers = false; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + "AF_NETLINK" + ]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateMounts = true; + ProcSubset = "pid"; + ProtectProc = "invisible"; + RemoveIPC = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@resources" + ]; + UMask = "0077"; + }; + }; + + systemd.services.httpd.serviceConfig = { + BindPaths = [ (lib.head config.systemd.sockets.bro-userweb-sendmail.listenStreams) ]; + }; }