Merge branch 'add-module'

Signed-off-by: Florian Brandes <florian.brandes@posteo.de>
This commit is contained in:
2024-07-12 16:15:46 +02:00
5 changed files with 173 additions and 8 deletions

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@ config.ini
*.pfx *.pfx
*.crt *.crt
*.pem *.pem
*.pw
!tests/privkey.pem !tests/privkey.pem
!tests/signer.pem !tests/signer.pem

View File

@@ -14,7 +14,6 @@ sender = foo@example.com
# start_tls = false # start_tls = false
# smime_cert = /path/to/cert # smime_cert = /path/to/cert
# smime_cert_private = /path/to/cert.key # smime_cert_private = /path/to/cert.key
# smime_to_cert = /path/to/recipient_cert
[emails] [emails]
# If you want to encrypt outgoing email, add the recipient certificate to the email # If you want to encrypt outgoing email, add the recipient certificate to the email

View File

@@ -22,13 +22,6 @@ pkgs.python3Packages.buildPythonPackage rec {
nativeCheckInputs = [ pkgs.python3Packages.pytestCheckHook ]; nativeCheckInputs = [ pkgs.python3Packages.pytestCheckHook ];
pythonImportsCheck = [ "smtprd_ng" ]; pythonImportsCheck = [ "smtprd_ng" ];
postInstall = ''
install -D -m 644 systemd/smtprd-ng.service \
$out/lib/systemd/system/smtprd-ng.service
substituteInPlace $out/lib/systemd/system/smtprd-ng.service \
--replace-fail @smtprd@ "$out/bin/smtprd-ng"
'';
meta = { meta = {
description = "SMTP forwarding relay daemon with signing and encryption"; description = "SMTP forwarding relay daemon with signing and encryption";
homepage = "https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z3gWc1qgaeZaoGwL4WTstLNoqjayM"; homepage = "https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z3gWc1qgaeZaoGwL4WTstLNoqjayM";

View File

@@ -10,6 +10,7 @@
outputs = { self, nixpkgs, flake-utils, pre-commit-hooks, }: outputs = { self, nixpkgs, flake-utils, pre-commit-hooks, }:
let supportedSystems = [ "x86_64-linux" "aarch64-darwin" ]; let supportedSystems = [ "x86_64-linux" "aarch64-darwin" ];
in { in {
nixosModules.smtprd-ng = import ./module.nix;
overlays.default = import ./overlay.nix { inherit self; }; overlays.default = import ./overlay.nix { inherit self; };
} // flake-utils.lib.eachSystem supportedSystems (system: } // flake-utils.lib.eachSystem supportedSystems (system:
let pkgs = import nixpkgs { inherit system; }; let pkgs = import nixpkgs { inherit system; };

171
module.nix Normal file
View File

@@ -0,0 +1,171 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.smtprd-ng;
smtprd-ng = pkgs.callPackage ./. { };
cfgText = generators.toINI { } {
server = {
hostname = cfg.server.hostname;
port = cfg.server.port;
};
client = {
hostname = cfg.client.hostname;
port = cfg.client.port;
username = cfg.client.username;
password_file = cfg.client.password_file;
sender = cfg.client.sender;
use_tls = cfg.client.use_tls;
start_tls = cfg.client.start_tls;
smime_cert = cfg.client.smime_cert;
smime_cert_private = cfg.client.smime_cert_private;
};
emails = cfg.emails;
};
confFile = pkgs.writeText "config.ini" cfgText;
in {
options.services.smtprd-ng = {
enable = mkEnableOption "smtprd-ng";
package = mkOption {
type = types.package;
default = smtprd-ng;
description = mdDoc ''
The smtprd-ng package to use.
'';
};
server = {
hostname = mkOption {
type = types.str;
default = "localhost";
description = mdDoc ''
The hostname the local SMTP server should listen on.
'';
};
port = mkOption {
type = types.port;
default = 8025;
description = mdDoc ''
The port the local SMTP server should listen on.
'';
};
};
client = {
hostname = mkOption {
type = types.str;
default = "";
description = mdDoc ''
The hostname of the remote SMTP server.
'';
};
port = mkOption {
type = types.port;
default = 587;
description = mdDoc ''
The port of the remote SMTP server.
'';
};
username = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
The username to login to the remote SMTP server.
'';
};
password_file = mkOption {
type = types.nullOr types.path;
default = null;
description = mdDoc ''
The path to the file containing the password to login to the remote SMTP server.
Should not be in /nix/store!
'';
};
sender = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
The email of the sender. Some SMTP servers require this to be the real FROM email address of the user.
'';
};
use_tls = mkOption {
type = types.bool;
default = false;
description = mdDoc ''
Use TLS to connect. Mutually exclusive with `start_tls`
'';
};
start_tls = mkOption {
type = types.bool;
default = false;
description = mdDoc ''
Use STARTLS to connect. Mutually exclusive with `use_tls`
'';
};
smime_cert = mkOption {
type = types.nullOr types.path;
default = null;
example = "''\${./mycert.pem}";
description = mdDoc ''
The path to the S/MIME certificate used to sign messages.
If empty, will neither encrypt, nor sign relayed messages.
'';
};
smime_cert_private = mkOption {
type = types.nullOr types.path;
default = null;
description = mdDoc ''
The path to the S/MIME private key for the certificate used to sign messages.
Should not be in /nix/store!
'';
};
};
emails = mkOption {
type = types.nullOr (types.attrsOf (types.nullOr types.str));
default = null;
description = ''
A required set of recipients. A certificate is optional, but required if
messages should be signed and encrypted.
'';
example = {
"monitoring.foo@example.com" = "`/path/to/certificate`";
"unencrypted@example.com" = "`null`";
};
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = !cfg.client.use_tls || !cfg.client.start_tls;
message = "Use either TLS or STARTTLS, not both.";
}
{
assertion = cfg.client.smime_cert == null || (cfg.client.smime_cert
!= null && cfg.client.smime_cert_private != null);
message =
"If a S/MIME certificate should be used to sign messages, the private key to this certificate must be supplied.";
}
{
assertion = cfg.emails != null;
message = "At least one recipient must be configured.";
}
];
systemd.services = {
smtprd-ng = {
description = "Run local SMTP relay";
wantedBy = [ "multi-user.target" ];
requires = [ "network.target" ];
serviceConfig = {
DynamicUser = true;
User = "smtprd-ng";
Group = "smtprd-ng";
Restart = "on-failure";
ExecStart = "${cfg.package}/bin/smtprd-ng --config ${confFile}";
};
};
};
};
}