diff --git a/data.nix b/data.nix index 4b95345..d6c55a7 100644 --- a/data.nix +++ b/data.nix @@ -9,6 +9,10 @@ password.file = ./secrets/machines/bicboye/password.age; root-password.file = ./secrets/machines/bicboye/root-password.age; }; + smolboye = { + password.file = ./secrets/machines/smolboye/password.age; + root-password.file = ./secrets/machines/smolboye/root-password.age; + }; }; monitoring = { grafana = { @@ -23,6 +27,9 @@ gitea = { password.file = ./secrets/services/gitea/password.age; }; + mailserver = { + watashi.password.file = ./secrets/services/mailserver/watashi.age; + }; miniflux = { password.file = ./secrets/services/miniflux/password.age; }; diff --git a/flake.lock b/flake.lock index 360a3a7..21a4a87 100644 --- a/flake.lock +++ b/flake.lock @@ -25,6 +25,22 @@ "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" + } + }, "cachix": { "locked": { "lastModified": 1635350005, @@ -243,6 +259,22 @@ } }, "flake-compat_4": { + "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-compat_5": { "flake": false, "locked": { "lastModified": 1650374568, @@ -677,6 +709,29 @@ "type": "github" } }, + "nixos-mailserver": { + "inputs": { + "blobs": "blobs", + "flake-compat": "flake-compat_4", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-24_05": "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" + } + }, "nixpkgs": { "locked": { "lastModified": 1727802920, @@ -693,6 +748,21 @@ "type": "github" } }, + "nixpkgs-24_05": { + "locked": { + "lastModified": 1717144377, + "narHash": "sha256-F/TKWETwB5RaR8owkPPi+SPJh83AQsm6KrQAlJ8v/uA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "805a384895c696f802a9bf5bf4720f37385df547", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-24.05", + "type": "indirect" + } + }, "nixpkgs-lib": { "locked": { "lastModified": 1727571693, @@ -794,6 +864,7 @@ "maych-in": "maych-in", "nil": "nil", "nixos-hardware": "nixos-hardware", + "nixos-mailserver": "nixos-mailserver", "nixpkgs": "nixpkgs_2", "nur": "nur", "snowfall-lib": "snowfall-lib", @@ -883,7 +954,7 @@ }, "snowfall-lib": { "inputs": { - "flake-compat": "flake-compat_4", + "flake-compat": "flake-compat_5", "flake-utils-plus": "flake-utils-plus", "nixpkgs": [ "nixpkgs" diff --git a/flake.nix b/flake.nix index d5b5705..029bb6b 100644 --- a/flake.nix +++ b/flake.nix @@ -22,7 +22,6 @@ chaotic.nixosModules.default disko.nixosModules.disko srvos.nixosModules.common - srvos.nixosModules.mixins-systemd-boot inputs.lanzaboote.nixosModules.lanzaboote ]; @@ -33,11 +32,19 @@ inherit userdata; }; # TODO: setup atticd - systems.hosts.bicboye.modules = [inputs.srvos.nixosModules.server]; + systems.hosts.bicboye.modules = [ + inputs.srvos.nixosModules.server + inputs.srvos.nixosModules.mixins-systemd-boot + ]; systems.hosts.bicboye.specialArgs = { inherit userdata; }; - systems.hosts.smolboye.modules = [inputs.srvos.nixosModules.server]; + systems.hosts.smolboye.modules = [ + inputs.nixos-hardware.nixosModules.common-cpu-intel + ]; + systems.hosts.smolboye.specialArgs = { + inherit userdata; + }; homes.modules = with inputs; [ nur.hmModules.nur @@ -103,6 +110,9 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixos-hardware.url = "github:nixos/nixos-hardware"; + nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver"; + nixos-mailserver.inputs.nixpkgs.follows = "nixpkgs"; + nur.url = "github:nix-community/nur"; snowfall-lib.url = "github:snowfallorg/lib"; diff --git a/homes/x86_64-linux/server@smolboye/default.nix b/homes/x86_64-linux/server@smolboye/default.nix new file mode 100644 index 0000000..31c8f5b --- /dev/null +++ b/homes/x86_64-linux/server@smolboye/default.nix @@ -0,0 +1,10 @@ +_: { + snowfallorg.user.enable = true; + snowfallorg.user.name = "server"; + + snowflake.development.helix.enable = true; + snowflake.development.tmux.enable = true; + snowflake.shell.fish.enable = true; + + home.stateVersion = "24.11"; +} diff --git a/modules/nixos/core/default.nix b/modules/nixos/core/default.nix index 6d00afa..e28f416 100644 --- a/modules/nixos/core/default.nix +++ b/modules/nixos/core/default.nix @@ -62,7 +62,6 @@ grub = { enable = config.snowflake.bootloader == "grub"; efiSupport = true; - efiInstallAsRemovable = true; forceInstall = true; }; }; diff --git a/modules/nixos/services/mailserver/default.nix b/modules/nixos/services/mailserver/default.nix new file mode 100644 index 0000000..31a6e88 --- /dev/null +++ b/modules/nixos/services/mailserver/default.nix @@ -0,0 +1,95 @@ +{ + config, + inputs, + lib, + ... +}: { + imports = [inputs.nixos-mailserver.nixosModules.mailserver]; + + options.snowflake.services.mailserver = { + enable = lib.mkEnableOption "Enable mailserver service"; + + fqdn = lib.mkOption { + type = lib.types.str; + description = "FQDN for the mailserver"; + }; + + domains = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + description = "Configuration domains to use for the mailserver"; + }; + + loginAccounts = lib.mkOption { + description = "Login accounts for the domain. Every account is mapped to a unix user"; + }; + }; + + config = let + cfg = config.snowflake.services.mailserver; + in + lib.mkIf cfg.enable { + # Ref: https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/issues/275 + services.dovecot2.sieve.extensions = ["fileinto"]; + + mailserver = { + inherit (cfg) enable fqdn domains loginAccounts; + + # Spin up a stripped-down nginx instance on + # port 80 to generate a certificate automatically. + certificateScheme = "acme-nginx"; + + # Enable a better way of storing emails. + useFsLayout = true; + + mailboxes = { + Archive = { + auto = "subscribe"; + specialUse = "Archive"; + }; + Drafts = { + auto = "subscribe"; + specialUse = "Drafts"; + }; + Sent = { + auto = "subscribe"; + specialUse = "Sent"; + }; + Junk = { + auto = "subscribe"; + specialUse = "Junk"; + }; + Trash = { + auto = "subscribe"; + specialUse = "Trash"; + }; + }; + }; + + # Prefer using ipv4 and use correct ipv6 address + # to avoid rDNS issues + # NOTE: this needs to be changed on every new system. + # TODO: figure out how to handle this case better. + services.postfix.extraConfig = '' + smtp_bind_address6 = 2a01:4f8:1c1c:90b:: + smtp_address_preference = ipv4 + ''; + + services.fail2ban.jails = { + postfix = { + settings = { + enabled = true; + mode = "extra"; + }; + }; + + dovecot = { + settings = { + enabled = true; + filter = "dovecot[mode=aggressive]"; + maxretry = 3; + }; + }; + }; + }; +} diff --git a/secrets/machines/smolboye/password.age b/secrets/machines/smolboye/password.age new file mode 100644 index 0000000..bc89ec3 Binary files /dev/null and b/secrets/machines/smolboye/password.age differ diff --git a/secrets/machines/smolboye/root-password.age b/secrets/machines/smolboye/root-password.age new file mode 100644 index 0000000..2dcc28c --- /dev/null +++ b/secrets/machines/smolboye/root-password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA BeG8hdmEGOcfCJGjZ8ps03XDV4DNPqMfXuFGIXitSVM +5lTE5CORKB107B8509PPiLCeYlwP1x80Jyh2CxI0BTg +-> ssh-ed25519 H9OGOA gqAqKcTLuE7gJ5lWvTUs/mnmTv4CyN9GWj6ce9YmSz0 +AVKH1l8QEuBlCJS7dZ8cFxbeWF6qjjZWn9fg3uOF9WU +--- U0k1MgVffkdgn+pStscCnCNOFgtlCW8URf5wesIjO5w + YzSfONP,N7~ b=K i~BkO=}}ANYmwS>uh\?Z%& X7a'H.+؏6%{LZ&T A. \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 4a4d7c4..ccd7c88 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -24,12 +24,15 @@ in { "machines/thonkpad/root-password.age".publicKeys = thunderbottom ++ thonkpad; "machines/bicboye/password.age".publicKeys = thunderbottom ++ bicboye; "machines/bicboye/root-password.age".publicKeys = thunderbottom ++ bicboye; + "machines/smolboye/password.age".publicKeys = thunderbottom ++ smolboye; + "machines/smolboye/root-password.age".publicKeys = thunderbottom ++ smolboye; "monitoring/grafana/password.age".publicKeys = thunderbottom ++ bicboye; - "services/backup/environment.age".publicKeys = thunderbottom ++ bicboye; - "services/backup/password.age".publicKeys = thunderbottom ++ bicboye; + "services/backups/environment.age".publicKeys = thunderbottom ++ bicboye; + "services/backups/password.age".publicKeys = thunderbottom ++ bicboye; "services/gitea/password.age".publicKeys = thunderbottom ++ bicboye; "services/maddy/password.age".publicKeys = thunderbottom ++ bicboye; "services/maddy/user-watashi.age".publicKeys = thunderbottom ++ servers; + "services/mailserver/watashi.age".publicKeys = thunderbottom ++ smolboye; "services/miniflux/password.age".publicKeys = thunderbottom ++ bicboye; "services/paperless/password.age".publicKeys = users ++ bicboye; "services/unifi-unpoller/password.age".publicKeys = users ++ bicboye; diff --git a/secrets/services/mailserver/watashi.age b/secrets/services/mailserver/watashi.age new file mode 100644 index 0000000..6705886 --- /dev/null +++ b/secrets/services/mailserver/watashi.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA 0tV+WcLas2COUWsw7WgtEzLSOrvDCSZH7af0Jk02PEI +JkrU4+JSaGqnaw5NEbQkeaPYT6xzyoIRukCaVtvBmMc +-> ssh-ed25519 H9OGOA JbMosLyeQ0LEL74KaKBWX7k+exHD3jmgLCLEW4X39i0 +tTPEU/0rhAwsSIrzEDPl3x164Qo3tiPazQ5GXPLjCg0 +--- J0fW7mm0Utkns/cbI5fGHW+EiMHaFaCoMcyU71woXqA +[kKSzdX#ځϮԃ49npY'Kp [J3k7Q$(<߷c5pní>H0Ot xybK/ P \ No newline at end of file diff --git a/systems/x86_64-linux/smolboye/default.nix b/systems/x86_64-linux/smolboye/default.nix new file mode 100644 index 0000000..71fb067 --- /dev/null +++ b/systems/x86_64-linux/smolboye/default.nix @@ -0,0 +1,92 @@ +{ + config, + lib, + userdata, + ... +}: { + imports = [./disk-config.nix]; + + hardware.cpu.intel.updateMicrocode = true; + hardware.enableRedistributableFirmware = true; + + networking = { + hostName = "smolboye"; + nameservers = ["1.1.1.1"]; + useDHCP = lib.mkDefault false; + interfaces.enp1s0 = { + useDHCP = lib.mkDefault true; + ipv6.addresses = [ + { + address = "2a01:4f8:1c1c:90b::"; + prefixLength = 64; + } + ]; + }; + defaultGateway6 = { + address = "fe80::1"; + interface = "enp1s0"; + }; + firewall.allowedTCPPorts = [80 443]; + }; + + boot = { + initrd.availableKernelModules = ["xhci_pci" "ahci" "ehci_pci" "nvme" "usb_storage" "sd_mod"]; + kernelModules = ["kvm-amd" "virtio_gpu"]; + kernelParams = ["console=tty"]; + loader.grub.device = "/dev/sda"; + supportedFilesystems = ["btrfs"]; + }; + + # Enable weekly btrfs auto-scrub. + services.btrfs.autoScrub = { + enable = true; + interval = "weekly"; + fileSystems = ["/"]; + }; + + security.acme.defaults.email = "chinmaydpai@gmail.com"; + + age.secrets = { + mailserver-watashi.file = userdata.secrets.services.mailserver.watashi.password.file; + }; + + snowflake = { + stateVersion = "24.11"; + bootloader = "grub"; + + core.security.sysctl.enable = lib.mkForce false; + + networking.firewall.enable = true; + networking.networkManager.enable = true; + networking.resolved.enable = true; + + services = { + mailserver = { + enable = true; + fqdn = "mail.deku.moe"; + domains = ["deku.moe"]; + loginAccounts = { + "watashi@deku.moe" = { + hashedPasswordFile = config.age.secrets.mailserver-watashi.path; + aliases = ["@deku.moe"]; + catchAll = ["deku.moe"]; + }; + }; + }; + }; + + user = { + enable = true; + username = "server"; + description = "Smolboye Server"; + userPasswordAgeModule = userdata.secrets.machines.smolboye.password; + rootPasswordAgeModule = userdata.secrets.machines.smolboye.root-password; + extraAuthorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG3PeMbehJBkmv8Ee7xJimTzXoSdmAnxhBatHSdS+saM" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOyY8ZkhwWiqJCiTqXvHnLpXQb1qWwSZAoqoSWJI1ogP" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJQWA+bAwpm9ca5IhC6q2BsxeQH4WAiKyaht48b7/xkN" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKJnFvU6nBXEuZF08zRLFfPpxYjV3o0UayX0zTPbDb7C" + ]; + }; + }; +} diff --git a/systems/x86_64-linux/smolboye/disk-config.nix b/systems/x86_64-linux/smolboye/disk-config.nix new file mode 100644 index 0000000..e66a77d --- /dev/null +++ b/systems/x86_64-linux/smolboye/disk-config.nix @@ -0,0 +1,57 @@ +{ + disko.devices = { + disk = { + sda = { + type = "disk"; + device = "/dev/sda"; + content = { + type = "gpt"; + partitions = { + boot = { + priority = 1; + name = "ESP"; + start = "1M"; + end = "128M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + size = "100%"; + content = { + type = "btrfs"; + extraArgs = ["-f"]; + subvolumes = { + "/root" = { + mountpoint = "/"; + mountOptions = ["compress=zstd" "noatime"]; + }; + "/home" = { + mountpoint = "/home"; + mountOptions = ["compress=zstd" "noatime"]; + }; + "/nix" = { + mountpoint = "/nix"; + mountOptions = ["compress=zstd" "noatime"]; + }; + "/swap" = { + mountpoint = "/.swapvol"; + mountOptions = ["nodatacow" "noatime"]; + swap.swapfile.size = "20M"; + }; + "/log" = { + mountpoint = "/var/log"; + mountOptions = ["compress=zstd" "noatime"]; + }; + }; + }; + }; + }; + }; + }; + }; + }; +}