diff options
| author | Alejandro Soto <alejandro@34project.org> | 2024-07-14 17:53:13 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2024-07-15 09:34:00 -0600 |
| commit | 02abf4ed0131237c25e0a10db50fa4c41a902a50 (patch) | |
| tree | 20904894fc0952806e341cdaff5941e81b3ce51c /sys/nspawn/dmz.nix | |
| parent | 08e746700341dda3e3bdf704332fc3c07053d3e7 (diff) | |
sys: final merge of dmz, hv into sys
Diffstat (limited to 'sys/nspawn/dmz.nix')
| -rw-r--r-- | sys/nspawn/dmz.nix | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/sys/nspawn/dmz.nix b/sys/nspawn/dmz.nix new file mode 100644 index 0000000..080b32d --- /dev/null +++ b/sys/nspawn/dmz.nix @@ -0,0 +1,160 @@ +{ lib, config, flakes, pkgs, ... }: +with lib; let + cfg = config.local.nspawn.dmz; + inherit (config.local) mailHost; +in +{ + options.local.nspawn.dmz = with types; { + enable = mkEnableOption "DMZ services in a container"; + + net = mkOption { + type = str; + }; + + netBits = mkOption { + type = int; + }; + + hostAddr = mkOption { + type = str; + }; + + system = mkOption { + type = attrs; + }; + }; + + # Situación con os-release + # + # La idea aquí es poder hacer 'btrfs subvol create /var/lib/machines/foo' y + # dejar que systemd-nspawn y el activation script creen todo lo demás. Esto + # no sirve bien debido a la prueba barata que hace systemd para revisar si el + # árbol parece contener una imagen de sistema operativo. Esta prueba falla en + # dos momentos distintos: + # + # 1. Inmediatamente tras crear un árbol vacío, puesto que os-release no existe. + # La solución naive es 'mkdir rootfs/etc && touch rootfs/etc/os-release'. + # + # 2. Luego de reiniciar el contenedor una vez que NixOS ha preparado /etc, ya que + # systemd espera un archivo regular y no telera el symlink a la store. + # + # Resulta ser que systemd revisa tanto /etc/os-release como /usr/lib/os-release. + # NixOS evidentemente no usa la segunda ruta por ser FHS, así que la duct tape + # final es 'mkdir rootfs/usr/lib && touch rootfs/usr/lib/os-release'. + + config = mkIf cfg.enable { + local = { + mailHost = { + mdaListen = cfg.hostAddr; + saslPort = 11000; + lmtpPort = 11001; + }; + + nspawn.dmz = { + system = + let + containerModule = { ... }: { + #TODO: urgente: bloquear puertos de dovecot a non-postfix con iptables + config = { + local = { + preset.dmz = { + enable = true; + container = true; + }; + + mta = { + mdaAddr = mailHost.mdaListen; + inherit (mailHost) saslPort lmtpPort; + }; + }; + + nixpkgs = { + pkgs = mkDefault pkgs; + localSystem = mkDefault pkgs.stdenv.hostPlatform; + }; + }; + }; + in + # Tomado de la definición de pkgs.nixos junto con definición de nixpkgs.{pkgs,localSystem} arriba + import "${flakes.nixpkgs}/nixos/lib/eval-config.nix" { + modules = [ + ../. + containerModule + ]; + + system = null; + specialArgs = { inherit flakes; }; + }; + + net = "10.34.3.0"; + netBits = 28; + hostAddr = "10.34.3.1"; + }; + }; + + systemd = { + nspawn.dmz = { + execConfig.PrivateUsers = "pick"; + + filesConfig.BindReadOnly = [ + # idmap porque algunos hacks en nixpkgs (postfix-setup.service) + # asumen que la store es de root + "/nix/store:/nix/store:idmap" + "${cfg.system.config.system.build.toplevel}/init:/sbin/init" + ]; + + networkConfig.Port = [ + "tcp:25" + "tcp:80" + "tcp:443" + "tcp:465" + "tcp:587" + ]; + }; + + network.networks."40-ve-dmz" = { + matchConfig = { + Name = "ve-dmz"; + Driver = "veth"; + }; + + networkConfig = { + Address = "${cfg.hostAddr}/${toString cfg.netBits}"; + LinkLocalAddressing = "yes"; + DHCPServer = "yes"; + IPMasquerade = "both"; + LLDP = "yes"; + EmitLLDP = "customer-bridge"; + IPv6SendRA = "yes"; + }; + + # IP de contenedor fijada en hostAddr + 1 + dhcpServerConfig = { + PoolOffset = 2; + PoolSize = 1; + }; + }; + + services = { + dovecot2.after = [ "systemd-nspawn@dmz.service" ]; + + "systemd-nspawn@dmz" = { + overrideStrategy = "asDropin"; + + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "machines.target" ]; + }; + }; + }; + + networking.firewall = { + allowedTCPPorts = [ 25 80 443 ]; + + interfaces.ve-dmz = { + allowedTCPPorts = [ mailHost.saslPort mailHost.lmtpPort ]; + allowedUDPPorts = [ 67 ]; # DHCP + }; + }; + }; +} |
