diff options
41 files changed, 1037 insertions, 334 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8cfc43a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Matches multiple files with brace expansion notation +# Set default charset +[*.{nix}] +charset = utf-8 +indent_style = space +indent_size = 2 diff --git a/.gitattributes b/.gitattributes index 80f5bb9..b9e9c86 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,2 @@ -system/mail/users.nix filter=git-crypt diff=git-crypt +system/services/mail/users.nix filter=git-crypt diff=git-crypt system/services/nginx/hosts.nix filter=git-crypt diff=git-crypt -system/services/acme/domains.nix filter=git-crypt diff=git-crypt diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ec31bd..1827e42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,89 @@ All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines. - - - +## v0.3.0 - 2023-07-10 +#### Bug Fixes +- **(host/server1)** Use working path to disk - (26b6c91) - Soispha +- **(system/disks)** Change partitioning scheme to support gpt/bios boot - (40458f4) - Soispha +- **(system/impermanence/m/mail)** Add rspamd dir - (a0d04e5) - Soispha +- **(system/impermanence/m/users)** Make /home readable - (8c1dd93) - Soispha +- **(system/secrets)** Update after redeploy - (778f8ad) - Soispha +- **(system/secrets)** Ensure that ssh host key is available in stage 2 - (5bb8cb3) - Soispha +- **(system/services/keycloak)** Use agenix to store passwd - (265eb9d) - Soispha +- **(system/services/nix-sync)** Nix build needs access to /proc/stat - (123a8d9) - Soispha +- **(treewide)** Move all persistent dirs to impermanence to set permissions - (7815ef2) - Soispha +#### Documentation +- **(notes)** Add section about redeployment - (3ea6a58) - Soispha +#### Features +- **(flake)** Add agenix module - (78b566e) - Soispha +- **(system/disks)** Add disko - (d176a33) - Soispha +#### Miscellaneous Chores +- **(.gitattributes)** Remove removed acme path - (81cf12b) - Soispha +#### Refactoring +- **(system/impermanence)** Move to own directory - (2a6b022) - Soispha + +- - - + +## v0.2.0 - 2023-07-07 +#### Bug Fixes +- **(system)** Import everything - (a1758ed) - Soispha +- **(system)** Import everything - (07f1e4a) - Soispha +- **(system/fs-layout)** Remove persistent dir as it's now in /srv - (ce36bb2) - Soispha +- **(system/fs_layout/impermanence)** Make sshd dir 755 - (4fdf20b) - Soispha +- **(system/services)** Move acmeWebRoot back to /var/lib/acme - (532412a) - Soispha +- **(system/services)** Inherit acmeRoot manually - (80e5776) - Soispha +- **(system/services/acme)** Leave certs generation to nixos - (1f6ff65) - Soispha +- **(system/services/git-sync)** Use correct systemd options - (77e512a) - Soispha +- **(system/services/git-sync)** Switch to str to avoid impurity - (a8ffaea) - Soispha +- **(system/services/git-sync)** Purge assertion, as we're always on linux - (74a735b) - Soispha +- **(system/services/mail)** Tell git-crypt new users.nix location - (cdea671) - sils +- **(system/services/nginx)** Set the correct acme webRoot - (252d983) - Soispha +- **(system/services/nginx)** Create nix-sync cache through impermanence - (869d74c) - Soispha +- **(system/services/nginx)** Remove slash from acme webroot - (bec5cf4) - Soispha +- **(system/services/nginx)** Actually enable git-sync - (374c499) - Soispha +- **(system/services/nginx/hosts)** Inherit acmeRoot setting - (990cb3c) - Soispha +- **(system/services/nix-sync)** Guard deletion of `repo.path` - (16da0f2) - Soispha +- **(system/services/nix-sync)** Pull before rebuilding - (3df8d67) - Soispha +- **(system/services/nix-sync)** Generate the needed repo paths - (5bed7c8) - Soispha +- **(system/services/nix-sync)** Rebuild website on gc - (393f0e6) - Soispha +- **(system/services/nix-sync)** Really remove last reference to git-sync - (0b36dbd) - Soispha +- **(system/services/nix-sync)** Small typos in ExecStart - (0ac9885) - Soispha +- **(system/services/nix-sync)** Use cache directory - (6e18fa4) - Soispha +- **(system/services/nix-sync)** Use correct git urls - (9f9a140) - Soispha +- **(system/services/nix-sync)** Generate root independent of path - (a505c18) - Soispha +- **(system/services/nix-sync)** Add the cachePath rw - (dd84945) - Soispha +- **(system/services/nix-sync)** Add '/etc/nginx/websites' to kept dirs - (6a5b874) - Soispha +- **(system/services/nix-sync)** Remove slash from cachePath - (33398b1) - Soispha +- **(system/services/nix-sync)** Add some required paths to unit - (e6b778b) - Soispha +- **(system/services/nix-sync)** Generate user and group if set to default - (39abbf7) - Soispha +- **(system/services/nix-sync)** Rename units to nix-sync-<domain> - (844ff55) - Soispha +- **(system/services/nix-sync)** Use correct shell escape for paths - (3c42c6b) - Soispha +- **(system/services/nix-sync)** Use correct writeScript function - (4ef4b09) - Soispha +- **(system/services/nix-sync)** Fully rename to nix-sync - (c35eeac) - Soispha +- **(system/services/openssh)** Set correct permissions on ssh dir - (f3f8e43) - Soispha +- **(system/services/openssh)** Rename to 'openssh' as the 'd' is a typo - (99d4b3b) - Soispha +#### Build system +- **(cog)** Remove 'prod' from whitelist as it's deprecated - (661a2d4) - Soispha +- **(flake)** Update - (2f10834) - Soispha +#### Documentation +- **(system/services/nix-sync)** Change last remnant from git-sync - (1fe7e31) - Soispha +#### Features +- **(system/file_system_layout)** Add impermanence - (1c4672d) - Soispha +- **(system/services/nix-sync)** Split unit into a timer and unit - (42d44c6) - Soispha +- **(system/services/nix-sync)** Remodel git-sync to make it useful - (3f2fedf) - Soispha +#### Miscellaneous Chores +- **(.gitattributes)** Remove removed acme path - (99ae5c9) - Soispha +#### Refactoring +- **(system/impermanence)** Move to own directory - (2c6c07e) - Soispha +- **(system/services/mail)** Move mail to services as it's one - (32ab086) - Soispha +- **(system/services/nginx)** Adapt to new nix-sync module - (9b88691) - Soispha +- **(system/services/nix-sync)** Consolidate into repoCachePath - (1c93755) - Soispha +#### Style +- **(system/fs_layouts)** Merge attrsets - (d0a8582) - Soispha +- **(system/services/nginx)** Use nested attr set for acme options - (9fc5517) - Soispha + +- - - + ## v0.1.0 - 2023-06-19 #### Bug Fixes - **(acme)** Store certs permanently. - (ab3c9aa) - sils diff --git a/cog.toml b/cog.toml index 814eccd..6f5f747 100644 --- a/cog.toml +++ b/cog.toml @@ -5,7 +5,6 @@ pre_package_bump_hooks = [] post_package_bump_hooks = [] branch_whitelist = [ - "prod", "main", ] diff --git a/flake.lock b/flake.lock index 687ac4f..c08cea2 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,27 @@ { "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1689334118, + "narHash": "sha256-djk5AZv1yU84xlKFaVHqFWvH73U7kIRstXwUAnDJPsk=", + "owner": "ryantm", + "repo": "agenix", + "rev": "0d8c5325fc81daf00532e3e26c6752f7bcde1143", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, "blobs": { "flake": false, "locked": { @@ -16,14 +38,85 @@ "type": "gitlab" } }, + "crane": { + "inputs": { + "flake-compat": [ + "flake-compat" + ], + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": [ + "rust-overlay" + ] + }, + "locked": { + "lastModified": 1688772518, + "narHash": "sha256-ol7gZxwvgLnxNSZwFTDJJ49xVY5teaSvF7lzlo3YQfM=", + "owner": "ipetkov", + "repo": "crane", + "rev": "8b08e96c9af8c6e3a2b69af5a7fa168750fcf88e", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1673295039, + "narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "87b9d090ad39b25b2400029c64825fc2a8868943", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1689324677, + "narHash": "sha256-83DCDJwBkulQFQESe37+tG0qUb8JkQLJHJ3Qn7iGx7Q=", + "owner": "nix-community", + "repo": "disko", + "rev": "7eb09408393faa5b8f3b3524c39cb93d938e8d04", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { - "lastModified": 1668681692, - "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=", + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", "owner": "edolstra", "repo": "flake-compat", - "rev": "009399224d5e398d03b22badca40a37ac85412a1", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", "type": "github" }, "original": { @@ -39,11 +132,11 @@ ] }, "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", "owner": "numtide", "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", "type": "github" }, "original": { @@ -52,13 +145,49 @@ "type": "github" } }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1682203081, + "narHash": "sha256-kRL4ejWDhi0zph/FpebFYhzqlOBrk0Pl3dzGEKSAlEw=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "32d3e39c491e2f91152c84f8ad8b003420eab0a1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "impermanence": { + "locked": { + "lastModified": 1684264534, + "narHash": "sha256-K0zr+ry3FwIo3rN2U/VWAkCJSgBslBisvfRIPwMbuCQ=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "89253fb1518063556edd5e54509c30ac3089d5e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1686968143, - "narHash": "sha256-NkXmT9ArJBeu56jo/agURQ1pvqrx0nUHi30yM7sttK8=", + "lastModified": 1689715163, + "narHash": "sha256-HgBowH0RUU+6SpvpXYfTSunAqaME/6d0bqAW+shW6e4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "56799517d0537a6f3e91a5171af8c4bfd82c092e", + "rev": "0171976ee0a1fa795b105c19a323e67b9c6094d9", "type": "github" }, "original": { @@ -98,18 +227,82 @@ "type": "indirect" } }, + "ragenix": { + "inputs": { + "agenix": [ + "agenix" + ], + "crane": [ + "crane" + ], + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": [ + "rust-overlay" + ] + }, + "locked": { + "lastModified": 1682237245, + "narHash": "sha256-xbBR7LNK+d5Yi/D6FXQGc1R6u2VV2nwr/Df5iaEbOEQ=", + "owner": "yaxitech", + "repo": "ragenix", + "rev": "281f68c3d477904f79ff1cd5807a8c226cd80a50", + "type": "github" + }, + "original": { + "owner": "yaxitech", + "repo": "ragenix", + "type": "github" + } + }, "root": { "inputs": { + "agenix": "agenix", + "crane": "crane", + "disko": "disko", + "flake-compat": "flake-compat", "flake-utils": "flake-utils", + "impermanence": "impermanence", "nixpkgs": "nixpkgs", + "ragenix": "ragenix", + "rust-overlay": "rust-overlay", "simple-nixos-mailserver": "simple-nixos-mailserver", "systems": "systems" } }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1689735719, + "narHash": "sha256-HOEDWJLm+f6HSD4j7n4xc8J4FcqjJ+U7ZnMLQQrZKYg=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "31d08cf9f5c3a49475e723c75c6f645171364a74", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "simple-nixos-mailserver": { "inputs": { "blobs": "blobs", - "flake-compat": "flake-compat", + "flake-compat": [ + "flake-compat" + ], "nixpkgs": [ "nixpkgs" ], @@ -118,11 +311,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1686496219, - "narHash": "sha256-8zXZ/813yzaRA84js98G3XQ3GEEzFGnxhjvVyxkEey0=", + "lastModified": 1687462267, + "narHash": "sha256-rNSputjn/0HEHHnsKfQ8mQVEPVchcBw7DsbND7Wg8dk=", "owner": "simple-nixos-mailserver", "repo": "nixos-mailserver", - "rev": "4966c0f63f04659015f064f2aa34b1893a16dfde", + "rev": "24128c3052090311688b09a400aa408ba61c6ee5", "type": "gitlab" }, "original": { diff --git a/flake.nix b/flake.nix index 3af5b41..dfa7222 100644 --- a/flake.nix +++ b/flake.nix @@ -4,16 +4,71 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05-small"; - systems.url = "github:nix-systems/x86_64-linux"; + # inputs for following + systems = { + url = "github:nix-systems/x86_64-linux"; # only evaluate for this system + }; + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; + crane = { + url = "github:ipetkov/crane"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-compat.follows = "flake-compat"; + flake-utils.follows = "flake-utils"; + rust-overlay.follows = "rust-overlay"; + }; + }; flake-utils = { url = "github:numtide/flake-utils"; - inputs.systems.follows = "systems"; + inputs = { + systems.follows = "systems"; + }; + }; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; }; + # modules + disko = { + url = "github:nix-community/disko"; + inputs = { + nixpkgs.follows = "nixpkgs"; + }; + }; + agenix = { + url = "github:ryantm/agenix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + }; + }; + impermanence = { + url = "github:nix-community/impermanence"; + inputs = {}; + }; simple-nixos-mailserver = { url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-23.05"; inputs = { nixpkgs.follows = "nixpkgs"; + flake-compat.follows = "flake-compat"; + }; + }; + + # bins + ragenix = { + url = "github:yaxitech/ragenix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + agenix.follows = "agenix"; + flake-utils.follows = "flake-utils"; + rust-overlay.follows = "rust-overlay"; + crane.follows = "crane"; }; }; }; @@ -21,7 +76,13 @@ outputs = { self, nixpkgs, + # modules simple-nixos-mailserver, + impermanence, + disko, + agenix, + # bins + ragenix, ... } @ attrs: let system = "x86_64-linux"; @@ -33,9 +94,9 @@ modules = [ ./hosts/server1/configuration.nix simple-nixos-mailserver.nixosModule - { - mailserver = import ./system/mail {inherit (pkgs) lib;}; - } + disko.nixosModules.default + impermanence.nixosModules.impermanence + agenix.nixosModules.default ]; }; devShells."${system}" = { @@ -48,9 +109,9 @@ ltex-ls cocogitto git-crypt + ragenix.packages."${system}".default ]; }; }; }; } -# vim: ts=2 diff --git a/hosts/server1/configuration.nix b/hosts/server1/configuration.nix index 78eacee..26de287 100644 --- a/hosts/server1/configuration.nix +++ b/hosts/server1/configuration.nix @@ -1,4 +1,4 @@ -{pkgs, ...}: { +{...}: { imports = [ ./networking.nix # network configuration that just works ./hardware.nix @@ -11,9 +11,8 @@ networking.hostName = "server1"; networking.domain = "vhack.eu"; - system.fileSystemLayouts.mainDisk = "/dev/disk/by-uuid/7d960eb9-9334-4aef-9f7c-9a908a91a6db"; + # FIXME: Find a better way to specify the disk + system.disks.disk = "/dev/vda"; system.stateVersion = "22.11"; } -# vim: ts=2 - diff --git a/hosts/server1/hardware.nix b/hosts/server1/hardware.nix index 9fabafe..6086362 100644 --- a/hosts/server1/hardware.nix +++ b/hosts/server1/hardware.nix @@ -3,6 +3,7 @@ (modulesPath + "/profiles/qemu-guest.nix") (modulesPath + "/profiles/headless.nix") ]; + # FIXME: The name of the grub device depends on the disko settings boot.loader.grub.device = "/dev/vda"; boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk"]; boot.initrd.kernelModules = []; diff --git a/notes/deploy.md b/notes/deploy.md new file mode 100644 index 0000000..61dcbfc --- /dev/null +++ b/notes/deploy.md @@ -0,0 +1,6 @@ +# Full redeployment +After a complete server purge just load up the newest NixOS ISO, set the root password and run: +```bash +ipv4_address=$(dig +short "<hostname>"); # ipv6 seems to fail in this context +nix run github:numtide/nixos-anywhere -- --flake .#<hostname> root@"$ipv4_address" +``` diff --git a/system/default.nix b/system/default.nix index d67ada2..14f0748 100644 --- a/system/default.nix +++ b/system/default.nix @@ -1,7 +1,9 @@ -{config, ...}: { +{...}: { imports = [ - ./file_system_layouts + ./disks + ./impermanence ./packages + ./secrets ./services ./users ]; diff --git a/system/disks/default.nix b/system/disks/default.nix new file mode 100644 index 0000000..f4e6935 --- /dev/null +++ b/system/disks/default.nix @@ -0,0 +1,82 @@ +{ + config, + lib, + ... +}: +with lib; let + cfg = config.system.disks; + defaultMountOptions = ["compress-force=zstd:15"]; +in { + options.system.disks = { + disk = mkOption { + type = lib.types.path; + example = literalExpression "/dev/disk/by-id/ata-WDC_WD10SDRW-11A0XS0_WD-WXP2A901KJN5"; + description = lib.mdDoc "Path to the disk"; + }; + }; + + config = { + disko.devices = { + disk.main = { + device = cfg.disk; + content = { + type = "table"; + format = "gpt"; + partitions = [ + { + name = "boot"; + start = "0"; + end = "1M"; + part-type = "primary"; + flags = ["bios_grub"]; + } + { + name = "root"; + # leave space for the grub aka BIOS boot + start = "1M"; + end = "100%"; + part-type = "primary"; + bootable = true; + content = { + type = "btrfs"; + extraArgs = ["-f" "--label nixos"]; # f: Override existing partitions + subvolumes = { + "nix" = { + mountpoint = "/nix"; + mountOptions = defaultMountOptions; + }; + "persistent-storage" = { + mountpoint = "/srv"; + mountOptions = defaultMountOptions; + }; + "persistent-storage@snapshots" = { + mountpoint = "/srv/.snapshots"; + mountOptions = defaultMountOptions; + }; + "boot" = { + mountpoint = "/boot"; + mountOptions = defaultMountOptions; + }; + }; + }; + } + ]; + }; + }; + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = ["defaults" "size=2G" "mode=755"]; + }; + }; + }; + fileSystems = { + "/srv" = { + neededForBoot = true; + }; + "/boot" = { + neededForBoot = true; + }; + }; + }; +} diff --git a/system/file_system_layouts/default.nix b/system/file_system_layouts/default.nix deleted file mode 100644 index 4cd9ff1..0000000 --- a/system/file_system_layouts/default.nix +++ /dev/null @@ -1,53 +0,0 @@ -{ - modulesPath, - config, - lib, - ... -}: -with lib; let - cfg = config.system.fileSystemLayouts; -in { - options.system.fileSystemLayouts = { - mainDisk = mkOption { - type = lib.types.path; - example = literalExpression "/dev/disk/by-uuid/0442cb6d-f13a-4635-b487-fa76189774c5"; - description = lib.mdDoc "Path to the main disk"; - }; - }; - config = { - fileSystems = { - "/" = { - device = "tmpfs"; - fsType = "tmpfs"; - options = ["defaults" "size=2G" "mode=755"]; - }; - "/nix" = { - device = cfg.mainDisk; - fsType = "btrfs"; - options = ["subvol=nix" "compress-force=zstd"]; - }; - "/srv" = { - device = cfg.mainDisk; - fsType = "btrfs"; - options = ["subvol=storage" "compress-force=zstd"]; - }; - "/boot" = { - device = cfg.mainDisk; - options = ["subvol=boot" "compress-force=zstd"]; - }; - - "/etc/nixos" = { - device = "/srv/nix-config"; - options = ["bind"]; - }; - "/var/lib/acme" = { - device = "/srv/acme"; - options = ["bind"]; - }; - "/var/lib/postgresql" = { - device = "/srv/postgresql"; - options = ["bind"]; - }; - }; - }; -} diff --git a/system/impermanence/default.nix b/system/impermanence/default.nix new file mode 100644 index 0000000..198eeba --- /dev/null +++ b/system/impermanence/default.nix @@ -0,0 +1,23 @@ +{...}: { + # TODO: Only activate them if their module is also active + imports = [ + ./mods/acme.nix + ./mods/keycloak.nix + ./mods/mail.nix + ./mods/minecraft.nix + ./mods/nix-sync.nix + ./mods/openssh.nix + ./mods/users.nix + ]; + + environment.persistence."/srv" = { + hideMounts = true; + directories = [ + "/etc/nixos" + "/var/log" + ]; + files = [ + "/etc/machine-id" + ]; + }; +} diff --git a/system/impermanence/mods/acme.nix b/system/impermanence/mods/acme.nix new file mode 100644 index 0000000..b16171e --- /dev/null +++ b/system/impermanence/mods/acme.nix @@ -0,0 +1,5 @@ +{...}: { + environment.persistence."/srv".directories = [ + "/var/lib/acme" + ]; +} diff --git a/system/impermanence/mods/fail2ban.nix b/system/impermanence/mods/fail2ban.nix new file mode 100644 index 0000000..a817876 --- /dev/null +++ b/system/impermanence/mods/fail2ban.nix @@ -0,0 +1,10 @@ +{...}: { + environment.persistence."/srv".directories = [ + { + directory = "/var/lib/fail2ban"; + user = "fail2ban"; + group = "fail2ban"; + mode = "0700"; + } + ]; +} diff --git a/system/impermanence/mods/keycloak.nix b/system/impermanence/mods/keycloak.nix new file mode 100644 index 0000000..63b02f5 --- /dev/null +++ b/system/impermanence/mods/keycloak.nix @@ -0,0 +1,5 @@ +{...}: { + environment.persistence."/srv".directories = [ + "/var/lib/postgresql" + ]; +} diff --git a/system/impermanence/mods/mail.nix b/system/impermanence/mods/mail.nix new file mode 100644 index 0000000..18151ad --- /dev/null +++ b/system/impermanence/mods/mail.nix @@ -0,0 +1,34 @@ +{...}: { + environment.persistence."/srv".directories = [ + { + directory = "/var/lib/mail/backup"; + user = "virtualMail"; + group = "virtualMail"; + mode = "0700"; + } + { + directory = "/var/lib/mail/sieve"; + user = "virtualMail"; + group = "virtualMail"; + mode = "0700"; + } + { + directory = "/var/lib/mail/vmail"; + user = "virtualMail"; + group = "virtualMail"; + mode = "0700"; + } + { + directory = "/var/lib/mail/dkim"; + user = "opendkim"; + group = "opendkim"; + mode = "0700"; + } + { + directory = "/var/lib/rspamd"; + user = "rspamd"; + group = "rspamd"; + mode = "0700"; + } + ]; +} diff --git a/system/impermanence/mods/minecraft.nix b/system/impermanence/mods/minecraft.nix new file mode 100644 index 0000000..2a02626 --- /dev/null +++ b/system/impermanence/mods/minecraft.nix @@ -0,0 +1,10 @@ +{...}: { + environment.persistence."/srv".directories = [ + { + directory = "/var/lib/minecraft"; + user = "minecraft"; + group = "minecraft"; + mode = "0700"; + } + ]; +} diff --git a/system/impermanence/mods/nix-sync.nix b/system/impermanence/mods/nix-sync.nix new file mode 100644 index 0000000..11449ea --- /dev/null +++ b/system/impermanence/mods/nix-sync.nix @@ -0,0 +1,10 @@ +{...}: { + environment.persistence."/srv".directories = [ + { + directory = "/var/lib/nix-sync"; + user = "nix-sync"; + group = "nix-sync"; + mode = "0700"; + } + ]; +} diff --git a/system/impermanence/mods/openssh.nix b/system/impermanence/mods/openssh.nix new file mode 100644 index 0000000..0373a83 --- /dev/null +++ b/system/impermanence/mods/openssh.nix @@ -0,0 +1,21 @@ +{...}: { + /* + FIXME: + This results in a boot error, as the `/var/lib/sshd` directory is only mounted _after_ the stage 2 init and with it the system activation. + Agenix needs the sshd hostkey however to decrypt the secrets and such we have to ensure that this directory is mounted _before_ the system activation. + Alas the only way I see to achieve that is to store the ssh hostkey directly on /srv, which is mounted before (it's marked as 'neededForBoot' after all). + + It should be possible to achieve this with impermanence however, as `/var/log` is mounted in the stage 1 init; The problem is that I have no idea _why_ only + this is mounted and nothing else. + + + environment.persistence."/srv".directories = [ + { + directory = "/var/lib/sshd"; + user = "root"; + group = "root"; + mode = "0755"; + } + ]; + */ +} diff --git a/system/impermanence/mods/users.nix b/system/impermanence/mods/users.nix new file mode 100644 index 0000000..0692b00 --- /dev/null +++ b/system/impermanence/mods/users.nix @@ -0,0 +1,28 @@ +{...}: { + environment.persistence."/srv".directories = [ + { + directory = "/home"; + user = "root"; + group = "root"; + mode = "0755"; + } + { + directory = "/home/sils"; + user = "sils"; + group = "sils"; + mode = "0700"; + } + { + directory = "/home/soispha"; + user = "soispha"; + group = "soispha"; + mode = "0700"; + } + { + directory = "/home/nightingale"; + user = "nightingale"; + group = "nightingale"; + mode = "0700"; + } + ]; +} diff --git a/system/mail/default.nix b/system/mail/default.nix deleted file mode 100644 index 1086f6e..0000000 --- a/system/mail/default.nix +++ /dev/null @@ -1,40 +0,0 @@ -# vim: ts=2 -{lib, ...}: let - all_admins = [ - "sils@vhack.eu" - "soispha@vhack.eu" - "nightingale@vhack.eu" - ]; - users = import ./users.nix {}; -in - lib.recursiveUpdate { - enable = true; - fqdn = "server1.vhack.eu"; - - useFsLayout = true; - - extraVirtualAliases = { - "abuse@vhack.eu" = all_admins; - "postmaster@vhack.eu" = all_admins; - "admin@vhack.eu" = all_admins; - }; - - mailDirectory = "/srv/mail/vmail"; - dkimKeyDirectory = "/srv/mail/dkim"; - sieveDirectory = "/srv/mail/sieve"; - backup.snapshotRoot = "/srv/mail/backup"; - - enableImap = false; - enableImapSsl = true; - enablePop3 = false; - enablePop3Ssl = true; - # SMTP - enableSubmission = false; - enableSubmissionSsl = true; - openFirewall = true; - - keyFile = "/var/lib/acme/server1.vhack.eu/key.pem"; - certificateScheme = "acme"; - certificateFile = "/var/lib/acme/server1.vhack.eu/fullchain.pem"; - } - users diff --git a/system/secrets/default.nix b/system/secrets/default.nix new file mode 100644 index 0000000..3d92fe8 --- /dev/null +++ b/system/secrets/default.nix @@ -0,0 +1,12 @@ +{...}: { + age = { + secrets = { + keycloak = { + file = ./keycloak/passwd.tix; + mode = "700"; + owner = "root"; + group = "root"; + }; + }; + }; +} diff --git a/system/secrets/keycloak/passwd.tix b/system/secrets/keycloak/passwd.tix new file mode 100644 index 0000000..b5c36cd --- /dev/null +++ b/system/secrets/keycloak/passwd.tix @@ -0,0 +1,17 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGeFZ2Uk10Z1lrNUV6SWtu +UFZLVFR2dWJsMnNZTkE0Q3loa1c0c3ZwTjJvCjhHcm9XVk1jWENYNG5VNVV2RlZp +SVZROEFrU2tNV1dDYmNOdmEzanoyd2sKLT4gWDI1NTE5IHFOTEhFUUtGOWMzWjVO +MGs2a0tsYlZSZGI3NXdBRktKNDgxdzRmQTI1emsKeVJzbHJhR3h5NDVwM2pqcFFW +UzROY2toa0ZBL1p2elRmeHdUTFNhRm91bwotPiBzc2gtZWQyNTUxOSBPRDhUNGcg +NG42WHBrcVh0cjJYKzMwR3FkTHN0VTZUY0xyZVQvMjR3azdtZ0V4M0dpRQpxSzlj +anVRVndxdWhaQldZeHJ0WVFCNzZJMHFnaG5KRDRQa003enoyME1FCi0+ICZ2LjlB +SS1ncmVhc2Ugfj51dWUyIG5XOExyNmR2IFNVdmkKK3QwSmRRCi0tLSBqb3FPRWtV +dUdLcWV4R1VnOGZmNGxBY0dVbTRZN094V0dIeWpZTWp1V1QwCpu/WQunSMxbtxwz +uiFrDcdAa3H3+2gIFHmktFbHZX9XNC2ri99G7nqQ9SoBvnpRFhhAiw0LSWnq2lqr +rMQeug/z0sooWO6R2H17aLHXwxz82Spm7eUlc3nMz243U0SChz7OnPDgHBgLztqJ +3zOMub3inn83jR7Pg+GjEuI26tqZUp6107CKzvBWI8ePsa7MW19UdmEVplewxrDq +fjNsmid3+NNJ0LjC3gGUppHtTJW9ikTvaDMtS5Ysn94JoS6xRzVgE2LBswGBiQBJ +ZDV+9het3ijDyljk3pjPRDKoWPEctT/cWLczEMK5vHqVt3pr/IAWqJTfXVkebP6Q +6QdZrUKl/xxKmApVRx9K0wQAhfwlKKTHpW3hFFNivZtSg0hSaF4= +-----END AGE ENCRYPTED FILE----- diff --git a/system/secrets/secrets.nix b/system/secrets/secrets.nix new file mode 100644 index 0000000..cdaf50d --- /dev/null +++ b/system/secrets/secrets.nix @@ -0,0 +1,12 @@ +let + soispha = "age1mshh4ynzhhzhff25tqwkg4j054g3xwrfznh98ycchludj9wjj48qn2uffn"; + sils = "age1vuhaey7kd9l76y6f9weeqmde3s4kjw38869ju6u3027yece2r3rqssjxst"; + + server1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMnqsfIZjelH7rcvFvnLR5zUZuC8thsBupBlvjcMRBUm"; +in { + "keycloak/passwd.tix".publicKeys = [ + soispha + sils + server1 + ]; +} diff --git a/system/services/acme/default.nix b/system/services/acme/default.nix deleted file mode 100644 index 0a0c4ce..0000000 --- a/system/services/acme/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -{lib, ...}: let - domains = import ./domains.nix {}; - - virtualHosts = builtins.listToAttrs ( - builtins.map (domain_name: { - name = "acmechallenge.${domain_name}"; - value = { - serverAliases = ["*.${domain_name}"]; - locations."/.well-known/acme-challenge" = { - root = "/var/lib/acme/.challenges"; - }; - locations."/" = { - return = "301 https://$host$request_uri"; - }; - }; - }) - domains - ); - certs = lib.attrsets.genAttrs domains ( - domain_name: { - webroot = "/var/lib/acme/.challenges"; - group = "nginx"; - } - ); -in { - users.users.nginx.extraGroups = ["acme"]; - - services.nginx = { - enable = true; - inherit virtualHosts; - }; - - security.acme = { - acceptTerms = true; - defaults.email = "admin@vhack.eu"; - inherit certs; - }; -} diff --git a/system/services/acme/domains.nix b/system/services/acme/domains.nix deleted file mode 100644 index 8f0930d..0000000 --- a/system/services/acme/domains.nix +++ /dev/null Binary files differdiff --git a/system/services/default.nix b/system/services/default.nix index 19a531f..7bf26c3 100644 --- a/system/services/default.nix +++ b/system/services/default.nix @@ -1,14 +1,14 @@ {...}: { imports = [ - ./acme + ./fail2ban ./keycloak + ./mail ./matrix ./minecraft ./nginx ./nix - ./opensshd + ./nix-sync + ./openssh ./rust-motd - ./fail2ban - ./git-sync ]; } diff --git a/system/services/fail2ban/default.nix b/system/services/fail2ban/default.nix index 5aee097..43fd674 100644 --- a/system/services/fail2ban/default.nix +++ b/system/services/fail2ban/default.nix @@ -1,4 +1,3 @@ -# vim: ts=2 {...}: { services.fail2ban = { enable = true; @@ -8,7 +7,7 @@ logtarget = SYSLOG socket = /run/fail2ban/fail2ban.sock pidfile = /run/fail2ban/fail2ban.pid - dbfile = /srv/fail2ban/fail2ban.sqlite3 + dbfile = /var/lib/fail2ban/db.sqlite3 ''; bantime-increment = { enable = true; diff --git a/system/services/git-sync/default.nix b/system/services/git-sync/default.nix deleted file mode 100644 index 776ca60..0000000 --- a/system/services/git-sync/default.nix +++ /dev/null @@ -1,104 +0,0 @@ -/* -Taken from: -https://github.com/nix-community/home-manager/blob/9ba7b3990eb1f4782ea3f5fe7ac4f3c88dd7a32c/modules/services/git-sync.nix -*/ -{ - config, - lib, - pkgs, - ... -}: let - cfg = config.services.git-sync; - - mkUnit = name: repo: { - Unit.Description = "Git Sync ${name}"; - - Install.WantedBy = ["default.target"]; - - Service = { - Environment = [ - "PATH=${lib.makeBinPath (with pkgs; [openssh git])}" - "GIT_SYNC_DIRECTORY=${repo.path}" - "GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync" - "GIT_SYNC_REPOSITORY=${repo.uri}" - "GIT_SYNC_INTERVAL=${toString repo.interval}" - ]; - ExecStart = "${cfg.package}/bin/git-sync-on-inotify"; - Restart = "on-abort"; - }; - }; - - services = - lib.mapAttrs' (name: repo: { - name = "git-sync-${name}"; - value = mkUnit name repo; - }) - cfg.repositories; - - repositoryType = lib.types.submodule ({name, ...}: { - options = { - name = lib.mkOption { - internal = true; - default = name; - type = lib.types.str; - description = "The name that should be given to this unit."; - }; - - path = lib.mkOption { - type = lib.types.path; - description = "The path at which to sync the repository"; - }; - - uri = lib.mkOption { - type = lib.types.str; - example = "git+ssh://user@example.com:/~[user]/path/to/repo.git"; - description = '' - The URI of the remote to be synchronized. This is only used in the - event that the directory does not already exist. See - <link xlink:href="https://git-scm.com/docs/git-clone#_git_urls"/> - for the supported URIs. - ''; - }; - - interval = lib.mkOption { - type = lib.types.int; - default = 500; - description = '' - The interval, specified in seconds, at which the synchronization will - be triggered even without filesystem changes. - ''; - }; - }; - }); -in { - options = { - services.git-sync = { - enable = lib.mkEnableOption "git-sync services"; - - package = lib.mkOption { - type = lib.types.package; - default = pkgs.git-sync; - defaultText = lib.literalExpression "pkgs.git-sync"; - description = '' - Package containing the <command>git-sync</command> program. - ''; - }; - - repositories = lib.mkOption { - type = with lib.types; attrsOf repositoryType; - description = '' - The repositories that should be synchronized. - ''; - }; - }; - }; - - config = lib.mkIf cfg.enable { - assertions = [ - (lib.hm.assertions.assertPlatform "services.git-sync" pkgs - lib.platforms.linux) - ]; - - systemd.user.services = services; - }; -} diff --git a/system/services/keycloak/default.nix b/system/services/keycloak/default.nix index dfeabc3..5f21b90 100644 --- a/system/services/keycloak/default.nix +++ b/system/services/keycloak/default.nix @@ -31,7 +31,7 @@ createLocally = true; username = "keycloak"; - passwordFile = "/srv/keycloak/password"; + passwordFile = "${config.age.secrets.keycloak.path}"; }; settings = { diff --git a/system/services/mail/default.nix b/system/services/mail/default.nix new file mode 100644 index 0000000..382a87f --- /dev/null +++ b/system/services/mail/default.nix @@ -0,0 +1,41 @@ +{lib, ...}: let + all_admins = [ + "sils@vhack.eu" + "soispha@vhack.eu" + "nightingale@vhack.eu" + ]; + users = import ./users.nix {}; +in { + mailserver = + lib.recursiveUpdate { + enable = true; + fqdn = "server1.vhack.eu"; + + useFsLayout = true; + + extraVirtualAliases = { + "abuse@vhack.eu" = all_admins; + "postmaster@vhack.eu" = all_admins; + "admin@vhack.eu" = all_admins; + }; + + mailDirectory = "/var/lib/mail/vmail"; + dkimKeyDirectory = "/var/lib/mail/dkim"; + sieveDirectory = "/var/lib/mail/sieve"; + backup.snapshotRoot = "/var/lib/mail/backup"; + + enableImap = false; + enableImapSsl = true; + enablePop3 = false; + enablePop3Ssl = true; + # SMTP + enableSubmission = false; + enableSubmissionSsl = true; + openFirewall = true; + + keyFile = "/var/lib/acme/server1.vhack.eu/key.pem"; + certificateScheme = "acme"; + certificateFile = "/var/lib/acme/server1.vhack.eu/fullchain.pem"; + } + users; +} diff --git a/system/mail/users.nix b/system/services/mail/users.nix index f3264a1..f3264a1 100644 --- a/system/mail/users.nix +++ b/system/services/mail/users.nix Binary files differdiff --git a/system/services/matrix/default.nix b/system/services/matrix/default.nix index d49fda2..e35c129 100644 --- a/system/services/matrix/default.nix +++ b/system/services/matrix/default.nix @@ -55,7 +55,6 @@ in { enable = true; dataDir = "/srv/matrix/data"; configFile = "/srv/matrix"; - extraConfigFiles = ["/srv/matrix/oid/config.yaml"]; settings = { media_store_path = "/srv/matrix/media_store"; server_name = "vhack.eu"; diff --git a/system/services/minecraft/default.nix b/system/services/minecraft/default.nix index e69ffb1..e659af0 100644 --- a/system/services/minecraft/default.nix +++ b/system/services/minecraft/default.nix @@ -7,7 +7,7 @@ enable = true; declarative = true; eula = true; - dataDir = "/srv/minecraft"; + dataDir = "/var/lib/minecraft"; openFirewall = true; jvmOpts = "-Xmx8192M -Xms8192M"; whitelist = { diff --git a/system/services/nginx/default.nix b/system/services/nginx/default.nix index 6753fb0..404c167 100644 --- a/system/services/nginx/default.nix +++ b/system/services/nginx/default.nix @@ -2,6 +2,14 @@ imports = [ ./hosts.nix ]; + security.acme = { + acceptTerms = true; + defaults = { + email = "admin@vhack.eu"; + webroot = "/var/lib/acme/acme-challenge"; + }; + }; + networking.firewall = { allowedTCPPorts = [80 443]; }; diff --git a/system/services/nginx/hosts.nix b/system/services/nginx/hosts.nix index 684bb68..1590756 100644 --- a/system/services/nginx/hosts.nix +++ b/system/services/nginx/hosts.nix Binary files differdiff --git a/system/services/nix-sync/default.nix b/system/services/nix-sync/default.nix new file mode 100644 index 0000000..44348c0 --- /dev/null +++ b/system/services/nix-sync/default.nix @@ -0,0 +1,262 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.services.nix-sync; + + mkTimer = name: repo: { + description = "Nix sync ${name} timer"; + wantedBy = ["timers.target"]; + timerConfig = { + OnActiveSec = repo.interval; + }; + after = ["network-online.target"]; + }; + + parents = path: let + split_path = builtins.split "/" path; + filename = builtins.elemAt split_path (builtins.length split_path - 1); + in + lib.strings.removeSuffix "/" (builtins.replaceStrings [filename] [""] path); + esa = lib.strings.escapeShellArg; + mkUnit = name: repo: let + optionalPathSeparator = + if lib.strings.hasPrefix "/" repo.path + then "" + else "/"; + repoCachePath = cfg.cachePath + optionalPathSeparator + repo.path; + execStartScript = pkgs.writeScript "nix-sync-exec" '' + #! /usr/bin/env dash + export XDG_CACHE_HOME="$CACHE_DIRECTORY"; + cd ${esa repoCachePath}; + + git fetch + origin="$(git rev-parse @{u})"; + branch="$(git rev-parse @)"; + + if ! [ "$origin" = "$branch" ]; then + git pull; + + out_paths=$(mktemp); + nix build . --print-out-paths --experimental-features 'nix-command flakes' > "$out_paths"; + [ "$(wc -l < "$out_paths")" -gt 1 ] && (echo "To many out-paths"; exit 1) + out_path="$(cat "$out_paths")"; + rm ${esa repo.path}; + ln -s "$out_path" ${esa repo.path}; + rm "$out_paths"; + fi + ''; + execStartPreScript = '' + export XDG_CACHE_HOME="$CACHE_DIRECTORY"; + + if ! [ -d ${esa repoCachePath}/.git ]; then + mkdir --parents ${esa repoCachePath}; + git clone ${esa repo.uri} ${esa repoCachePath}; + + out_paths=$(mktemp); + nix build ${esa repoCachePath} --print-out-paths --experimental-features 'nix-command flakes' > "$out_paths"; + [ "$(wc -l < "$out_paths")" -gt 1 ] && (echo "To many out-paths"; exit 1) + out_path="$(cat "$out_paths")"; + ln -s "$out_path" ${esa repo.path}; + rm "$out_paths"; + fi + + if ! [ -L ${esa repo.path} ]; then + cd ${esa repoCachePath}; + + git pull; + + out_paths=$(mktemp); + nix build . --print-out-paths --experimental-features 'nix-command flakes' > "$out_paths"; + [ "$(wc -l < "$out_paths")" -gt 1 ] && (echo "To many out-paths"; exit 1) + out_path="$(cat "$out_paths")"; + + [ -d ${esa repo.path} ] && rm -d ${esa repo.path}; + [ -e ${esa repo.path} ] && rm ${esa repo.path}; + + ln -s "$out_path" ${esa repo.path}; + rm "$out_paths"; + fi + ''; + in { + description = "Nix Sync ${name}"; + wantedBy = ["default.target"]; + after = ["network.target"]; + path = with pkgs; [openssh git nix mktemp coreutils dash]; + preStart = execStartPreScript; + + serviceConfig = { + ExecStart = execStartScript; + Restart = "on-abort"; + # User and group + User = cfg.user; + Group = cfg.group; + # Runtime directory and mode + RuntimeDirectory = "nix-sync"; + RuntimeDirectoryMode = "0750"; + # Cache directory and mode + CacheDirectory = "nix-sync"; + CacheDirectoryMode = "0750"; + # Logs directory and mode + LogsDirectory = "nix-sync"; + LogsDirectoryMode = "0750"; + # Proc filesystem + ProcSubset = "all"; + ProtectProc = "invisible"; + # New file permissions + UMask = "0027"; # 0640 / 0750 + # Capabilities + AmbientCapabilities = ["CAP_CHOWN"]; + CapabilityBoundingSet = ["CAP_CHOWN"]; + # Security + NoNewPrivileges = true; + # Sandboxing (sorted by occurrence in https://www.freedesktop.org/software/systemd/man/systemd.exec.html) + ReadWritePaths = ["${esa (parents repo.path)}" "-${esa repoCachePath}" "-${esa cfg.cachePath}"]; + ReadOnlyPaths = ["/nix"]; + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictNamespaces = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + # System Call Filtering + SystemCallArchitectures = "native"; + SystemCallFilter = ["~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid"]; + }; + }; + + services = + lib.mapAttrs' (name: repo: { + name = "nix-sync-${name}"; + value = mkUnit name repo; + }) + cfg.repositories; + timers = + lib.mapAttrs' (name: repo: { + name = "nix-sync-${name}"; + value = mkTimer name repo; + }) + cfg.repositories; + + # generate the websites directory, so systemd can mount it read write + generatedDirectories = + lib.mapAttrsToList ( + _: repo: "d ${esa (parents repo.path)} 0755 ${cfg.user} ${cfg.group}" + ) + cfg.repositories; + + repositoryType = lib.types.submodule ({name, ...}: { + options = { + name = lib.mkOption { + internal = true; + default = name; + type = lib.types.str; + description = "The name that should be given to this unit."; + }; + + path = lib.mkOption { + type = lib.types.str; + description = "The path at which to sync the repository"; + }; + + uri = lib.mkOption { + type = lib.types.str; + example = "ssh://user@example.com:/~[user]/path/to/repo.git"; + description = '' + The URI of the remote to be synchronized. This is only used in the + event that the directory does not already exist. See + <link xlink:href="https://git-scm.com/docs/git-clone#_git_urls"/> + for the supported URIs. + ''; + }; + + interval = lib.mkOption { + type = lib.types.int; + default = 500; + description = '' + The interval, specified in seconds, at which the synchronization will + be triggered. + ''; + }; + }; + }); +in { + options = { + services.nix-sync = { + enable = lib.mkEnableOption "nix-sync services"; + + user = lib.mkOption { + type = lib.types.str; + default = "nix-sync"; + description = lib.mdDoc "User account under which nix-sync units runs."; + }; + + group = lib.mkOption { + type = lib.types.str; + default = "nix-sync"; + description = lib.mdDoc "Group account under which nix-sync units runs."; + }; + + cachePath = lib.mkOption { + type = lib.types.str; + default = "/var/lib/nix-sync"; + description = lib.mdDoc '' + Where to cache git directories. Should not end with a slash ("/") + ''; + }; + + repositories = lib.mkOption { + type = with lib.types; attrsOf repositoryType; + description = '' + The repositories that should be synchronized. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = !lib.strings.hasSuffix "/" cfg.cachePath; + message = "Your cachePath ('${cfg.cachePath}') ends with a slash ('/'), please use: '${lib.strings.removeSuffix "/" cfg.cachePath}'."; + } + ]; + + systemd.tmpfiles.rules = + generatedDirectories; + + systemd.services = services; + systemd.timers = timers; + users.users = + if cfg.user == "nix-sync" + then { + nix-sync = { + group = "${cfg.group}"; + isSystemUser = true; + }; + } + else lib.warnIf (cfg.user != "nix-sync") "The user (${cfg.user}) is not \"nix-sync\", thus you are responible for generating it."; + users.groups = + if cfg.group == "nix-sync" + then { + nix-sync = { + members = ["${cfg.user}"]; + }; + } + else lib.warnIf (cfg.group != "nix-sync") "The group (${cfg.group}) is not \"nix-sync\", thus you are responible for generating it."; + }; +} diff --git a/system/services/openssh/default.nix b/system/services/openssh/default.nix new file mode 100644 index 0000000..46b7ffd --- /dev/null +++ b/system/services/openssh/default.nix @@ -0,0 +1,17 @@ +{...}: { + services.openssh = { + enable = true; + settings.PasswordAuthentication = false; + hostKeys = [ + { + # See the explanation for this in /system/impermanence/mods/openssh.nix + # path = "/var/lib/sshd/ssh_host_ed25519_key"; + + # FIXME: Remove this workaround + path = "/srv/var/lib/sshd/ssh_host_ed25519_key"; + rounds = 1000; + type = "ed25519"; + } + ]; + }; +} diff --git a/system/services/opensshd/default.nix b/system/services/opensshd/default.nix deleted file mode 100644 index 1bb37ee..0000000 --- a/system/services/opensshd/default.nix +++ /dev/null @@ -1,13 +0,0 @@ -{...}: { - services.openssh = { - enable = true; - settings.PasswordAuthentication = false; - hostKeys = [ - { - path = "/srv/sshd/ssh_host_ed25519_key"; - rounds = 1000; - type = "ed25519"; - } - ]; - }; -} diff --git a/system/users/default.nix b/system/users/default.nix index 3555221..822c94b 100644 --- a/system/users/default.nix +++ b/system/users/default.nix @@ -1,56 +1,53 @@ {pkgs, ...}: { - users.mutableUsers = false; - users.defaultUserShell = pkgs.zsh; + users = { + mutableUsers = false; + defaultUserShell = pkgs.zsh; + users = { + root = { + initialHashedPassword = null; # to lock root + openssh.authorizedKeys.keys = []; + }; - users.users = { - root = { - #uid = 0; - initialHashedPassword = null; # to lock root - openssh.authorizedKeys.keys = [ - ]; - }; + sils = { + name = "sils"; + isNormalUser = true; + home = "/home/sils"; + initialHashedPassword = "$y$jFT$KpFnahVCE9JbE.5P3us8o.$ZzSxCusWqe3sL7b6DLgOXNNUf114tiiptM6T8lDxtKC"; + uid = 1000; + extraGroups = [ + "wheel" + ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG63gxw8JePmrC8Fni0pLV4TnPBhCPmSV9FYEdva+6s7 sils" + ]; + }; - sils = { - name = "sils"; - isNormalUser = true; - home = "/srv/home/sils"; - initialHashedPassword = "$y$jFT$KpFnahVCE9JbE.5P3us8o.$ZzSxCusWqe3sL7b6DLgOXNNUf114tiiptM6T8lDxtKC"; - uid = 1000; - extraGroups = [ - "wheel" - ]; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG63gxw8JePmrC8Fni0pLV4TnPBhCPmSV9FYEdva+6s7 sils" - ]; - }; + soispha = { + name = "soispha"; + isNormalUser = true; + home = "/home/soispha"; + initialHashedPassword = "$y$jFT$3.8XmUyukZvpExMUxDZkI.$IVrJgm8ysNDF/0vDD2kF6w73ozXgr1LMVRNN4Bq7pv1"; + uid = 1001; + extraGroups = [ + "wheel" + ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGBFuTNNn71Rhfnop2cdz3r/RhWWlCePnSBOhTBbu2ME soispha" + ]; + }; - soispha = { - name = "soispha"; - isNormalUser = true; - home = "/srv/home/soispha"; - initialHashedPassword = "$y$jFT$3.8XmUyukZvpExMUxDZkI.$IVrJgm8ysNDF/0vDD2kF6w73ozXgr1LMVRNN4Bq7pv1"; - uid = 1001; - extraGroups = [ - "wheel" - ]; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGBFuTNNn71Rhfnop2cdz3r/RhWWlCePnSBOhTBbu2ME soispha" - ]; - }; - - nightingale = { - name = "nightingale"; - isNormalUser = true; - home = "/srv/home/nightingale"; - initialHashedPassword = null; # TODO CHANGE - uid = 1002; - extraGroups = [ - "wheel" - ]; - openssh.authorizedKeys.keys = [ - ]; + nightingale = { + name = "nightingale"; + isNormalUser = true; + home = "/home/nightingale"; + initialHashedPassword = null; # TODO CHANGE + uid = 1002; + extraGroups = [ + "wheel" + ]; + openssh.authorizedKeys.keys = [ + ]; + }; }; }; } -# vim: ts=2 - |