mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 14:50:40 +02:00
chore: update flake
This commit is contained in:
parent
2fece6e5cc
commit
3906586a95
13 changed files with 162 additions and 1242 deletions
|
@ -1,9 +1,4 @@
|
|||
{inputs, ...}: {
|
||||
disabledModules = [
|
||||
"services/security/kanidm.nix"
|
||||
"services/networking/netbird.nix"
|
||||
];
|
||||
|
||||
# Not setting this causes infinite recursion because it has a very weird default.
|
||||
# The default should probably be removed upstream and only applied with mkDefault
|
||||
# if hardware.nvidia.enable is true
|
||||
|
|
260
flake.lock
generated
260
flake.lock
generated
|
@ -28,11 +28,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722339003,
|
||||
"narHash": "sha256-ZeS51uJI30ehNkcZ4uKqT4ZDARPyqrHADSKAwv5vVCU=",
|
||||
"lastModified": 1723293904,
|
||||
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"rev": "3f1dae074a12feb7327b4bf43cbac0d124488bb7",
|
||||
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -371,7 +371,7 @@
|
|||
},
|
||||
"devshell_6": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_9",
|
||||
"flake-utils": "flake-utils_10",
|
||||
"nixpkgs": [
|
||||
"whisper-overlay",
|
||||
"nixpkgs"
|
||||
|
@ -398,11 +398,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722476845,
|
||||
"narHash": "sha256-7gZ8uf3qOox8Vrwd+p9EhUHHLhhK8lis/5KcXGmIaow=",
|
||||
"lastModified": 1725377834,
|
||||
"narHash": "sha256-tqoAO8oT6zEUDXte98cvA1saU9+1dLJQe3pMKLXv8ps=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "7e1b215a0a96efb306ad6440bf706d2b307dc267",
|
||||
"rev": "e55f9a8678adc02024a4877c2a403e3f6daf24fe",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -644,11 +644,11 @@
|
|||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722555600,
|
||||
"narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
|
||||
"lastModified": 1725234343,
|
||||
"narHash": "sha256-+ebgonl3NbiKD2UD0x4BszCZQ6sTfL4xioaM49o5B3Y=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
|
||||
"rev": "567b938d64d4b4112ee253b9274472dc3a346eb6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -662,11 +662,11 @@
|
|||
"nixpkgs-lib": "nixpkgs-lib_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722555600,
|
||||
"narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
|
||||
"lastModified": 1725234343,
|
||||
"narHash": "sha256-+ebgonl3NbiKD2UD0x4BszCZQ6sTfL4xioaM49o5B3Y=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
|
||||
"rev": "567b938d64d4b4112ee253b9274472dc3a346eb6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -719,11 +719,11 @@
|
|||
"nixpkgs-lib": "nixpkgs-lib_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719745305,
|
||||
"narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
|
||||
"lastModified": 1719994518,
|
||||
"narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
|
||||
"rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -750,6 +750,24 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_10": {
|
||||
"inputs": {
|
||||
"systems": "systems_13"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_4"
|
||||
|
@ -878,14 +896,17 @@
|
|||
},
|
||||
"flake-utils_9": {
|
||||
"inputs": {
|
||||
"systems": "systems_12"
|
||||
"systems": [
|
||||
"stylix",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -927,11 +948,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1721042469,
|
||||
"narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=",
|
||||
"lastModified": 1724857454,
|
||||
"narHash": "sha256-Qyl9Q4QMTLZnnBb/8OuQ9LSkzWjBU1T5l5zIzTxkkhk=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "f451c19376071a90d8c58ab1a953c6e9840527fd",
|
||||
"rev": "4509ca64f1084e73bc7a721b20c669a8d4c5ebe6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1139,11 +1160,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722630065,
|
||||
"narHash": "sha256-QfM/9BMRkCmgWzrPDK+KbgJOUlSJnfX4OvsUupEUZvA=",
|
||||
"lastModified": 1725180166,
|
||||
"narHash": "sha256-fzssXuGR/mCeGbzM1ExaTqDz7QDGta3WA4jJsZyRruo=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "afc892db74d65042031a093adb6010c4c3378422",
|
||||
"rev": "471e3eb0a114265bcd62d11d58ba8d3421ee68eb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1160,11 +1181,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722630065,
|
||||
"narHash": "sha256-QfM/9BMRkCmgWzrPDK+KbgJOUlSJnfX4OvsUupEUZvA=",
|
||||
"lastModified": 1724435763,
|
||||
"narHash": "sha256-UNky3lJNGQtUEXT2OY8gMxejakSWPTfWKvpFkpFlAfM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "afc892db74d65042031a093adb6010c4c3378422",
|
||||
"rev": "c2cd2a52e02f1dfa1c88f95abeb89298d46023be",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1183,11 +1204,11 @@
|
|||
"pre-commit-hooks": "pre-commit-hooks_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722815593,
|
||||
"narHash": "sha256-GJkmvEyLHxvNWNAXOuptP8QNMkTsm9VH+JBcTx5pSHA=",
|
||||
"lastModified": 1725631023,
|
||||
"narHash": "sha256-TjZYW9XURpKHwOanUs1vEfgZbOP6e3Pvb+c5KA4/SFg=",
|
||||
"owner": "oddlama",
|
||||
"repo": "idmail",
|
||||
"rev": "a26d3a21962396e26d1f7891938229a0cce34ba9",
|
||||
"rev": "f0190ff0a777752039e5b4404e59d98651e6c41a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1198,11 +1219,11 @@
|
|||
},
|
||||
"impermanence": {
|
||||
"locked": {
|
||||
"lastModified": 1719091691,
|
||||
"narHash": "sha256-AxaLX5cBEcGtE02PeGsfscSb/fWMnyS7zMWBXQWDKbE=",
|
||||
"lastModified": 1724489415,
|
||||
"narHash": "sha256-ey8vhwY/6XCKoh7fyTn3aIQs7WeYSYtLbYEG87VCzX4=",
|
||||
"owner": "nix-community",
|
||||
"repo": "impermanence",
|
||||
"rev": "23c1f06316b67cb5dabdfe2973da3785cfe9c34a",
|
||||
"rev": "c7f5b394397398c023000cf843986ee2571a1fd7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1234,11 +1255,11 @@
|
|||
"spectrum": "spectrum"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722696400,
|
||||
"narHash": "sha256-8bz0+XpjGgio5Bjte0PWsYRArVR2godIBoArly0D+HU=",
|
||||
"lastModified": 1725388988,
|
||||
"narHash": "sha256-hjO/ZpmaXUHUzTSefzbj0Bosj6inFHRplbb+YqQQULc=",
|
||||
"owner": "astro",
|
||||
"repo": "microvm.nix",
|
||||
"rev": "dc326ff7fa41aa5cc210b99617743bbc51275924",
|
||||
"rev": "d52082cc2668b8cd788e3133526c8693ee71f6a5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1274,11 +1295,11 @@
|
|||
"treefmt": "treefmt"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722751969,
|
||||
"narHash": "sha256-cl4M94gy6Qd4lFfygeNhCyhSBGG0XCLqd8UfMxyGPvU=",
|
||||
"lastModified": 1725603283,
|
||||
"narHash": "sha256-eOyl4yoauBYOl73LUFt8TM3c1b3ThwqCRVt3Xtflwb4=",
|
||||
"owner": "yusdacra",
|
||||
"repo": "nix-cargo-integration",
|
||||
"rev": "deac3b762f1de75571dadfaa36c44f365a1006e3",
|
||||
"rev": "24027f551d04ba6f709b37e5045beb0a10b6d4e6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1295,11 +1316,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722609272,
|
||||
"narHash": "sha256-Kkb+ULEHVmk07AX+OhwyofFxBDpw+2WvsXguUS2m6e4=",
|
||||
"lastModified": 1724561770,
|
||||
"narHash": "sha256-zv8C9RNa86CIpyHwPIVO/k+5TfM8ZbjGwOOpTe1grls=",
|
||||
"owner": "lnl7",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "f7142b8024d6b70c66fd646e1d099d3aa5bfec49",
|
||||
"rev": "ac5694a0b855a981e81b4d9f14052e3ff46ca39e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1315,11 +1336,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722740924,
|
||||
"narHash": "sha256-UQPgA5d8azLZuDHZMPmvDszhuKF1Ek89SrTRtqsQ4Ss=",
|
||||
"lastModified": 1725161148,
|
||||
"narHash": "sha256-WfAHq3Ag3vLNFfWxKHjFBFdPI6JIideWFJod9mx1eoo=",
|
||||
"owner": "Mic92",
|
||||
"repo": "nix-index-database",
|
||||
"rev": "97ca0a0fca0391de835f57e44f369a283e37890f",
|
||||
"rev": "32058e9138248874773630c846563b1a78ee7a5b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1338,11 +1359,11 @@
|
|||
"pre-commit-hooks": "pre-commit-hooks_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722338736,
|
||||
"narHash": "sha256-bSnWgJ7eXgHZ/pwL7+NTDGfOzsbOiw899BV3k7TawWE=",
|
||||
"lastModified": 1725483443,
|
||||
"narHash": "sha256-WzOlGMKV/51Fccn/OMHcm5yrqgbOJZrJIy1ya4pW0u8=",
|
||||
"owner": "oddlama",
|
||||
"repo": "nix-topology",
|
||||
"rev": "870dcc9074077a327220b36597098c295944a47d",
|
||||
"rev": "8738d94670265beb166954c4e3a26e432f79f68c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1353,11 +1374,11 @@
|
|||
},
|
||||
"nixlib": {
|
||||
"locked": {
|
||||
"lastModified": 1722128034,
|
||||
"narHash": "sha256-L8rwzYPsLo/TYtydPJoQyYOfetuiyQYnTWYcyB8UE/s=",
|
||||
"lastModified": 1725152544,
|
||||
"narHash": "sha256-Tm344cnFM9f2YZsgWtJduvhIrvLr3Bi8J4Xc+UZDKYE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "d15f6f6021693898fcd2c6a9bb13707383da9bbc",
|
||||
"rev": "7f0b9e4fbd91826cb9ce6babbc11c87903191051",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1398,11 +1419,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722214420,
|
||||
"narHash": "sha256-qfHC1p5hcErGcE672/KhBkyWYloekQpqIxtcbcUVYkA=",
|
||||
"lastModified": 1725497951,
|
||||
"narHash": "sha256-fayKyVs/9FQdYH+3SCOkQM1GCsEPPVE+lSiVGlYQ7i0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-generators",
|
||||
"rev": "75cbb2a5e19c18840d105a72d036c6c92fc46c5d",
|
||||
"rev": "15a07ebf4a041bf232026263f1f96f2af390f3bc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1413,11 +1434,11 @@
|
|||
},
|
||||
"nixos-hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1722332872,
|
||||
"narHash": "sha256-2xLM4sc5QBfi0U/AANJAW21Bj4ZX479MHPMPkB+eKBU=",
|
||||
"lastModified": 1725477728,
|
||||
"narHash": "sha256-ahej1VRqKmWbG7gewty+GlrSBEeGY/J2Zy8Nt8+3fdg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "14c333162ba53c02853add87a0000cbd7aa230c2",
|
||||
"rev": "880be1ab837e1e9fe0449dae41ac4d034694d4ce",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1449,11 +1470,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1722421184,
|
||||
"narHash": "sha256-/DJBI6trCeVnasdjUo9pbnodCLZcFqnVZiLUfqLH4jA=",
|
||||
"lastModified": 1725432240,
|
||||
"narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9f918d616c5321ad374ae6cb5ea89c9e04bf3e58",
|
||||
"rev": "ad416d066ca1222956472ab7d0555a6946746a80",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1465,26 +1486,26 @@
|
|||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1722555339,
|
||||
"narHash": "sha256-uFf2QeW7eAHlYXuDktm9c25OxOyCoUOQmh5SZ9amE5Q=",
|
||||
"lastModified": 1725233747,
|
||||
"narHash": "sha256-Ss8QWLXdr2JCBPcYChJhz4xJm+h/xjl4G0c0XlP6a74=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib_2": {
|
||||
"locked": {
|
||||
"lastModified": 1722555339,
|
||||
"narHash": "sha256-uFf2QeW7eAHlYXuDktm9c25OxOyCoUOQmh5SZ9amE5Q=",
|
||||
"lastModified": 1725233747,
|
||||
"narHash": "sha256-Ss8QWLXdr2JCBPcYChJhz4xJm+h/xjl4G0c0XlP6a74=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib_3": {
|
||||
|
@ -1501,14 +1522,14 @@
|
|||
},
|
||||
"nixpkgs-lib_4": {
|
||||
"locked": {
|
||||
"lastModified": 1717284937,
|
||||
"narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=",
|
||||
"lastModified": 1719876945,
|
||||
"narHash": "sha256-Fm2rDDs86sHy0/1jxTOKB1118Q0O3Uc7EC0iXvXKpbI=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
|
@ -1625,11 +1646,11 @@
|
|||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1722630782,
|
||||
"narHash": "sha256-hMyG9/WlUi0Ho9VkRrrez7SeNlDzLxalm9FwY7n/Noo=",
|
||||
"lastModified": 1725432240,
|
||||
"narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d04953086551086b44b6f3c6b7eeb26294f207da",
|
||||
"rev": "ad416d066ca1222956472ab7d0555a6946746a80",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1670,11 +1691,11 @@
|
|||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722763580,
|
||||
"narHash": "sha256-LgYIYkNYzqCldWJ/xJRQ156WDp6P9hHb4EsIXsRa+u4=",
|
||||
"lastModified": 1725478117,
|
||||
"narHash": "sha256-Ly0DgmYniwBtQ+3aW4JO9ETJq9nbPemlISxC6MEDyB8=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixvim",
|
||||
"rev": "6f7cf23b226ceaee0a2d479c505652065dfe526f",
|
||||
"rev": "2ef974182ef62a6a6992118f0beb54dce812ae9b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1692,11 +1713,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722493084,
|
||||
"narHash": "sha256-ktjl908zZKWcGdMyz6kX1kHSg7LFFGPYBvTi9FgQleM=",
|
||||
"lastModified": 1724584782,
|
||||
"narHash": "sha256-7FfHv7b1jwMPSu9SPY9hdxStk8E6EeSwzqdvV69U4BM=",
|
||||
"owner": "NuschtOS",
|
||||
"repo": "search",
|
||||
"rev": "3f5abffa5f28b4ac3c9212c81c5e8d2d22876071",
|
||||
"rev": "5a08d691de30b6fc28d58ce71a5e420f2694e087",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1714,11 +1735,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722555600,
|
||||
"narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
|
||||
"lastModified": 1725234343,
|
||||
"narHash": "sha256-+ebgonl3NbiKD2UD0x4BszCZQ6sTfL4xioaM49o5B3Y=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
|
||||
"rev": "567b938d64d4b4112ee253b9274472dc3a346eb6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1794,11 +1815,11 @@
|
|||
"nixpkgs-stable": "nixpkgs-stable_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1721042469,
|
||||
"narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=",
|
||||
"lastModified": 1725513492,
|
||||
"narHash": "sha256-tyMUA6NgJSvvQuzB7A1Sf8+0XCHyfSPRx/b00o6K0uo=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "f451c19376071a90d8c58ab1a953c6e9840527fd",
|
||||
"rev": "7570de7b9b504cfe92025dd1be797bf546f66528",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1873,11 +1894,11 @@
|
|||
"nixpkgs-stable": "nixpkgs-stable_6"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1721042469,
|
||||
"narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=",
|
||||
"lastModified": 1725513492,
|
||||
"narHash": "sha256-tyMUA6NgJSvvQuzB7A1Sf8+0XCHyfSPRx/b00o6K0uo=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "f451c19376071a90d8c58ab1a953c6e9840527fd",
|
||||
"rev": "7570de7b9b504cfe92025dd1be797bf546f66528",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -2024,11 +2045,11 @@
|
|||
"rust-overlay_2": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1722738111,
|
||||
"narHash": "sha256-cWD5pCs9AYb+512/yCx9D0Pl5KcmyuXHeJpsDw/D1vs=",
|
||||
"lastModified": 1725589472,
|
||||
"narHash": "sha256-+OB00N6Yql/ZRQQkQ0PNnxfW2tH89DHnv29hBS7tXMM=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "27ec296d93cb4b2d03e8cbd019b1b4cde8c34280",
|
||||
"rev": "2b00881d2ff72174cffdc007238cb6bedd6e1d8e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -2042,11 +2063,11 @@
|
|||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719714047,
|
||||
"narHash": "sha256-MeNPopLLv63EZj5L43j4TZkmW4wj1ouoc/h/E20sl/U=",
|
||||
"lastModified": 1722391647,
|
||||
"narHash": "sha256-JTi7l1oxnatF1uX/gnGMlRnyFMtylRw4MqhCUdoN2K4=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "cb216719ce89a43dfb3d1b86a9575e89f4b727a4",
|
||||
"rev": "0fd4a5d2098faa516a9b83022aec7db766cd1de8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -2105,20 +2126,22 @@
|
|||
"base16-tmux": "base16-tmux",
|
||||
"base16-vim": "base16-vim",
|
||||
"flake-compat": "flake-compat_9",
|
||||
"flake-utils": "flake-utils_9",
|
||||
"gnome-shell": "gnome-shell",
|
||||
"home-manager": [
|
||||
"home-manager"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
],
|
||||
"systems": "systems_12"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722295291,
|
||||
"narHash": "sha256-3XpT9GMw50NCGT1Gd2YAwEjrEcFtDqnuQ7sRUcuU/Pc=",
|
||||
"lastModified": 1725290973,
|
||||
"narHash": "sha256-+jwXF9KI0HfvDgpsoJGvOdfOGGSKOrID1wQB79zjUbo=",
|
||||
"owner": "danth",
|
||||
"repo": "stylix",
|
||||
"rev": "feb2973dfa8232c07efbd2b48f11a5cfa2276570",
|
||||
"rev": "ef81ad9e85e60420cc83d4642619c14b57139d33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -2187,6 +2210,21 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_13": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
|
@ -2316,11 +2354,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722330636,
|
||||
"narHash": "sha256-uru7JzOa33YlSRwf9sfXpJG+UAV+bnBEYMjrzKrQZFw=",
|
||||
"lastModified": 1725271838,
|
||||
"narHash": "sha256-VcqxWT0O/gMaeWTTjf1r4MOyG49NaNxW4GHTO3xuThE=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "768acdb06968e53aa1ee8de207fd955335c754b7",
|
||||
"rev": "9fb342d14b69aefdf46187f6bb80a4a0d97007cd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -2337,11 +2375,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722330636,
|
||||
"narHash": "sha256-uru7JzOa33YlSRwf9sfXpJG+UAV+bnBEYMjrzKrQZFw=",
|
||||
"lastModified": 1724833132,
|
||||
"narHash": "sha256-F4djBvyNRAXGusJiNYInqR6zIMI3rvlp6WiKwsRISos=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "768acdb06968e53aa1ee8de207fd955335c754b7",
|
||||
"rev": "3ffd842a5f50f435d3e603312eefa4790db46af5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -2382,11 +2420,11 @@
|
|||
"rust-overlay": "rust-overlay_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1721535277,
|
||||
"narHash": "sha256-A6qIy2n3aomj5XooUmqz0s3G/A44Y3+GoFrGxIOolIM=",
|
||||
"lastModified": 1723726454,
|
||||
"narHash": "sha256-CdsBLja4rJ7VPvtsivyZm9VFKAt4hzL3jZbKrfiDvsQ=",
|
||||
"owner": "Toqozz",
|
||||
"repo": "wired-notify",
|
||||
"rev": "d079126c43f22179650f3d4c59f580c5993b9217",
|
||||
"rev": "946adddcb704806195d976b738066f591b41b7d4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
diff --git a/crates/jmap/src/api/management/domain.rs b/crates/jmap/src/api/management/domain.rs
|
||||
index e3890df5..7083aaf6 100644
|
||||
--- a/crates/jmap/src/api/management/domain.rs
|
||||
+++ b/crates/jmap/src/api/management/domain.rs
|
||||
@@ -123,6 +123,8 @@ impl JMAP {
|
||||
}
|
||||
|
||||
async fn build_dns_records(&self, domain_name: &str) -> trc::Result<Vec<DnsRecord>> {
|
||||
+ let signature_config = self.core.storage.config.build_config("signature").await?;
|
||||
+
|
||||
// Obtain server name
|
||||
let server_name = self
|
||||
.core
|
||||
@@ -143,7 +145,11 @@ impl JMAP {
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
- keys.insert(key, value);
|
||||
+ let val = signature_config.keys
|
||||
+ .get(&format!("signature.{key}"))
|
||||
+ .cloned()
|
||||
+ .unwrap_or(value.clone());
|
||||
+ keys.insert(key, val);
|
||||
}
|
||||
|
||||
// Add MX and CNAME records
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
globals,
|
||||
lib,
|
||||
|
@ -43,6 +44,7 @@ in {
|
|||
};
|
||||
|
||||
services.idmail = {
|
||||
package = inputs.idmail.packages."x86_64-linux".default;
|
||||
enable = true;
|
||||
# Stalwart will change permissions due to SQLite implementation.
|
||||
# Therefore, run as stalwart-mail since we don't allow reading
|
||||
|
|
|
@ -51,14 +51,6 @@ in {
|
|||
|
||||
services.stalwart-mail = {
|
||||
enable = true;
|
||||
package = pkgs.stalwart-mail.overrideAttrs (old: {
|
||||
patches =
|
||||
old.patches
|
||||
++ [
|
||||
./a.patch
|
||||
];
|
||||
doCheck = false;
|
||||
});
|
||||
settings = let
|
||||
case = field: check: value: data: {
|
||||
"if" = field;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
config,
|
||||
globals,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
kanidmDomain = "auth.${globals.domains.me}";
|
||||
|
@ -85,6 +86,7 @@ in {
|
|||
];
|
||||
|
||||
services.kanidm = {
|
||||
package = pkgs.kanidm.withSecretProvisioning;
|
||||
enableServer = true;
|
||||
serverSettings = {
|
||||
domain = kanidmDomain;
|
||||
|
@ -114,6 +116,7 @@ in {
|
|||
systems.oauth2.immich = {
|
||||
displayName = "Immich";
|
||||
originUrl = "https://${globals.services.immich.domain}/";
|
||||
originLanding = "https://${globals.services.immich.domain}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-immich.path;
|
||||
preferShortUsername = true;
|
||||
# XXX: PKCE is currently not supported by immich
|
||||
|
@ -129,6 +132,7 @@ in {
|
|||
public = true;
|
||||
displayName = "Netbird";
|
||||
originUrl = "https://${globals.services.netbird.domain}/";
|
||||
originLanding = "https://${globals.services.netbird.domain}/";
|
||||
preferShortUsername = true;
|
||||
enableLocalhostRedirects = true;
|
||||
enableLegacyCrypto = true;
|
||||
|
@ -140,6 +144,7 @@ in {
|
|||
systems.oauth2.paperless = {
|
||||
displayName = "Paperless";
|
||||
originUrl = "https://${globals.services.paperless.domain}/";
|
||||
originLanding = "https://${globals.services.paperless.domain}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-paperless.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."paperless.access" = ["openid" "email" "profile"];
|
||||
|
@ -153,6 +158,7 @@ in {
|
|||
systems.oauth2.grafana = {
|
||||
displayName = "Grafana";
|
||||
originUrl = "https://${globals.services.grafana.domain}/";
|
||||
originLanding = "https://${globals.services.grafana.domain}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-grafana.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."grafana.access" = ["openid" "email" "profile"];
|
||||
|
@ -172,6 +178,7 @@ in {
|
|||
systems.oauth2.forgejo = {
|
||||
displayName = "Forgejo";
|
||||
originUrl = "https://${globals.services.forgejo.domain}/";
|
||||
originLanding = "https://${globals.services.forgejo.domain}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-forgejo.path;
|
||||
scopeMaps."forgejo.access" = ["openid" "email" "profile"];
|
||||
# XXX: PKCE is currently not supported by gitea/forgejo,
|
||||
|
@ -191,6 +198,7 @@ in {
|
|||
systems.oauth2.web-sentinel = {
|
||||
displayName = "Web Sentinel";
|
||||
originUrl = "https://oauth2.${globals.domains.me}/";
|
||||
originLanding = "https://oauth2.${globals.domains.me}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-web-sentinel.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."web-sentinel.access" = ["openid" "email"];
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
disabledModules = [
|
||||
"services/security/kanidm.nix"
|
||||
"services/networking/netbird.nix"
|
||||
];
|
||||
|
||||
|
@ -10,7 +9,6 @@
|
|||
./deterministic-ids.nix
|
||||
./distributed-config.nix
|
||||
./globals.nix
|
||||
./kanidm.nix
|
||||
./meta.nix
|
||||
./netbird-client.nix
|
||||
./nginx-upstream-monitoring.nix
|
||||
|
|
|
@ -1,891 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(lib)
|
||||
any
|
||||
attrNames
|
||||
attrValues
|
||||
concatLines
|
||||
concatLists
|
||||
converge
|
||||
filter
|
||||
filterAttrs
|
||||
filterAttrsRecursive
|
||||
flip
|
||||
foldl'
|
||||
getExe
|
||||
hasInfix
|
||||
hasPrefix
|
||||
isStorePath
|
||||
last
|
||||
mapAttrsToList
|
||||
mdDoc
|
||||
mkEnableOption
|
||||
mkForce
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
mkPackageOption
|
||||
optional
|
||||
optionalString
|
||||
splitString
|
||||
subtractLists
|
||||
types
|
||||
unique
|
||||
;
|
||||
|
||||
cfg = config.services.kanidm;
|
||||
settingsFormat = pkgs.formats.toml {};
|
||||
# Remove null values, so we can document optional values that don't end up in the generated TOML file.
|
||||
filterConfig = converge (filterAttrsRecursive (_: v: v != null));
|
||||
serverConfigFile = settingsFormat.generate "server.toml" (filterConfig cfg.serverSettings);
|
||||
clientConfigFile = settingsFormat.generate "kanidm-config.toml" (filterConfig cfg.clientSettings);
|
||||
unixConfigFile = settingsFormat.generate "kanidm-unixd.toml" (filterConfig cfg.unixSettings);
|
||||
certPaths = builtins.map builtins.dirOf [cfg.serverSettings.tls_chain cfg.serverSettings.tls_key];
|
||||
|
||||
# Merge bind mount paths and remove paths where a prefix is already mounted.
|
||||
# This makes sure that if e.g. the tls_chain is in the nix store and /nix/store is already in the mount
|
||||
# paths, no new bind mount is added. Adding subpaths caused problems on ofborg.
|
||||
hasPrefixInList = list: newPath: any (path: hasPrefix (builtins.toString path) (builtins.toString newPath)) list;
|
||||
mergePaths = foldl' (merged: newPath: let
|
||||
# If the new path is a prefix to some existing path, we need to filter it out
|
||||
filteredPaths = filter (p: !hasPrefix (builtins.toString newPath) (builtins.toString p)) merged;
|
||||
# If a prefix of the new path is already in the list, do not add it
|
||||
filteredNew = optional (!hasPrefixInList filteredPaths newPath) newPath;
|
||||
in
|
||||
filteredPaths ++ filteredNew) [];
|
||||
|
||||
defaultServiceConfig = {
|
||||
BindReadOnlyPaths = [
|
||||
"/nix/store"
|
||||
"-/etc/resolv.conf"
|
||||
"-/etc/nsswitch.conf"
|
||||
"-/etc/hosts"
|
||||
"-/etc/localtime"
|
||||
];
|
||||
CapabilityBoundingSet = [];
|
||||
# ProtectClock= adds DeviceAllow=char-rtc r
|
||||
DeviceAllow = "";
|
||||
# Implies ProtectSystem=strict, which re-mounts all paths
|
||||
# DynamicUser = true;
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
PrivateNetwork = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
# Would re-mount paths ignored by temporary root
|
||||
#ProtectSystem = "strict";
|
||||
ProtectControlGroups = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
RestrictAddressFamilies = [];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = ["@system-service" "~@privileged @resources @setuid @keyring"];
|
||||
# Does not work well with the temporary root
|
||||
#UMask = "0066";
|
||||
};
|
||||
|
||||
mkPresentOption = what:
|
||||
mkOption {
|
||||
description = mdDoc "Whether to ensure that this ${what} is present or absent.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
filterPresent = filterAttrs (_: v: v.present);
|
||||
|
||||
provisionStateJson = pkgs.writeText "provision-state.json" (builtins.toJSON {
|
||||
inherit (cfg.provision) groups persons systems;
|
||||
});
|
||||
|
||||
serverPort =
|
||||
# ipv6:
|
||||
if hasInfix "]:" cfg.serverSettings.bindaddress
|
||||
then last (splitString "]:" cfg.serverSettings.bindaddress)
|
||||
else
|
||||
# ipv4:
|
||||
if hasInfix "." cfg.serverSettings.bindaddress
|
||||
then last (splitString ":" cfg.serverSettings.bindaddress)
|
||||
# default is 8443
|
||||
else "8443";
|
||||
|
||||
# Only recover the admin account if a password should explicitly be provisioned
|
||||
# for the account. Otherwise it is not needed for provisioning.
|
||||
maybeRecoverAdmin = optionalString (cfg.provision.adminPasswordFile != null) ''
|
||||
KANIDM_ADMIN_PASSWORD=$(< ${cfg.provision.adminPasswordFile})
|
||||
# We always reset the admin account password if a desired password was specified.
|
||||
if ! KANIDM_RECOVER_ACCOUNT_PASSWORD=$KANIDM_ADMIN_PASSWORD ${cfg.package}/bin/kanidmd recover-account -c ${serverConfigFile} admin --from-environment >/dev/null; then
|
||||
echo "Failed to recover admin account" >&2
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
# Recover the idm_admin account. If a password should explicitly be provisioned
|
||||
# for the account we set it, otherwise we generate a new one because it is required
|
||||
# for provisioning.
|
||||
recoverIdmAdmin =
|
||||
if cfg.provision.idmAdminPasswordFile != null
|
||||
then ''
|
||||
KANIDM_IDM_ADMIN_PASSWORD=$(< ${cfg.provision.idmAdminPasswordFile})
|
||||
# We always reset the idm_admin account password if a desired password was specified.
|
||||
if ! KANIDM_RECOVER_ACCOUNT_PASSWORD=$KANIDM_IDM_ADMIN_PASSWORD ${cfg.package}/bin/kanidmd recover-account -c ${serverConfigFile} idm_admin --from-environment >/dev/null; then
|
||||
echo "Failed to recover idm_admin account" >&2
|
||||
exit 1
|
||||
fi
|
||||
''
|
||||
else ''
|
||||
# Recover idm_admin account
|
||||
if ! recover_out=$(${cfg.package}/bin/kanidmd recover-account -c ${serverConfigFile} idm_admin -o json); then
|
||||
echo "$recover_out" >&2
|
||||
echo "kanidm provision: Failed to recover admin account" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! KANIDM_IDM_ADMIN_PASSWORD=$(grep '{"password' <<< "$recover_out" | ${getExe pkgs.jq} -r .password); then
|
||||
echo "$recover_out" >&2
|
||||
echo "kanidm provision: Failed to parse password for idm_admin account" >&2
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
postStartScript = pkgs.writeShellScript "post-start" ''
|
||||
set -euo pipefail
|
||||
|
||||
# Wait for the kanidm server to come online
|
||||
count=0
|
||||
main_pid_existed=false
|
||||
while ! test -e /run/kanidmd/sock; do
|
||||
sleep 0.1
|
||||
if [[ "$count" -eq 600 ]]; then
|
||||
echo "Tried for 60 seconds, giving up..."
|
||||
exit 1
|
||||
fi
|
||||
if [[ -d "/proc/$MAINPID" ]]; then
|
||||
main_pid_existed=true
|
||||
elif [[ "$main_pid_existed" == true ]]; then
|
||||
echo "Main server died, giving up..."
|
||||
exit 1
|
||||
fi
|
||||
count=$((count++))
|
||||
done
|
||||
|
||||
${recoverIdmAdmin}
|
||||
${maybeRecoverAdmin}
|
||||
|
||||
KANIDM_PROVISION_IDM_ADMIN_TOKEN=$KANIDM_IDM_ADMIN_PASSWORD \
|
||||
${getExe pkgs.kanidm-provision} --url "${cfg.provision.instanceUrl}" --state ${provisionStateJson} ${optionalString cfg.provision.acceptInvalidCerts "--accept-invalid-certs"}
|
||||
'';
|
||||
in {
|
||||
options.services.kanidm = {
|
||||
enableClient = mkEnableOption (mdDoc "the Kanidm client");
|
||||
enableServer = mkEnableOption (mdDoc "the Kanidm server");
|
||||
enablePam = mkEnableOption (mdDoc "the Kanidm PAM and NSS integration");
|
||||
|
||||
package = mkPackageOption pkgs "kanidm" {};
|
||||
|
||||
serverSettings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
|
||||
options = {
|
||||
bindaddress = mkOption {
|
||||
description = mdDoc "Address/port combination the webserver binds to.";
|
||||
example = "[::1]:8443";
|
||||
type = types.str;
|
||||
};
|
||||
# Should be optional but toml does not accept null
|
||||
ldapbindaddress = mkOption {
|
||||
description = mdDoc ''
|
||||
Address and port the LDAP server is bound to. Setting this to `null` disables the LDAP interface.
|
||||
'';
|
||||
example = "[::1]:636";
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
origin = mkOption {
|
||||
description = mdDoc "The origin of your Kanidm instance. Must have https as protocol.";
|
||||
example = "https://idm.example.org";
|
||||
type = types.strMatching "^https://.*";
|
||||
};
|
||||
domain = mkOption {
|
||||
description = mdDoc ''
|
||||
The `domain` that Kanidm manages. Must be below or equal to the domain
|
||||
specified in `serverSettings.origin`.
|
||||
This can be left at `null`, only if your instance has the role `ReadOnlyReplica`.
|
||||
While it is possible to change the domain later on, it requires extra steps!
|
||||
Please consider the warnings and execute the steps described
|
||||
[in the documentation](https://kanidm.github.io/kanidm/stable/administrivia.html#rename-the-domain).
|
||||
'';
|
||||
example = "example.org";
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
db_path = mkOption {
|
||||
description = mdDoc "Path to Kanidm database.";
|
||||
default = "/var/lib/kanidm/kanidm.db";
|
||||
readOnly = true;
|
||||
type = types.path;
|
||||
};
|
||||
tls_chain = mkOption {
|
||||
description = mdDoc "TLS chain in pem format.";
|
||||
type = types.path;
|
||||
};
|
||||
tls_key = mkOption {
|
||||
description = mdDoc "TLS key in pem format.";
|
||||
type = types.path;
|
||||
};
|
||||
log_level = mkOption {
|
||||
description = mdDoc "Log level of the server.";
|
||||
default = "info";
|
||||
type = types.enum ["info" "debug" "trace"];
|
||||
};
|
||||
role = mkOption {
|
||||
description = mdDoc "The role of this server. This affects the replication relationship and thereby available features.";
|
||||
default = "WriteReplica";
|
||||
type = types.enum ["WriteReplica" "WriteReplicaNoUI" "ReadOnlyReplica"];
|
||||
};
|
||||
online_backup = {
|
||||
path = mkOption {
|
||||
description = mdDoc "Path to the output directory for backups.";
|
||||
type = types.path;
|
||||
default = "/var/lib/kanidm/backups";
|
||||
};
|
||||
schedule = mkOption {
|
||||
description = mdDoc "The schedule for backups in cron format.";
|
||||
type = types.str;
|
||||
default = "00 22 * * *";
|
||||
};
|
||||
versions = mkOption {
|
||||
description = mdDoc ''
|
||||
Number of backups to keep.
|
||||
|
||||
The default is set to `0`, in order to disable backups by default.
|
||||
'';
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
example = 7;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
description = mdDoc ''
|
||||
Settings for Kanidm, see
|
||||
[the documentation](https://kanidm.github.io/kanidm/stable/server_configuration.html)
|
||||
and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/server.toml)
|
||||
for possible values.
|
||||
'';
|
||||
};
|
||||
|
||||
clientSettings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
|
||||
options.uri = mkOption {
|
||||
description = mdDoc "Address of the Kanidm server.";
|
||||
example = "http://127.0.0.1:8080";
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
description = mdDoc ''
|
||||
Configure Kanidm clients, needed for the PAM daemon. See
|
||||
[the documentation](https://kanidm.github.io/kanidm/stable/client_tools.html#kanidm-configuration)
|
||||
and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/config)
|
||||
for possible values.
|
||||
'';
|
||||
};
|
||||
|
||||
unixSettings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
|
||||
options = {
|
||||
pam_allowed_login_groups = mkOption {
|
||||
description = mdDoc "Kanidm groups that are allowed to login using PAM.";
|
||||
example = "my_pam_group";
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
hsm_pin_path = mkOption {
|
||||
description = mdDoc "Path to a HSM pin.";
|
||||
default = "/var/cache/kanidm-unixd/hsm-pin";
|
||||
type = types.path;
|
||||
};
|
||||
};
|
||||
};
|
||||
description = mdDoc ''
|
||||
Configure Kanidm unix daemon.
|
||||
See [the documentation](https://kanidm.github.io/kanidm/stable/integrations/pam_and_nsswitch.html#the-unix-daemon)
|
||||
and [example configuration](https://github.com/kanidm/kanidm/blob/master/examples/unixd)
|
||||
for possible values.
|
||||
'';
|
||||
};
|
||||
|
||||
provision = {
|
||||
enable = mkEnableOption "provisioning of groups, users and oauth2 resource servers";
|
||||
|
||||
instanceUrl = mkOption {
|
||||
description = "The instance url to which the provisioning tool should connect.";
|
||||
default = "https://localhost:${serverPort}";
|
||||
defaultText = ''"https://localhost:<port from serverSettings.bindaddress>"'';
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
acceptInvalidCerts = mkOption {
|
||||
description = ''
|
||||
Whether to allow invalid certificates when provisioning the target instance.
|
||||
By default this is only allowed when the instanceUrl is localhost. This is
|
||||
dangerous when used with an external URL.
|
||||
'';
|
||||
type = types.bool;
|
||||
default = hasPrefix "https://localhost:" cfg.provision.instanceUrl;
|
||||
defaultText = ''hasPrefix "https://localhost:" cfg.provision.instanceUrl'';
|
||||
};
|
||||
|
||||
adminPasswordFile = mkOption {
|
||||
description = "Path to a file containing the admin password for kanidm. Do NOT use a file from the nix store here!";
|
||||
example = "/run/secrets/kanidm-admin-password";
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
|
||||
idmAdminPasswordFile = mkOption {
|
||||
description = ''
|
||||
Path to a file containing the idm admin password for kanidm. Do NOT use a file from the nix store here!
|
||||
If this is not given but provisioning is enabled, the idm_admin password will be reset on each restart.
|
||||
'';
|
||||
example = "/run/secrets/kanidm-idm-admin-password";
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
|
||||
autoRemove = mkOption {
|
||||
description = ''
|
||||
Determines whether deleting an entity in this provisioning config should automatically
|
||||
cause them to be removed from kanidm, too. This works because the provisioning tool tracks
|
||||
all entities it has ever created. If this is set to false, you need to explicitly specify
|
||||
`present = false` to delete an entity.
|
||||
'';
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
groups = mkOption {
|
||||
description = "Provisioning of kanidm groups";
|
||||
default = {};
|
||||
type = types.attrsOf (types.submodule (groupSubmod: {
|
||||
options = {
|
||||
present = mkPresentOption "group";
|
||||
|
||||
members = mkOption {
|
||||
description = "List of kanidm entities (persons, groups, ...) which are part of this group.";
|
||||
type = types.listOf types.str;
|
||||
apply = unique;
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
config.members = concatLists (flip mapAttrsToList cfg.provision.persons (
|
||||
person: personCfg:
|
||||
optional (personCfg.present && builtins.elem groupSubmod.config._module.args.name personCfg.groups) person
|
||||
));
|
||||
}));
|
||||
};
|
||||
|
||||
persons = mkOption {
|
||||
description = "Provisioning of kanidm persons";
|
||||
default = {};
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
present = mkPresentOption "person";
|
||||
|
||||
displayName = mkOption {
|
||||
description = "Display name";
|
||||
type = types.str;
|
||||
example = "My User";
|
||||
};
|
||||
|
||||
legalName = mkOption {
|
||||
description = "Full legal name";
|
||||
type = types.nullOr types.str;
|
||||
example = "Jane Doe";
|
||||
default = null;
|
||||
};
|
||||
|
||||
mailAddresses = mkOption {
|
||||
description = "Mail addresses. First given address is considered the primary address.";
|
||||
type = types.listOf types.str;
|
||||
example = ["jane.doe@example.com"];
|
||||
default = [];
|
||||
};
|
||||
|
||||
groups = mkOption {
|
||||
description = "List of groups this person should belong to.";
|
||||
type = types.listOf types.str;
|
||||
apply = unique;
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
systems.oauth2 = mkOption {
|
||||
description = "Provisioning of oauth2 resource servers";
|
||||
default = {};
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
present = mkPresentOption "oauth2 resource server";
|
||||
|
||||
public = mkOption {
|
||||
description = "Whether this is a public client (enforces PKCE, doesn't use a basic secret)";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
displayName = mkOption {
|
||||
description = "Display name";
|
||||
type = types.str;
|
||||
example = "Some Service";
|
||||
};
|
||||
|
||||
originUrl = mkOption {
|
||||
description = "The origin URL of the service. OAuth2 redirects will only be allowed to sites under this origin. Must end with a slash.";
|
||||
type = types.strMatching ".*://.*/$";
|
||||
example = "https://someservice.example.com/";
|
||||
};
|
||||
|
||||
originLanding = mkOption {
|
||||
description = "When redirecting from the Kanidm Apps Listing page, some linked applications may need to land on a specific page to trigger oauth2/oidc interactions.";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "https://someservice.example.com/home";
|
||||
};
|
||||
|
||||
basicSecretFile = mkOption {
|
||||
description = ''
|
||||
The basic secret to use for this service. If null, the random secret generated
|
||||
by kanidm will not be touched. Do NOT use a path from the nix store here!
|
||||
'';
|
||||
type = types.nullOr types.path;
|
||||
example = "/run/secrets/some-oauth2-basic-secret";
|
||||
default = null;
|
||||
};
|
||||
|
||||
enableLocalhostRedirects = mkOption {
|
||||
description = "Allow localhost redirects. Only for public clients.";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
enableLegacyCrypto = mkOption {
|
||||
description = "Enable legacy crypto on this client. Allows JWT signing algorthms like RS256.";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
allowInsecureClientDisablePkce = mkOption {
|
||||
description = ''
|
||||
Disable PKCE on this oauth2 resource server to work around insecure clients
|
||||
that may not support it. You should request the client to enable PKCE!
|
||||
Only for non-public clients.
|
||||
'';
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
preferShortUsername = mkOption {
|
||||
description = "Use 'name' instead of 'spn' in the preferred_username claim";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
scopeMaps = mkOption {
|
||||
description = ''
|
||||
Maps kanidm groups to returned oauth scopes.
|
||||
See [Scope Relations](https://kanidm.github.io/kanidm/stable/integrations/oauth2.html#scope-relationships) for more information.
|
||||
'';
|
||||
type = types.attrsOf (types.listOf types.str);
|
||||
default = {};
|
||||
};
|
||||
|
||||
supplementaryScopeMaps = mkOption {
|
||||
description = ''
|
||||
Maps kanidm groups to additionally returned oauth scopes.
|
||||
See [Scope Relations](https://kanidm.github.io/kanidm/stable/integrations/oauth2.html#scope-relationships) for more information.
|
||||
'';
|
||||
type = types.attrsOf (types.listOf types.str);
|
||||
default = {};
|
||||
};
|
||||
|
||||
removeOrphanedClaimMaps = mkOption {
|
||||
description = "Whether claim maps not specified here but present in kanidm should be removed from kanidm.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
claimMaps = mkOption {
|
||||
description = ''
|
||||
Adds additional claims (and values) based on which kanidm groups an authenticating party belongs to.
|
||||
See [Claim Maps](https://kanidm.github.io/kanidm/master/integrations/oauth2.html#custom-claim-maps) for more information.
|
||||
'';
|
||||
default = {};
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
joinType = mkOption {
|
||||
description = ''
|
||||
Determines how multiple values are joined to create the claim value.
|
||||
See [Claim Maps](https://kanidm.github.io/kanidm/master/integrations/oauth2.html#custom-claim-maps) for more information.
|
||||
'';
|
||||
type = types.enum ["array" "csv" "ssv"];
|
||||
default = "array";
|
||||
};
|
||||
|
||||
valuesByGroup = mkOption {
|
||||
description = "Maps kanidm groups to values for the claim.";
|
||||
default = {};
|
||||
type = types.attrsOf (types.listOf types.str);
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enableClient || cfg.enableServer || cfg.enablePam) {
|
||||
assertions = let
|
||||
entityList = type: attrs: flip mapAttrsToList (filterPresent attrs) (name: _: {inherit type name;});
|
||||
entities =
|
||||
entityList "group" cfg.provision.groups
|
||||
++ entityList "person" cfg.provision.persons
|
||||
++ entityList "oauth2" cfg.provision.systems.oauth2;
|
||||
|
||||
# Accumulate entities by name. Track corresponding entity types for later duplicate check.
|
||||
entitiesByName =
|
||||
foldl' (
|
||||
acc: {
|
||||
type,
|
||||
name,
|
||||
}:
|
||||
acc
|
||||
// {
|
||||
${name} = (acc.${name} or []) ++ [type];
|
||||
}
|
||||
) {}
|
||||
entities;
|
||||
|
||||
assertGroupsKnown = opt: groups: let
|
||||
knownGroups = attrNames (filterPresent cfg.provision.groups);
|
||||
unknownGroups = subtractLists knownGroups groups;
|
||||
in {
|
||||
assertion = (cfg.enableServer && cfg.provision.enable) -> unknownGroups == [];
|
||||
message = "${opt} refers to unknown groups: ${toString unknownGroups}";
|
||||
};
|
||||
|
||||
assertEntitiesKnown = opt: entities: let
|
||||
unknownEntities = subtractLists (attrNames entitiesByName) entities;
|
||||
in {
|
||||
assertion = (cfg.enableServer && cfg.provision.enable) -> unknownEntities == [];
|
||||
message = "${opt} refers to unknown entities: ${toString unknownEntities}";
|
||||
};
|
||||
in
|
||||
[
|
||||
{
|
||||
assertion = !cfg.enableServer || ((cfg.serverSettings.tls_chain or null) == null) || (!isStorePath cfg.serverSettings.tls_chain);
|
||||
message = ''
|
||||
<option>services.kanidm.serverSettings.tls_chain</option> points to
|
||||
a file in the Nix store. You should use a quoted absolute path to
|
||||
prevent this.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = !cfg.enableServer || ((cfg.serverSettings.tls_key or null) == null) || (!isStorePath cfg.serverSettings.tls_key);
|
||||
message = ''
|
||||
<option>services.kanidm.serverSettings.tls_key</option> points to
|
||||
a file in the Nix store. You should use a quoted absolute path to
|
||||
prevent this.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = !cfg.enableClient || options.services.kanidm.clientSettings.isDefined;
|
||||
message = ''
|
||||
<option>services.kanidm.clientSettings</option> needs to be configured
|
||||
if the client is enabled.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = !cfg.enablePam || options.services.kanidm.clientSettings.isDefined;
|
||||
message = ''
|
||||
<option>services.kanidm.clientSettings</option> needs to be configured
|
||||
for the PAM daemon to connect to the Kanidm server.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
!cfg.enableServer
|
||||
|| (cfg.serverSettings.domain
|
||||
== null
|
||||
-> cfg.serverSettings.role == "WriteReplica" || cfg.serverSettings.role == "WriteReplicaNoUI");
|
||||
message = ''
|
||||
<option>services.kanidm.serverSettings.domain</option> can only be set if this instance
|
||||
is not a ReadOnlyReplica. Otherwise the db would inherit it from
|
||||
the instance it follows.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = cfg.provision.enable -> cfg.enableServer;
|
||||
message = "<option>services.kanidm.provision</option> requires <option>services.kanidm.enableServer</option> to be true";
|
||||
}
|
||||
# If any secret is provisioned, the kanidm package must have some required patches applied to it
|
||||
{
|
||||
assertion =
|
||||
(cfg.provision.enable
|
||||
&& (
|
||||
cfg.provision.adminPasswordFile
|
||||
!= null
|
||||
|| cfg.provision.idmAdminPasswordFile != null
|
||||
|| any (x: x.basicSecretFile != null) (attrValues (filterPresent cfg.provision.systems.oauth2))
|
||||
))
|
||||
-> cfg.package.enableSecretProvisioning;
|
||||
message = ''
|
||||
Specifying an admin account password or oauth2 basicSecretFile requires kanidm to be built with the secret provisioning patches.
|
||||
You may want to set `services.kanidm.package = pkgs.kanidm.withSecretProvisioning;`.
|
||||
'';
|
||||
}
|
||||
# Entity names must be globally unique:
|
||||
(let
|
||||
# Filter all names that occurred in more than one entity type.
|
||||
duplicateNames = filterAttrs (_: v: builtins.length v > 1) entitiesByName;
|
||||
in {
|
||||
assertion = cfg.provision.enable -> duplicateNames == {};
|
||||
message = ''
|
||||
services.kanidm.provision requires all entity names (group, person, oauth2, ...) to be unique!
|
||||
${concatLines (mapAttrsToList (name: xs: " - '${name}' used as: ${toString xs}") duplicateNames)}'';
|
||||
})
|
||||
]
|
||||
++ flip mapAttrsToList (filterPresent cfg.provision.persons) (
|
||||
person: personCfg:
|
||||
assertGroupsKnown "services.kanidm.provision.persons.${person}.groups" personCfg.groups
|
||||
)
|
||||
++ flip mapAttrsToList (filterPresent cfg.provision.groups) (
|
||||
group: groupCfg:
|
||||
assertEntitiesKnown "services.kanidm.provision.groups.${group}.members" groupCfg.members
|
||||
)
|
||||
++ concatLists (flip mapAttrsToList (filterPresent cfg.provision.systems.oauth2) (
|
||||
oauth2: oauth2Cfg:
|
||||
[
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.scopeMaps" (attrNames oauth2Cfg.scopeMaps))
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.supplementaryScopeMaps" (attrNames oauth2Cfg.supplementaryScopeMaps))
|
||||
]
|
||||
++ concatLists (flip mapAttrsToList oauth2Cfg.claimMaps (claim: claimCfg: [
|
||||
(assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim}.valuesByGroup" (attrNames claimCfg.valuesByGroup))
|
||||
# At least one group must map to a value in each claim map
|
||||
{
|
||||
assertion = (cfg.provision.enable && cfg.enableServer) -> any (xs: xs != []) (attrValues claimCfg.valuesByGroup);
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim} does not specify any values for any group";
|
||||
}
|
||||
# Public clients cannot define a basic secret
|
||||
{
|
||||
assertion = (cfg.provision.enable && cfg.enableServer && oauth2Cfg.public) -> oauth2Cfg.basicSecretFile == null;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a public client and thus cannot specify a basic secret";
|
||||
}
|
||||
# Public clients cannot disable PKCE
|
||||
{
|
||||
assertion = (cfg.provision.enable && cfg.enableServer && oauth2Cfg.public) -> !oauth2Cfg.allowInsecureClientDisablePkce;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a public client and thus cannot disable PKCE";
|
||||
}
|
||||
# Non-public clients cannot enable localhost redirects
|
||||
{
|
||||
assertion = (cfg.provision.enable && cfg.enableServer && !oauth2Cfg.public) -> !oauth2Cfg.enableLocalhostRedirects;
|
||||
message = "services.kanidm.provision.systems.oauth2.${oauth2} is a non-public client and thus cannot enable localhost redirects";
|
||||
}
|
||||
]))
|
||||
));
|
||||
|
||||
environment.systemPackages = mkIf cfg.enableClient [cfg.package];
|
||||
|
||||
systemd.tmpfiles.settings."10-kanidm" = {
|
||||
${cfg.serverSettings.online_backup.path}.d = {
|
||||
mode = "0700";
|
||||
user = "kanidm";
|
||||
group = "kanidm";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.kanidm = mkIf cfg.enableServer {
|
||||
description = "kanidm identity management daemon";
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["network.target"];
|
||||
serviceConfig = mkMerge [
|
||||
# Merge paths and ignore existing prefixes needs to sidestep mkMerge
|
||||
(defaultServiceConfig
|
||||
// {
|
||||
BindReadOnlyPaths = mergePaths (defaultServiceConfig.BindReadOnlyPaths ++ certPaths);
|
||||
})
|
||||
{
|
||||
StateDirectory = "kanidm";
|
||||
StateDirectoryMode = "0700";
|
||||
RuntimeDirectory = "kanidmd";
|
||||
ExecStart = "${cfg.package}/bin/kanidmd server -c ${serverConfigFile}";
|
||||
ExecStartPost = mkIf cfg.provision.enable postStartScript;
|
||||
User = "kanidm";
|
||||
Group = "kanidm";
|
||||
|
||||
BindPaths = [
|
||||
# To create the socket
|
||||
"/run/kanidmd:/run/kanidmd"
|
||||
# To store backups
|
||||
cfg.serverSettings.online_backup.path
|
||||
];
|
||||
|
||||
AmbientCapabilities = ["CAP_NET_BIND_SERVICE"];
|
||||
CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"];
|
||||
# This would otherwise override the CAP_NET_BIND_SERVICE capability.
|
||||
PrivateUsers = mkForce false;
|
||||
# Port needs to be exposed to the host network
|
||||
PrivateNetwork = mkForce false;
|
||||
RestrictAddressFamilies = ["AF_INET" "AF_INET6" "AF_UNIX"];
|
||||
TemporaryFileSystem = "/:ro";
|
||||
}
|
||||
];
|
||||
environment.RUST_LOG = "info";
|
||||
};
|
||||
|
||||
systemd.services.kanidm-unixd = mkIf cfg.enablePam {
|
||||
description = "Kanidm PAM daemon";
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["network.target"];
|
||||
restartTriggers = [unixConfigFile clientConfigFile];
|
||||
serviceConfig = mkMerge [
|
||||
defaultServiceConfig
|
||||
{
|
||||
CacheDirectory = "kanidm-unixd";
|
||||
CacheDirectoryMode = "0700";
|
||||
RuntimeDirectory = "kanidm-unixd";
|
||||
ExecStart = "${cfg.package}/bin/kanidm_unixd";
|
||||
User = "kanidm-unixd";
|
||||
Group = "kanidm-unixd";
|
||||
|
||||
BindReadOnlyPaths = [
|
||||
"-/etc/kanidm"
|
||||
"-/etc/static/kanidm"
|
||||
"-/etc/ssl"
|
||||
"-/etc/static/ssl"
|
||||
"-/etc/passwd"
|
||||
"-/etc/group"
|
||||
];
|
||||
BindPaths = [
|
||||
# To create the socket
|
||||
"/run/kanidm-unixd:/var/run/kanidm-unixd"
|
||||
];
|
||||
# Needs to connect to kanidmd
|
||||
PrivateNetwork = mkForce false;
|
||||
RestrictAddressFamilies = ["AF_INET" "AF_INET6" "AF_UNIX"];
|
||||
TemporaryFileSystem = "/:ro";
|
||||
}
|
||||
];
|
||||
environment.RUST_LOG = "info";
|
||||
};
|
||||
|
||||
systemd.services.kanidm-unixd-tasks = mkIf cfg.enablePam {
|
||||
description = "Kanidm PAM home management daemon";
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["network.target" "kanidm-unixd.service"];
|
||||
partOf = ["kanidm-unixd.service"];
|
||||
restartTriggers = [unixConfigFile clientConfigFile];
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/kanidm_unixd_tasks";
|
||||
|
||||
BindReadOnlyPaths = [
|
||||
"/nix/store"
|
||||
"-/etc/resolv.conf"
|
||||
"-/etc/nsswitch.conf"
|
||||
"-/etc/hosts"
|
||||
"-/etc/localtime"
|
||||
"-/etc/kanidm"
|
||||
"-/etc/static/kanidm"
|
||||
];
|
||||
BindPaths = [
|
||||
# To manage home directories
|
||||
"/home"
|
||||
# To connect to kanidm-unixd
|
||||
"/run/kanidm-unixd:/var/run/kanidm-unixd"
|
||||
];
|
||||
# CAP_DAC_OVERRIDE is needed to ignore ownership of unixd socket
|
||||
CapabilityBoundingSet = ["CAP_CHOWN" "CAP_FOWNER" "CAP_DAC_OVERRIDE" "CAP_DAC_READ_SEARCH"];
|
||||
IPAddressDeny = "any";
|
||||
# Need access to users
|
||||
PrivateUsers = false;
|
||||
# Need access to home directories
|
||||
ProtectHome = false;
|
||||
RestrictAddressFamilies = ["AF_UNIX"];
|
||||
TemporaryFileSystem = "/:ro";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
environment.RUST_LOG = "info";
|
||||
};
|
||||
|
||||
# These paths are hardcoded
|
||||
environment.etc = mkMerge [
|
||||
(mkIf cfg.enableServer {
|
||||
"kanidm/server.toml".source = serverConfigFile;
|
||||
})
|
||||
(mkIf options.services.kanidm.clientSettings.isDefined {
|
||||
"kanidm/config".source = clientConfigFile;
|
||||
})
|
||||
(mkIf cfg.enablePam {
|
||||
"kanidm/unixd".source = unixConfigFile;
|
||||
})
|
||||
];
|
||||
|
||||
system.nssModules = mkIf cfg.enablePam [cfg.package];
|
||||
|
||||
system.nssDatabases.group = optional cfg.enablePam "kanidm";
|
||||
system.nssDatabases.passwd = optional cfg.enablePam "kanidm";
|
||||
|
||||
users.groups = mkMerge [
|
||||
(mkIf cfg.enableServer {
|
||||
kanidm = {};
|
||||
})
|
||||
(mkIf cfg.enablePam {
|
||||
kanidm-unixd = {};
|
||||
})
|
||||
];
|
||||
users.users = mkMerge [
|
||||
(mkIf cfg.enableServer {
|
||||
kanidm = {
|
||||
description = "Kanidm server";
|
||||
isSystemUser = true;
|
||||
group = "kanidm";
|
||||
packages = [cfg.package];
|
||||
};
|
||||
})
|
||||
(mkIf cfg.enablePam {
|
||||
kanidm-unixd = {
|
||||
description = "Kanidm PAM daemon";
|
||||
isSystemUser = true;
|
||||
group = "kanidm-unixd";
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [erictapen Flakebi oddlama];
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
|
@ -4,26 +4,7 @@ _inputs: [
|
|||
(_final: prev: {
|
||||
deploy = prev.callPackage ./deploy.nix {};
|
||||
git-fuzzy = prev.callPackage ./git-fuzzy {};
|
||||
stalwart-mail = builtins.trace "remove once 0.9.1 is stable" (prev.callPackage ./stal.nix {});
|
||||
kanidm = prev.kanidm.overrideAttrs (old: let
|
||||
provisionSrc = prev.fetchFromGitHub {
|
||||
owner = "oddlama";
|
||||
repo = "kanidm-provision";
|
||||
rev = "v1.1.1";
|
||||
hash = "sha256-tX24cszmWu7kB5Eoa3OrPqU1bayD62OpAV12U0ayoEo=";
|
||||
};
|
||||
in {
|
||||
patches =
|
||||
old.patches
|
||||
++ [
|
||||
"${provisionSrc}/patches/1.3.2-oauth2-basic-secret-modify.patch"
|
||||
"${provisionSrc}/patches/1.3.2-recover-account.patch"
|
||||
];
|
||||
passthru.enableSecretProvisioning = true;
|
||||
doCheck = false;
|
||||
});
|
||||
awakened-poe-trade = prev.callPackage ./awakened-poe-trade.nix {};
|
||||
kanidm-provision = prev.callPackage ./kanidm-provision.nix {};
|
||||
segoe-ui-ttf = prev.callPackage ./segoe-ui-ttf.nix {};
|
||||
zsh-histdb-skim = prev.callPackage ./zsh-skim-histdb.nix {};
|
||||
neovim-clean = prev.neovim-unwrapped.overrideAttrs (old: {
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
rustPlatform,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "kanidm-provision";
|
||||
version = "1.1.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "oddlama";
|
||||
repo = "kanidm-provision";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-tX24cszmWu7kB5Eoa3OrPqU1bayD62OpAV12U0ayoEo=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-Ok8A47z5Z3QW4teql/4RyDlox/nrhkdA6IN/qJm13bM=";
|
||||
|
||||
meta = with lib; {
|
||||
description = "A small utility to help with kanidm provisioning";
|
||||
homepage = "https://github.com/oddlama/kanidm-provision";
|
||||
license = with licenses; [asl20 mit];
|
||||
maintainers = with maintainers; [oddlama];
|
||||
mainProgram = "kanidm-provision";
|
||||
};
|
||||
}
|
149
pkgs/stal.nix
149
pkgs/stal.nix
|
@ -1,149 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
rustPlatform,
|
||||
fetchFromGitHub,
|
||||
fetchpatch,
|
||||
pkg-config,
|
||||
protobuf,
|
||||
bzip2,
|
||||
openssl,
|
||||
sqlite,
|
||||
foundationdb,
|
||||
zstd,
|
||||
stdenv,
|
||||
darwin,
|
||||
nix-update-script,
|
||||
nixosTests,
|
||||
rocksdb_8_11,
|
||||
}: let
|
||||
# Stalwart depends on rocksdb crate:
|
||||
# https://github.com/stalwartlabs/mail-server/blob/v0.8.0/crates/store/Cargo.toml#L10
|
||||
# which expects a specific rocksdb versions:
|
||||
# https://github.com/rust-rocksdb/rust-rocksdb/blob/v0.22.0/librocksdb-sys/Cargo.toml#L3
|
||||
# See upstream issue for rocksdb 9.X support
|
||||
# https://github.com/stalwartlabs/mail-server/issues/407
|
||||
rocksdb = rocksdb_8_11;
|
||||
version = "0.9.0";
|
||||
in
|
||||
rustPlatform.buildRustPackage {
|
||||
pname = "stalwart-mail";
|
||||
inherit version;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "stalwartlabs";
|
||||
repo = "mail-server";
|
||||
# XXX: We need to use a revisoin two commits after v0.9.0, which includes fixes for test cases.
|
||||
# Can be reverted to "v${version}" next release.
|
||||
rev = "2a12e251f2591b7785d7a921364f125d2e9c1e6e";
|
||||
hash = "sha256-qoU09tLpOlsy5lKv2GdCV23bd70hnNZ0r/O5APGVDyw=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
cargoHash = "sha256-rGCu3J+hTxiIENDIQM/jPz1wUNJr0ouoa1IkwWKfOWM=";
|
||||
|
||||
patches = [
|
||||
# Remove "PermissionsStartOnly" from systemd service files,
|
||||
# which is deprecated and conflicts with our module's ExecPreStart.
|
||||
# Upstream PR: https://github.com/stalwartlabs/mail-server/pull/528
|
||||
(fetchpatch {
|
||||
url = "https://github.com/stalwartlabs/mail-server/pull/528/commits/6e292b3d7994441e58e367b87967c9a277bce490.patch";
|
||||
hash = "sha256-j/Li4bYNE7IppxG3FGfljra70/rHyhRvDgOkZOlhMHY=";
|
||||
})
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
protobuf
|
||||
rustPlatform.bindgenHook
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
[
|
||||
bzip2
|
||||
openssl
|
||||
sqlite
|
||||
foundationdb
|
||||
zstd
|
||||
]
|
||||
++ lib.optionals stdenv.isDarwin [
|
||||
darwin.apple_sdk.frameworks.CoreFoundation
|
||||
darwin.apple_sdk.frameworks.Security
|
||||
darwin.apple_sdk.frameworks.SystemConfiguration
|
||||
];
|
||||
|
||||
env = {
|
||||
OPENSSL_NO_VENDOR = true;
|
||||
ZSTD_SYS_USE_PKG_CONFIG = true;
|
||||
ROCKSDB_INCLUDE_DIR = "${rocksdb}/include";
|
||||
ROCKSDB_LIB_DIR = "${rocksdb}/lib";
|
||||
};
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p $out/etc/stalwart
|
||||
cp resources/config/spamfilter.toml $out/etc/stalwart/spamfilter.toml
|
||||
cp -r resources/config/spamfilter $out/etc/stalwart/
|
||||
|
||||
mkdir -p $out/lib/systemd/system
|
||||
|
||||
substitute resources/systemd/stalwart-mail.service $out/lib/systemd/system/stalwart-mail.service \
|
||||
--replace "__PATH__" "$out"
|
||||
'';
|
||||
|
||||
checkFlags = [
|
||||
# Require running mysql, postgresql daemon
|
||||
"--skip=directory::imap::imap_directory"
|
||||
"--skip=directory::internal::internal_directory"
|
||||
"--skip=directory::ldap::ldap_directory"
|
||||
"--skip=directory::sql::sql_directory"
|
||||
"--skip=store::blob::blob_tests"
|
||||
"--skip=store::lookup::lookup_tests"
|
||||
# thread 'directory::smtp::lmtp_directory' panicked at tests/src/store/mod.rs:122:44:
|
||||
# called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }
|
||||
"--skip=directory::smtp::lmtp_directory"
|
||||
# thread 'imap::imap_tests' panicked at tests/src/imap/mod.rs:436:14:
|
||||
# Missing store type. Try running `STORE=<store_type> cargo test`: NotPresent
|
||||
"--skip=imap::imap_tests"
|
||||
# thread 'jmap::jmap_tests' panicked at tests/src/jmap/mod.rs:303:14:
|
||||
# Missing store type. Try running `STORE=<store_type> cargo test`: NotPresent
|
||||
"--skip=jmap::jmap_tests"
|
||||
# Failed to read system DNS config: io error: No such file or directory (os error 2)
|
||||
"--skip=smtp::inbound::data::data"
|
||||
# Expected "X-My-Header: true" but got Received: from foobar.net (unknown [10.0.0.123])
|
||||
"--skip=smtp::inbound::scripts::sieve_scripts"
|
||||
# panicked at tests/src/smtp/outbound/smtp.rs:173:5:
|
||||
"--skip=smtp::outbound::smtp::smtp_delivery"
|
||||
# thread 'smtp::queue::retry::queue_retry' panicked at tests/src/smtp/queue/retry.rs:119:5:
|
||||
# assertion `left == right` failed
|
||||
# left: [1, 2, 2]
|
||||
# right: [1, 2, 3]
|
||||
"--skip=smtp::queue::retry::queue_retry"
|
||||
# Missing store type. Try running `STORE=<store_type> cargo test`: NotPresent
|
||||
"--skip=store::store_tests"
|
||||
# thread 'config::parser::tests::toml_parse' panicked at crates/utils/src/config/parser.rs:463:58:
|
||||
# called `Result::unwrap()` on an `Err` value: "Expected ['\\n'] but found '!' in value at line 70."
|
||||
"--skip=config::parser::tests::toml_parse"
|
||||
# error[E0432]: unresolved import `r2d2_sqlite`
|
||||
# use of undeclared crate or module `r2d2_sqlite`
|
||||
"--skip=backend::sqlite::pool::SqliteConnectionManager::with_init"
|
||||
# thread 'smtp::reporting::analyze::report_analyze' panicked at tests/src/smtp/reporting/analyze.rs:88:5:
|
||||
# assertion `left == right` failed
|
||||
# left: 0
|
||||
# right: 12
|
||||
"--skip=smtp::reporting::analyze::report_analyze"
|
||||
];
|
||||
|
||||
doCheck = !(stdenv.isLinux && stdenv.isAarch64);
|
||||
|
||||
passthru = {
|
||||
update-script = nix-update-script {};
|
||||
tests.stalwart-mail = nixosTests.stalwart-mail;
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "Secure & Modern All-in-One Mail Server (IMAP, JMAP, SMTP)";
|
||||
homepage = "https://github.com/stalwartlabs/mail-server";
|
||||
changelog = "https://github.com/stalwartlabs/mail-server/blob/${version}/CHANGELOG";
|
||||
license = licenses.agpl3Only;
|
||||
maintainers = with maintainers; [happysalada onny oddlama];
|
||||
};
|
||||
}
|
|
@ -6,8 +6,7 @@
|
|||
}:
|
||||
lib.optionalAttrs (!minimal) {
|
||||
home = {
|
||||
packages = builtins.trace "reenable bandwhich later" (with pkgs; [
|
||||
#bandwhich
|
||||
packages = with pkgs; [
|
||||
btop
|
||||
delta
|
||||
fd
|
||||
|
@ -29,7 +28,7 @@ lib.optionalAttrs (!minimal) {
|
|||
wget
|
||||
usbutils
|
||||
pciutils
|
||||
]);
|
||||
];
|
||||
};
|
||||
|
||||
programs = {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
plugins = {
|
||||
luasnip = {
|
||||
enable = true;
|
||||
extraConfig = {
|
||||
settings = {
|
||||
history = true;
|
||||
# Update dynamic snippets while typing
|
||||
updateevents = "TextChanged,TextChangedI";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue