Basic ver1 getmail, maildrop, dovecot setup

Signed-off-by: main <magic_rb@redalder.org>
This commit is contained in:
main 2022-04-26 09:55:22 +02:00
parent fd57407030
commit 1c8ed3236a
No known key found for this signature in database
GPG key ID: 08D5287CC5DDCA0E
12 changed files with 506 additions and 0 deletions

72
containers/dovecot.nix Normal file
View file

@ -0,0 +1,72 @@
{ nglib, nixpkgs }:
nglib.makeSystem {
system = "x86_64-linux";
name = "ra-systems-dovecot";
inherit nixpkgs;
config = ({ pkgs, config, nglib, lib, ... }:
{
config = {
dumb-init = {
enable = true;
type.services = {};
};
services.dovecot = {
enable = true;
package = pkgs.dovecot;
config = {
protocols = "imap lmtp";
# auth
ssl = "no";
disable_plaintext_auth = "no";
auth_mechanisms = "plain login";
mail_location = "maildir:/maildir/%u";
protocol."imap" = { };
# Optimizations:
# dotlock_use_excl = true;
maildir_copy_with_hardlinks = true;
lda_mailbox_autocreate = "yes";
lmtp_save_to_detail_mailbox = "yes";
service."lmtp" = {
inet_listener."lmtp" = {
address = [ "127.0.0.1" ];
port = 24;
};
};
service."imap-login" = {
inet_listener."imap" = {
port = 143;
};
# inet_listener."imaps" = {
# port = 993;
# ssl = "yes";
# };
};
# Authentication configuration:
auth_debug = true;
log_path = "/proc/self/fd/1";
info_log_path = "/proc/self/fd/1";
debug_log_path = "/proc/self/fd/1";
passdb."" = {
driver = "passwd-file";
args = "scheme=plain-md5 username_format=%u /secrets/passwd.dovecot";
};
userdb."" = {
driver = "passwd-file";
args = "username_format=%u /secrets/passwd.dovecot";
};
};
};
};
});
}

View file

@ -0,0 +1,98 @@
{ nglib, nixpkgs }@a:
nglib.makeSystem {
system = "x86_64-linux";
name = "ra-systems-getmail";
inherit nixpkgs;
config = ({ pkgs, config, nglib, lib, ... }:
{
config = {
dumb-init = {
enable = true;
type.services = {};
};
users.users."vmail" = {
uid = config.ids.uids.vmail;
description = "vmail user.";
group = "vmail";
shell = "${pkgs.bash}/bin/bash";
};
users.groups."vmail" = {
gid = config.ids.gids.vmail;
};
init.services.getmail =
let
courier-unicode = with pkgs;
stdenv.mkDerivation rec {
name = "courier-unicode";
version = "2.2.3";
src = pkgs.fetchurl {
url = "mirror://sourceforge/courier/courier-unicode/${version}/${name}-${version}.tar.bz2";
sha256 = "sha256-COz13JdSnOOqncqghYYHYt5jbr75aL9LbgzfqvGMev8=";
};
nativeBuildInputs = [ perl ];
};
maildrop-fixed = pkgs.maildrop.overrideAttrs (
old:
{ patches =
[ ./dont-reset-path.patch
./maildrop.configure.hack.patch
];
version = "3.0.7";
src = pkgs.fetchurl {
url = "mirror://sourceforge/courier/maildrop/3.0.7/maildrop-3.0.7.tar.bz2";
sha256 = "sha256-YFzoHDk5BEcy2uRyQhlTTl27UVyAdgvjYRkUq1wfeCU=";
};
nativeBuildInputs = with pkgs; [ pcre2 pkg-config ];
buildInputs = with pkgs; [ libidn courier-unicode ];
});
getmail6-fixed = pkgs.getmail6.overrideAttrs (
old:
{ patches =
[ ./getmail-read-exec-from-path.patch
];
}
);
in
{
shutdownOnExit = true;
script = pkgs.writeShellScript "getmail-run"
''
export PATH=${with pkgs; lib.makeBinPath [ busybox runit bash getmail6-fixed maildrop-fixed ]}:${pkgs.opensmtpd}/libexec/opensmtpd:$PATH
chown vmail:vmail -R /getmail.d
set -m
for rcfile in /getmail.d/getmail.*.rc
do
foo="$(basename "''${rcfile}")"
bar="''${foo#"getmail."}"
email="''${bar%".rc"}"
mkdir -p "/getmail.d/''${email}"
chown vmail:vmail -R "/getmail.d/''${email}"
(
while true
do
chpst -u vmail:vmail getmail -i INBOX -n -r "/getmail.d/getmail.''${email}.rc" --getmaildir "/getmail.d/''${email}"
sleep 10
done
) &
done
wait
'';
enabled = true;
};
};
});
}
# /usr/lib/sendmail -i -oem -f %F %T

View file

@ -0,0 +1,29 @@
From 205aad195842ce19350261849d6378b39e00b11c Mon Sep 17 00:00:00 2001
From: main <magic_rb@redalder.org>
Date: Sun, 10 Apr 2022 15:35:10 +0200
Subject: [PATCH] dont reset path
---
libs/maildrop/main.C | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libs/maildrop/main.C b/libs/maildrop/main.C
index efc7d1f..daf9d2d 100644
--- a/libs/maildrop/main.C
+++ b/libs/maildrop/main.C
@@ -66,8 +66,8 @@ int quota_warn_percent = -1;
const char *quota_warn_message=0;
static const char *defaults_vars[]={"LOCKEXT","LOCKSLEEP","LOCKTIMEOUT",
- "LOCKREFRESH", "PATH", "SENDMAIL",
+ "LOCKREFRESH", "SENDMAIL",
"MAILDIRQUOTA"};
static const char *defaults_vals[]={LOCKEXT_DEF,LOCKSLEEP_DEF,LOCKTIMEOUT_DEF,
- LOCKREFRESH_DEF, DEFAULT_PATH,
+ LOCKREFRESH_DEF,
SENDMAIL_DEF, ""};
Maildrop maildrop;
--
2.35.1

View file

@ -0,0 +1,72 @@
diff --git a/getmailcore/baseclasses.py b/getmailcore/baseclasses.py
index 7143886..e94ba0d 100755
--- a/getmailcore/baseclasses.py
+++ b/getmailcore/baseclasses.py
@@ -261,7 +261,7 @@ class ConfFile(ConfString):
if val is None:
return None
val = expand_user_vars(val)
- if not os.path.isfile(val):
+ if not os.path.isfile(val) and not self.name == 'path' and not self.name == 'password_command':
raise getmailConfigurationError(
'%s: specified file "%s" does not exist' % (self.name, val)
)
@@ -473,4 +473,4 @@ class ForkingBase(object):
stdout, stderr, args, nolog=False):
self._pipemail(msg, delivered_to, received, unixfrom, stdout, stderr)
nolog or self.log.debug('about to execl() with args %s\n' % str(args))
- os.execl(*args)
+ os.execlp(*args)
def forkchild(self, childfun, with_out=True):
self.child = child = Namespace()
diff --git a/getmailcore/destinations.py b/getmailcore/destinations.py
index 2d25558..d7adeba 100755
--- a/getmailcore/destinations.py
+++ b/getmailcore/destinations.py
@@ -607,9 +607,9 @@ class MDA_external(DeliverySkeleton, ForkingBase):
def initialize(self):
self.log.trace()
self.conf['command'] = os.path.basename(self.conf['path'])
- if not os.access(self.conf['path'], os.X_OK):
- raise getmailConfigurationError('%s not executable'
- % self.conf['path'])
+ # if not os.access(self.conf['path'], os.X_OK):
+ # raise getmailConfigurationError('%s not executable'
+ # % self.conf['path'])
if type(self.conf['arguments']) != tuple:
raise getmailConfigurationError(
'incorrect arguments format; see documentation (%s)'
diff --git a/getmailcore/filters.py b/getmailcore/filters.py
index e118e8e..014970a 100755
--- a/getmailcore/filters.py
+++ b/getmailcore/filters.py
@@ -193,10 +193,10 @@ class Filter_external(FilterSkeleton, ForkingBase):
def initialize(self):
self.log.trace()
self.conf['command'] = os.path.basename(self.conf['path'])
- if not os.access(self.conf['path'], os.X_OK):
- raise getmailConfigurationError(
- '%s not executable' % self.conf['path']
- )
+ # if not os.access(self.conf['path'], os.X_OK):
+ # raise getmailConfigurationError(
+ # '%s not executable' % self.conf['path']
+ # )
if type(self.conf['arguments']) != tuple:
raise getmailConfigurationError(
'incorrect arguments format; see documentation (%s)'
@@ -332,9 +332,9 @@ class Filter_TMDA(FilterSkeleton, ForkingBase):
def initialize(self):
self.log.trace()
self.conf['command'] = os.path.basename(self.conf['path'])
- if not os.access(self.conf['path'], os.X_OK):
- raise getmailConfigurationError(
- '%s not executable' % self.conf['path']
- )
+ # if not os.access(self.conf['path'], os.X_OK):
+ # raise getmailConfigurationError(
+ # '%s not executable' % self.conf['path']
+ # )
self.exitcodes_keep = (0, )
self.exitcodes_drop = (99, )

View file

@ -0,0 +1,13 @@
--- a/libs/maildrop/configure 2012-09-06 01:52:13.000000000 +0100
+++ b/libs/maildrop/configure 2013-01-04 03:00:57.095628327 +0000
@@ -17562,8 +17562,8 @@
check_spooldir() {
if test "$CHECKED_SPOOLDIR" != 1
then
- get_spooldir
- MBOX_DIR="$SPOOLDIR"
+ MBOX_DIR="/var/spool/mail"
+ MBOX_RESET_GID=0
CHECKED_SPOOLDIR=1
fi
}

View file

@ -37,6 +37,8 @@
gitea = import ./containers/gitea.nix base;
minecraft = import ./containers/minecraft.nix base;
mosquitto = import ./containers/mosquitto.nix base;
dovecot = import ./containers/dovecot.nix base;
getmail = import ./containers/getmail base;
syncthing = import ./containers/syncthing.nix base;
zigbee2mqtt = import ./containers/zigbee2mqtt.nix base;
home-assistant = import ./containers/home-assistant.nix base;

View file

@ -0,0 +1,19 @@
type = "csi"
id = "dovecot_maildir"
name = "dovecot_maildir"
plugin_id = "nfs"
capability {
access_mode = "multi-node-multi-writer"
attachment_mode = "file-system"
}
context {
server = "blowhole.in.redalder.org"
share = "/var/nfs/dovecot/maildir"
}
mount_options {
fs_type = "nfs"
mount_flags = [ "nolock", "hard" ]
}

View file

@ -0,0 +1,3 @@
path "kv/data/dovecot" {
capabilities = ["read"]
}

View file

@ -0,0 +1,19 @@
type = "csi"
id = "getmail_getmail-d"
name = "getmail_getmail-d"
plugin_id = "nfs"
capability {
access_mode = "multi-node-multi-writer"
attachment_mode = "file-system"
}
context {
server = "blowhole.in.redalder.org"
share = "/var/nfs/getmail/getmail.d"
}
mount_options {
fs_type = "nfs"
mount_flags = [ "nolock", "hard" ]
}

View file

@ -0,0 +1,3 @@
path "kv/data/getmail" {
capabilities = ["read"]
}

View file

@ -0,0 +1,159 @@
job "email" {
datacenters = [ "homelab-1" ]
type = "service"
constraint {
attribute = "${attr.unique.hostname}"
value = "blowhole"
}
group "getmail" {
count = 1
volume "dovecot_maildir" {
type = "csi"
source = "dovecot_maildir"
read_only = false
attachment_mode = "file-system"
access_mode = "multi-node-multi-writer"
}
volume "getmail_getmail-d" {
type = "csi"
source = "getmail_getmail-d"
read_only = false
attachment_mode = "file-system"
access_mode = "single-node-writer"
}
restart {
attempts = 5
delay = "5s"
}
network {
mode = "bridge"
}
service {
name = "getmail"
port = "666"
connect {
sidecar_service {
proxy {
upstreams {
destination_name = "dovecot-lmtp"
local_bind_port = 24
datacenter = "homelab-1"
}
}
}
}
}
task "app" {
driver = "docker"
volume_mount {
volume = "dovecot_maildir"
destination = "/maildir"
read_only = false
}
volume_mount {
volume = "getmail_getmail-d"
destination = "/getmail.d"
read_only = false
}
config {
image = "ra-systems-getmail:local"
}
env {
}
resources {
cpu = 256
memory = 512
}
}
}
group "dovecot" {
count = 1
volume "dovecot_maildir" {
type = "csi"
source = "dovecot_maildir"
read_only = false
attachment_mode = "file-system"
access_mode = "multi-node-multi-writer"
}
restart {
attempts = 5
delay = "5s"
}
network {
mode = "bridge"
}
service {
name = "dovecot-lmtp"
port = "24"
connect {
sidecar_service {}
}
}
service {
name = "dovecot-imap"
port = "143"
connect {
sidecar_service {}
}
}
task "app" {
driver = "docker"
volume_mount {
volume = "dovecot_maildir"
destination = "/maildir"
read_only = false
}
config {
image = "ra-systems-dovecot:local"
}
env {
}
resources {
cpu = 128
memory = 256
}
vault {
policies = ["dovecot-policy"]
}
template {
data = <<EOF
{{ with secret "kv/data/dovecot" }}{{ .Data.data.passwd }}{{ end }}
EOF
destination = "secrets/passwd.dovecot"
change_mode = "noop"
}
}
}
}

View file

@ -312,6 +312,11 @@ EOF
static = 8096
to = 8096
}
port "imap" {
static = 143
to = 143
}
}
service {
@ -341,6 +346,10 @@ EOF
local_bind_port = 8004
}
upstreams {
destination_name = "dovecot-imap"
local_bind_port = 8005
}
}
}
@ -505,7 +514,15 @@ EOF
template {
data = <<EOF
upstream dovecot-imap {
server {{ env "NOMAD_UPSTREAM_ADDR_dovecot-imap" }};
}
server {
listen 143;
proxy_pass dovecot-imap;
}
EOF
destination = "local/streams.conf"
change_mode = "signal"