This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

Replace Alejandra with official Nix formatter

author
Łukasz Niemier
date (May 13, 2026, 5:12 PM +0200) commit 25a08ca1 parent 367576f5 change-id unprkqrn
+558 -425
+133 -112
flake.nix
··· 52 52 ]; 53 53 }; 54 54 55 - outputs = { 56 - self, 57 - nixpkgs, 58 - deploy, 59 - ... 60 - } @ inputs: 61 - inputs.flake-parts.lib.mkFlake {inherit inputs;} { 62 - flake = let 63 - inherit (nixpkgs.lib) const nixosSystem; 64 - inherit (builtins) readDir mapAttrs; 65 - inherit (nixpkgs.lib.attrsets) mapAttrs'; 66 - inherit (nixpkgs.lib.strings) removeSuffix; 55 + outputs = 56 + { 57 + self, 58 + nixpkgs, 59 + deploy, 60 + ... 61 + }@inputs: 62 + inputs.flake-parts.lib.mkFlake { inherit inputs; } { 63 + flake = 64 + let 65 + inherit (nixpkgs.lib) const nixosSystem; 66 + inherit (builtins) readDir mapAttrs; 67 + inherit (nixpkgs.lib.attrsets) mapAttrs'; 68 + inherit (nixpkgs.lib.strings) removeSuffix; 67 69 68 - # Automatically load servers configuration using directories in `server/` 69 - servers = 70 - mapAttrs (path: _: import ./servers/${path}) (readDir ./servers); 70 + # Automatically load servers configuration using directories in `server/` 71 + servers = mapAttrs (path: _: import ./servers/${path}) (readDir ./servers); 71 72 72 - # Load all secrets as flake attributes 73 - secrets = {...}: { 74 - age.secrets = let 75 - secrets = mapAttrs' (path: _: { 76 - name = removeSuffix ".age" path; 77 - value = ./secrets/${path}; 78 - }) (readDir ./secrets); 79 - toFile = file: {inherit file;}; 80 - in 81 - mapAttrs (const toFile) secrets; 82 - }; 73 + # Load all secrets as flake attributes 74 + secrets = 75 + { ... }: 76 + { 77 + age.secrets = 78 + let 79 + secrets = mapAttrs' (path: _: { 80 + name = removeSuffix ".age" path; 81 + value = ./secrets/${path}; 82 + }) (readDir ./secrets); 83 + toFile = file: { inherit file; }; 84 + in 85 + mapAttrs (const toFile) secrets; 86 + }; 83 87 84 - # Load all NixOS modules as flake attributes 85 - nixosModules = mapAttrs' (path: _: { 86 - name = removeSuffix ".nix" path; 87 - value = import ./modules/${path}; 88 - }) (readDir ./modules); 88 + # Load all NixOS modules as flake attributes 89 + nixosModules = mapAttrs' (path: _: { 90 + name = removeSuffix ".nix" path; 91 + value = import ./modules/${path}; 92 + }) (readDir ./modules); 89 93 90 - system = "x86_64-linux"; 94 + system = "x86_64-linux"; 91 95 92 - sshKeys = import ./keys.nix; 96 + sshKeys = import ./keys.nix; 93 97 94 - mkSystem = config: 95 - nixosSystem { 96 - inherit system; 97 - modules = [ 98 - inputs.agenix.nixosModules.default 99 - inputs.tangled.nixosModules.knot 100 - secrets 101 - nixosModules.common 102 - config 103 - ]; 104 - specialArgs = { 105 - inherit inputs sshKeys secrets; 98 + mkSystem = 99 + config: 100 + nixosSystem { 101 + inherit system; 102 + modules = [ 103 + inputs.agenix.nixosModules.default 104 + inputs.tangled.nixosModules.knot 105 + secrets 106 + nixosModules.common 107 + config 108 + ]; 109 + specialArgs = { 110 + inherit inputs sshKeys secrets; 111 + }; 106 112 }; 107 - }; 108 113 109 - nodeConfig = import ./nodes.nix; 114 + nodeConfig = import ./nodes.nix; 110 115 111 - tryAttr = attrSet: key: default: 112 - if attrSet ? ${key} 113 - then attrSet.${key} 114 - else default; 115 - in { 116 - nixosConfigurations = mapAttrs (const mkSystem) servers; 116 + tryAttr = 117 + attrSet: key: default: 118 + if attrSet ? ${key} then attrSet.${key} else default; 119 + in 120 + { 121 + nixosConfigurations = mapAttrs (const mkSystem) servers; 117 122 118 - inherit nixosModules sshKeys; 123 + inherit nixosModules sshKeys; 119 124 120 - lib = {inherit tryAttr;}; 125 + lib = { inherit tryAttr; }; 121 126 122 - # Deployments definition 123 - deploy = { 124 - magicRollback = true; 125 - autoRollback = true; 127 + # Deployments definition 128 + deploy = { 129 + magicRollback = true; 130 + autoRollback = true; 126 131 127 - # Build on remote node, as building Linux on macOS is problematic 128 - remoteBuild = true; 132 + # Build on remote node, as building Linux on macOS is problematic 133 + remoteBuild = true; 129 134 130 - sshOpts = ["-p" "2222"]; 135 + sshOpts = [ 136 + "-p" 137 + "2222" 138 + ]; 131 139 132 - nodes = 133 - mapAttrs 134 - (name: nixosConfig: 140 + nodes = mapAttrs ( 141 + name: nixosConfig: 135 142 { 136 143 sshUser = "hauleth"; 137 144 user = "root"; ··· 146 153 path = deploy.lib.${nixosConfig.pkgs.stdenv.hostPlatform.system}.activate.nixos nixosConfig; 147 154 }; 148 155 } 149 - // (tryAttr nodeConfig name {})) 150 - self.nixosConfigurations; 156 + // (tryAttr nodeConfig name { }) 157 + ) self.nixosConfigurations; 158 + }; 159 + 160 + # TODO: Check why this fails 161 + # checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy.lib; 151 162 }; 152 163 153 - # TODO: Check why this fails 154 - # checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy.lib; 155 - }; 164 + systems = [ 165 + "x86_64-linux" 166 + "x86_64-darwin" 167 + "aarch64-darwin" 168 + ]; 156 169 157 - systems = ["x86_64-linux" "x86_64-darwin" "aarch64-darwin"]; 158 - 159 - perSystem = { 160 - self', 161 - inputs', 162 - pkgs, 163 - ... 164 - }: { 165 - formatter = pkgs.alejandra; 170 + perSystem = 171 + { 172 + self', 173 + inputs', 174 + pkgs, 175 + ... 176 + }: 177 + { 178 + formatter = pkgs.nixfmt-tree; 166 179 167 - # Default application will deploy all nodes 168 - apps.default = self'.apps.deploy; 180 + # Default application will deploy all nodes 181 + apps.default = self'.apps.deploy; 169 182 170 - # Deployment of all servers 171 - apps.deploy = inputs'.deploy.apps.default; 183 + # Deployment of all servers 184 + apps.deploy = inputs'.deploy.apps.default; 172 185 173 - # Terraform management 174 - apps.tf = let 175 - providers = inputs'.terraform-providers-bin.legacyPackages.providers; 176 - terraform = pkgs.opentofu.withPlugins (plugins: [ 177 - providers.Backblaze.b2 178 - providers.hashicorp.dns 179 - providers.hetznercloud.hcloud 180 - providers.ovh.ovh 181 - providers.tailscale.tailscale 182 - ]); 183 - in { 184 - type = "app"; 185 - # Make it use Terranix 186 - # Use _1password from Nixpkgs instead of one from environment 187 - program = toString (pkgs.writeShellScript "op-tf" '' 188 - exec op run --env-file ${./tf.env} -- ${pkgs.lib.getExe terraform} -chdir=./infra "$@" 189 - ''); 190 - }; 186 + # Terraform management 187 + apps.tf = 188 + let 189 + providers = inputs'.terraform-providers-bin.legacyPackages.providers; 190 + terraform = pkgs.opentofu.withPlugins (plugins: [ 191 + providers.Backblaze.b2 192 + providers.hashicorp.dns 193 + providers.hetznercloud.hcloud 194 + providers.ovh.ovh 195 + providers.tailscale.tailscale 196 + ]); 197 + in 198 + { 199 + type = "app"; 200 + # Make it use Terranix 201 + # Use _1password from Nixpkgs instead of one from environment 202 + program = toString ( 203 + pkgs.writeShellScript "op-tf" '' 204 + exec op run --env-file ${./tf.env} -- ${pkgs.lib.getExe terraform} -chdir=./infra "$@" 205 + '' 206 + ); 207 + }; 191 208 192 - # Secrets management 193 - packages.agenix = inputs'.agenix.packages.default; 209 + # Secrets management 210 + packages.agenix = inputs'.agenix.packages.default; 194 211 195 - # SSH keys 196 - apps.fuk = let 197 - fuk = inputs'.fuk.packages.default; 198 - in { 199 - type = "app"; 200 - program = toString (pkgs.writeShellScript "fuk-keys" '' 201 - exec ${pkgs.lib.getExe fuk} ${./keys.toml} 202 - ''); 212 + # SSH keys 213 + apps.fuk = 214 + let 215 + fuk = inputs'.fuk.packages.default; 216 + in 217 + { 218 + type = "app"; 219 + program = toString ( 220 + pkgs.writeShellScript "fuk-keys" '' 221 + exec ${pkgs.lib.getExe fuk} ${./keys.toml} 222 + '' 223 + ); 224 + }; 203 225 }; 204 - }; 205 226 }; 206 227 }
+2 -1
modules/backup.nix
··· 1 - {config, ...}: { 1 + { config, ... }: 2 + { 2 3 services.borgbackup.jobs."local" = { 3 4 paths = [ 4 5 "/home/git/"
+6 -4
modules/beszel-agent.nix
··· 5 5 secrets, 6 6 inputs, 7 7 ... 8 - }: let 8 + }: 9 + let 9 10 hostName = "${config.networking.hostName}.${config.networking.domain}"; 10 11 unstable = inputs.nixpkgs-unstable.legacyPackages.${pkgs.stdenv.hostPlatform.system}; 11 - in { 12 + in 13 + { 12 14 users.users.beszel-agent = { 13 15 isSystemUser = true; 14 16 group = "beszel-agent"; 15 17 }; 16 18 17 - users.groups.beszel-agent = {}; 19 + users.groups.beszel-agent = { }; 18 20 19 21 services.beszel.agent = { 20 22 enable = true; ··· 39 41 40 42 systemd.services.beszel-agent = { 41 43 serviceConfig = { 42 - SupplementaryGroups = ["messagebus"]; 44 + SupplementaryGroups = [ "messagebus" ]; 43 45 DynamicUser = lib.mkForce false; 44 46 User = "beszel-agent"; 45 47 Group = "beszel-agent";
+5 -3
modules/beszel-hub.nix
··· 5 5 secrets, 6 6 inputs, 7 7 ... 8 - }: let 8 + }: 9 + let 9 10 hostName = "${config.networking.hostName}.${config.networking.domain}"; 10 11 unstable = inputs.nixpkgs-unstable.legacyPackages.${pkgs.stdenv.hostPlatform.system}; 11 - in { 12 - logs.services = ["beszel"]; 12 + in 13 + { 14 + logs.services = [ "beszel" ]; 13 15 14 16 services.beszel.hub = { 15 17 enable = true;
+17 -15
modules/bridge.nix
··· 3 3 pkgs, 4 4 secrets, 5 5 ... 6 - }: { 6 + }: 7 + { 7 8 services.matterbridge = { 8 9 enable = false; 9 10 10 - configPath = let 11 - config = 12 - pkgs.writeTextFile 13 - { 11 + configPath = 12 + let 13 + config = pkgs.writeTextFile { 14 14 name = "matterbridge.conf.toml"; 15 15 text = '' 16 16 [discord.4p] ··· 38 38 channel = "ogólne" 39 39 ''; 40 40 }; 41 - in 41 + in 42 42 toString config; 43 43 }; 44 44 45 - systemd.services.matterbridge = let 46 - envFile = config.age.secrets."matterbridge.conf"; 47 - in { 48 - enable = config.services.matterbridge.enable; 49 - serviceConfig.EnvironmentFile = envFile.path; 45 + systemd.services.matterbridge = 46 + let 47 + envFile = config.age.secrets."matterbridge.conf"; 48 + in 49 + { 50 + enable = config.services.matterbridge.enable; 51 + serviceConfig.EnvironmentFile = envFile.path; 50 52 51 - restartTriggers = [ 52 - (builtins.hashFile "sha256" envFile.file) 53 - ]; 54 - }; 53 + restartTriggers = [ 54 + (builtins.hashFile "sha256" envFile.file) 55 + ]; 56 + }; 55 57 }
+25 -10
modules/common/default.nix
··· 3 3 pkgs, 4 4 sshKeys, 5 5 ... 6 - }: { 6 + }: 7 + { 7 8 imports = [ 8 9 ./nginx.nix 9 10 ./hardening.nix ··· 14 15 15 16 settings = { 16 17 auto-optimise-store = true; 17 - experimental-features = ["nix-command" "flakes"]; 18 - allowed-users = ["root" "@wheel"]; 18 + experimental-features = [ 19 + "nix-command" 20 + "flakes" 21 + ]; 22 + allowed-users = [ 23 + "root" 24 + "@wheel" 25 + ]; 19 26 }; 20 27 21 28 gc = { ··· 33 40 34 41 services.openssh = { 35 42 enable = true; 36 - ports = [22 2222]; 43 + ports = [ 44 + 22 45 + 2222 46 + ]; 37 47 openFirewall = false; 38 48 39 49 settings = { ··· 49 59 services.dbus.implementation = "broker"; 50 60 51 61 # Expose only 22, not 2222 52 - networking.firewall.allowedTCPPorts = [22]; 62 + networking.firewall.allowedTCPPorts = [ 22 ]; 53 63 54 64 # Use Quad9 DNS 55 - networking.nameservers = ["9.9.9.9" "149.112.112.112" "2620:fe::fe" "2620:fe::9"]; 65 + networking.nameservers = [ 66 + "9.9.9.9" 67 + "149.112.112.112" 68 + "2620:fe::fe" 69 + "2620:fe::9" 70 + ]; 56 71 57 72 # services.resolved = { 58 73 # enable = true; ··· 64 79 # ''; 65 80 # }; 66 81 67 - environment.systemPackages = []; 82 + environment.systemPackages = [ ]; 68 83 69 84 # Disable sudo, SSH into root instead 70 85 # security.sudo.enable = false; ··· 77 92 services.polkit.rssh = true; 78 93 }; 79 94 80 - boot.kernelParams = ["ia32_emulation=off"]; 95 + boot.kernelParams = [ "ia32_emulation=off" ]; 81 96 82 97 security.polkit = { 83 98 enable = true; ··· 107 122 users.users.hauleth = { 108 123 isNormalUser = true; 109 124 group = "hauleth"; 110 - extraGroups = ["wheel"]; 125 + extraGroups = [ "wheel" ]; 111 126 112 127 createHome = true; 113 128 114 129 openssh.authorizedKeys.keys = sshKeys.hauleth; 115 130 }; 116 131 117 - users.groups.hauleth = {}; 132 + users.groups.hauleth = { }; 118 133 119 134 security.acme = { 120 135 acceptTerms = true;
+116 -99
modules/common/hardening.nix
··· 2 2 config, 3 3 lib, 4 4 ... 5 - }: let 5 + }: 6 + let 6 7 inherit (lib) types; 7 - in { 8 + in 9 + { 8 10 options.systemd.services = lib.mkOption { 9 - type = types.attrsOf (types.submodule ({ 10 - name, 11 - config, 12 - ... 13 - }: { 14 - options.harden = { 15 - enable = lib.mkOption { 16 - type = types.bool; 17 - default = false; 18 - description = lib.mdDoc '' 19 - Basic restrictions for systemd services 20 - ''; 21 - }; 11 + type = types.attrsOf ( 12 + types.submodule ( 13 + { 14 + name, 15 + config, 16 + ... 17 + }: 18 + { 19 + options.harden = { 20 + enable = lib.mkOption { 21 + type = types.bool; 22 + default = false; 23 + description = lib.mdDoc '' 24 + Basic restrictions for systemd services 25 + ''; 26 + }; 22 27 23 - execOnlyNix = lib.mkOption { 24 - type = types.bool; 25 - default = true; 26 - description = lib.mdDoc '' 27 - Mark whole system as non-executable with exception for `/nix/store`. 28 - ''; 29 - }; 28 + execOnlyNix = lib.mkOption { 29 + type = types.bool; 30 + default = true; 31 + description = lib.mdDoc '' 32 + Mark whole system as non-executable with exception for `/nix/store`. 33 + ''; 34 + }; 30 35 31 - protectKernel = lib.mkOption { 32 - type = types.bool; 33 - default = true; 34 - description = lib.mdDoc '' 35 - Protect kernel internals from being reachable by the service. 36 - ''; 37 - }; 36 + protectKernel = lib.mkOption { 37 + type = types.bool; 38 + default = true; 39 + description = lib.mdDoc '' 40 + Protect kernel internals from being reachable by the service. 41 + ''; 42 + }; 38 43 39 - proc = lib.mkOption { 40 - type = types.bool; 41 - default = true; 42 - description = lib.mdDoc '' 43 - Restrict view into `/proc` to only allow access for limited subset. 44 - ''; 45 - }; 44 + proc = lib.mkOption { 45 + type = types.bool; 46 + default = true; 47 + description = lib.mdDoc '' 48 + Restrict view into `/proc` to only allow access for limited subset. 49 + ''; 50 + }; 46 51 47 - onlyLocalhost = lib.mkOption { 48 - type = types.bool; 49 - default = true; 50 - description = lib.mdDoc '' 51 - Allow listening sockets only on localhost. 52 - ''; 53 - }; 52 + onlyLocalhost = lib.mkOption { 53 + type = types.bool; 54 + default = true; 55 + description = lib.mdDoc '' 56 + Allow listening sockets only on localhost. 57 + ''; 58 + }; 54 59 55 - ipSockets = lib.mkOption { 56 - type = types.bool; 57 - default = false; 58 - description = lib.mdDoc '' 59 - Allow using AF_INET and AF_INET6 60 - ''; 61 - }; 62 - }; 63 - config.serviceConfig = let 64 - cfg = config.harden; 65 - inherit (lib) mkDefault; 66 - in 67 - lib.optionalAttrs cfg.enable ({ 68 - NoNewPrivileges = mkDefault true; 69 - LockPersonality = mkDefault true; 70 - RemoveIPC = mkDefault true; 60 + ipSockets = lib.mkOption { 61 + type = types.bool; 62 + default = false; 63 + description = lib.mdDoc '' 64 + Allow using AF_INET and AF_INET6 65 + ''; 66 + }; 67 + }; 68 + config.serviceConfig = 69 + let 70 + cfg = config.harden; 71 + inherit (lib) mkDefault; 72 + in 73 + lib.optionalAttrs cfg.enable ( 74 + { 75 + NoNewPrivileges = mkDefault true; 76 + LockPersonality = mkDefault true; 77 + RemoveIPC = mkDefault true; 71 78 72 - MemoryDenyWriteExecute = mkDefault true; 79 + MemoryDenyWriteExecute = mkDefault true; 73 80 74 - CapabilityBoundingSet = mkDefault [""]; 81 + CapabilityBoundingSet = mkDefault [ "" ]; 75 82 76 - RestrictNamespaces = mkDefault true; 77 - RestrictRealtime = mkDefault true; 78 - RestrictSUIDSGID = mkDefault true; 83 + RestrictNamespaces = mkDefault true; 84 + RestrictRealtime = mkDefault true; 85 + RestrictSUIDSGID = mkDefault true; 79 86 80 - ProtectHostname = mkDefault true; 81 - ProtectHome = mkDefault true; 82 - ProtectClock = mkDefault true; 83 - ProtectControlGroups = mkDefault true; 87 + ProtectHostname = mkDefault true; 88 + ProtectHome = mkDefault true; 89 + ProtectClock = mkDefault true; 90 + ProtectControlGroups = mkDefault true; 84 91 85 - RestrictAddressFamilies = mkDefault ( 86 - ["AF_UNIX"] ++ lib.optional cfg.ipSockets ["AF_INET" "AF_INET6"] 87 - ); 92 + RestrictAddressFamilies = mkDefault ( 93 + [ "AF_UNIX" ] 94 + ++ lib.optional cfg.ipSockets [ 95 + "AF_INET" 96 + "AF_INET6" 97 + ] 98 + ); 88 99 89 - DeviceAllow = mkDefault [""]; 100 + DeviceAllow = mkDefault [ "" ]; 90 101 91 - PrivateDevices = mkDefault true; 92 - PrivateTmp = mkDefault true; 93 - PrivateMounts = mkDefault true; 94 - PrivateUsers = mkDefault true; 102 + PrivateDevices = mkDefault true; 103 + PrivateTmp = mkDefault true; 104 + PrivateMounts = mkDefault true; 105 + PrivateUsers = mkDefault true; 95 106 96 - # By default it does nothing as everything is allowed unless we use 97 - # `NoExecPaths`. So this is good default. 98 - ExecPaths = mkDefault ["/nix/store"]; 107 + # By default it does nothing as everything is allowed unless we use 108 + # `NoExecPaths`. So this is good default. 109 + ExecPaths = mkDefault [ "/nix/store" ]; 99 110 100 - ProtectSystem = mkDefault "strict"; 111 + ProtectSystem = mkDefault "strict"; 101 112 102 - ProtectKernelLogs = cfg.protectKernel; 103 - ProtectKernelModules = cfg.protectKernel; 104 - ProtectKernelTunables = cfg.protectKernel; 113 + ProtectKernelLogs = cfg.protectKernel; 114 + ProtectKernelModules = cfg.protectKernel; 115 + ProtectKernelTunables = cfg.protectKernel; 105 116 106 - SystemCallFilter = mkDefault ["@system-service" "~@privileged"]; 107 - SystemCallArchitectures = ["native"]; 108 - SystemCallErrorNumber = mkDefault "EPERM"; 109 - } 110 - // (lib.optionalAttrs cfg.execOnlyNix { 111 - NoExecPaths = ["/"]; 112 - }) 113 - // (lib.optionalAttrs config.harden.proc { 114 - ProtectProc = mkDefault "invisible"; 115 - ProcSubset = "pid"; 116 - }) 117 - // (lib.optionalAttrs config.harden.onlyLocalhost { 118 - IPAddressAllow = ["localhost"]; 119 - IPAddressDeny = ["any"]; 120 - })); 121 - })); 117 + SystemCallFilter = mkDefault [ 118 + "@system-service" 119 + "~@privileged" 120 + ]; 121 + SystemCallArchitectures = [ "native" ]; 122 + SystemCallErrorNumber = mkDefault "EPERM"; 123 + } 124 + // (lib.optionalAttrs cfg.execOnlyNix { 125 + NoExecPaths = [ "/" ]; 126 + }) 127 + // (lib.optionalAttrs config.harden.proc { 128 + ProtectProc = mkDefault "invisible"; 129 + ProcSubset = "pid"; 130 + }) 131 + // (lib.optionalAttrs config.harden.onlyLocalhost { 132 + IPAddressAllow = [ "localhost" ]; 133 + IPAddressDeny = [ "any" ]; 134 + }) 135 + ); 136 + } 137 + ) 138 + ); 122 139 }; 123 140 }
+16 -13
modules/common/nginx.nix
··· 1 - {config, ...}: { 1 + { config, ... }: 2 + { 2 3 services.nginx = { 3 4 enable = true; 4 5 ··· 45 46 }; 46 47 47 48 # Add `httpasswd` file to Nginx credentials 48 - systemd.services.nginx = let 49 - httpasswd = config.age.secrets."httpasswd"; 50 - in { 51 - serviceConfig = { 52 - LoadCredential = [ 53 - "httpasswd:${httpasswd.path}" 49 + systemd.services.nginx = 50 + let 51 + httpasswd = config.age.secrets."httpasswd"; 52 + in 53 + { 54 + serviceConfig = { 55 + LoadCredential = [ 56 + "httpasswd:${httpasswd.path}" 57 + ]; 58 + ReadWritePaths = [ "/run" ]; 59 + }; 60 + 61 + restartTriggers = [ 62 + (builtins.hashFile "sha256" httpasswd.file) 54 63 ]; 55 - ReadWritePaths = ["/run"]; 56 64 }; 57 - 58 - restartTriggers = [ 59 - (builtins.hashFile "sha256" httpasswd.file) 60 - ]; 61 - }; 62 65 63 66 networking.firewall.allowedTCPPorts = with config.services.nginx; [ 64 67 defaultHTTPListenPort
+8 -3
modules/git.nix
··· 2 2 config, 3 3 lib, 4 4 ... 5 - }: let 5 + }: 6 + let 6 7 config' = config.service.radicle; 7 - in { 8 - logs.services = ["radicle" "knot"]; 8 + in 9 + { 10 + logs.services = [ 11 + "radicle" 12 + "knot" 13 + ]; 9 14 10 15 services.radicle = { 11 16 enable = false;
+29 -23
modules/irc-bouncer.nix
··· 1 - {config, ...}: let 1 + { config, ... }: 2 + let 2 3 hostName = "${config.networking.hostName}.${config.networking.domain}"; 3 4 port = 6697; 4 - in { 5 - logs.services = ["soju"]; 5 + in 6 + { 7 + logs.services = [ "soju" ]; 6 8 7 - services.soju = let 8 - certDir = "/run/credentials/soju.service"; 9 - in { 10 - enable = true; 9 + services.soju = 10 + let 11 + certDir = "/run/credentials/soju.service"; 12 + in 13 + { 14 + enable = true; 11 15 12 - inherit hostName; 16 + inherit hostName; 13 17 14 - listen = [ 15 - ":${toString port}" 16 - "http+prometheus://localhost:6698" 17 - ]; 18 + listen = [ 19 + ":${toString port}" 20 + "http+prometheus://localhost:6698" 21 + ]; 18 22 19 - tlsCertificate = "${certDir}/cert.pem"; 20 - tlsCertificateKey = "${certDir}/key.pem"; 21 - }; 23 + tlsCertificate = "${certDir}/cert.pem"; 24 + tlsCertificateKey = "${certDir}/key.pem"; 25 + }; 22 26 23 27 systemd.services.soju = { 24 - requires = ["acme-${hostName}.service"]; 28 + requires = [ "acme-${hostName}.service" ]; 25 29 26 - serviceConfig.LoadCredential = let 27 - certDir = config.security.acme.certs.${hostName}.directory; 28 - in [ 29 - "cert.pem:${certDir}/cert.pem" 30 - "key.pem:${certDir}/key.pem" 31 - ]; 30 + serviceConfig.LoadCredential = 31 + let 32 + certDir = config.security.acme.certs.${hostName}.directory; 33 + in 34 + [ 35 + "cert.pem:${certDir}/cert.pem" 36 + "key.pem:${certDir}/key.pem" 37 + ]; 32 38 33 39 harden = { 34 40 enable = true; ··· 37 43 }; 38 44 }; 39 45 40 - networking.firewall.allowedTCPPorts = [port]; 46 + networking.firewall.allowedTCPPorts = [ port ]; 41 47 42 48 services.nginx.virtualHosts.${hostName} = { 43 49 forceSSL = true;
+58 -53
modules/logs.nix
··· 3 3 config, 4 4 lib, 5 5 ... 6 - }: { 7 - options = let 8 - inherit (lib) mkOption mkEnableOption types; 9 - in { 10 - logs = { 11 - enable = mkEnableOption "Enables logs dispatching"; 6 + }: 7 + { 8 + options = 9 + let 10 + inherit (lib) mkOption mkEnableOption types; 11 + in 12 + { 13 + logs = { 14 + enable = mkEnableOption "Enables logs dispatching"; 12 15 13 - services = mkOption { 14 - default = []; 15 - type = types.listOf types.str; 16 - description = '' 17 - List of systemd services that should be dispatched 18 - ''; 16 + services = mkOption { 17 + default = [ ]; 18 + type = types.listOf types.str; 19 + description = '' 20 + List of systemd services that should be dispatched 21 + ''; 22 + }; 19 23 }; 20 24 }; 21 - }; 22 25 23 - config = let 24 - conf = config.logs; 25 - in { 26 - logs.services = [ 27 - "postgresql" 28 - "sshd" 29 - ]; 26 + config = 27 + let 28 + conf = config.logs; 29 + in 30 + { 31 + logs.services = [ 32 + "postgresql" 33 + "sshd" 34 + ]; 30 35 31 - services.vector = { 32 - enable = conf.enable; 36 + services.vector = { 37 + enable = conf.enable; 33 38 34 - journaldAccess = true; 39 + journaldAccess = true; 40 + 41 + settings = { 42 + sources.journald = { 43 + type = "journald"; 44 + include_units = conf.services ++ [ "vector" ]; 45 + since_now = true; 46 + }; 35 47 36 - settings = { 37 - sources.journald = { 38 - type = "journald"; 39 - include_units = conf.services ++ ["vector"]; 40 - since_now = true; 41 - }; 48 + transforms.journald-mapped = { 49 + type = "remap"; 50 + inputs = [ "journald" ]; 42 51 43 - transforms.journald-mapped = { 44 - type = "remap"; 45 - inputs = ["journald"]; 52 + source = '' 53 + .event_message = .message 54 + .timestamp = to_int!(.__REALTIME_TIMESTAMP) 55 + .metadata = { 56 + "level": to_syslog_level!(to_int!(.PRIORITY)), 57 + "unit": ._SYSTEMD_UNIT, 58 + "host": .host, 59 + "boot_id": ._BOOT_ID, 60 + "machine_id": ._MACHINE_ID, 61 + "pid": ._PID, 62 + "uid": ._UID 63 + } 64 + ''; 65 + }; 46 66 47 - source = '' 48 - .event_message = .message 49 - .timestamp = to_int!(.__REALTIME_TIMESTAMP) 50 - .metadata = { 51 - "level": to_syslog_level!(to_int!(.PRIORITY)), 52 - "unit": ._SYSTEMD_UNIT, 53 - "host": .host, 54 - "boot_id": ._BOOT_ID, 55 - "machine_id": ._MACHINE_ID, 56 - "pid": ._PID, 57 - "uid": ._UID 58 - } 59 - ''; 67 + # No sink for now, I need to find better service for log viewing 60 68 }; 61 - 62 - # No sink for now, I need to find better service for log viewing 63 69 }; 64 - }; 65 70 66 - systemd.services.vector = { 67 - enable = conf.enable; 68 - serviceConfig.EnvironmentFile = config.age.secrets."vector.conf".path; 71 + systemd.services.vector = { 72 + enable = conf.enable; 73 + serviceConfig.EnvironmentFile = config.age.secrets."vector.conf".path; 69 74 70 - harden.enable = true; 75 + harden.enable = true; 76 + }; 71 77 }; 72 - }; 73 78 }
+41 -24
modules/mail/default.nix
··· 3 3 config, 4 4 pkgs, 5 5 ... 6 - }: let 6 + }: 7 + let 7 8 domain = "hauleth.dev"; 8 9 mail-domain = "mail.${domain}"; 9 10 data-dir = "/var/lib/stalwart-mail"; 10 11 secrets = "/run/credentials/stalwart.service"; 11 12 unstable = inputs.nixpkgs-unstable.legacyPackages.${pkgs.stdenv.hostPlatform.system}; 12 - in { 13 + in 14 + { 13 15 imports = [ 14 16 ./module.nix 15 17 ]; ··· 27 29 28 30 # TODO: Use `stalwart-cli` to refresh renewed certificates 29 31 systemd.services.stalwart = { 30 - requires = ["acme-${mail-domain}.service"]; 32 + requires = [ "acme-${mail-domain}.service" ]; 31 33 32 - serviceConfig.LoadCredential = let 33 - certDir = config.security.acme.certs.${mail-domain}.directory; 34 - in [ 35 - "cert.pem:${certDir}/cert.pem" 36 - "key.pem:${certDir}/key.pem" 37 - "dkim.cert:${config.age.secrets."dkim-hauleth.dev-priv.key".path}" 38 - ]; 34 + serviceConfig.LoadCredential = 35 + let 36 + certDir = config.security.acme.certs.${mail-domain}.directory; 37 + in 38 + [ 39 + "cert.pem:${certDir}/cert.pem" 40 + "key.pem:${certDir}/key.pem" 41 + "dkim.cert:${config.age.secrets."dkim-hauleth.dev-priv.key".path}" 42 + ]; 39 43 }; 40 44 41 - logs.services = ["stalwart"]; 45 + logs.services = [ "stalwart" ]; 42 46 43 47 services.stalwart = { 44 48 enable = true; ··· 91 95 directory.memory = { 92 96 type = "memory"; 93 97 94 - principals = let 95 - emails = map (value: "${value}@${domain}"); 96 - in [ 97 - { 98 - name = "hauleth"; 99 - class = "admin"; 100 - description = "Main email account"; 101 - secret = "$argon2id$v=19$m=4096,t=3,p=1$VFllNFdnOURZWjRWWGtyeg$DPmQ/bOHi4QNvKP7PkyZ/Qb6CjKdiAU58EPWrNKZy+U"; 102 - email = emails ["~" "#" "$" "hauleth"]; 103 - } 104 - ]; 98 + principals = 99 + let 100 + emails = map (value: "${value}@${domain}"); 101 + in 102 + [ 103 + { 104 + name = "hauleth"; 105 + class = "admin"; 106 + description = "Main email account"; 107 + secret = "$argon2id$v=19$m=4096,t=3,p=1$VFllNFdnOURZWjRWWGtyeg$DPmQ/bOHi4QNvKP7PkyZ/Qb6CjKdiAU58EPWrNKZy+U"; 108 + email = emails [ 109 + "~" 110 + "#" 111 + "$" 112 + "hauleth" 113 + ]; 114 + } 115 + ]; 105 116 }; 106 117 107 118 # webadmin.auto-update = true; ··· 123 134 "if" = "listener == 'smtp'"; 124 135 "then" = false; 125 136 } 126 - {"else" = "['rsa']";} 137 + { "else" = "['rsa']"; } 127 138 ]; 128 139 }; 129 140 ··· 132 143 133 144 private-key = "%{file:${secrets}/dkim.cert}%"; 134 145 selector = "default"; 135 - headers = ["From" "To" "Date" "Subject" "Message-ID"]; 146 + headers = [ 147 + "From" 148 + "To" 149 + "Date" 150 + "Subject" 151 + "Message-ID" 152 + ]; 136 153 algorithm = "rsa-sha256"; 137 154 canonicalization = "relaxed/relaxed"; 138 155 set-body-length = false;
+38 -25
modules/mail/module.nix
··· 4 4 pkgs, 5 5 inputs, 6 6 ... 7 - }: let 8 - inherit (lib) mkOption mkEnableOption mkPackageOption types; 7 + }: 8 + let 9 + inherit (lib) 10 + mkOption 11 + mkEnableOption 12 + mkPackageOption 13 + types 14 + ; 9 15 cfg = config.services.stalwart; 10 - configFormat = pkgs.formats.toml {}; 16 + configFormat = pkgs.formats.toml { }; 11 17 configFile = configFormat.generate "stalwart-mail.toml" cfg.settings; 12 18 13 19 listenerOpts = name: defaultPort: tls: { ··· 36 42 default = tls; 37 43 }; 38 44 }; 39 - in { 45 + in 46 + { 40 47 options.services.stalwart = { 41 48 enable = mkEnableOption "Enables Stalwart service"; 42 49 ··· 52 59 53 60 settings = mkOption { 54 61 inherit (configFormat) type; 55 - default = {}; 62 + default = { }; 56 63 description = '' 57 64 Configuration options for the Stalwart email server. 58 65 See <https://stalw.art/docs/category/configuration> for available options. ··· 106 113 ]; 107 114 }; 108 115 109 - server.listener = let 110 - mkListener = listCfg: protocol: 111 - lib.mkIf listCfg.enable { 112 - inherit protocol; 116 + server.listener = 117 + let 118 + mkListener = 119 + listCfg: protocol: 120 + lib.mkIf listCfg.enable { 121 + inherit protocol; 113 122 114 - bind = ["${listCfg.listenAddress}:${toString listCfg.port}"]; 123 + bind = [ "${listCfg.listenAddress}:${toString listCfg.port}" ]; 115 124 116 - tls.implicit = listCfg.tls; 117 - }; 118 - in { 119 - smtp = mkListener cfg.smtp "smtp"; 120 - submissions = mkListener cfg.submissions "smtp"; 121 - imap = mkListener cfg.imap "imap"; 122 - sieve = mkListener cfg.sieve "managesieve"; 123 - jmap = mkListener cfg.jmap "http"; 124 - }; 125 + tls.implicit = listCfg.tls; 126 + }; 127 + in 128 + { 129 + smtp = mkListener cfg.smtp "smtp"; 130 + submissions = mkListener cfg.submissions "smtp"; 131 + imap = mkListener cfg.imap "imap"; 132 + sieve = mkListener cfg.sieve "managesieve"; 133 + jmap = mkListener cfg.jmap "http"; 134 + }; 125 135 126 136 store.rocksdb = { 127 137 type = "rocksdb"; ··· 157 167 # service is restarted on a potentially large number of files. 158 168 # That would cause unnecessary and unwanted delays. 159 169 users = { 160 - groups.stalwart-mail = {}; 170 + groups.stalwart-mail = { }; 161 171 users.stalwart-mail = { 162 172 isSystemUser = true; 163 173 group = "stalwart-mail"; ··· 167 177 systemd.services.stalwart = { 168 178 enable = cfg.enable; 169 179 170 - wantedBy = ["multi-user.target"]; 171 - after = ["local-fs.target" "network.target"]; 180 + wantedBy = [ "multi-user.target" ]; 181 + after = [ 182 + "local-fs.target" 183 + "network.target" 184 + ]; 172 185 173 186 harden = { 174 187 enable = true; ··· 197 210 CacheDirectory = "stalwart"; 198 211 199 212 # Bind standard privileged ports 200 - AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; 201 - CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"]; 213 + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; 214 + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; 202 215 203 216 # Hardening 204 217 PrivateUsers = false; # incompatible with CAP_NET_BIND_SERVICE ··· 207 220 }; 208 221 209 222 # Make admin commands available in the shell 210 - environment.systemPackages = [cfg.package]; 223 + environment.systemPackages = [ cfg.package ]; 211 224 }; 212 225 }
+11 -5
modules/ovh.nix
··· 2 2 modulesPath, 3 3 pkgs, 4 4 ... 5 - }: { 6 - imports = [(modulesPath + "/profiles/qemu-guest.nix")]; 5 + }: 6 + { 7 + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; 7 8 # boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_7; 8 - boot.kernelParams = ["ia32_emulation=off"]; 9 + boot.kernelParams = [ "ia32_emulation=off" ]; 9 10 10 11 boot.kernel.sysctl = { 11 12 "net.ipv4.tcp_fastopen" = 3; 12 13 }; 13 14 14 15 boot.loader.grub.device = "/dev/sda"; 15 - boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi"]; 16 - boot.initrd.kernelModules = ["nvme"]; 16 + boot.initrd.availableKernelModules = [ 17 + "ata_piix" 18 + "uhci_hcd" 19 + "xen_blkfront" 20 + "vmw_pvscsi" 21 + ]; 22 + boot.initrd.kernelModules = [ "nvme" ]; 17 23 fileSystems."/" = { 18 24 device = "/dev/sda1"; 19 25 fsType = "ext4";
+5 -3
modules/pastebin.nix
··· 2 2 config, 3 3 inputs, 4 4 ... 5 - }: let 5 + }: 6 + let 6 7 domain = "bin.hauleth.dev"; 7 8 port = "6701"; 8 9 cfg = config.services.ubin; 9 - in { 10 + in 11 + { 10 12 imports = [ 11 13 inputs.ubin.nixosModules.default 12 14 ]; 13 15 14 - logs.services = ["ubin"]; 16 + logs.services = [ "ubin" ]; 15 17 16 18 services.ubin = { 17 19 enable = false;
+3 -2
modules/postgres.nix
··· 1 - {pkgs, ...}: { 2 - logs.services = ["postgresql"]; 1 + { pkgs, ... }: 2 + { 3 + logs.services = [ "postgresql" ]; 3 4 4 5 services.postgresql = { 5 6 # enable = true;
+5 -3
modules/rss.nix
··· 1 - {config, ...}: let 1 + { config, ... }: 2 + let 2 3 domain = "rss.srebrna.space"; 3 4 port = 8080; 4 5 portStr = toString port; 5 - in { 6 - logs.services = ["miniflux"]; 6 + in 7 + { 8 + logs.services = [ "miniflux" ]; 7 9 8 10 services.miniflux = { 9 11 enable = true;
+3 -2
modules/tailscale.nix
··· 1 - {config, ...}: { 2 - logs.services = ["tailscaled"]; 1 + { config, ... }: 2 + { 3 + logs.services = [ "tailscaled" ]; 3 4 4 5 services.tailscale.enable = true; 5 6
+1 -1
nodes.nix
··· 1 - {} 1 + { }
+12 -11
secrets.nix
··· 1 - with (import ./keys.nix); let 2 - join = builtins.foldl' (a: b: a ++ b) []; 3 - build = builtins.mapAttrs (_: value: value // {publicKeys = join value.publicKeys;}); 1 + with (import ./keys.nix); 2 + let 3 + join = builtins.foldl' (a: b: a ++ b) [ ]; 4 + build = builtins.mapAttrs (_: value: value // { publicKeys = join value.publicKeys; }); 4 5 keys = [ 5 6 hauleth 6 7 heimdall 7 8 mimir 8 9 ]; 9 10 in 10 - build { 11 - "secrets/miniflux-admin.age".publicKeys = keys; 12 - "secrets/matterbridge.conf.age".publicKeys = keys; 13 - "secrets/httpasswd.age".publicKeys = keys; 14 - "secrets/netdata-alarm.age".publicKeys = keys; 15 - "secrets/dkim-hauleth.dev-priv.key.age".publicKeys = keys; 16 - "secrets/vector.conf.age".publicKeys = keys; 17 - } 11 + build { 12 + "secrets/miniflux-admin.age".publicKeys = keys; 13 + "secrets/matterbridge.conf.age".publicKeys = keys; 14 + "secrets/httpasswd.age".publicKeys = keys; 15 + "secrets/netdata-alarm.age".publicKeys = keys; 16 + "secrets/dkim-hauleth.dev-priv.key.age".publicKeys = keys; 17 + "secrets/vector.conf.age".publicKeys = keys; 18 + }
+4 -2
servers/heimdall/default.nix
··· 1 - {inputs, ...}: let 1 + { inputs, ... }: 2 + let 2 3 ipv6Prefix = "2001:41d0:0601:1100"; 3 4 prefixLength = 128; 4 5 ipv6Address = "${ipv6Prefix}::16f0"; 5 6 ipv6Gateway = "${ipv6Prefix}::0001"; 6 - in { 7 + in 8 + { 7 9 networking.hostName = "heimdall"; 8 10 networking.domain = "hauleth.dev"; 9 11
+5 -3
servers/mimir/default.nix
··· 1 - {inputs, ...}: let 1 + { inputs, ... }: 2 + let 2 3 ipv6Prefix = "2001:41d0:0601:1100"; 3 4 prefixLength = 128; 4 5 ipv6Address = "${ipv6Prefix}::178f"; 5 6 ipv6Gateway = "${ipv6Prefix}::0001"; 6 - in { 7 + in 8 + { 7 9 networking.hostName = "mimir"; 8 10 networking.domain = "hauleth.dev"; 9 11 ··· 57 59 ]; 58 60 }; 59 61 60 - networking.firewall.allowedTCPPorts = [2222]; 62 + networking.firewall.allowedTCPPorts = [ 2222 ]; 61 63 62 64 services.beszel.agent.environment = { 63 65 TOKEN = "8c42e760-da30-429b-852c-3e26ca20d90b";
+4 -3
servers/mimir/disks.nix
··· 1 - {lib, ...}: { 1 + { lib, ... }: 2 + { 2 3 disko.devices = { 3 4 disk.main = { 4 5 device = lib.mkDefault "/dev/sda"; ··· 22 23 type = "filesystem"; 23 24 format = "vfat"; 24 25 mountpoint = "/boot"; 25 - mountOptions = ["defaults"]; 26 + mountOptions = [ "defaults" ]; 26 27 }; 27 28 }; 28 29 ··· 30 31 size = "100%"; 31 32 content = { 32 33 type = "btrfs"; 33 - extraArgs = ["-f"]; 34 + extraArgs = [ "-f" ]; 34 35 35 36 subvolumes = { 36 37 "@root" = {
+11 -5
servers/mimir/hardware.nix
··· 7 7 pkgs, 8 8 modulesPath, 9 9 ... 10 - }: { 10 + }: 11 + { 11 12 imports = [ 12 13 (modulesPath + "/profiles/qemu-guest.nix") 13 14 ]; 14 15 15 - boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi"]; 16 - boot.initrd.kernelModules = []; 17 - boot.kernelModules = ["kvm-intel"]; 18 - boot.extraModulePackages = []; 16 + boot.initrd.availableKernelModules = [ 17 + "ata_piix" 18 + "uhci_hcd" 19 + "virtio_pci" 20 + "virtio_scsi" 21 + ]; 22 + boot.initrd.kernelModules = [ ]; 23 + boot.kernelModules = [ "kvm-intel" ]; 24 + boot.extraModulePackages = [ ]; 19 25 20 26 nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 21 27 }