'';
services.nginx = {
recommendedTlsSettings = true;
- virtualHosts = { "${config.hostEnv.FQDN}" = { useACMEHost = name; forceSSL = true; }; };
+ virtualHosts = { "${config.hostEnv.fqdn}" = { useACMEHost = name; forceSSL = true; }; };
};
services.websites.certs = config.myServices.certificates.certConfig;
myServices.databasesCerts = config.myServices.certificates.certConfig;
security.acme.certs = {
"${name}" = config.myServices.certificates.certConfig // {
- domain = config.hostEnv.FQDN;
+ domain = config.hostEnv.fqdn;
};
};
'')
cfg.zones }
'';
+ mxes = lib.attrsets.filterAttrs
+ (n: v: v.mx.enable)
+ config.myEnv.servers;
+ ip4mxes = builtins.concatStringsSep "\n" (lib.mapAttrsToList
+ (n: v: "${v.mx.subdomain} IN A ${v.ips.main.ip4}")
+ mxes);
+ ip6mxes = builtins.concatStringsSep "\n" (lib.mapAttrsToList
+ (n: v: builtins.concatStringsSep "\n" (map (i: "${v.mx.subdomain} IN AAAA ${i}") v.ips.main.ip6))
+ mxes);
+ mxmxes = n: conf: builtins.concatStringsSep "\n" (lib.mapAttrsToList
+ (_: v: "${n} IN MX ${v.mx.priority} ${v.mx.subdomain}.${conf.name}.")
+ mxes);
in lib.mkIf config.myServices.dns.enable {
networking.firewall.allowedUDPPorts = [ 53 ];
networking.firewall.allowedTCPPorts = [ 53 ];
${conf.entries}
${if lib.attrsets.hasAttr "withEmail" conf && lib.lists.length conf.withEmail > 0 then ''
- mx-1 IN A ${config.myEnv.servers.eldiron.ips.main.ip4}
- mx-2 IN A ${config.myEnv.servers.immaeEu.ips.main.ip4}
- ${builtins.concatStringsSep "\n" (map (i: "mx-1 IN AAAA ${i}") config.myEnv.servers.eldiron.ips.main.ip6)}
- ${builtins.concatStringsSep "\n" (map (i: "mx-2 IN AAAA ${i}") config.myEnv.servers.immaeEu.ips.main.ip6)}
+ ${ip4mxes}
+ ${ip6mxes}
${lib.concatStringsSep "\n\n" (map (e:
let
n = if e.domain == "" then "@" else "${e.domain} ";
in
''
; ------------------ mail: ${n} ---------------------------
- ${n} IN MX 10 mx-1.${conf.name}.
- ${n} IN MX 20 mx-2.${conf.name}.
+ ${mxmxes n conf}
; https://tools.ietf.org/html/rfc6186
_submission._tcp${suffix} SRV 0 1 587 smtp.immae.eu.
; MTA-STS
; https://blog.delouw.ch/2018/12/16/using-mta-sts-to-enhance-email-transport-security-and-privacy/
; https://support.google.com/a/answer/9261504
- _mta-sts${suffix} IN TXT "v=STSv1;id=20190630054629Z"
+ _mta-sts${suffix} IN TXT "v=STSv1;id=20200109150200Z"
_smtp._tls${suffix} IN TXT "v=TLSRPTv1;rua=mailto:postmaster+mta-sts@immae.eu"
mta-sts${suffix} IN A ${config.myEnv.servers.eldiron.ips.main.ip4}
${builtins.concatStringsSep "\n" (map (i: "mta-sts${suffix} IN AAAA ${i}") config.myEnv.servers.eldiron.ips.main.ip6)}
-{ lib, ... }:
+{ config, lib, name, ... }:
with lib;
with types;
with lists;
};
mysqlOptions = {
host = mkOption { description = "Host to access Mysql"; type = str; };
+ remoteHost = mkOption { description = "Host to access Mysql from outside"; type = str; };
port = mkOption { description = "Port to access Mysql"; type = str; };
socket = mkOption { description = "Socket to access Mysql"; type = path; };
systemUsers = mkOption {
};
};
};
+ hostEnv = submodule {
+ options = {
+ fqdn = mkOption {
+ description = "Host FQDN";
+ type = str;
+ };
+ emails = mkOption {
+ default = [];
+ description = "List of e-mails that the server can be a sender of";
+ type = listOf str;
+ };
+ ldap = mkOption {
+ description = ''
+ LDAP credentials for the host
+ '';
+ type = submodule {
+ options = {
+ password = mkOption { type = string; description = "Password for the LDAP connection"; };
+ dn = mkOption { type = string; description = "DN for the LDAP connection"; };
+ };
+ };
+ };
+ mx = mkOption {
+ description = "subdomain and priority for MX server";
+ default = { enable = false; };
+ type = submodule {
+ options = {
+ enable = mkEnableOption "Enable MX";
+ subdomain = mkOption { type = nullOr str; description = "Subdomain name (mx-*)"; };
+ priority = mkOption { type = nullOr str; description = "Priority"; };
+ };
+ };
+ };
+ ips = mkOption {
+ description = ''
+ attrs of ip4/ip6 grouped by section
+ '';
+ type = attrsOf (submodule {
+ options = {
+ ip4 = mkOption {
+ type = string;
+ description = ''
+ ip4 address of the host
+ '';
+ };
+ ip6 = mkOption {
+ type = listOf string;
+ default = [];
+ description = ''
+ ip6 addresses of the host
+ '';
+ };
+ };
+ });
+ };
+ };
+ };
in
{
options.myEnv = {
Attrs of servers information in the cluster (not necessarily handled by nixops)
'';
default = {};
- type = attrsOf (submodule {
- options = {
- emails = mkOption {
- default = [];
- description = "List of e-mails that the server can be a sender of";
- type = listOf str;
- };
- ldap = mkOption {
- description = ''
- LDAP credentials for the host
- '';
- type = submodule {
- options = {
- password = mkOption { type = string; description = "Password for the LDAP connection"; };
- dn = mkOption { type = string; description = "DN for the LDAP connection"; };
- };
- };
- };
- ips = mkOption {
- description = ''
- attrs of ip4/ip6 grouped by section
- '';
- type = attrsOf (submodule {
- options = {
- ip4 = mkOption {
- type = string;
- description = ''
- ip4 address of the host
- '';
- };
- ip6 = mkOption {
- type = listOf string;
- default = [];
- description = ''
- ip6 addresses of the host
- '';
- };
- };
- });
- };
- };
- });
+ type = attrsOf hostEnv;
};
hetznerCloud = mkOption {
description = ''
'';
};
};
- options.hostEnv = {
- FQDN = mkOption {
- type = string;
- description = ''
- FQDN of the current host.
- '';
- };
+ options.hostEnv = mkOption {
+ readOnly = true;
+ type = hostEnv;
+ default = config.myEnv.servers."${name}";
+ description = "Host environment";
};
}
-{ lib, pkgs, config, ... }:
+{ lib, pkgs, config, ... }:
{
imports = [
./milters.nix
./postfix.nix
./dovecot.nix
+ ./relay.nix
./rspamd.nix
./opensmtpd.nix
];
options.myServices.mail.enable = lib.mkEnableOption "enable Mail services";
options.myServices.mailRelay.enable = lib.mkEnableOption "enable Mail relay services";
+ options.myServices.mailBackup.enable = lib.mkEnableOption "enable MX backup services";
config = lib.mkIf config.myServices.mail.enable {
security.acme.certs."mail" = config.myServices.certificates.certConfig // {
- domain = "eldiron.immae.eu";
+ domain = config.hostEnv.fqdn;
extraDomains = let
zonesWithMx = builtins.filter (zone:
lib.attrsets.hasAttr "withEmail" zone && lib.lists.length zone.withEmail > 0
) config.myEnv.dns.masterZones;
- mxs = map (zone: "mx-1.${zone.name}") zonesWithMx;
+ mxs = map (zone: "${config.hostEnv.mx.subdomain}.${zone.name}") zonesWithMx;
in builtins.listToAttrs (map (mx: lib.attrsets.nameValuePair mx null) mxs);
};
services.duplyBackup.profiles = {
milters sockets
'';
};
- config = lib.mkIf config.myServices.mail.enable {
+ config = lib.mkIf (config.myServices.mail.enable || config.myServices.mailBackup.enable) {
secrets.keys = [
{
dest = "opendkim/eldiron.private";
user = config.services.opendmarc.user;
group = config.services.opendmarc.group;
permissions = "0400";
- text = config.myEnv.mail.dmarc.ignore_hosts;
+ text = let
+ mxes = lib.attrsets.filterAttrs
+ (n: v: v.mx.enable)
+ config.myEnv.servers;
+ in
+ builtins.concatStringsSep "\n" ([
+ config.myEnv.mail.dmarc.ignore_hosts
+ ] ++ lib.mapAttrsToList (n: v: v.fqdn) mxes);
}
];
users.users."${config.services.opendkim.user}".extraGroups = [ "keys" ];
keyPath = "${config.secrets.location}/opendkim";
selector = "eldiron";
configFile = pkgs.writeText "opendkim.conf" ''
- SubDomains yes
- UMask 002
+ SubDomains yes
+ UMask 002
+ AlwaysAddARHeader yes
'';
group = config.services.postfix.group;
};
configFile = pkgs.writeText "opendmarc.conf" ''
AuthservID HOSTNAME
FailureReports false
- FailureReportsBcc postmaster@localhost.immae.eu
+ FailureReportsBcc postmaster@immae.eu
FailureReportsOnNone true
FailureReportsSentBy postmaster@immae.eu
IgnoreAuthenticatedClients true
IgnoreHosts ${config.secrets.fullPaths."opendmarc/ignore.hosts"}
SoftwareHeader true
+ SPFIgnoreResults true
SPFSelfValidate true
- TrustedAuthservIDs HOSTNAME, immae.eu, nef2.ens.fr
UMask 002
'';
group = config.services.postfix.group;
group = "smtpd";
permissions = "0400";
text = ''
- eldiron ${name}:${config.myEnv.servers."${name}".ldap.password}
+ eldiron ${name}:${config.hostEnv.ldap.password}
'';
}
];
# filter "fixfrom" \
# proc-exec "${pkgs.procmail}/bin/formail -i 'From: ${name}@immae.eu'"
action "relay-rewrite-from" relay \
- helo ${config.hostEnv.FQDN} \
+ helo ${config.hostEnv.fqdn} \
host smtp+tls://eldiron@eldiron.immae.eu:587 \
auth <creds> \
mail-from ${name}@immae.eu
action "relay" relay \
- helo ${config.hostEnv.FQDN} \
+ helo ${config.hostEnv.fqdn} \
host smtp+tls://eldiron@eldiron.immae.eu:587 \
auth <creds>
match for any !mail-from "@immae.eu" action "relay-rewrite-from"
-{ lib, pkgs, config, nodes, ... }:
+{ lib, pkgs, config, nodes, name, ... }:
{
config = lib.mkIf config.myServices.mail.enable {
services.duplyBackup.profiles.mail.excludeFile = ''
lib.imap1 (i: m: "${m.type}:/etc/postfix/relay_${n}_${toString i}") v.recipient_maps
) config.myEnv.mail.postfix.backup_domains);
smtpd_relay_restrictions = [
- "permit_mynetworks"
- "permit_sasl_authenticated"
"defer_unauth_destination"
] ++ lib.flatten (lib.attrsets.mapAttrsToList (n: v:
if lib.attrsets.hasAttr "relay_restrictions" v
smtp_tls_loglevel = "1";
### Force ip bind for smtp
- smtp_bind_address = config.myEnv.servers.eldiron.ips.main.ip4;
- smtp_bind_address6 = builtins.head config.myEnv.servers.eldiron.ips.main.ip6;
+ smtp_bind_address = config.hostEnv.ips.main.ip4;
+ smtp_bind_address6 = builtins.head config.hostEnv.ips.main.ip6;
# Use some relays when authorized senders are not myself
smtp_sasl_mechanism_filter = "plain,login"; # GSSAPI Not correctly supported by postfix
### opendkim, opendmarc, openarc milters
non_smtpd_milters = [
"unix:${config.myServices.mail.milters.sockets.opendkim}"
- "unix:${config.myServices.mail.milters.sockets.opendmarc}"
- "unix:${config.myServices.mail.milters.sockets.openarc}"
];
smtpd_milters = [
"unix:${config.myServices.mail.milters.sockets.opendkim}"
- "unix:${config.myServices.mail.milters.sockets.opendmarc}"
"unix:${config.myServices.mail.milters.sockets.openarc}"
+ "unix:${config.myServices.mail.milters.sockets.opendmarc}"
];
};
enable = true;
smtpd_sasl_path = "private/auth";
smtpd_reject_unlisted_recipient = "no";
smtpd_client_restrictions = "permit_sasl_authenticated,reject";
+ smtpd_relay_restrictions = "permit_sasl_authenticated,reject";
# Refuse to send e-mails with a From that is not handled
smtpd_sender_restrictions =
"reject_sender_login_mismatch,reject_unlisted_sender,permit_sasl_authenticated,reject";
'';
destination = ["localhost"];
# This needs to reverse DNS
- hostname = "eldiron.immae.eu";
+ hostname = config.hostEnv.fqdn;
setSendmail = true;
sslCert = "/var/lib/acme/mail/fullchain.pem";
sslKey = "/var/lib/acme/mail/key.pem";
--- /dev/null
+{ lib, pkgs, config, nodes, name, ... }:
+{
+ config = lib.mkIf config.myServices.mailBackup.enable {
+ security.acme.certs."mail" = config.myServices.certificates.certConfig // {
+ postRun = ''
+ systemctl restart postfix.service
+ '';
+ domain = config.hostEnv.fqdn;
+ extraDomains = let
+ zonesWithMx = builtins.filter (zone:
+ lib.attrsets.hasAttr "withEmail" zone && lib.lists.length zone.withEmail > 0
+ ) config.myEnv.dns.masterZones;
+ mxs = map (zone: "${config.myEnv.servers."${name}".mx.subdomain}.${zone.name}") zonesWithMx;
+ in builtins.listToAttrs (map (mx: lib.attrsets.nameValuePair mx null) mxs);
+ };
+ secrets.keys = [
+ {
+ dest = "postfix/mysql_alias_maps";
+ user = config.services.postfix.user;
+ group = config.services.postfix.group;
+ permissions = "0440";
+ text = ''
+ # We need to specify that option to trigger ssl connection
+ tls_ciphers = TLSv1.2
+ user = ${config.myEnv.mail.postfix.mysql.user}
+ password = ${config.myEnv.mail.postfix.mysql.password}
+ hosts = ${config.myEnv.mail.postfix.mysql.remoteHost}
+ dbname = ${config.myEnv.mail.postfix.mysql.database}
+ query = SELECT DISTINCT 1
+ FROM forwardings_merge
+ WHERE
+ ((regex = 1 AND '%s' REGEXP CONCAT('^',source,'$') ) OR (regex = 0 AND source = '%s'))
+ AND active = 1
+ AND '%s' NOT IN
+ (
+ SELECT source
+ FROM forwardings_blacklisted
+ WHERE source = '%s'
+ ) UNION
+ SELECT 'devnull@immae.eu'
+ FROM forwardings_blacklisted
+ WHERE source = '%s'
+ '';
+ }
+ {
+ dest = "postfix/mysql_mailbox_maps";
+ user = config.services.postfix.user;
+ group = config.services.postfix.group;
+ permissions = "0440";
+ text = ''
+ # We need to specify that option to trigger ssl connection
+ tls_ciphers = TLSv1.2
+ user = ${config.myEnv.mail.postfix.mysql.user}
+ password = ${config.myEnv.mail.postfix.mysql.password}
+ hosts = ${config.myEnv.mail.postfix.mysql.remoteHost}
+ dbname = ${config.myEnv.mail.postfix.mysql.database}
+ query = SELECT DISTINCT 1
+ FROM mailboxes
+ WHERE active = 1
+ AND (
+ (domain = '%d' AND user = '%u' AND regex = 0)
+ OR (
+ regex = 1
+ AND '%d' REGEXP CONCAT('^',domain,'$')
+ AND '%u' REGEXP CONCAT('^',user,'$')
+ )
+ )
+ LIMIT 1
+ '';
+ }
+ {
+ dest = "postfix/ldap_ejabberd_users_immae_fr";
+ user = config.services.postfix.user;
+ group = config.services.postfix.group;
+ permissions = "0440";
+ text = ''
+ server_host = ldaps://${config.myEnv.jabber.ldap.host}:636
+ search_base = ${config.myEnv.jabber.ldap.base}
+ query_filter = ${config.myEnv.jabber.postfix_user_filter}
+ domain = immae.fr
+ bind_dn = ${config.myEnv.jabber.ldap.dn}
+ bind_pw = ${config.myEnv.jabber.ldap.password}
+ result_attribute = immaeXmppUid
+ result_format = ejabberd@localhost
+ version = 3
+ '';
+ }
+ ];
+
+ networking.firewall.allowedTCPPorts = [ 25 ];
+
+ nixpkgs.overlays = [ (self: super: {
+ postfix = super.postfix.override { withMySQL = true; };
+ }) ];
+ users.users."${config.services.postfix.user}".extraGroups = [ "keys" ];
+ services.filesWatcher.postfix = {
+ restart = true;
+ paths = [
+ config.secrets.fullPaths."postfix/mysql_alias_maps"
+ config.secrets.fullPaths."postfix/mysql_mailbox_maps"
+ config.secrets.fullPaths."postfix/ldap_ejabberd_users_immae_fr"
+ ];
+ };
+ services.postfix = {
+ mapFiles = let
+ recipient_maps = let
+ name = n: i: "relay_${n}_${toString i}";
+ pair = n: i: m: lib.attrsets.nameValuePair (name n i) (
+ if m.type == "hash"
+ then pkgs.writeText (name n i) m.content
+ else null
+ );
+ pairs = n: v: lib.imap1 (i: m: pair n i m) v.recipient_maps;
+ in lib.attrsets.filterAttrs (k: v: v != null) (
+ lib.attrsets.listToAttrs (lib.flatten (
+ lib.attrsets.mapAttrsToList pairs config.myEnv.mail.postfix.backup_domains
+ ))
+ );
+ relay_restrictions = lib.attrsets.filterAttrs (k: v: v != null) (
+ lib.attrsets.mapAttrs' (n: v:
+ lib.attrsets.nameValuePair "recipient_access_${n}" (
+ if lib.attrsets.hasAttr "relay_restrictions" v
+ then pkgs.writeText "recipient_access_${n}" v.relay_restrictions
+ else null
+ )
+ ) config.myEnv.mail.postfix.backup_domains
+ );
+ virtual_map = {
+ virtual = pkgs.writeText "postfix-virtual" (
+ builtins.concatStringsSep "\n" (
+ lib.attrsets.mapAttrsToList (
+ n: v: lib.optionalString v.external ''
+ script_${n}@mail.immae.eu 1
+ ''
+ ) config.myEnv.mail.scripts
+ )
+ );
+ };
+ sasl_access = {
+ host_dummy_mailboxes = pkgs.writeText "host-virtual-mailbox"
+ (builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList (n: v: "${n}@immae.eu 1") nodes));
+ };
+ in
+ recipient_maps // relay_restrictions // virtual_map // sasl_access;
+ config = {
+ ### postfix module overrides
+ readme_directory = "${pkgs.postfix}/share/postfix/doc";
+ smtp_tls_CAfile = lib.mkForce "";
+ smtp_tls_cert_file = lib.mkForce "";
+ smtp_tls_key_file = lib.mkForce "";
+
+ message_size_limit = "1073741824"; # Don't put 0 here, it's not equivalent to "unlimited"
+ mailbox_size_limit = "1073741825"; # Workaround, local delivered mails should all go through scripts
+ alias_database = "\$alias_maps";
+
+ ### Relay domains
+ relay_domains = let
+ backups = lib.flatten (lib.attrsets.mapAttrsToList (n: v: v.domains or []) config.myEnv.mail.postfix.backup_domains);
+ virtual_domains = config.myEnv.mail.postfix.additional_mailbox_domains
+ ++ lib.remove "localhost.immae.eu" (lib.remove null (lib.flatten (map
+ (zone: map
+ (e: if e.receive
+ then "${e.domain}${lib.optionalString (e.domain != "") "."}${zone.name}"
+ else null
+ )
+ (zone.withEmail or [])
+ )
+ config.myEnv.dns.masterZones
+ )));
+ in
+ backups ++ virtual_domains;
+ relay_recipient_maps = let
+ backup_recipients = lib.flatten (lib.attrsets.mapAttrsToList (n: v:
+ lib.imap1 (i: m: "${m.type}:/etc/postfix/relay_${n}_${toString i}") v.recipient_maps
+ ) config.myEnv.mail.postfix.backup_domains);
+ virtual_alias_maps = [
+ "hash:/etc/postfix/virtual"
+ "mysql:${config.secrets.fullPaths."postfix/mysql_alias_maps"}"
+ "ldap:${config.secrets.fullPaths."postfix/ldap_ejabberd_users_immae_fr"}"
+ ];
+ virtual_mailbox_maps = [
+ "hash:/etc/postfix/host_dummy_mailboxes"
+ "mysql:${config.secrets.fullPaths."postfix/mysql_mailbox_maps"}"
+ ];
+ in
+ backup_recipients ++ virtual_alias_maps ++ virtual_mailbox_maps;
+ smtpd_relay_restrictions = [
+ "defer_unauth_destination"
+ ] ++ lib.flatten (lib.attrsets.mapAttrsToList (n: v:
+ if lib.attrsets.hasAttr "relay_restrictions" v
+ then [ "check_recipient_access hash:/etc/postfix/recipient_access_${n}" ]
+ else []
+ ) config.myEnv.mail.postfix.backup_domains);
+
+ ### Additional smtpd configuration
+ smtpd_tls_received_header = "yes";
+ smtpd_tls_loglevel = "1";
+
+ ### Email sending configuration
+ smtp_tls_security_level = "may";
+ smtp_tls_loglevel = "1";
+
+ ### Force ip bind for smtp
+ smtp_bind_address = config.myEnv.servers."${name}".ips.main.ip4;
+ smtp_bind_address6 = builtins.head config.myEnv.servers."${name}".ips.main.ip6;
+
+ smtpd_milters = [
+ "unix:${config.myServices.mail.milters.sockets.opendkim}"
+ "unix:${config.myServices.mail.milters.sockets.openarc}"
+ "unix:${config.myServices.mail.milters.sockets.opendmarc}"
+ ];
+ };
+ enable = true;
+ enableSmtp = true;
+ enableSubmission = false;
+ # FIXME: Mail adressed to localhost.immae.eu will still have mx-1 as
+ # prioritized MX, which provokes "mail for localhost.immae.eu loops
+ # back to myself" errors. This transport entry forces to push
+ # e-mails to its right destination.
+ transport = ''
+ localhost.immae.eu smtp:[immae.eu]:25
+ '';
+ destination = ["localhost"];
+ # This needs to reverse DNS
+ hostname = config.hostEnv.fqdn;
+ setSendmail = false;
+ sslCert = "/var/lib/acme/mail/fullchain.pem";
+ sslKey = "/var/lib/acme/mail/key.pem";
+ recipientDelimiter = "+";
+ };
+ };
+}
+
masterObjects = pkgs.callPackage ./objects_master.nix { inherit config; };
commonObjects = pkgs.callPackage ./objects_common.nix ({
master = cfg.master;
- hostFQDN = config.hostEnv.FQDN;
+ hostFQDN = config.hostEnv.fqdn;
hostName = name;
sudo = "/run/wrappers/bin/sudo";
} // builtins.getAttr name commonConfig);
(builtins.pathExists specific_file)
(pkgs.callPackage specific_file {
inherit config;
- hostFQDN = config.hostEnv.FQDN;
+ hostFQDN = config.hostEnv.fqdn;
hostName = name;
});
in
security.acme.certs."${name}".extraDomains."status.immae.eu" = null;
myServices.certificates.enable = true;
- networking.firewall.allowedTCPPorts = [ 80 443 18000 ];
+ networking.firewall.allowedTCPPorts = [ 80 443 ];
systemd.services.naemon-status = {
description = "Naemon status";
after = [ "network.target" ];
-{ pkgs, lib, ... }:
+{ pkgs, lib, config, name, ... }:
{
config = {
services.duplyBackup.profiles.system = {
{ privateFiles }:
-{ config, pkgs, resources, name, ... }:
+{ config, pkgs, resources, ... }:
{
boot.kernelPackages = pkgs.linuxPackages_latest;
myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
- hostEnv.FQDN = "backup-2.v.immae.eu";
imports = builtins.attrValues (import ../..);
firewall.enable = true;
interfaces."ens3".ipv4.addresses = pkgs.lib.attrsets.mapAttrsToList
(n: ips: { address = ips.ip4; prefixLength = 32; })
- (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.myEnv.servers.backup-2.ips);
+ (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.hostEnv.ips);
interfaces."ens3".ipv6.addresses = pkgs.lib.flatten (pkgs.lib.attrsets.mapAttrsToList
(n: ips: map (ip: { address = ip; prefixLength = (if n == "main" && ip == pkgs.lib.head ips.ip6 then 64 else 128); }) (ips.ip6 or []))
- config.myEnv.servers.backup-2.ips);
+ config.hostEnv.ips);
defaultGateway6 = { address = "fe80::1"; interface = "ens3"; };
};
+ myServices.certificates.enable = true;
+ services.nginx = {
+ enable = true;
+ recommendedOptimisation = true;
+ recommendedGzipSettings = true;
+ recommendedProxySettings = true;
+ };
+ networking.firewall.allowedTCPPorts = [ 80 443 ];
+
services.cron = {
mailto = "cron@immae.eu";
enable = true;
};
myServices.mailRelay.enable = true;
+ myServices.mailBackup.enable = true;
myServices.monitoring.enable = true;
myServices.databasesReplication = {
postgresql = {
hosts = {
eldiron = {
slot = "backup_2";
- connection = "postgresql://backup-2:${config.myEnv.servers.backup-2.ldap.password}@eldiron.immae.eu";
+ connection = "postgresql://backup-2:${config.hostEnv.ldap.password}@eldiron.immae.eu";
};
};
};
host = config.myEnv.servers.eldiron.ips.main.ip4;
port = "3306";
user = "backup-2";
- password = config.myEnv.servers.backup-2.ldap.password;
+ password = config.hostEnv.ldap.password;
dumpUser = "root";
dumpPassword = config.myEnv.databases.mysql.systemUsers.root;
};
{
boot.kernelPackages = pkgs.linuxPackages_latest;
myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
- hostEnv.FQDN = "eldiron.immae.eu";
networking = {
firewall.enable = true;
# 176.9.151.89 declared in nixops -> infra / tools
interfaces."eth0".ipv4.addresses = pkgs.lib.attrsets.mapAttrsToList
(n: ips: { address = ips.ip4; prefixLength = 32; })
- (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.myEnv.servers.eldiron.ips);
+ (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.hostEnv.ips);
interfaces."eth0".ipv6.addresses = pkgs.lib.flatten (pkgs.lib.attrsets.mapAttrsToList
(n: ips: map (ip: { address = ip; prefixLength = (if n == "main" && ip == pkgs.lib.head ips.ip6 then 64 else 128); }) (ips.ip6 or []))
- config.myEnv.servers.eldiron.ips);
+ config.hostEnv.ips);
};
imports = builtins.attrValues (import ../..);
hetzner = {
robotUser = config.myEnv.hetzner.user;
robotPass = config.myEnv.hetzner.pass;
- mainIPv4 = config.myEnv.servers.eldiron.ips.main.ip4;
+ mainIPv4 = config.hostEnv.ips.main.ip4;
partitions = ''
clearpart --all --initlabel --drives=sda,sdb
{
boot.kernelPackages = pkgs.linuxPackages_latest;
myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; };
- hostEnv.FQDN = "monitoring-1.v.immae.eu";
imports = builtins.attrValues (import ../..);
firewall.enable = true;
interfaces."ens3".ipv4.addresses = pkgs.lib.attrsets.mapAttrsToList
(n: ips: { address = ips.ip4; prefixLength = 32; })
- (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.myEnv.servers.monitoring-1.ips);
+ (pkgs.lib.attrsets.filterAttrs (n: v: n != "main") config.hostEnv.ips);
interfaces."ens3".ipv6.addresses = pkgs.lib.flatten (pkgs.lib.attrsets.mapAttrsToList
(n: ips: map (ip: { address = ip; prefixLength = (if n == "main" && ip == pkgs.lib.head ips.ip6 then 64 else 128); }) (ips.ip6 or []))
- config.myEnv.servers.monitoring-1.ips);
+ config.hostEnv.ips);
defaultGateway6 = { address = "fe80::1"; interface = "ens3"; };
};
myServices.mailRelay.enable = true;
$g_from_email = 'mantisbt@tools.immae.eu';
$g_return_path_email = 'mantisbt@tools.immae.eu';
$g_from_name = 'Mantis Bug Tracker at git.immae.eu';
- $g_email_receive_own = OFF;
+ $g_email_receive_own = ON;
# --- LDAP ---
$g_login_method = LDAP;
$g_ldap_protocol_version = 3;
)
config.myEnv.dns.masterZones
)));
+ mxes = lib.mapAttrsToList
+ (n: v: v.mx.subdomain)
+ (lib.attrsets.filterAttrs (n: v: v.mx.enable) config.myEnv.servers);
# FIXME: increase the id number in modules/private/dns.nix when this
# file change (date -u +'%Y%m%d%H%M%S'Z)
file = domain: pkgs.writeText "mta-sts-${domain.domain}.txt" ''
version: STSv1
mode: testing
- mx: mx-1.${domain.mail}
- mx: mx-2.${domain.mail}
+ ${builtins.concatStringsSep "\n" (map (v: "mx: ${v}.${domain.mail}") mxes)}
max_age: 604800
'';
root = pkgs.runCommand "mta-sts_root" {} ''