Compare commits

...

5 commits

17 changed files with 46 additions and 337 deletions

View file

@ -65,11 +65,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1706134977, "lastModified": 1707175763,
"narHash": "sha256-KwNb1Li3K6vuVwZ77tFjZ89AWBo7AiCs9t0Cens4BsM=", "narHash": "sha256-0MKHC6tQ4KEuM5rui6DjKZ/VNiSANB4E+DJ/+wPS1PU=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "6359d40f6ec0b72a38e02b333f343c3d4929ec10", "rev": "f99eace7c167b8a6a0871849493b1c613d0f1b80",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -115,11 +115,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1706071294, "lastModified": 1707162675,
"narHash": "sha256-mpt86O5GQxKQoIg4nzKz810PeXjGSEFb4rW+shXbRco=", "narHash": "sha256-ZojPqn5+cuuqCt/VVGo+uuRxYLtMomahHseFj9HB3O8=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NixOS-WSL", "repo": "NixOS-WSL",
"rev": "31346e340e828f79be23d9c83ec1674b152f17bc", "rev": "4bb6b2e814be63caa115038e917c6c25b7fc2ac1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -146,11 +146,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1705856552, "lastModified": 1707092692,
"narHash": "sha256-JXfnuEf5Yd6bhMs/uvM67/joxYKoysyE3M2k6T3eWbg=", "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "612f97239e2cc474c13c9dafa0df378058c5ad8d", "rev": "faf912b086576fd1a15fca610166c98d47bc667e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -194,11 +194,11 @@
}, },
"nur": { "nur": {
"locked": { "locked": {
"lastModified": 1706174248, "lastModified": 1707403461,
"narHash": "sha256-VNN7md+kJhBvl5bINEXybSG4jHavrQIlXdywpcaEEwc=", "narHash": "sha256-obSWLYqen4I/jArO04QLAKT2DZSLksCiskmeDRgS3bM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "20f64c7125413fc19372f11b45db99363bea7c1f", "rev": "9621e2bfc47bbfe644c0f9f64b1aa44dec1f3afc",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -53,21 +53,6 @@ in {
}; };
}; };
rspamd = {
enable = mkOption {
type = types.bool;
default = true;
};
extraConfig = mkOption {
type = types.lines;
default = "";
};
redisPort = mkOption {
type = types.number;
default = 6380;
};
};
accounts = mkOption { accounts = mkOption {
# where attrName = email for login # where attrName = email for login
default = {}; default = {};

View file

@ -53,20 +53,11 @@ in {
sslServerKey = mailConfig.sslConfig.key; sslServerKey = mailConfig.sslConfig.key;
# For Sieve # For Sieve
modules = with pkgs; [dovecot_pigeonhole]; modules = with pkgs; [
dovecot_pigeonhole
];
protocols = ["sieve"]; protocols = ["sieve"];
sieveScripts = {
# BROKEN: after: line 1: error: require command: unknown Sieve capability `fileinto'.
# after = builtins.toFile "spam.sieve" ''
# require "fileinto";
# if header :is "X-Spam" "Yes" {
# fileinto "Junk";
# stop;
# }
# '';
};
mailboxes = { mailboxes = {
Trash = { Trash = {
auto = "no"; auto = "no";
@ -159,40 +150,7 @@ in {
sieve = file:${mailConfig.sieveDirectory}/%u/scripts;active=${mailConfig.sieveDirectory}/%u/active.sieve sieve = file:${mailConfig.sieveDirectory}/%u/scripts;active=${mailConfig.sieveDirectory}/%u/active.sieve
sieve_default = file:${mailConfig.sieveDirectory}/%u/default.sieve sieve_default = file:${mailConfig.sieveDirectory}/%u/default.sieve
sieve_default_name = default sieve_default_name = default
sieve_global_extensions = +vnd.dovecot.environment
# From elsewhere to Spam folder
imapsieve_mailbox1_name = Junk
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:${./spam_sieve/report-spam.sieve}
# From Spam folder to elsewhere
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Junk
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:${./spam_sieve/report-ham.sieve}
${optionalString mailConfig.rspamd.enable (let
pipeBin = pkgs.stdenv.mkDerivation {
name = "pipe_bin";
src = ./pipe_bin;
buildInputs = with pkgs; [makeWrapper coreutils bash rspamd];
buildCommand = ''
mkdir -p $out/pipe/bin
cp $src/* $out/pipe/bin/
chmod a+x $out/pipe/bin/*
patchShebangs $out/pipe/bin
for file in $out/pipe/bin/*; do
wrapProgram $file \
--set PATH "${pkgs.coreutils}/bin:${pkgs.rspamd}/bin"
done
'';
};
in ''
sieve_pipe_bin_dir = ${pipeBin}/pipe/bin
'')}
sieve_global_extensions = ${optionalString mailConfig.rspamd.enable "+vnd.dovecot.pipe"} +vnd.dovecot.environment
} }
lda_mailbox_autosubscribe = yes lda_mailbox_autosubscribe = yes
lda_mailbox_autocreate = yes lda_mailbox_autocreate = yes

View file

@ -1,3 +0,0 @@
#!/bin/bash
set -o errexit
exec rspamc -h /run/rspamd/worker-controller.sock learn_ham

View file

@ -1,3 +0,0 @@
#!/bin/bash
set -o errexit
exec rspamc -h /run/rspamd/worker-controller.sock learn_spam

View file

@ -148,7 +148,6 @@ in {
smtpd_milters = flatten [ smtpd_milters = flatten [
(optional mailConfig.dkim.enable "unix:/run/opendkim/opendkim.sock") (optional mailConfig.dkim.enable "unix:/run/opendkim/opendkim.sock")
(optional mailConfig.rspamd.enable "unix:/run/rspamd/rspamd-milter.sock")
]; ];
non_smtpd_milters = flatten [ non_smtpd_milters = flatten [

View file

@ -1,101 +0,0 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
mailConfig = config.services.mailserver;
rspamdCfg = config.services.rspamd;
rspamdSocket = "rspamd.service";
in {
config = mkIf (mailConfig.enable && mailConfig.rspamd.enable) {
services.rspamd = {
enable = true;
debug = mailConfig.debugMode;
locals = {
"milter_headers.conf" = {
text = ''
extended_spam_headers = yes;
'';
};
"redis.conf" = {
text = ''
servers = "127.0.0.1:${toString mailConfig.rspamd.redisPort}";
'';
};
"classifier-bayes.conf" = {
text = ''
cache {
backend = "redis";
}
min_learns = 5;
'';
};
"dkim_signing.conf" = {
text = ''
# opendkim does this
enabled = false;
'';
};
};
overrides = {
"milter_headers.conf" = {
text = ''
extended_spam_headers = true;
'';
};
};
workers.rspamd_proxy = {
type = "rspamd_proxy";
bindSockets = [
{
socket = "/run/rspamd/rspamd-milter.sock";
mode = "0664";
}
];
count = 1;
extraConfig = ''
milter = yes;
timeout = 120s;
upstream "local" {
default = yes;
self_scan = yes;
}
'';
};
workers.controller = {
type = "controller";
count = 1;
bindSockets = [
{
socket = "/run/rspamd/worker-controller.sock";
mode = "0666";
}
];
includes = [];
};
};
services.redis.servers.rspamd = {
enable = true;
port = mailConfig.rspamd.redisPort;
};
systemd.services.rspamd = {
requires = ["redis-rspamd.service"];
after = ["redis-rspamd.service"];
};
systemd.services.postfix = {
after = [rspamdSocket];
requires = [rspamdSocket];
};
users.extraUsers.postfix.extraGroups = [rspamdCfg.group];
};
}

View file

@ -1,15 +0,0 @@
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "${1}";
}
if string "${mailbox}" "Trash" {
stop;
}
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "rspam-learn-ham.sh" [ "${username}" ];

View file

@ -1,7 +0,0 @@
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "rspam-learn-spam.sh" [ "${username}" ];

View file

@ -13,7 +13,6 @@ in {
key = "/var/lib/acme/mail.owo.monster/key.pem"; key = "/var/lib/acme/mail.owo.monster/key.pem";
}; };
rspamd.enable = false;
spf.enable = false; spf.enable = false;
accounts = { accounts = {

View file

@ -23,7 +23,6 @@ in {
mailConfig.vmail.directory mailConfig.vmail.directory
mailConfig.sieveDirectory mailConfig.sieveDirectory
mailConfig.dkim.directory mailConfig.dkim.directory
"/var/lib/redis-rspamd"
]; ];
# repository is overrided in environmentFile to contain auth # repository is overrided in environmentFile to contain auth

View file

@ -58,7 +58,7 @@ in {
++ (with hosts.hetzner-arm.containers.music.profiles; [ ++ (with hosts.hetzner-arm.containers.music.profiles; [
mpd mpd
musicSync musicSync
soulseek #soulseek
]); ]);
networking.firewall.allowedTCPPorts = with ports; [ networking.firewall.allowedTCPPorts = with ports; [

View file

@ -27,12 +27,16 @@ in {
extraConfig = extraConfig =
'' ''
host_permissions "127.0.0.1 read,add,control,admin" host_permissions "127.0.0.1 read,add,control,admin"
samplerate_converter "0"
metadata_to_use "title,artist" metadata_to_use "title,artist"
auto_update "yes" auto_update "yes"
audio_buffer_size "4096" audio_buffer_size "4096"
replaygain "track" replaygain "track"
audio_output_format "44100:16:2" audio_output_format "48000:24:2"
resampler {
plugin "soxr"
quality "very high"
threads "0"
}
'' ''
+ concatStringsSep "\n" (forEach ["low" "medium" "high"] (quality: let + concatStringsSep "\n" (forEach ["low" "medium" "high"] (quality: let
bitrates = { bitrates = {
@ -44,11 +48,11 @@ in {
in '' in ''
audio_output { audio_output {
type "httpd" type "httpd"
name "HTTP Opus ${bitrate}k" name "http (opus-${bitrate}k) /opus/${quality}"
encoder "opus" encoder "opus"
port "${toString ports."mpd-opus-${quality}"}" port "${toString ports."mpd-opus-${quality}"}"
bitrate "${bitrate}000" bitrate "${bitrate}000"
format "44100:16:2" format "48000:24:2"
always_on "yes" always_on "yes"
tags "yes" tags "yes"
signal "music" signal "music"
@ -57,10 +61,10 @@ in {
+ '' + ''
audio_output { audio_output {
type "httpd" type "httpd"
name "HTTP FLAC" name "http (flac) /flac"
encoder "flac" encoder "flac"
port "${toString ports.mpd-flac}" port "${toString ports.mpd-flac}"
format "44100:16:2" format "48000:24:2"
always_on "yes" always_on "yes"
tags "yes" tags "yes"
} }

View file

@ -1,55 +0,0 @@
{
self,
tree,
inputs,
config,
pkgs,
hostPath,
...
}: let
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
hostIP = containerAddresses.host;
containerIP = containerAddresses.containers.roundcube;
in {
containers.roundcube = {
autoStart = true;
privateNetwork = true;
hostAddress = hostIP;
localAddress = containerIP;
specialArgs = {
inherit inputs;
inherit tree;
inherit self;
inherit hostPath;
};
config = {...}: {
nixpkgs.pkgs = pkgs;
imports = with tree; [
presets.nixos.containerBase
profiles.nginx
profiles.sshd
profiles.firewallAllow.ssh
./profiles/roundcube.nix
];
home-manager.users.root.home.stateVersion = "23.05";
system.stateVersion = "23.05";
};
};
services.nginx = {
enable = true;
virtualHosts."mail.owo.monster" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://unix:/var/lib/nixos-containers/roundcube/var/sockets/roundcube.sock";
};
};
};
}

View file

@ -1,55 +0,0 @@
{
pkgs,
lib,
hostPath,
...
}: let
inherit (lib.modules) mkForce;
localContainersAddresses = import "${hostPath}/data/containerAddresses.nix";
in {
services.roundcube = {
enable = true;
hostName = "mail.owo.monster";
package = pkgs.roundcube.withPlugins (_plugins:
with pkgs.roundcubePlugins; [
persistent_login
]);
plugins = [
"persistent_login"
"managesieve"
];
database = {
host = localContainersAddresses.containers.postgresql;
passwordFile = builtins.toFile "pw" "";
};
extraConfig = ''
$config['smtp_server'] = "tls://mail.owo.monster";
$config['smtp_user'] = "%u";
$config['smtp_pass'] = "%p";
$config['managesieve_host'] = 'tls://mail.owo.monster';
$config['session_lifetime'] = (60 * 24 * 7 * 2); # 2 Weeks
$config['product_name'] = 'Chaos Mail';
$config['username_domain'] = "owo.monster";
$config['username_domain_forced'] = true;
$config['log_driver'] = 'syslog';
$config['smtp_debug'] = true;
'';
};
systemd.tmpfiles.rules = [
"d /var/sockets - nginx nginx"
];
systemd.services.nginx.serviceConfig.ReadWritePaths = [
"/var/sockets"
];
services.nginx.virtualHosts."mail.owo.monster" = {
forceSSL = mkForce false;
enableACME = mkForce false;
extraConfig = "listen unix:/var/sockets/roundcube.sock;";
};
}

View file

@ -29,6 +29,8 @@ final: prev: rec {
hash = "sha256-LMwGxx++z6TpZLnpeRGraid4653Mp8T4pY5EP4Z7GXY="; hash = "sha256-LMwGxx++z6TpZLnpeRGraid4653Mp8T4pY5EP4Z7GXY=";
}; };
patches = [];
buildInputs = old.buildInputs ++ [prev.chromaprint]; buildInputs = old.buildInputs ++ [prev.chromaprint];
configureFlags = configureFlags =
@ -94,9 +96,9 @@ final: prev: rec {
owner = "superseriousbusiness"; owner = "superseriousbusiness";
repo = "gotosocial"; repo = "gotosocial";
version = "0.13.1"; version = "0.13.2";
source-hash = "sha256-hqESRm+UOBFd+882Qfru1Dc4CnFaHFatX+K12meDODs="; source-hash = "sha256-VQnE4Xff4gtjQ6V2B42zK8UjosBWEMgcL/3Q8S0wc5Q=";
web-assets-hash = "sha256-I/vwAB5F1A2cGmu76CIAYioYoycTHt0RxPOsPr5uQas="; web-assets-hash = "sha256-Iyqn0/VyigmOhlyyz1NfvNIXmWtF617QbWzM2c7jHWw=";
web-assets = final.fetchurl { web-assets = final.fetchurl {
url = "https://github.com/${owner}/${repo}/releases/download/v${version}/${repo}_${version}_web-assets.tar.gz"; url = "https://github.com/${owner}/${repo}/releases/download/v${version}/${repo}_${version}_web-assets.tar.gz";

View file

@ -74,5 +74,7 @@ in {
services.gnome.gnome-keyring.enable = mkForce false; services.gnome.gnome-keyring.enable = mkForce false;
services.xserver = {layout = "gb";}; services.xserver.xkb = {
layout = "gb";
};
} }