nixos-mailserver/default.nix

286 lines
8.0 KiB
Nix
Raw Normal View History

2017-08-30 03:58:44 +05:00
# nixos-mailserver: a simple mail server
# Copyright (C) 2016-2017 Robin Raymond
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.mailserver;
in
{
options.mailserver = {
enable = mkEnableOption "nixos-mailserver";
domain = mkOption {
type = types.str;
example = "example.com";
description = "The domain that this mail server serves. So far only one domain is supported";
};
2017-09-02 16:23:37 +05:00
hostPrefix = mkOption {
2017-08-30 03:58:44 +05:00
type = types.str;
default = "mail";
description = ''
The prefix of the FQDN of the server. In this example the FQDN of the server
is given by 'mail.example.com'
'';
};
2017-09-02 16:23:37 +05:00
loginAccounts = mkOption {
2017-08-30 03:58:44 +05:00
type = types.loaOf (types.submodule ({ name, ... }: {
options = {
name = mkOption {
type = types.str;
example = "user1";
description = "Username";
};
hashedPassword = mkOption {
type = types.str;
example = "$6$evQJs5CFQyPAW09S$Cn99Y8.QjZ2IBnSu4qf1vBxDRWkaIZWOtmu1Ddsm3.H3CFpeVc0JU4llIq8HQXgeatvYhh5O33eWG3TSpjzu6/";
description = ''
Hashed password. Use `mkpasswd` as follows
```
mkpasswd -m sha-512 "super secret password"
```
'';
};
};
config.name = mkDefault name;
}));
example = {
user1 = {
hashedPassword = "$6$evQJs5CFQyPAW09S$Cn99Y8.QjZ2IBnSu4qf1vBxDRWkaIZWOtmu1Ddsm3.H3CFpeVc0JU4llIq8HQXgeatvYhh5O33eWG3TSpjzu6/";
};
user2 = {
hashedPassword = "$6$oE0ZNv2n7Vk9gOf$9xcZWCCLGdMflIfuA0vR1Q1Xblw6RZqPrP94mEit2/81/7AKj2bqUai5yPyWE.QYPyv6wLMHZvjw3Rlg7yTCD/";
};
};
description = ''
The login account of the domain. Every account is mapped to a unix user,
e.g. `user1@example.com`. To generate the passwords use `mkpasswd` as
follows
```
mkpasswd -m sha-512 "super secret password"
```
'';
2017-09-02 15:59:07 +05:00
default = {};
2017-08-30 03:58:44 +05:00
};
2017-09-02 16:23:37 +05:00
virtualAliases = mkOption {
type = types.attrsOf (types.enum (builtins.attrNames cfg.loginAccounts));
2017-08-30 03:58:44 +05:00
example = {
info = "user1";
postmaster = "user1";
abuse = "user1";
};
description = ''
Virtual Aliases. A virtual alias `info = "user1"` means that
all mail to `info@example.com` is forwarded to `user1@example.com`. Note
that it is expected that `postmaster@example.com` and `abuse@example.com` is
forwarded to some valid email address. (Alternatively you can create login
accounts for `postmaster` and (or) `abuse`).
'';
2017-09-02 15:59:07 +05:00
default = {};
2017-08-30 03:58:44 +05:00
};
2017-09-02 16:23:37 +05:00
vmailUIDStart = mkOption {
2017-08-30 03:58:44 +05:00
type = types.int;
default = 5000;
description = ''
2017-09-02 16:23:37 +05:00
The unix UID where the loginAccounts are created. 5000 means that the first
2017-08-30 03:58:44 +05:00
user will get 5000, the second 5001, ...
'';
};
2017-09-02 16:23:37 +05:00
vmailUserName = mkOption {
2017-08-30 03:58:44 +05:00
type = types.str;
default = "vmail";
description = ''
The user name and group name of the user that owns the directory where all
the mail is stored.
'';
};
2017-09-02 16:23:37 +05:00
vmailGroupName = mkOption {
2017-08-30 03:58:44 +05:00
type = types.str;
default = "vmail";
description = ''
The user name and group name of the user that owns the directory where all
the mail is stored.
'';
};
2017-09-02 16:23:37 +05:00
mailDirectory = mkOption {
2017-08-30 03:58:44 +05:00
type = types.string;
default = "/var/vmail";
description = ''
Where to store the mail.
'';
};
2017-09-02 16:23:37 +05:00
certificateScheme = mkOption {
2017-08-30 03:58:44 +05:00
type = types.enum [ 1 2 ];
default = 2;
description = ''
Certificate Files. There are three options for these.
1) You specify locations and manually copy certificates there.
2) You let the server create new (self signed) certificates on the fly.
3) You let the server create a certificate via `Let's Encrypt`. Note that
this implies that a stripped down webserver has to be started. This also
implies that the FQDN must be set as an `A` record to point to the IP of
the server. TODO: Explain more details
TODO: Only certificate scheme 1) and 2) work as of yet.
'';
};
2017-09-02 16:23:37 +05:00
certificateFile = mkOption {
2017-08-30 03:58:44 +05:00
type = types.path;
example = "/root/mail-server.crt";
description = ''
Scheme 1)
Location of the certificate
'';
};
2017-09-02 16:23:37 +05:00
keyFile = mkOption {
2017-08-30 03:58:44 +05:00
type = types.path;
example = "/root/mail-server.key";
description = ''
Scheme 1)
Location of the key file
'';
};
2017-09-02 16:29:49 +05:00
certificateDirectory = mkOption {
2017-08-30 03:58:44 +05:00
type = types.path;
default = "/var/certs";
description = ''
Sceme 2)
This is the folder where the certificate will be created. The name is
hardcoded to "cert-<domain>.pem" and "key-<domain>.pem" and the
certificate is valid for 10 years.
'';
};
2017-09-02 16:29:49 +05:00
enableImap = mkOption {
2017-08-30 03:58:44 +05:00
type = types.bool;
default = true;
description = ''
Whether to enable imap / pop3. Both variants are only supported in the
(sane) startTLS configuration. (TODO: Allow SSL ports). The ports are
110 - Pop3
143 - IMAP
587 - SMTP with login
'';
};
2017-09-02 16:29:49 +05:00
enablePop3 = mkOption {
2017-08-30 03:58:44 +05:00
type = types.bool;
default = false;
description = ''
Whether to enable POP3. Both variants are only supported in the
(sane) startTLS configuration. (TODO: Allow SSL ports). The ports are
110 - Pop3
143 - IMAP
587 - SMTP with login
'';
};
# imapSsl = mkOption {} #< TODO
# pop3Ssl = mkOption {} #< TODO
2017-09-02 16:23:37 +05:00
virusScanning = mkOption {
2017-08-30 03:58:44 +05:00
type = types.bool;
default = false;
description = ''
Whether to activate virus scanning. Note that virus scanning is _very_
expensive memory wise.
'';
};
2017-09-02 16:29:49 +05:00
dkimSigning = mkOption {
2017-08-30 03:58:44 +05:00
type = types.bool;
default = true;
description = ''
Whether to activate dkim signing.
TODO: Explain how to put signature into domain record
'';
};
2017-09-02 16:29:49 +05:00
dkimSelector = mkOption {
2017-08-30 03:58:44 +05:00
type = types.string;
default = "mail";
description = ''
'';
};
2017-09-02 16:29:49 +05:00
dkimKeyDirectory = mkOption {
2017-08-30 03:58:44 +05:00
type = types.path;
default = "/var/dkim";
description = ''
'';
};
};
2017-09-02 15:59:07 +05:00
imports = [
./mail-server/clamav.nix
];
2017-08-30 03:58:44 +05:00
config = mkIf cfg.enable {
services = import ./mail-server/services.nix {
inherit lib;
2017-09-02 16:23:37 +05:00
inherit (cfg) mailDirectory vmailUserName vmailGroupName virtualAliases domain
2017-09-02 16:29:49 +05:00
enableImap enablePop3 dkimSigning dkimSelector dkimKeyDirectory
certificateScheme certificateFile keyFile certificateDirectory virusScanning;
2017-08-30 03:58:44 +05:00
};
environment = import ./mail-server/environment.nix {
inherit pkgs;
2017-09-02 16:23:37 +05:00
inherit (cfg) certificateScheme;
2017-08-30 03:58:44 +05:00
};
networking = import ./mail-server/networking.nix {
2017-09-02 16:29:49 +05:00
inherit (cfg) domain hostPrefix enableImap enablePop3;
2017-08-30 03:58:44 +05:00
};
systemd = import ./mail-server/systemd.nix {
inherit pkgs;
2017-09-02 16:29:49 +05:00
inherit (cfg) mailDirectory vmailGroupName certificateScheme
certificateDirectory
hostPrefix domain dkimSelector dkimKeyDirectory;
2017-08-30 03:58:44 +05:00
};
users = import ./mail-server/users.nix {
inherit lib;
2017-09-02 16:23:37 +05:00
inherit (cfg) vmailUIDStart vmailUserName vmailGroupName domain
mailDirectory
loginAccounts;
2017-08-30 03:58:44 +05:00
};
};
}