summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.editorconfig16
-rw-r--r--.gitattributes3
-rw-r--r--CHANGELOG.md83
-rw-r--r--cog.toml1
-rw-r--r--flake.lock219
-rw-r--r--flake.nix73
-rw-r--r--hosts/server1/configuration.nix7
-rw-r--r--hosts/server1/hardware.nix1
-rw-r--r--notes/deploy.md6
-rw-r--r--system/default.nix6
-rw-r--r--system/disks/default.nix82
-rw-r--r--system/file_system_layouts/default.nix53
-rw-r--r--system/impermanence/default.nix23
-rw-r--r--system/impermanence/mods/acme.nix5
-rw-r--r--system/impermanence/mods/fail2ban.nix10
-rw-r--r--system/impermanence/mods/keycloak.nix5
-rw-r--r--system/impermanence/mods/mail.nix34
-rw-r--r--system/impermanence/mods/minecraft.nix10
-rw-r--r--system/impermanence/mods/nix-sync.nix10
-rw-r--r--system/impermanence/mods/openssh.nix21
-rw-r--r--system/impermanence/mods/users.nix28
-rw-r--r--system/mail/default.nix40
-rw-r--r--system/secrets/default.nix12
-rw-r--r--system/secrets/keycloak/passwd.tix17
-rw-r--r--system/secrets/secrets.nix12
-rw-r--r--system/services/acme/default.nix38
-rw-r--r--system/services/acme/domains.nixbin130 -> 0 bytes
-rw-r--r--system/services/default.nix8
-rw-r--r--system/services/fail2ban/default.nix3
-rw-r--r--system/services/git-sync/default.nix104
-rw-r--r--system/services/keycloak/default.nix2
-rw-r--r--system/services/mail/default.nix41
-rw-r--r--system/services/mail/users.nix (renamed from system/mail/users.nix)bin486 -> 486 bytes
-rw-r--r--system/services/matrix/default.nix1
-rw-r--r--system/services/minecraft/default.nix2
-rw-r--r--system/services/nginx/default.nix8
-rw-r--r--system/services/nginx/hosts.nixbin630 -> 976 bytes
-rw-r--r--system/services/nix-sync/default.nix262
-rw-r--r--system/services/openssh/default.nix17
-rw-r--r--system/services/opensshd/default.nix13
-rw-r--r--system/users/default.nix95
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 differ
diff --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 differ
diff --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 differ
diff --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
-