Compare commits

...

2 commits

Author SHA1 Message Date
Janik Haag 991578a87b
wip: feat(mail): init host and module 2024-09-25 01:01:34 +02:00
Maxine Aubrey 8d95d1f850
fix(dns): dnsimple expects FQDNs in CNAMEs
DNSimple doesn't appear to follow the typical behaviour of appending the
domain unless the CNAME is terminated with `.`

To avoid further problems, let's just explicilty use the FQDN for all
CNAMEs.

https://support.dnsimple.com/articles/cname-record/

For comparison:
```
;; ANSWER SECTION:
alerts.forkos.org.	300	IN	CNAME	meta01.infra.p.
```

```
;; ANSWER SECTION:
alerts.forkos.org.	181	IN	CNAME	meta01.infra.p.forkos.org.
meta01.infra.p.forkos.org. 181	IN	A	163.172.69.160
```
2024-09-24 23:11:28 +02:00
6 changed files with 176 additions and 18 deletions

View file

@ -78,6 +78,22 @@
"type": "github" "type": "github"
} }
}, },
"blobs": {
"flake": false,
"locked": {
"lastModified": 1604995301,
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"type": "gitlab"
}
},
"buildbot-nix": { "buildbot-nix": {
"inputs": { "inputs": {
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
@ -298,6 +314,22 @@
"type": "github" "type": "github"
} }
}, },
"flake-compat_5": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": { "flake-parts": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
@ -715,6 +747,7 @@
], ],
"nix-gerrit": "nix-gerrit", "nix-gerrit": "nix-gerrit",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_2",
"simple-nixos-mailserver": "simple-nixos-mailserver",
"terranix": "terranix" "terranix": "terranix"
} }
}, },
@ -747,6 +780,29 @@
"url": "https://static.rust-lang.org/dist/channel-rust-1.78.0.toml" "url": "https://static.rust-lang.org/dist/channel-rust-1.78.0.toml"
} }
}, },
"simple-nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"flake-compat": "flake-compat_5",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-24_05": []
},
"locked": {
"lastModified": 1722877200,
"narHash": "sha256-qgKDNJXs+od+1UbRy62uk7dYal3h98I4WojfIqMoGcg=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "af7d3bf5daeba3fc28089b015c0dd43f06b176f2",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"stable": { "stable": {
"locked": { "locked": {
"lastModified": 1696039360, "lastModified": 1696039360,

View file

@ -37,6 +37,11 @@
repo = "grapevine-fork"; repo = "grapevine-fork";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
simple-nixos-mailserver.inputs.nixpkgs.follows = "nixpkgs";
simple-nixos-mailserver.inputs.nixpkgs-24_05.follows = "";
}; };
outputs = { self, nixpkgs, terranix, colmena, ... } @ inputs: outputs = { self, nixpkgs, terranix, colmena, ... } @ inputs:
@ -131,6 +136,7 @@
buildbot.imports = commonModules ++ [ ./hosts/buildbot ]; buildbot.imports = commonModules ++ [ ./hosts/buildbot ];
public01.imports = commonModules ++ [ ./hosts/public01 ]; public01.imports = commonModules ++ [ ./hosts/public01 ];
build-coord.imports = commonModules ++ [ ./hosts/build-coord ]; build-coord.imports = commonModules ++ [ ./hosts/build-coord ];
mail.imports = commonModules ++ [ ./hosts/mail ];
} // builders; } // builders;
hydraJobs = builtins.mapAttrs (n: v: v.config.system.build.netbootDir or v.config.system.build.toplevel) self.nixosConfigurations; hydraJobs = builtins.mapAttrs (n: v: v.config.system.build.netbootDir or v.config.system.build.toplevel) self.nixosConfigurations;

51
hosts/mail/default.nix Normal file
View file

@ -0,0 +1,51 @@
{ lib, modulesPath, ... }: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
deployment.targetHost = "mail.infra.forkos.org";
bagel.services.mail.enable = true;
bagel.sysadmin.enable = true;
networking = {
hostName = "mail";
domain = "infra.forkos.org";
dhcpcd.enable = false;
useNetworkd = true;
nameservers = [
# hetzner
"2a01:4ff:ff00::add:2"
"2a01:4ff:ff00::add:1"
];
};
systemd.network = {
networks = {
"10-wan" = {
matchConfig.Name = "enp1s0";
address = [
"49.13.86.172/32"
"2a01:4f8:1c17:6866::1/64"
"fe80::9400:3ff:feba:39b9/64"
];
routes = [
{ Gateway = "fe80::1"; }
{ Destination = "172.31.1.1"; }
{
Gateway = "172.31.1.1";
GatewayOnLink = true;
}
];
linkConfig.RequiredForOnline = "routable";
};
};
};
boot.loader.grub.device = "/dev/sda";
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
boot.initrd.kernelModules = [ "nvme" ];
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
system.stateVersion = "23.11";
}

View file

@ -13,5 +13,6 @@
./buildbot ./buildbot
./newsletter ./newsletter
./s3-revproxy ./s3-revproxy
./mail
]; ];
} }

36
services/mail/default.nix Normal file
View file

@ -0,0 +1,36 @@
{ config, lib, inputs, ... }: let
cfg = config.bagel.services.mail;
inherit (lib) mkEnableOption mkIf;
in {
imports = [
inputs.simple-nixos-mailserver.nixosModule
];
options.bagel.services.mail = {
enable = mkEnableOption "E-Mail";
};
config = mkIf cfg.enable {
mailserver = {
enable = true;
fqdn = "mail.infra.forkos.org";
domains = [
"vzfdfp.de"
];
forwards = let
infraMembers = [
"forkos.janik@aq0.de"
];
boardMembers = [
"forkos-board@lahfa.xyz"
"vzfdfp.janik@aq0.de"
];
in {
"abuse@vzfdfp.de" = infraMembers;
"postmaster@vzfdfp.de" = infraMembers;
"board@vzfdfp.de" = boardMembers;
"vorstand@vzfdfp.de" = boardMembers;
};
certificateScheme = "acme-nginx";
};
};
}

View file

@ -96,32 +96,37 @@ in
(dualProxyRecords "buildbot.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::50") (dualProxyRecords "buildbot.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::50")
(dualProxyRecords "public01.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::60") (dualProxyRecords "public01.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::60")
(record "cl" 300 "CNAME" "gerrit01.infra.p") (record "cl" 300 "CNAME" "gerrit01.infra.p.forkos.org")
(record "fodwatch" 300 "CNAME" "fodwatch.infra.p") (record "fodwatch" 300 "CNAME" "fodwatch.infra.p.forkos.org")
# git.p.forkos.org is the proxy variant of the Forgejo server. # git.p.forkos.org is the proxy variant of the Forgejo server.
(record "git" 300 "CNAME" "git.p") (record "git" 300 "CNAME" "git.p.forkos.org")
(record "netbox" 300 "CNAME" "meta01.infra.p") (record "netbox" 300 "CNAME" "meta01.infra.p.forkos.org")
(record "amqp" 300 "CNAME" "bagel-box.infra.p") (record "amqp" 300 "CNAME" "bagel-box.infra.p.forkos.org")
(record "grafana" 300 "CNAME" "meta01.infra.p") (record "grafana" 300 "CNAME" "meta01.infra.p.forkos.org")
(record "hydra" 300 "CNAME" "build-coord.wob01.infra.p") (record "hydra" 300 "CNAME" "build-coord.wob01.infra.p.forkos.org")
(record "loki" 300 "CNAME" "meta01.infra.p") (record "loki" 300 "CNAME" "meta01.infra.p.forkos.org")
(record "mimir" 300 "CNAME" "meta01.infra.p") (record "mimir" 300 "CNAME" "meta01.infra.p.forkos.org")
(record "pyroscope" 300 "CNAME" "meta01.infra.p") (record "pyroscope" 300 "CNAME" "meta01.infra.p.forkos.org")
(record "tempo" 300 "CNAME" "meta01.infra.p") (record "tempo" 300 "CNAME" "meta01.infra.p.forkos.org")
(record "matrix" 300 "CNAME" "meta01.infra.p") (record "matrix" 300 "CNAME" "meta01.infra.p.forkos.org")
(record "alerts" 300 "CNAME" "meta01.infra.p") (record "alerts" 300 "CNAME" "meta01.infra.p.forkos.org")
(record "buildbot" 300 "CNAME" "buildbot.infra.p") (record "buildbot" 300 "CNAME" "buildbot.infra.p.forkos.org")
(record "b" 300 "CNAME" "public01.infra.p") (record "b" 300 "CNAME" "public01.infra.p.forkos.org")
(record "postgres" 300 "CNAME" "bagel-box.infra.p") (record "postgres" 300 "CNAME" "bagel-box.infra.p.forkos.org")
(record "news" 3600 "CNAME" "public01.infra.p") (record "news" 3600 "CNAME" "public01.infra.p.forkos.org")
# S3 in delroth's basement # S3 in delroth's basement
(record "cache" 300 "AAAA" "2a02:168:6426::12") # smol.delroth.net (record "cache" 300 "AAAA" "2a02:168:6426::12") # smol.delroth.net
(record "cache" 300 "A" "195.39.247.161") # sni proxy (record "cache" 300 "A" "195.39.247.161") # sni proxy
# misc
(record "vpn-gw.wob01.infra" 300 "AAAA" "2a01:584:11::2") (record "vpn-gw.wob01.infra" 300 "AAAA" "2a01:584:11::2")
(dualProxyRecords "build-coord.wob01.infra" 300 "AAAA" "2a01:584:11::1:11") (dualProxyRecords "build-coord.wob01.infra" 300 "AAAA" "2a01:584:11::1:11")
(record "mail.infra" 300 "A" "49.13.86.172")
(record "mail.infra" 300 "AAAA" "2a01:4f8:1c17:6866::1")
# TODO: do not hardcode, just reuse the Colmena hive module outputs to generate all the required details. # TODO: do not hardcode, just reuse the Colmena hive module outputs to generate all the required details.
] ]
++ (map (index: record "builder-${toString index}.wob01.infra" 300 "AAAA" "2a01:584:11::1:${toString index}") (genList lib.id 11)) ++ (map (index: record "builder-${toString index}.wob01.infra" 300 "AAAA" "2a01:584:11::1:${toString index}") (genList lib.id 11))
@ -135,12 +140,15 @@ in
"channel-scripts-test" "channel-scripts-test"
]; ];
in in
map (bucket: record "${bucket}" 300 "CNAME" "public01.infra.p") buckets map (bucket: record "${bucket}" 300 "CNAME" "public01.infra.p.forkos.org") buckets
)); ));
"flowery.systems" = [ "flowery.systems" = [
(record "" 300 "ALIAS" "news.forkos.org") (record "" 300 "ALIAS" "news.forkos.org")
]; ];
"vzfdfp.de" = [ "vzfdfp.de" = [
((record "" 300 "MX" "mail.infra.forkos.org") // { priority = 10; })
(record "_dmarc" 300 "TXT" "v=DMARC1; p=none") # TODO: Setup dmarc and dmarc exporer/monitoring
(record "mail._domainkey" 3600 "TXT" "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8Xy2Rytpa3X/9Or3gKqH0LTn/TD3BoLf77HtUu+GsAsZit+yIVz+zTt3NoNoYsygl2Qc27zAeJhcK3w7dbKVbuWlVBqBzrLP/QK1NqR499RUAwQfyQHZkI+BCTYEY5UkWrFAwZ7LeHgtqDNtbyeCdS7MTST0DhogtIqSJKpP0/QIDAQAB")
]; ];
}; };
}; };