From: Ismaƫl Bouya Date: Thu, 9 Jan 2020 23:01:45 +0000 (+0100) Subject: Add backup MX X-Git-Url: https://git.immae.eu/?p=perso%2FImmae%2FConfig%2FNix.git;a=commitdiff_plain;h=619e4f46adc15e409122c4e0fa0e0a0b811bb32f Add backup MX --- diff --git a/modules/private/certificates.nix b/modules/private/certificates.nix index 9e60a09..2d24579 100644 --- a/modules/private/certificates.nix +++ b/modules/private/certificates.nix @@ -24,7 +24,7 @@ ''; 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; @@ -34,7 +34,7 @@ security.acme.certs = { "${name}" = config.myServices.certificates.certConfig // { - domain = config.hostEnv.FQDN; + domain = config.hostEnv.fqdn; }; }; diff --git a/modules/private/dns.nix b/modules/private/dns.nix index fb90824..ebced42 100644 --- a/modules/private/dns.nix +++ b/modules/private/dns.nix @@ -50,6 +50,18 @@ '') 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 ]; @@ -94,10 +106,8 @@ ${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} "; @@ -105,8 +115,7 @@ 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. @@ -120,7 +129,7 @@ ; 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)} diff --git a/modules/private/environment.nix b/modules/private/environment.nix index 5f5f6c8..98d50b1 100644 --- a/modules/private/environment.nix +++ b/modules/private/environment.nix @@ -1,4 +1,4 @@ -{ lib, ... }: +{ config, lib, name, ... }: with lib; with types; with lists; @@ -23,6 +23,7 @@ let }; 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 { @@ -107,6 +108,63 @@ let }; }; }; + 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 = { @@ -115,48 +173,7 @@ in 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 = '' @@ -1172,12 +1189,10 @@ in ''; }; }; - 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"; }; } diff --git a/modules/private/mail/default.nix b/modules/private/mail/default.nix index a617934..b50e346 100644 --- a/modules/private/mail/default.nix +++ b/modules/private/mail/default.nix @@ -1,23 +1,25 @@ -{ 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 = { diff --git a/modules/private/mail/milters.nix b/modules/private/mail/milters.nix index 6b033e8..16c8a7a 100644 --- a/modules/private/mail/milters.nix +++ b/modules/private/mail/milters.nix @@ -12,7 +12,7 @@ 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"; @@ -34,7 +34,14 @@ 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" ]; @@ -51,8 +58,9 @@ 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; }; @@ -74,14 +82,14 @@ 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; diff --git a/modules/private/mail/opensmtpd.nix b/modules/private/mail/opensmtpd.nix index 7831ac0..e4a6140 100644 --- a/modules/private/mail/opensmtpd.nix +++ b/modules/private/mail/opensmtpd.nix @@ -8,7 +8,7 @@ group = "smtpd"; permissions = "0400"; text = '' - eldiron ${name}:${config.myEnv.servers."${name}".ldap.password} + eldiron ${name}:${config.hostEnv.ldap.password} ''; } ]; @@ -22,12 +22,12 @@ # 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 \ 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 match for any !mail-from "@immae.eu" action "relay-rewrite-from" diff --git a/modules/private/mail/postfix.nix b/modules/private/mail/postfix.nix index 6623735..bd284cb 100644 --- a/modules/private/mail/postfix.nix +++ b/modules/private/mail/postfix.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, config, nodes, ... }: +{ lib, pkgs, config, nodes, name, ... }: { config = lib.mkIf config.myServices.mail.enable { services.duplyBackup.profiles.mail.excludeFile = '' @@ -299,8 +299,6 @@ 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 @@ -317,8 +315,8 @@ 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 @@ -333,13 +331,11 @@ ### 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; @@ -357,6 +353,7 @@ 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"; @@ -378,7 +375,7 @@ ''; 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"; diff --git a/modules/private/mail/relay.nix b/modules/private/mail/relay.nix new file mode 100644 index 0000000..9111350 --- /dev/null +++ b/modules/private/mail/relay.nix @@ -0,0 +1,233 @@ +{ 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 = "+"; + }; + }; +} + diff --git a/modules/private/monitoring/default.nix b/modules/private/monitoring/default.nix index a1f4b3f..2c2f693 100644 --- a/modules/private/monitoring/default.nix +++ b/modules/private/monitoring/default.nix @@ -85,7 +85,7 @@ let 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); @@ -97,7 +97,7 @@ let (builtins.pathExists specific_file) (pkgs.callPackage specific_file { inherit config; - hostFQDN = config.hostEnv.FQDN; + hostFQDN = config.hostEnv.fqdn; hostName = name; }); in diff --git a/modules/private/monitoring/status.nix b/modules/private/monitoring/status.nix index ed4d681..d25d934 100644 --- a/modules/private/monitoring/status.nix +++ b/modules/private/monitoring/status.nix @@ -37,7 +37,7 @@ 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" ]; diff --git a/modules/private/system.nix b/modules/private/system.nix index 184add5..66208c4 100644 --- a/modules/private/system.nix +++ b/modules/private/system.nix @@ -1,4 +1,4 @@ -{ pkgs, lib, ... }: +{ pkgs, lib, config, name, ... }: { config = { services.duplyBackup.profiles.system = { diff --git a/modules/private/system/backup-2.nix b/modules/private/system/backup-2.nix index ede5bc2..1d84667 100644 --- a/modules/private/system/backup-2.nix +++ b/modules/private/system/backup-2.nix @@ -1,9 +1,8 @@ { 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 ../..); @@ -28,13 +27,22 @@ 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; @@ -49,6 +57,7 @@ }; myServices.mailRelay.enable = true; + myServices.mailBackup.enable = true; myServices.monitoring.enable = true; myServices.databasesReplication = { postgresql = { @@ -57,7 +66,7 @@ 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"; }; }; }; @@ -71,7 +80,7 @@ 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; }; diff --git a/modules/private/system/eldiron.nix b/modules/private/system/eldiron.nix index bbe1345..0490cfc 100644 --- a/modules/private/system/eldiron.nix +++ b/modules/private/system/eldiron.nix @@ -3,17 +3,16 @@ { 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 ../..); @@ -44,7 +43,7 @@ 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 diff --git a/modules/private/system/monitoring-1.nix b/modules/private/system/monitoring-1.nix index 1460478..20c12df 100644 --- a/modules/private/system/monitoring-1.nix +++ b/modules/private/system/monitoring-1.nix @@ -3,7 +3,6 @@ { boot.kernelPackages = pkgs.linuxPackages_latest; myEnv = import "${privateFiles}/environment.nix" // { inherit privateFiles; }; - hostEnv.FQDN = "monitoring-1.v.immae.eu"; imports = builtins.attrValues (import ../..); @@ -24,10 +23,10 @@ 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; diff --git a/modules/private/websites/tools/git/mantisbt.nix b/modules/private/websites/tools/git/mantisbt.nix index d0d7a98..8606819 100644 --- a/modules/private/websites/tools/git/mantisbt.nix +++ b/modules/private/websites/tools/git/mantisbt.nix @@ -31,7 +31,7 @@ rec { $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; diff --git a/modules/private/websites/tools/mail/mta-sts.nix b/modules/private/websites/tools/mail/mta-sts.nix index a401b41..ed3fce8 100644 --- a/modules/private/websites/tools/mail/mta-sts.nix +++ b/modules/private/websites/tools/mail/mta-sts.nix @@ -13,13 +13,15 @@ let ) 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" {} ''