Compare commits
22 Commits
f2ca2bd317
...
dbc7be6376
Author | SHA1 | Date | |
---|---|---|---|
dbc7be6376 | |||
7cb753b5ae | |||
086b90ba40 | |||
e1cad63e03 | |||
3c6a03f09f | |||
523083b6dc | |||
732b0ecfa0 | |||
15244723e0 | |||
5ed18790da | |||
7f5baec450 | |||
e9ddba98e6 | |||
36d3ebd510 | |||
f56f99d107 | |||
aa91244df7 | |||
38fec28a21 | |||
762f67b21f | |||
0bfd296347 | |||
0a4a1126b8 | |||
5c71130851 | |||
7a32221b4e | |||
84e835a6a2 | |||
561eefff3e |
216
flake.lock
generated
216
flake.lock
generated
@ -8,11 +8,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718735045,
|
||||
"narHash": "sha256-5PaPrMjQu0ojps12ecRO6qFntCU+pkUCrJIjDUFJknE=",
|
||||
"lastModified": 1719327076,
|
||||
"narHash": "sha256-m9QOr0ut3qlWBCRCrggV7/my4oePeg9mAgUpyWvVOy8=",
|
||||
"owner": "ezKEa",
|
||||
"repo": "aagl-gtk-on-nix",
|
||||
"rev": "2d4d6c0f286bd6901c8eab5e2d08593ca3394d6c",
|
||||
"rev": "f98006101733084ad17ba328752d0c7f22cef359",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -24,11 +24,11 @@
|
||||
"arkenfox-userjs": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1717796213,
|
||||
"narHash": "sha256-Ex+eSb7tZ428MMJDIF/nqUOtnzjqEIPNaDXJPm9FvuY=",
|
||||
"lastModified": 1719071094,
|
||||
"narHash": "sha256-8mzY85wkUokd1Oau9D95Gp1myCJdGU0Dd47bmCygxnE=",
|
||||
"owner": "arkenfox",
|
||||
"repo": "user.js",
|
||||
"rev": "47cbf5b9740ef59ed866874346d3fee3379f8da3",
|
||||
"rev": "23caf6961483e0e55544cd4f3594734d0aa35cf0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -42,11 +42,11 @@
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718525922,
|
||||
"narHash": "sha256-hBXj+7nqwTQt1yMyy7SQhGlOTBII63rESvLE2kTI92M=",
|
||||
"lastModified": 1719476421,
|
||||
"narHash": "sha256-PBntLY2mQ0AUDdueyl43cyPPrhQYuTU7c+n68FpXJKM=",
|
||||
"owner": "AtaraxiaSjel",
|
||||
"repo": "nur",
|
||||
"rev": "dc3604665992f4cb4f96d3729d5775d1af895207",
|
||||
"rev": "b33a812a2d7f746af7bcd25810c021e16c1db24d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -164,11 +164,11 @@
|
||||
},
|
||||
"catppuccin": {
|
||||
"locked": {
|
||||
"lastModified": 1718339789,
|
||||
"narHash": "sha256-Q3fgY7huFE+uaw7BNsAl1x+FvjDAi3EDWPnlALJt5pM=",
|
||||
"lastModified": 1719457243,
|
||||
"narHash": "sha256-5rOWwMAp/suWVKGavhfdyLsF2mA7Fv2DQWXlt7S+QWA=",
|
||||
"owner": "catppuccin",
|
||||
"repo": "nix",
|
||||
"rev": "73e06d5bd7ed34bdd0168030893ef8364fdc1d4a",
|
||||
"rev": "53967ef237edd38a5b5cc5441e9b6a44b9554977",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -245,11 +245,11 @@
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718297307,
|
||||
"narHash": "sha256-itCqNMgHdfhL7z+7viDaiSyb1sJ36xKRPpZGoYKMVAc=",
|
||||
"lastModified": 1719323427,
|
||||
"narHash": "sha256-f4ppP2MBPJzkuy/q+PIfyyTWX9OzqgPV1XSphX71tdA=",
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"rev": "24b3e5dd32e85ab6bd234ff3eed1fc3670bea583",
|
||||
"rev": "f810f8d8cb4e674d7e635107510bcbbabaa755a3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -296,11 +296,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718242063,
|
||||
"narHash": "sha256-n3AWItJ4a94GT0cray/eUV7tt3mulQ52L+lWJN9d1E8=",
|
||||
"lastModified": 1719451710,
|
||||
"narHash": "sha256-h+bFEQHQ46pBkEsOXbxmmY6QNPPGrgpDbNlHtAKG49M=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "832a9f2c81ff3485404bd63952eadc17bf7ccef2",
|
||||
"rev": "8767dbf5d723b1b6834f4d09b217da7c31580d58",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -566,16 +566,16 @@
|
||||
"flake-utils": "flake-utils_5"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1696281284,
|
||||
"narHash": "sha256-xcmtTmoiiAOSk4abifbtqVZk0iwBcqJfg47iUbkwhcE=",
|
||||
"lastModified": 1715533576,
|
||||
"narHash": "sha256-fT4ppWeCJ0uR300EH3i7kmgRZnAVxrH+XtK09jQWihk=",
|
||||
"owner": "gytis-ivaskevicius",
|
||||
"repo": "flake-utils-plus",
|
||||
"rev": "6cf1e312fb259693c4930d07ca3cbe1d07ef4a48",
|
||||
"rev": "3542fe9126dc492e53ddd252bb0260fe035f2c0f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "gytis-ivaskevicius",
|
||||
"ref": "v1.4.0",
|
||||
"ref": "1.5.0",
|
||||
"repo": "flake-utils-plus",
|
||||
"type": "github"
|
||||
}
|
||||
@ -769,11 +769,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718788307,
|
||||
"narHash": "sha256-SqiOz0sljM0GjyQEVinPXQxaGcbOXw5OgpCWGPgh/vo=",
|
||||
"lastModified": 1719438532,
|
||||
"narHash": "sha256-/Vmso2ZMoFE3M7d1MRsQ2K5sR8CVKnrM6t1ys9Xjpz4=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "d7830d05421d0ced83a0f007900898bdcaf2a2ca",
|
||||
"rev": "1a4f12ae0bda877ec4099b429cf439aad897d7e9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -798,11 +798,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717181720,
|
||||
"narHash": "sha256-yv+QZWsusu/NWjydkxixHC2g+tIJ9v+xkE2EiVpJj6g=",
|
||||
"lastModified": 1718450675,
|
||||
"narHash": "sha256-jpsns6buS4bK+1sF8sL8AaixAiCRjA+nldTKvcwmvUs=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprcursor",
|
||||
"rev": "9e27a2c2ceb1e0b85bd55b0afefad196056fe87c",
|
||||
"rev": "66d5b46ff94efbfa6fa3d1d1b66735f1779c34a6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -824,11 +824,11 @@
|
||||
"xdph": "xdph"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718313803,
|
||||
"narHash": "sha256-OpXugBH3tF9Jc3Vt0gnqhdQvlNmte7Km1SmyIDo1G3Y=",
|
||||
"lastModified": 1719350558,
|
||||
"narHash": "sha256-xZqPfxOvvBWPTfJnxoyUVewVQjQssxETYbxZ+fySFhg=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "Hyprland",
|
||||
"rev": "8055b1c00a102f5419e40f5eddfb6ee8be693f33",
|
||||
"rev": "e4d09aa3a9de9a9e71c10bf4b6800585b3db9a4c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -851,11 +851,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1691753796,
|
||||
"narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=",
|
||||
"lastModified": 1714869498,
|
||||
"narHash": "sha256-vbLVOWvQqo4n1yvkg/Q70VTlPbMmTiCQfNTgcWDCfJM=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03",
|
||||
"rev": "e06482e0e611130cd1929f75e8c1cf679e57d161",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -946,11 +946,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717881334,
|
||||
"narHash": "sha256-a0inRgJhPL6v9v7RPM/rx1kbXdfe3xJA1c9z0ZkYnh4=",
|
||||
"lastModified": 1719316102,
|
||||
"narHash": "sha256-dmRz128j/lJmMuTYeCYPfSBRHHQO3VeH4PbmoyAhHzw=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "0693f9398ab693d89c9a0aa3b3d062dd61b7a60e",
|
||||
"rev": "1f6bbec5954f623ff8d68e567bddcce97cd2f085",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -971,11 +971,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717784906,
|
||||
"narHash": "sha256-YxmfxHfWed1fosaa7fC1u7XoKp1anEZU+7Lh/ojRKoM=",
|
||||
"lastModified": 1719067853,
|
||||
"narHash": "sha256-mAnZG/eQy72Fp1ImGtqCgUrDumnR1rMZv2E/zgP4U74=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwayland-scanner",
|
||||
"rev": "0f30f9eca6e404130988554accbb64d1c9ec877d",
|
||||
"rev": "914f083741e694092ee60a39d31f693d0a6dc734",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -986,11 +986,11 @@
|
||||
},
|
||||
"impermanence": {
|
||||
"locked": {
|
||||
"lastModified": 1717932370,
|
||||
"narHash": "sha256-7C5lCpiWiyPoIACOcu2mukn/1JRtz6HC/1aEMhUdcw0=",
|
||||
"lastModified": 1719091691,
|
||||
"narHash": "sha256-AxaLX5cBEcGtE02PeGsfscSb/fWMnyS7zMWBXQWDKbE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "impermanence",
|
||||
"rev": "27979f1c3a0d3b9617a3563e2839114ba7d48d3f",
|
||||
"rev": "23c1f06316b67cb5dabdfe2973da3785cfe9c34a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1089,11 +1089,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1715754082,
|
||||
"narHash": "sha256-2hAydsdMk6QmDar+16ryyn+pVksxudwC5vRiatJbysM=",
|
||||
"lastModified": 1718448591,
|
||||
"narHash": "sha256-TDzUlwvCmkY4IzEMLV7vmB/GlKznsS+/oBO4Z6z9ACE=",
|
||||
"owner": "thiagokokada",
|
||||
"repo": "nix-alien",
|
||||
"rev": "ea6ebda03c5537eebbb93af57ca6f2c2979981be",
|
||||
"rev": "d457975f39a4eaf8bec55b7cc3ff26226d4fb062",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1109,11 +1109,11 @@
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717994481,
|
||||
"narHash": "sha256-sm2Dd21dT0g7akjySmMN0X3jT0/vN0wvBEjcJE/HzwU=",
|
||||
"lastModified": 1718859026,
|
||||
"narHash": "sha256-DHUQqshVVBNuHRGEWXObNor7OIHGj2fVNbn8j1TuS2I=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nix-direnv",
|
||||
"rev": "40db0380eb86cf8479ce8eef63b68b47c77e66c5",
|
||||
"rev": "bdce8848530fc882ecb151a7eb131757e5d458ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1131,11 +1131,11 @@
|
||||
"treefmt-nix": "treefmt-nix_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1715803356,
|
||||
"narHash": "sha256-wvsg/UMM/jekzgbggH56KLZJzRmwrB9ErevaXXyWyqc=",
|
||||
"lastModified": 1719475157,
|
||||
"narHash": "sha256-8zW6eWvE9T03cMpo/hY8RRZIsSCfs1zmsJOkEZzuYwM=",
|
||||
"owner": "Mic92",
|
||||
"repo": "nix-fast-build",
|
||||
"rev": "cfff239d93716e92f6467f8953d8f8c12da1892a",
|
||||
"rev": "030e586195c97424844965d2ce680140f6565c02",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1188,11 +1188,11 @@
|
||||
"nixpkgs": "nixpkgs_11"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1715483403,
|
||||
"narHash": "sha256-WMDuQj7J5jbpXI/X/E6FZRKgBFGcaSTvYyVxPnKE6KU=",
|
||||
"lastModified": 1718011381,
|
||||
"narHash": "sha256-sFXI+ZANp/OC+MwfJoZgPSf4xMdtzQMe1pS3FGti4C8=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nix-index-database",
|
||||
"rev": "f9027322f48b427da23746aa359a6510dfcd0228",
|
||||
"rev": "88ad3d7501e22b2401dd72734b032b7baa794434",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1210,11 +1210,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718673998,
|
||||
"narHash": "sha256-0fYv4qkbp1buCAEIuFnsN0NUFcI6SlSHiuG5YwDl5kU=",
|
||||
"lastModified": 1719451583,
|
||||
"narHash": "sha256-2FHGp9cH5q42yVdYAfLjMCYJgr+VYfMW4LYmCOptlpg=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nix-vscode-extensions",
|
||||
"rev": "b1d364d5f9d3d7fee8fa854d553cd95d69b9ff4c",
|
||||
"rev": "4157bcc67488e09407f5edc130ebf62c1a1a1433",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1272,11 +1272,11 @@
|
||||
},
|
||||
"nixlib": {
|
||||
"locked": {
|
||||
"lastModified": 1712450863,
|
||||
"narHash": "sha256-K6IkdtMtq9xktmYPj0uaYc8NsIqHuaAoRBaMgu9Fvrw=",
|
||||
"lastModified": 1719103869,
|
||||
"narHash": "sha256-kbTUy+/lfjUrMfV7JkTJwxowsFhi9Tb3BdbiOcIGcsc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "3c62b6a12571c9a7f65ab037173ee153d539905f",
|
||||
"rev": "f820613f886cd1aa4bcfd1dbaa6c83c8a3dcd863",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1293,11 +1293,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718025593,
|
||||
"narHash": "sha256-WZ1gdKq/9u1Ns/oXuNsDm+W0salonVA0VY1amw8urJ4=",
|
||||
"lastModified": 1719450236,
|
||||
"narHash": "sha256-fh0l6pLvuTrTBakFMQfK7lwpjvWd5i+CFyVs8TMzPNo=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-generators",
|
||||
"rev": "35c20ba421dfa5059e20e0ef2343c875372bdcf3",
|
||||
"rev": "1867f28f87fcf4e817f165003aff967a5280aaab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1336,11 +1336,11 @@
|
||||
},
|
||||
"nixpkgs-master": {
|
||||
"locked": {
|
||||
"lastModified": 1718334394,
|
||||
"narHash": "sha256-eDQUMwMfrv/vxSCcgPL4THGG9k5rRy2k2U9cNJk9nzE=",
|
||||
"lastModified": 1719483014,
|
||||
"narHash": "sha256-A7z3iygqdSgs659vGIH2b66oM6lbXw1j9yXwV+JzmRY=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8dbf10c3c93d97ac91bdfe248b5cd7173481c5b6",
|
||||
"rev": "c3d2469feee46b3ca1aca909f4257c53186f310b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1432,11 +1432,11 @@
|
||||
},
|
||||
"nixpkgs-stable_3": {
|
||||
"locked": {
|
||||
"lastModified": 1718208800,
|
||||
"narHash": "sha256-US1tAChvPxT52RV8GksWZS415tTS7PV42KTc2PNDBmc=",
|
||||
"lastModified": 1719426051,
|
||||
"narHash": "sha256-yJL9VYQhaRM7xs0M867ZFxwaONB9T2Q4LnGo1WovuR4=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cc54fb41d13736e92229c21627ea4f22199fee6b",
|
||||
"rev": "89c49874fb15f4124bf71ca5f42a04f2ee5825fd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1448,11 +1448,11 @@
|
||||
},
|
||||
"nixpkgs-stable_4": {
|
||||
"locked": {
|
||||
"lastModified": 1717880976,
|
||||
"narHash": "sha256-BRvSCsKtDUr83NEtbGfHLUOdDK0Cgbezj2PtcHnz+sQ=",
|
||||
"lastModified": 1719099622,
|
||||
"narHash": "sha256-YzJECAxFt+U5LPYf/pCwW/e1iUd2PF21WITHY9B/BAs=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4913a7c3d8b8d00cb9476a6bd730ff57777f740c",
|
||||
"rev": "5e8e3b89adbd0be63192f6e645e0a54080004924",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1480,15 +1480,15 @@
|
||||
},
|
||||
"nixpkgs_11": {
|
||||
"locked": {
|
||||
"lastModified": 1715266358,
|
||||
"narHash": "sha256-doPgfj+7FFe9rfzWo1siAV2mVCasW+Bh8I1cToAXEE4=",
|
||||
"owner": "nixos",
|
||||
"lastModified": 1717786204,
|
||||
"narHash": "sha256-4q0s6m0GUcN7q+Y2DqD27iLvbcd1G50T2lv08kKxkSI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f1010e0469db743d14519a1efd37e23f8513d714",
|
||||
"rev": "051f920625ab5aabe37c920346e3e69d7d34400e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
@ -1496,11 +1496,11 @@
|
||||
},
|
||||
"nixpkgs_12": {
|
||||
"locked": {
|
||||
"lastModified": 1717868076,
|
||||
"narHash": "sha256-c83Y9t815Wa34khrux81j8K8ET94ESmCuwORSKm2bQY=",
|
||||
"lastModified": 1718606988,
|
||||
"narHash": "sha256-pmjP5ePc1jz+Okona3HxD7AYT0wbrCwm9bXAlj08nDM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cd18e2ae9ab8e2a0a8d715b60c91b54c0ac35ff9",
|
||||
"rev": "38d3352a65ac9d621b0cd3074d3bef27199ff78f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1512,11 +1512,11 @@
|
||||
},
|
||||
"nixpkgs_13": {
|
||||
"locked": {
|
||||
"lastModified": 1718160348,
|
||||
"narHash": "sha256-9YrUjdztqi4Gz8n3mBuqvCkMo4ojrA6nASwyIKWMpus=",
|
||||
"lastModified": 1719254875,
|
||||
"narHash": "sha256-ECni+IkwXjusHsm9Sexdtq8weAq/yUyt1TWIemXt3Ko=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "57d6973abba7ea108bac64ae7629e7431e0199b6",
|
||||
"rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1528,16 +1528,16 @@
|
||||
},
|
||||
"nixpkgs_14": {
|
||||
"locked": {
|
||||
"lastModified": 1717112898,
|
||||
"narHash": "sha256-7R2ZvOnvd9h8fDd65p0JnB7wXfUvreox3xFdYWd1BnY=",
|
||||
"owner": "nixos",
|
||||
"lastModified": 1718276985,
|
||||
"narHash": "sha256-u1fA0DYQYdeG+5kDm1bOoGcHtX0rtC7qs2YA2N1X++I=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "6132b0f6e344ce2fe34fc051b72fb46e34f668e0",
|
||||
"rev": "3f84a279f1a6290ce154c5531378acc827836fbb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@ -1740,11 +1740,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1716213921,
|
||||
"narHash": "sha256-xrsYFST8ij4QWaV6HEokCUNIZLjjLP1bYC60K8XiBVA=",
|
||||
"lastModified": 1717664902,
|
||||
"narHash": "sha256-7XfBuLULizXjXfBYy/VV+SpYMHreNRHk9nKMsm1bgb4=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "0e8fcc54b842ad8428c9e705cb5994eaf05c26a0",
|
||||
"rev": "cc4d466cb1254af050ff7bdf47f6d404a7c646d1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1762,11 +1762,11 @@
|
||||
"pre-commit-hooks": "pre-commit-hooks_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717816313,
|
||||
"narHash": "sha256-GCNM9mlbHML1uISUuZquyPbrPfvHT+ZBM+M1u4H5JfM=",
|
||||
"lastModified": 1719025961,
|
||||
"narHash": "sha256-XlBQF+1+hd3Jep7we0zUCpigvcY4ESV8MsVqZv4CKhI=",
|
||||
"owner": "AtaraxiaSjel",
|
||||
"repo": "PrismLauncher",
|
||||
"rev": "6b48bb6b93f5fdbd2a96fa07f29f5da9f7a3c4f0",
|
||||
"rev": "755d56101f9cd1ee134afc4c2d6765720c2cf24b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -1814,11 +1814,11 @@
|
||||
"rycee": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1718251401,
|
||||
"narHash": "sha256-enzmGqA0Cjwoh3ptVvbFh+ZUxwavM0awYJPK/KnLH3E=",
|
||||
"lastModified": 1719461007,
|
||||
"narHash": "sha256-1Tayi+LGCNB2mPaBdQ4k6TXTBjTDq82aFj0qQtoM8P0=",
|
||||
"owner": "rycee",
|
||||
"repo": "nur-expressions",
|
||||
"rev": "89accb69b1fd641dbafba9619a30b50af318820b",
|
||||
"rev": "40d828403e999d99480fe53940a2f376599bde95",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
@ -1835,11 +1835,11 @@
|
||||
"nixpkgs-stable": "nixpkgs-stable_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718137936,
|
||||
"narHash": "sha256-psA+1Q5fPaK6yI3vzlLINNtb6EeXj111zQWnZYyJS9c=",
|
||||
"lastModified": 1719268571,
|
||||
"narHash": "sha256-pcUk2Fg5vPXLUEnFI97qaB8hto/IToRfqskFqsjvjb8=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "c279dec105dd53df13a5e57525da97905cc0f0d6",
|
||||
"rev": "c2ea1186c0cbfa4d06d406ae50f3e4b085ddc9b3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -2006,11 +2006,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717850719,
|
||||
"narHash": "sha256-npYqVg+Wk4oxnWrnVG7416fpfrlRhp/lQ6wQ4DHI8YE=",
|
||||
"lastModified": 1718522839,
|
||||
"narHash": "sha256-ULzoKzEaBOiLRtjeY3YoGFJMwWSKRYOic6VNw2UyTls=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "4fc1c45a5f50169f9f29f6a98a438fb910b834ed",
|
||||
"rev": "68eb1dc333ce82d0ab0c0357363ea17c31ea1f81",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -2096,11 +2096,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717918856,
|
||||
"narHash": "sha256-I38bmPLqamvOfVSArd1hhZtkVRAYBK38fOHZCU1P9Qg=",
|
||||
"lastModified": 1718619174,
|
||||
"narHash": "sha256-FWW68AVYmB91ZDQnhLMBNCUUTCjb1ZpO2k2KIytHtkA=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"rev": "72907822c19afc0983c69d59d299204381623725",
|
||||
"rev": "c7894aa54f9a7dbd16df5cd24d420c8af22d5623",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
15
flake.nix
15
flake.nix
@ -2,7 +2,7 @@
|
||||
description = "System configuration";
|
||||
|
||||
inputs = {
|
||||
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/v1.4.0";
|
||||
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/1.5.0";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nixpkgs-master.url = "github:nixos/nixpkgs/master";
|
||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05";
|
||||
@ -117,8 +117,7 @@
|
||||
secretsDir = ./secrets;
|
||||
|
||||
sharedPatches = patchesPath [
|
||||
"onlyoffice.patch"
|
||||
"vaultwarden.patch"
|
||||
|
||||
];
|
||||
sharedOverlays = [ flake-utils-plus.overlay inputs.sops-nix.overlays.default ];
|
||||
channelsConfig = {
|
||||
@ -126,9 +125,15 @@
|
||||
# permittedInsecurePackages = [ "electron-25.9.0" ];
|
||||
};
|
||||
channels.unstable.input = nixpkgs;
|
||||
channels.unstable.patches = patchesPath [ "zen-kernels.patch" ] ++ sharedPatches;
|
||||
channels.unstable.patches = sharedPatches ++ patchesPath [
|
||||
"onlyoffice.patch" "vaultwarden.patch"
|
||||
"jaxlib.patch" "zen-kernels.patch"
|
||||
"netbird-24.11.patch"
|
||||
];
|
||||
channels.stable.input = inputs.nixpkgs-stable;
|
||||
channels.stable.patches = sharedPatches;
|
||||
channels.stable.patches = sharedPatches ++ patchesPath [
|
||||
"netbird-24.05.patch"
|
||||
];
|
||||
|
||||
hostDefaults.system = "x86_64-linux";
|
||||
hostDefaults.channelName = "unstable";
|
||||
|
@ -81,7 +81,7 @@
|
||||
services.openssh.settings.PermitRootLogin = lib.mkForce "without-password";
|
||||
services.ratbagd.enable = true;
|
||||
# Networking
|
||||
networking.firewall.allowedTCPPorts = [ 8000 5900 52736 ];
|
||||
networking.firewall.allowedTCPPorts = [ 8000 5900 52736 3456 ];
|
||||
networking.nameservers = [ "192.168.0.1" ];
|
||||
networking.defaultGateway = "192.168.0.1";
|
||||
networking.bridges.br0.interfaces = [ "enp9s0" ];
|
||||
@ -103,7 +103,7 @@
|
||||
# pkgs.nix-init
|
||||
pkgs.nixpkgs-review
|
||||
pkgs.anydesk
|
||||
# pkgs.winbox
|
||||
pkgs.winbox
|
||||
pkgs.devenv
|
||||
pkgs.radeontop
|
||||
pkgs.wayvnc
|
||||
@ -120,7 +120,24 @@
|
||||
home.stateVersion = "24.05";
|
||||
};
|
||||
|
||||
services.netbird.clients.priv = {
|
||||
interface = "wt0";
|
||||
port = 58467;
|
||||
hardened = false;
|
||||
ui.enable = true;
|
||||
autoStart = false;
|
||||
config = {
|
||||
AdminURL.Host = "net.ataraxiadev.com:443";
|
||||
AdminURL.Scheme = "https";
|
||||
ManagementURL.Host = "net.ataraxiadev.com:443";
|
||||
ManagementURL.Scheme = "https";
|
||||
RosenpassEnabled = true;
|
||||
RosenpassPermissive = true;
|
||||
};
|
||||
};
|
||||
|
||||
persist.state = {
|
||||
directories = [ "/var/lib/netbird-priv" ];
|
||||
homeDirectories = [
|
||||
".local/share/winbox"
|
||||
".local/share/PrismLauncher"
|
||||
|
@ -2,7 +2,7 @@
|
||||
let persistRoot = config.autoinstall.persist.persistRoot or "/persist";
|
||||
in {
|
||||
imports = with inputs.self; [
|
||||
./backups.nix
|
||||
# ./backups.nix
|
||||
./boot.nix
|
||||
./hardware-configuration.nix
|
||||
./usb-hdd.nix
|
||||
@ -10,27 +10,31 @@ in {
|
||||
customProfiles.hardened
|
||||
customRoles.hypervisor
|
||||
|
||||
customProfiles.tg-bot
|
||||
|
||||
customProfiles.acme
|
||||
customProfiles.attic
|
||||
customProfiles.atticd
|
||||
customProfiles.authentik
|
||||
customProfiles.battery-historian
|
||||
customProfiles.coturn
|
||||
customProfiles.fail2ban
|
||||
customProfiles.gitea
|
||||
customProfiles.homepage
|
||||
# customProfiles.homepage
|
||||
customProfiles.hoyolab
|
||||
customProfiles.inpx-web
|
||||
# customProfiles.inpx-web
|
||||
customProfiles.it-tools
|
||||
customProfiles.media-stack
|
||||
customProfiles.metrics
|
||||
customProfiles.minio
|
||||
# customProfiles.media-stack
|
||||
# customProfiles.metrics
|
||||
# customProfiles.minio
|
||||
customProfiles.netbird-server
|
||||
customProfiles.nginx
|
||||
customProfiles.ocis
|
||||
customProfiles.onlyoffice
|
||||
customProfiles.openbooks
|
||||
# customProfiles.ocis
|
||||
# customProfiles.onlyoffice
|
||||
# customProfiles.openbooks
|
||||
customProfiles.outline
|
||||
customProfiles.radicale
|
||||
customProfiles.spdf
|
||||
# customProfiles.spdf
|
||||
customProfiles.synapse
|
||||
customProfiles.tinyproxy
|
||||
customProfiles.vault
|
||||
@ -58,7 +62,6 @@ in {
|
||||
fileSystem = "zfs";
|
||||
};
|
||||
deviceSpecific.isServer = true;
|
||||
deviceSpecific.enableVirtualisation = true;
|
||||
deviceSpecific.vpn.tailscale.enable = true;
|
||||
# Tailscale auto-login
|
||||
services.headscale-auth.home-hypervisor = {
|
||||
@ -133,7 +136,7 @@ in {
|
||||
networking.networkmanager.enable = false;
|
||||
networking.hostName = config.device;
|
||||
|
||||
networking.nameservers = [ "192.168.0.1" ];
|
||||
networking.nameservers = [ "192.168.0.5" "192.168.0.1" "9.9.9.9" ];
|
||||
networking.defaultGateway = "192.168.0.1";
|
||||
networking.bridges.br0.interfaces = [ "enp2s0f0" ];
|
||||
networking.interfaces.br0 = {
|
||||
|
@ -18,6 +18,7 @@
|
||||
{ name = "lib.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
|
||||
{ name = "matrix.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
|
||||
{ name = "medusa.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
|
||||
{ name = "net.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
|
||||
{ name = "openbooks.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
|
||||
{ name = "pdf.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
|
||||
{ name = "qbit.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
|
||||
@ -50,6 +51,7 @@
|
||||
{ name = "lib.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
|
||||
{ name = "matrix.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
|
||||
{ name = "medusa.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
|
||||
{ name = "net.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
|
||||
{ name = "openbooks.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
|
||||
{ name = "pdf.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
|
||||
{ name = "qbit.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
|
||||
@ -85,6 +87,7 @@
|
||||
"/ldap.ataraxiadev.com/192.168.0.10"
|
||||
"/lib.ataraxiadev.com/192.168.0.10"
|
||||
"/medusa.ataraxiadev.com/192.168.0.10"
|
||||
"/net.ataraxiadev.com/192.168.0.10"
|
||||
"/openbooks.ataraxiadev.com/192.168.0.10"
|
||||
"/pdf.ataraxiadev.com/192.168.0.10"
|
||||
"/qbit.ataraxiadev.com/192.168.0.10"
|
||||
|
@ -1,11 +1,11 @@
|
||||
{ ... }: {
|
||||
boot.initrd = rec {
|
||||
luks.devices = {
|
||||
"crypt-nas" = {
|
||||
device = "/dev/disk/by-id/usb-JMicron_Tech_A311737E-0:0";
|
||||
keyFile = "/nas_keyfile0.bin";
|
||||
};
|
||||
};
|
||||
# luks.devices = {
|
||||
# "crypt-nas" = {
|
||||
# device = "/dev/disk/by-id/usb-JMicron_Tech_A311737E-0:0";
|
||||
# keyFile = "/nas_keyfile0.bin";
|
||||
# };
|
||||
# };
|
||||
secrets = {
|
||||
"nas_keyfile0.bin" = "/etc/secrets/nas_keyfile0.bin";
|
||||
};
|
||||
@ -19,5 +19,5 @@
|
||||
kernelModules = availableKernelModules;
|
||||
};
|
||||
|
||||
boot.zfs.extraPools = [ "nas-pool" ];
|
||||
# boot.zfs.extraPools = [ "nas-pool" ];
|
||||
}
|
@ -1,61 +1,17 @@
|
||||
{ config, pkgs, lib, ... }: {
|
||||
{ config, pkgs, lib, inputs, ... }: {
|
||||
imports = with inputs.self; [
|
||||
customProfiles.virtualisation
|
||||
];
|
||||
deviceSpecific.enableVirtualisation = true;
|
||||
|
||||
boot.kernelModules = [ "x_tables" ];
|
||||
|
||||
environment.systemPackages = [ pkgs.virtiofsd ];
|
||||
|
||||
virtualisation = {
|
||||
oci-containers.backend = lib.mkForce "podman";
|
||||
docker.enable = lib.mkForce false;
|
||||
podman = {
|
||||
enable = true;
|
||||
extraPackages = [ pkgs.zfs ];
|
||||
dockerSocket.enable = true;
|
||||
};
|
||||
containers.registries.search = [
|
||||
"docker.io" "gcr.io" "quay.io"
|
||||
];
|
||||
containers.storage.settings = {
|
||||
storage = {
|
||||
driver = "overlay";
|
||||
# driver = "zfs";
|
||||
graphroot = "/var/lib/podman/storage";
|
||||
runroot = "/run/containers/storage";
|
||||
};
|
||||
};
|
||||
lxd = {
|
||||
enable = true;
|
||||
zfsSupport = true;
|
||||
recommendedSysctlSettings = true;
|
||||
};
|
||||
lxc = {
|
||||
enable = true;
|
||||
lxcfs.enable = true;
|
||||
systemConfig = ''
|
||||
lxc.lxcpath = /var/lib/lxd/containers
|
||||
lxc.bdev.zfs.root = rpool/persistent/lxd
|
||||
'';
|
||||
};
|
||||
libvirtd = {
|
||||
enable = true;
|
||||
qemu = {
|
||||
ovmf.enable = true;
|
||||
ovmf.packages = [
|
||||
pkgs.OVMFFull.fd
|
||||
];
|
||||
runAsRoot = false;
|
||||
};
|
||||
onBoot = "ignore";
|
||||
onShutdown = "shutdown";
|
||||
};
|
||||
};
|
||||
|
||||
security.unprivilegedUsernsClone = true;
|
||||
|
||||
home-manager.users.${config.mainuser} = {
|
||||
home.file.".config/containers/storage.conf".text = ''
|
||||
[storage]
|
||||
driver = "overlay"
|
||||
'';
|
||||
podman.defaultNetwork.settings.dns_enabled = lib.mkForce false;
|
||||
podman.extraPackages = [ pkgs.zfs ];
|
||||
spiceUSBRedirection.enable = lib.mkForce false;
|
||||
containers.storage.settings.storage.graphroot = lib.mkForce "/var/lib/podman/storage";
|
||||
};
|
||||
|
||||
users.users.${config.mainuser} = {
|
||||
@ -68,6 +24,4 @@
|
||||
startGid = 10000;
|
||||
}];
|
||||
};
|
||||
|
||||
networking.firewall.interfaces."podman+".allowedUDPPorts = [ 53 5353 ];
|
||||
}
|
@ -143,7 +143,7 @@
|
||||
# Locale
|
||||
i18n.defaultLocale = "en_IE.UTF-8";
|
||||
i18n.extraLocaleSettings = {
|
||||
LANGUAGE = "en_IE:en:C:ru_RU";
|
||||
LANGUAGE = "en_IE:en_US:en:C:ru_RU";
|
||||
LC_TIME = "en_DK.UTF-8";
|
||||
LC_ADDRESS = "ru_RU.UTF-8";
|
||||
LC_MONETARY = "ru_RU.UTF-8";
|
||||
|
@ -2,7 +2,7 @@
|
||||
nix = {
|
||||
nixPath = lib.mkForce [ "self=/etc/self/compat" "nixpkgs=/etc/nixpkgs" ];
|
||||
registry.self.flake = inputs.self;
|
||||
registry.nixpkgs.flake = inputs.nixpkgs;
|
||||
# registry.nixpkgs.flake = inputs.nixpkgs;
|
||||
optimise.automatic = lib.mkDefault true;
|
||||
extraOptions = ''
|
||||
builders-use-substitutes = true
|
||||
|
@ -3,9 +3,11 @@ let
|
||||
bridgeName = (import ../hardware/networks.nix).interfaces.main'.bridgeName;
|
||||
tailscalePort = config.services.tailscale.port;
|
||||
tailscaleIfname = config.services.tailscale.interfaceName;
|
||||
netbirdPort = config.services.netbird.clients.priv.port;
|
||||
netbirdIfname = config.services.netbird.clients.priv.interface;
|
||||
in {
|
||||
networking.firewall.interfaces.${bridgeName}.allowedUDPPorts = [ tailscalePort ];
|
||||
networking.firewall.trustedInterfaces = [ tailscaleIfname ];
|
||||
networking.firewall.interfaces.${bridgeName}.allowedUDPPorts = [ tailscalePort netbirdPort ];
|
||||
networking.firewall.trustedInterfaces = [ tailscaleIfname netbirdIfname ];
|
||||
|
||||
systemd.network.networks."50-tailscale" = {
|
||||
matchConfig.Name = tailscaleIfname;
|
||||
@ -19,5 +21,22 @@ in {
|
||||
useRoutingFeatures = "both";
|
||||
};
|
||||
|
||||
persist.state.directories = [ "/var/lib/tailscale" ];
|
||||
services.netbird.clients.priv = {
|
||||
interface = "wt0";
|
||||
port = 52674;
|
||||
hardened = false;
|
||||
ui.enable = false;
|
||||
config = {
|
||||
AdminURL.Host = "net.ataraxiadev.com:443";
|
||||
AdminURL.Scheme = "https";
|
||||
ManagementURL.Host = "net.ataraxiadev.com:443";
|
||||
ManagementURL.Scheme = "https";
|
||||
DisableAutoConnect = false;
|
||||
RosenpassEnabled = true;
|
||||
RosenpassPermissive = true;
|
||||
};
|
||||
};
|
||||
users.users.${config.mainuser}.extraGroups = [ "netbird-priv" ];
|
||||
|
||||
persist.state.directories = [ "/var/lib/tailscale" "/var/lib/netbird-priv" ];
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
{ config, pkgs, inputs, ... }:
|
||||
{ config, pkgs, inputs, modulesPath, ... }:
|
||||
let
|
||||
inherit (pkgs.hostPlatform) system;
|
||||
cert-key = config.sops.secrets."cert.key".path;
|
||||
@ -6,6 +6,7 @@ let
|
||||
nginx-conf = config.sops.secrets."nginx.conf".path;
|
||||
marzban-env = config.sops.secrets.marzban.path;
|
||||
in {
|
||||
disabledModules = [ "${modulesPath}/services/web-apps/ocis.nix" ];
|
||||
imports = [ inputs.ataraxiasjel-nur.nixosModules.ocis ];
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
|
13
patches/jaxlib.patch
Normal file
13
patches/jaxlib.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/pkgs/development/python-modules/jaxlib/default.nix b/pkgs/development/python-modules/jaxlib/default.nix
|
||||
index b77a7de7b..a00def5fb 100644
|
||||
--- a/pkgs/development/python-modules/jaxlib/default.nix
|
||||
+++ b/pkgs/development/python-modules/jaxlib/default.nix
|
||||
@@ -377,7 +377,7 @@ let
|
||||
{ x86_64-linux = "sha256-vUoAPkYKEnHkV4fw6BI0mCeuP2e8BMCJnVuZMm9LwSA="; }
|
||||
else
|
||||
{
|
||||
- x86_64-linux = "sha256-R1TIIyyyLlDqAlUkuhJhtyTxZMra2q5S/jX0OCInsEQ=";
|
||||
+ x86_64-linux = "sha256-R5Bm+0GYN1zJ1aEUBW76907MxYKAIawHHJoIb1RdsKE=";
|
||||
aarch64-linux = "sha256-P5JEmJljN1DeRA0dNkzyosKzRnJH+5SD2aWdV5JsoiY=";
|
||||
}
|
||||
).${effectiveStdenv.system} or (throw "jaxlib: unsupported system: ${effectiveStdenv.system}");
|
603
patches/netbird-24.05.patch
Normal file
603
patches/netbird-24.05.patch
Normal file
@ -0,0 +1,603 @@
|
||||
diff --git a/nixos/modules/services/networking/netbird.nix b/nixos/modules/services/networking/netbird.nix
|
||||
index 7add37789..0160a8964 100644
|
||||
--- a/nixos/modules/services/networking/netbird.nix
|
||||
+++ b/nixos/modules/services/networking/netbird.nix
|
||||
@@ -1,73 +1,155 @@
|
||||
-{
|
||||
- config,
|
||||
- lib,
|
||||
- pkgs,
|
||||
- ...
|
||||
+{ config
|
||||
+, lib
|
||||
+, pkgs
|
||||
+, ...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
- attrNames
|
||||
+ attrValues
|
||||
+ concatLists
|
||||
+ concatStringsSep
|
||||
+ escapeShellArgs
|
||||
+ filterAttrs
|
||||
getExe
|
||||
literalExpression
|
||||
maintainers
|
||||
+ makeBinPath
|
||||
mapAttrs'
|
||||
+ mapAttrsToList
|
||||
mkDefault
|
||||
- mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
+ mkOptionDefault
|
||||
mkPackageOption
|
||||
+ mkRemovedOptionModule
|
||||
nameValuePair
|
||||
optional
|
||||
+ optionalString
|
||||
+ toShellVars
|
||||
+ versionAtLeast
|
||||
versionOlder
|
||||
;
|
||||
|
||||
inherit (lib.types)
|
||||
attrsOf
|
||||
+ bool
|
||||
+ enum
|
||||
+ package
|
||||
port
|
||||
str
|
||||
submodule
|
||||
;
|
||||
|
||||
- kernel = config.boot.kernelPackages;
|
||||
+ inherit (config.boot) kernelPackages;
|
||||
+ inherit (config.boot.kernelPackages) kernel;
|
||||
|
||||
cfg = config.services.netbird;
|
||||
+
|
||||
+ toClientList = fn: map fn (attrValues cfg.clients);
|
||||
+ toClientAttrs = fn: mapAttrs' (_: fn) cfg.clients;
|
||||
+
|
||||
+ hardenedClients = filterAttrs (_: client: client.hardened) cfg.clients;
|
||||
+ toHardenedClientList = fn: map fn (attrValues hardenedClients);
|
||||
+ toHardenedClientAttrs = fn: mapAttrs' (_: fn) hardenedClients;
|
||||
+
|
||||
+ nixosConfig = config;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with maintainers; [
|
||||
misuzu
|
||||
- thubrecht
|
||||
+ nazarewk
|
||||
];
|
||||
meta.doc = ./netbird.md;
|
||||
|
||||
+ imports = [
|
||||
+ (mkRemovedOptionModule [ "services" "netbird" "tunnels" ]
|
||||
+ "The option `services.netbird.tunnels` has been renamed to `services.netbird.clients`")
|
||||
+ ];
|
||||
+
|
||||
options.services.netbird = {
|
||||
- enable = mkEnableOption "Netbird daemon";
|
||||
+ enable = mkOption {
|
||||
+ type = bool;
|
||||
+ default = false;
|
||||
+ description = ''
|
||||
+ Enables backwards compatible Netbird client service.
|
||||
+
|
||||
+ This is strictly equivalent to:
|
||||
+
|
||||
+ ```nix
|
||||
+ services.netbird.clients.wt0 = {
|
||||
+ port = 51820;
|
||||
+ name = "netbird";
|
||||
+ interface = "wt0";
|
||||
+ hardened = false;
|
||||
+ };
|
||||
+ ```
|
||||
+ '';
|
||||
+ };
|
||||
package = mkPackageOption pkgs "netbird" { };
|
||||
|
||||
- tunnels = mkOption {
|
||||
+ ui.enable = mkOption {
|
||||
+ type = bool;
|
||||
+ default = config.services.displayManager.sessionPackages != [ ] || config.services.xserver.enable;
|
||||
+ defaultText = literalExpression ''
|
||||
+ config.services.displayManager.sessionPackages != [ ] || config.services.xserver.enable
|
||||
+ '';
|
||||
+ description = ''
|
||||
+ Controls presence `netbird-ui` wrappers, defaults to presence of graphical sessions.
|
||||
+ '';
|
||||
+ };
|
||||
+ ui.package = mkPackageOption pkgs "netbird-ui" { };
|
||||
+
|
||||
+ clients = mkOption {
|
||||
type = attrsOf (
|
||||
submodule (
|
||||
{ name, config, ... }:
|
||||
+ let client = config; in
|
||||
{
|
||||
options = {
|
||||
port = mkOption {
|
||||
type = port;
|
||||
- default = 51820;
|
||||
+ example = literalExpression "51820";
|
||||
description = ''
|
||||
- Port for the ${name} netbird interface.
|
||||
+ Port the Netbird client listens on.
|
||||
'';
|
||||
};
|
||||
|
||||
+ name = mkOption {
|
||||
+ type = str;
|
||||
+ default = name;
|
||||
+ description = ''
|
||||
+ Primary name for use (as a suffix) in:
|
||||
+ - systemd service name,
|
||||
+ - hardened user name and group,
|
||||
+ - [systemd `*Directory=`](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory=) names,
|
||||
+ - desktop application identification,
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ interface = mkOption {
|
||||
+ type = str;
|
||||
+ default = "nb-${client.name}";
|
||||
+ description = ''
|
||||
+ Name of the network interface managed by this client.
|
||||
+ '';
|
||||
+ apply = iface:
|
||||
+ lib.throwIfNot (builtins.stringLength iface <= 15) "Network interface name must be 15 characters or less"
|
||||
+ iface;
|
||||
+ };
|
||||
+
|
||||
environment = mkOption {
|
||||
type = attrsOf str;
|
||||
defaultText = literalExpression ''
|
||||
{
|
||||
- NB_CONFIG = "/var/lib/''${stateDir}/config.json";
|
||||
- NB_LOG_FILE = "console";
|
||||
- NB_WIREGUARD_PORT = builtins.toString port;
|
||||
- NB_INTERFACE_NAME = name;
|
||||
- NB_DAMEON_ADDR = "/var/run/''${stateDir}"
|
||||
+ NB_CONFIG = "/var/lib/netbird-''${client.name}/config.json";
|
||||
+ NB_DAEMON_ADDR = "unix:///var/run/netbird-''${client.name}/sock";
|
||||
+ NB_INTERFACE_NAME = config.interface;
|
||||
+ NB_LOG_FILE = mkOptionDefault "console";
|
||||
+ NB_LOG_LEVEL = config.logLevel;
|
||||
+ NB_SERVICE = "netbird-''${client.name}";
|
||||
+ NB_WIREGUARD_PORT = toString config.port;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
@@ -75,97 +157,361 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
- stateDir = mkOption {
|
||||
- type = str;
|
||||
- default = "netbird-${name}";
|
||||
+ autoStart = mkOption {
|
||||
+ type = bool;
|
||||
+ default = true;
|
||||
+ description = ''
|
||||
+ Start the service with the system.
|
||||
+
|
||||
+ As of 2024-02-13 it is not possible to start a Netbird client daemon without immediately
|
||||
+ connecting to the network, but it is [planned for a near future](https://github.com/netbirdio/netbird/projects/2#card-91718018).
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ openFirewall = mkOption {
|
||||
+ type = bool;
|
||||
+ default = true;
|
||||
+ description = ''
|
||||
+ Opens up firewall `port` for communication between Netbird peers directly over LAN or public IP,
|
||||
+ without using (internet-hosted) TURN servers as intermediaries.
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ hardened = mkOption {
|
||||
+ type = bool;
|
||||
+ default = true;
|
||||
description = ''
|
||||
- Directory storing the netbird configuration.
|
||||
+ Hardened service:
|
||||
+ - runs as a dedicated user with minimal set of permissions (see caveats),
|
||||
+ - restricts daemon configuration socket access to dedicated user group
|
||||
+ (you can grant access to it with `users.users."<user>".extraGroups = [ "netbird-${client.name}" ]`),
|
||||
+
|
||||
+ Even though the local system resources access is restricted:
|
||||
+ - `CAP_NET_RAW`, `CAP_NET_ADMIN` and `CAP_BPF` still give unlimited network manipulation possibilites,
|
||||
+ - older kernels don't have `CAP_BPF` and use `CAP_SYS_ADMIN` instead,
|
||||
+
|
||||
+ Known security features that are not (yet) integrated into the module:
|
||||
+ - 2024-02-14: `rosenpass` is an experimental feature configurable solely
|
||||
+ through `--enable-rosenpass` flag on the `netbird up` command,
|
||||
+ see [the docs](https://docs.netbird.io/how-to/enable-post-quantum-cryptography)
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ logLevel = mkOption {
|
||||
+ type = enum [
|
||||
+ # logrus loglevels
|
||||
+ "panic"
|
||||
+ "fatal"
|
||||
+ "error"
|
||||
+ "warn"
|
||||
+ "warning"
|
||||
+ "info"
|
||||
+ "debug"
|
||||
+ "trace"
|
||||
+ ];
|
||||
+ default = "info";
|
||||
+ description = "Log level of the Netbird daemon.";
|
||||
+ };
|
||||
+
|
||||
+ ui.enable = mkOption {
|
||||
+ type = bool;
|
||||
+ default = nixosConfig.services.netbird.ui.enable;
|
||||
+ defaultText = literalExpression ''config.ui.enable'';
|
||||
+ description = ''
|
||||
+ Controls presence of `netbird-ui` wrapper for this Netbird client.
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ wrapper = mkOption {
|
||||
+ type = package;
|
||||
+ internal = true;
|
||||
+ default =
|
||||
+ let
|
||||
+ makeWrapperArgs = concatLists (mapAttrsToList
|
||||
+ (key: value: [ "--set-default" key value ])
|
||||
+ config.environment
|
||||
+ );
|
||||
+ in
|
||||
+ pkgs.stdenv.mkDerivation {
|
||||
+ name = "${cfg.package.name}-wrapper-${client.name}";
|
||||
+ meta.mainProgram = "netbird-${client.name}";
|
||||
+ nativeBuildInputs = with pkgs; [ makeWrapper ];
|
||||
+ phases = [ "installPhase" ];
|
||||
+ installPhase = concatStringsSep "\n" [
|
||||
+ ''
|
||||
+ mkdir -p "$out/bin"
|
||||
+ makeWrapper ${lib.getExe cfg.package} "$out/bin/netbird-${client.name}" \
|
||||
+ ${escapeShellArgs makeWrapperArgs}
|
||||
+ ''
|
||||
+ (optionalString cfg.ui.enable ''
|
||||
+ # netbird-ui doesn't support envvars
|
||||
+ makeWrapper ${lib.getExe cfg.ui.package} "$out/bin/netbird-ui-${client.name}" \
|
||||
+ --add-flags '--daemon-addr=${config.environment.NB_DAEMON_ADDR}'
|
||||
+
|
||||
+ mkdir -p "$out/share/applications"
|
||||
+ substitute ${cfg.ui.package}/share/applications/netbird.desktop \
|
||||
+ "$out/share/applications/netbird-${client.name}.desktop" \
|
||||
+ --replace-fail 'Name=Netbird' "Name=Netbird @ netbird-${client.name}" \
|
||||
+ --replace-fail '${lib.getExe cfg.ui.package}' "$out/bin/netbird-ui-${client.name}"
|
||||
+ '')
|
||||
+ ];
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ # see https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82
|
||||
+ config = mkOption {
|
||||
+ type = (pkgs.formats.json { }).type;
|
||||
+ defaultText = literalExpression ''
|
||||
+ {
|
||||
+ DisableAutoConnect = !config.autoStart;
|
||||
+ WgIface = config.interface;
|
||||
+ WgPort = config.port;
|
||||
+ }
|
||||
+ '';
|
||||
+ description = ''
|
||||
+ Additional configuration that exists before the first start and
|
||||
+ later overrides the existing values in `config.json`.
|
||||
+
|
||||
+ It is mostly helpful to manage configuration ignored/not yet implemented
|
||||
+ outside of `netbird up` invocation.
|
||||
+
|
||||
+ WARNING: this is not an upstream feature, it could break in the future
|
||||
+ (by having lower priority) after upstream implements an equivalent.
|
||||
+
|
||||
+ It is implemented as a `preStart` script which overrides `config.json`
|
||||
+ with content of `/etc/netbird-${client.name}/config.d/*.json` files.
|
||||
+ This option manages specifically `50-nixos.json` file.
|
||||
+
|
||||
+ Consult [the source code](https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82)
|
||||
+ or inspect existing file for a complete list of available configurations.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
- config.environment = builtins.mapAttrs (_: mkDefault) {
|
||||
- NB_CONFIG = "/var/lib/${config.stateDir}/config.json";
|
||||
- NB_LOG_FILE = "console";
|
||||
- NB_WIREGUARD_PORT = builtins.toString config.port;
|
||||
- NB_INTERFACE_NAME = name;
|
||||
- NB_DAEMON_ADDR = "unix:///var/run/${config.stateDir}/sock";
|
||||
+ config.environment = {
|
||||
+ NB_CONFIG = "/var/lib/netbird-${client.name}/config.json";
|
||||
+ NB_DAEMON_ADDR = "unix:///var/run/netbird-${client.name}/sock";
|
||||
+ NB_INTERFACE_NAME = config.interface;
|
||||
+ NB_LOG_FILE = mkOptionDefault "console";
|
||||
+ NB_LOG_LEVEL = config.logLevel;
|
||||
+ NB_SERVICE = "netbird-${client.name}";
|
||||
+ NB_WIREGUARD_PORT = toString config.port;
|
||||
+ };
|
||||
+
|
||||
+ config.config = {
|
||||
+ DisableAutoConnect = !config.autoStart;
|
||||
+ WgIface = config.interface;
|
||||
+ WgPort = config.port;
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
description = ''
|
||||
- Attribute set of Netbird tunnels, each one will spawn a daemon listening on ...
|
||||
+ Attribute set of Netbird client daemons, by default each one will:
|
||||
+
|
||||
+ 1. be manageable using dedicated tooling:
|
||||
+ - `netbird-<name>` script,
|
||||
+ - `Netbird - netbird-<name>` graphical interface when appropriate (see `ui.enable`),
|
||||
+ 2. run as a `netbird-<name>.service`,
|
||||
+ 3. listen for incoming remote connections on the port `51820` (`openFirewall` by default),
|
||||
+ 4. manage the `netbird-<name>` wireguard interface,
|
||||
+ 5. use the `/var/lib/netbird-<name>/config.json` configuration file,
|
||||
+ 6. override `/var/lib/netbird-<name>/config.json` with values from `/etc/netbird-<name>/config.d/*.json`,
|
||||
+ 7. (`hardened`) be locally manageable by `netbird-<name>` system group,
|
||||
+
|
||||
+ With following caveats:
|
||||
+
|
||||
+ - multiple daemons will interfere with each other's DNS resolution of `netbird.cloud`, but
|
||||
+ should remain fully operational otherwise.
|
||||
+ Setting up custom (non-conflicting) DNS zone is currently possible only when self-hosting.
|
||||
+ '';
|
||||
+ example = lib.literalExpression ''
|
||||
+ {
|
||||
+ services.netbird.clients.wt0.port = 51820;
|
||||
+ services.netbird.clients.personal.port = 51821;
|
||||
+ services.netbird.clients.work1.port = 51822;
|
||||
+ }
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
- (mkIf cfg.enable {
|
||||
- # For backwards compatibility
|
||||
- services.netbird.tunnels.wt0.stateDir = "netbird";
|
||||
- })
|
||||
+ (mkIf cfg.enable (
|
||||
+ let name = "wt0"; client = cfg.clients."${name}"; in {
|
||||
+ services.netbird.clients."${name}" = {
|
||||
+ port = mkDefault 51820;
|
||||
+ name = mkDefault "netbird";
|
||||
+ interface = mkDefault "wt0";
|
||||
+ hardened = mkDefault false;
|
||||
+ };
|
||||
|
||||
- (mkIf (cfg.tunnels != { }) {
|
||||
- boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
|
||||
+ environment.systemPackages = [
|
||||
+ (lib.hiPrio (pkgs.runCommand "${client.name}-as-default" { } ''
|
||||
+ mkdir -p "$out/bin"
|
||||
+ for binary in netbird ${optionalString cfg.ui.enable "netbird-ui"} ; do
|
||||
+ ln -s "${client.wrapper}/bin/$binary-${client.name}" "$out/bin/$binary"
|
||||
+ done
|
||||
+ ''))
|
||||
+ ];
|
||||
+ }
|
||||
+ ))
|
||||
+ {
|
||||
+ boot.extraModulePackages = optional
|
||||
+ (cfg.clients != { } && (versionOlder kernel.version "5.6"))
|
||||
+ kernelPackages.wireguard;
|
||||
|
||||
- environment.systemPackages = [ cfg.package ];
|
||||
+ environment.systemPackages =
|
||||
+ toClientList (client: client.wrapper)
|
||||
+ # omitted due to https://github.com/netbirdio/netbird/issues/1562
|
||||
+ #++ optional (cfg.clients != { }) cfg.package
|
||||
+ # omitted due to https://github.com/netbirdio/netbird/issues/1581
|
||||
+ #++ optional (cfg.clients != { } && cfg.ui.enable) cfg.ui.package
|
||||
+ ;
|
||||
|
||||
- networking.dhcpcd.denyInterfaces = attrNames cfg.tunnels;
|
||||
+ networking.dhcpcd.denyInterfaces = toClientList (client: client.interface);
|
||||
+ networking.networkmanager.unmanaged = toClientList (client: "interface-name:${client.interface}");
|
||||
|
||||
- systemd.network.networks = mkIf config.networking.useNetworkd (
|
||||
- mapAttrs'
|
||||
- (
|
||||
- name: _:
|
||||
- nameValuePair "50-netbird-${name}" {
|
||||
- matchConfig = {
|
||||
- Name = name;
|
||||
- };
|
||||
- linkConfig = {
|
||||
- Unmanaged = true;
|
||||
- ActivationPolicy = "manual";
|
||||
- };
|
||||
- }
|
||||
- )
|
||||
- cfg.tunnels
|
||||
- );
|
||||
+ networking.firewall.allowedUDPPorts = concatLists (toClientList (client: optional client.openFirewall client.port));
|
||||
|
||||
- systemd.services =
|
||||
- mapAttrs'
|
||||
- (
|
||||
- name:
|
||||
- { environment, stateDir, ... }:
|
||||
- nameValuePair "netbird-${name}" {
|
||||
- description = "A WireGuard-based mesh network that connects your devices into a single private network";
|
||||
+ systemd.network.networks = mkIf config.networking.useNetworkd (toClientAttrs (client:
|
||||
+ nameValuePair "50-netbird-${client.interface}" {
|
||||
+ matchConfig = {
|
||||
+ Name = client.interface;
|
||||
+ };
|
||||
+ linkConfig = {
|
||||
+ Unmanaged = true;
|
||||
+ ActivationPolicy = "manual";
|
||||
+ };
|
||||
+ }
|
||||
+ ));
|
||||
|
||||
- documentation = [ "https://netbird.io/docs/" ];
|
||||
+ environment.etc = toClientAttrs (client: nameValuePair "netbird-${client.name}/config.d/50-nixos.json" {
|
||||
+ text = builtins.toJSON client.config;
|
||||
+ mode = "0444";
|
||||
+ });
|
||||
|
||||
- after = [ "network.target" ];
|
||||
- wantedBy = [ "multi-user.target" ];
|
||||
+ systemd.services = toClientAttrs (client: nameValuePair "netbird-${client.name}" {
|
||||
+ description = "A WireGuard-based mesh network that connects your devices into a single private network";
|
||||
|
||||
- path = with pkgs; [ openresolv ];
|
||||
+ documentation = [ "https://netbird.io/docs/" ];
|
||||
|
||||
- inherit environment;
|
||||
+ after = [ "network.target" ];
|
||||
+ wantedBy = [ "multi-user.target" ];
|
||||
|
||||
- serviceConfig = {
|
||||
- ExecStart = "${getExe cfg.package} service run";
|
||||
- Restart = "always";
|
||||
- RuntimeDirectory = stateDir;
|
||||
- StateDirectory = stateDir;
|
||||
- StateDirectoryMode = "0700";
|
||||
- WorkingDirectory = "/var/lib/${stateDir}";
|
||||
- };
|
||||
+ path = optional (!config.services.resolved.enable) pkgs.openresolv;
|
||||
|
||||
- unitConfig = {
|
||||
- StartLimitInterval = 5;
|
||||
- StartLimitBurst = 10;
|
||||
- };
|
||||
+ serviceConfig = {
|
||||
+ ExecStart = "${getExe client.wrapper} service run";
|
||||
+ Restart = "always";
|
||||
+
|
||||
+ RuntimeDirectory = "netbird-${client.name}";
|
||||
+ RuntimeDirectoryMode = mkDefault "0755";
|
||||
+ ConfigurationDirectory = "netbird-${client.name}";
|
||||
+ StateDirectory = "netbird-${client.name}";
|
||||
+ StateDirectoryMode = "0700";
|
||||
+
|
||||
+ WorkingDirectory = "/var/lib/netbird-${client.name}";
|
||||
+ };
|
||||
+
|
||||
+ unitConfig = {
|
||||
+ StartLimitInterval = 5;
|
||||
+ StartLimitBurst = 10;
|
||||
+ };
|
||||
+
|
||||
+ stopIfChanged = false;
|
||||
+ });
|
||||
+ }
|
||||
+ # Hardening section
|
||||
+ (mkIf (hardenedClients != { }) {
|
||||
+ users.groups = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" { });
|
||||
+ users.users = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" {
|
||||
+ isSystemUser = true;
|
||||
+ home = "/var/lib/netbird-${client.name}";
|
||||
+ group = "netbird-${client.name}";
|
||||
+ });
|
||||
+
|
||||
+ systemd.services = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" (mkIf client.hardened {
|
||||
+ serviceConfig = {
|
||||
+ RuntimeDirectoryMode = "0750";
|
||||
+
|
||||
+ User = "netbird-${client.name}";
|
||||
+ Group = "netbird-${client.name}";
|
||||
+
|
||||
+ # settings implied by DynamicUser=true, without actully using it,
|
||||
+ # see https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser=
|
||||
+ RemoveIPC = true;
|
||||
+ PrivateTmp = true;
|
||||
+ ProtectSystem = "strict";
|
||||
+ ProtectHome = "yes";
|
||||
|
||||
- stopIfChanged = false;
|
||||
- }
|
||||
- )
|
||||
- cfg.tunnels;
|
||||
+ AmbientCapabilities = [
|
||||
+ # see https://man7.org/linux/man-pages/man7/capabilities.7.html
|
||||
+ # see https://docs.netbird.io/how-to/installation#running-net-bird-in-docker
|
||||
+ #
|
||||
+ # seems to work fine without CAP_SYS_ADMIN and CAP_SYS_RESOURCE
|
||||
+ # CAP_NET_BIND_SERVICE could be added to allow binding on low ports, but is not required,
|
||||
+ # see https://github.com/netbirdio/netbird/pull/1513
|
||||
+
|
||||
+ # failed creating tunnel interface wt-priv: [operation not permitted
|
||||
+ "CAP_NET_ADMIN"
|
||||
+ # failed to pull up wgInterface [wt-priv]: failed to create ipv4 raw socket: socket: operation not permitted
|
||||
+ "CAP_NET_RAW"
|
||||
+ ]
|
||||
+ # required for eBPF filter, used to be subset of CAP_SYS_ADMIN
|
||||
+ ++ optional (versionAtLeast kernel.version "5.8") "CAP_BPF"
|
||||
+ ++ optional (versionOlder kernel.version "5.8") "CAP_SYS_ADMIN"
|
||||
+ ;
|
||||
+ };
|
||||
+ }));
|
||||
+
|
||||
+ # see https://github.com/systemd/systemd/blob/17f3e91e8107b2b29fe25755651b230bbc81a514/src/resolve/org.freedesktop.resolve1.policy#L43-L43
|
||||
+ security.polkit.extraConfig = mkIf config.services.resolved.enable ''
|
||||
+ // systemd-resolved access for Netbird clients
|
||||
+ polkit.addRule(function(action, subject) {
|
||||
+ var actions = [
|
||||
+ "org.freedesktop.resolve1.set-dns-servers",
|
||||
+ "org.freedesktop.resolve1.set-domains",
|
||||
+ ];
|
||||
+ var users = ${builtins.toJSON (toHardenedClientList (client: "netbird-${client.name}"))};
|
||||
+
|
||||
+ if (actions.indexOf(action.id) >= 0 && users.indexOf(subject.user) >= 0 ) {
|
||||
+ return polkit.Result.YES;
|
||||
+ }
|
||||
+ });
|
||||
+ '';
|
||||
})
|
||||
+ # migration & temporary fixups section
|
||||
+ {
|
||||
+ systemd.services = toClientAttrs (client: nameValuePair "netbird-${client.name}" {
|
||||
+ preStart = ''
|
||||
+ set -eEuo pipefail
|
||||
+ ${optionalString (client.logLevel == "trace" || client.logLevel == "debug") "set -x"}
|
||||
+
|
||||
+ PATH="${makeBinPath (with pkgs; [coreutils jq diffutils])}:$PATH"
|
||||
+ export ${toShellVars client.environment}
|
||||
+
|
||||
+ # merge /etc/netbird-${client.name}/config.d' into "$NB_CONFIG"
|
||||
+ {
|
||||
+ test -e "$NB_CONFIG" || echo -n '{}' > "$NB_CONFIG"
|
||||
+
|
||||
+ # merge config.d with "$NB_CONFIG" into "$NB_CONFIG.new"
|
||||
+ jq -sS 'reduce .[] as $i ({}; . * $i)' \
|
||||
+ "$NB_CONFIG" \
|
||||
+ /etc/netbird-${client.name}/config.d/*.json \
|
||||
+ > "$NB_CONFIG.new"
|
||||
+
|
||||
+ echo "Comparing $NB_CONFIG with $NB_CONFIG.new ..."
|
||||
+ if ! diff <(jq -S <"$NB_CONFIG") "$NB_CONFIG.new" ; then
|
||||
+ echo "Updating $NB_CONFIG ..."
|
||||
+ mv "$NB_CONFIG.new" "$NB_CONFIG"
|
||||
+ else
|
||||
+ echo "Files are the same, not doing anything."
|
||||
+ rm "$NB_CONFIG.new"
|
||||
+ fi
|
||||
+ }
|
||||
+ '';
|
||||
+ });
|
||||
+ }
|
||||
];
|
||||
}
|
816
patches/netbird-24.11.patch
Normal file
816
patches/netbird-24.11.patch
Normal file
@ -0,0 +1,816 @@
|
||||
From dc09dca1f66c940060825868dbeeeaa865c79744 Mon Sep 17 00:00:00 2001
|
||||
From: Krzysztof Nazarewski <gpg@kdn.im>
|
||||
Date: Tue, 2 Apr 2024 12:04:11 +0200
|
||||
Subject: [PATCH 1/2] netbird-ui: fix incorrect meta.mainProgram
|
||||
|
||||
---
|
||||
pkgs/tools/networking/netbird/default.nix | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pkgs/tools/networking/netbird/default.nix b/pkgs/tools/networking/netbird/default.nix
|
||||
index b10663216e035b..905247c2d4bdc1 100644
|
||||
--- a/pkgs/tools/networking/netbird/default.nix
|
||||
+++ b/pkgs/tools/networking/netbird/default.nix
|
||||
@@ -111,6 +111,6 @@ buildGoModule rec {
|
||||
description = "Connect your devices into a single secure private WireGuard®-based mesh network with SSO/MFA and simple access controls";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ misuzu ];
|
||||
- mainProgram = "netbird";
|
||||
+ mainProgram = if ui then "netbird-ui" else "netbird";
|
||||
};
|
||||
}
|
||||
|
||||
From 835617072b8bc1ffe1be551696d9e8d2ce193a60 Mon Sep 17 00:00:00 2001
|
||||
From: Krzysztof Nazarewski <gpg@kdn.im>
|
||||
Date: Tue, 2 Apr 2024 12:01:25 +0200
|
||||
Subject: [PATCH 2/2] nixos/netbird: harden and extend options
|
||||
|
||||
---
|
||||
.../manual/release-notes/rl-2405.section.md | 2 +-
|
||||
.../manual/release-notes/rl-2411.section.md | 3 +
|
||||
nixos/modules/services/networking/netbird.md | 72 ++-
|
||||
nixos/modules/services/networking/netbird.nix | 507 +++++++++++++++---
|
||||
nixos/tests/netbird.nix | 26 +-
|
||||
5 files changed, 503 insertions(+), 107 deletions(-)
|
||||
|
||||
diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md
|
||||
index b1b18b35e9c281..096bd6a2f2cc15 100644
|
||||
--- a/nixos/doc/manual/release-notes/rl-2405.section.md
|
||||
+++ b/nixos/doc/manual/release-notes/rl-2405.section.md
|
||||
@@ -698,7 +698,7 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi
|
||||
and `services.kavita.settings.IpAddresses`. The file at `services.kavita.tokenKeyFile` now needs to contain a secret with
|
||||
512+ bits instead of 128+ bits.
|
||||
|
||||
-- `services.netbird` now allows running multiple tunnels in parallel through [`services.netbird.tunnels`](#opt-services.netbird.tunnels).
|
||||
+- `services.netbird` now allows running multiple tunnels in parallel through [`services.netbird.tunnels`](#opt-services.netbird.clients).
|
||||
|
||||
- `services.nginx.virtualHosts` using `forceSSL` or
|
||||
`globalRedirect` can now have redirect codes other than 301 through `redirectCode`.
|
||||
diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md
|
||||
index 2de4cf4d08af2d..a5d3566fe9bd87 100644
|
||||
--- a/nixos/doc/manual/release-notes/rl-2411.section.md
|
||||
+++ b/nixos/doc/manual/release-notes/rl-2411.section.md
|
||||
@@ -98,6 +98,9 @@
|
||||
support, which is the intended default behavior by Tracy maintainers.
|
||||
X11 users have to switch to the new package `tracy-x11`.
|
||||
|
||||
+- `services.netbird.tunnels` was renamed to [`services.netbird.clients`](#opt-services.netbird.clients),
|
||||
+ hardened (using dedicated less-privileged users) and significantly extended.
|
||||
+
|
||||
## Other Notable Changes {#sec-release-24.11-notable-changes}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
diff --git a/nixos/modules/services/networking/netbird.md b/nixos/modules/services/networking/netbird.md
|
||||
index e1f6753cbd30cc..876c27cb0d22e7 100644
|
||||
--- a/nixos/modules/services/networking/netbird.md
|
||||
+++ b/nixos/modules/services/networking/netbird.md
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Quickstart {#module-services-netbird-quickstart}
|
||||
|
||||
-The absolute minimal configuration for the netbird daemon looks like this:
|
||||
+The absolute minimal configuration for the Netbird client daemon looks like this:
|
||||
|
||||
```nix
|
||||
{
|
||||
@@ -13,52 +13,76 @@ The absolute minimal configuration for the netbird daemon looks like this:
|
||||
This will set up a netbird service listening on the port `51820` associated to the
|
||||
`wt0` interface.
|
||||
|
||||
-It is strictly equivalent to setting:
|
||||
+Which is equivalent to:
|
||||
|
||||
```nix
|
||||
{
|
||||
- services.netbird.tunnels.wt0.stateDir = "netbird";
|
||||
+ services.netbird.clients.wt0 = {
|
||||
+ port = 51820;
|
||||
+ name = "netbird";
|
||||
+ interface = "wt0";
|
||||
+ hardened = false;
|
||||
+ };
|
||||
}
|
||||
```
|
||||
|
||||
-The `enable` option is mainly kept for backward compatibility, as defining netbird
|
||||
-tunnels through the `tunnels` option is more expressive.
|
||||
+This will set up a `netbird.service` listening on the port `51820` associated to the
|
||||
+`wt0` interface. There will also be `netbird-wt0` binary installed in addition to `netbird`.
|
||||
+
|
||||
+see [clients](#opt-services.netbird.clients) option documentation for more details.
|
||||
|
||||
## Multiple connections setup {#module-services-netbird-multiple-connections}
|
||||
|
||||
-Using the `services.netbird.tunnels` option, it is also possible to define more than
|
||||
+Using the `services.netbird.clients` option, it is possible to define more than
|
||||
one netbird service running at the same time.
|
||||
|
||||
-The following configuration will start a netbird daemon using the interface `wt1` and
|
||||
-the port 51830. Its configuration file will then be located at `/var/lib/netbird-wt1/config.json`.
|
||||
+You must at least define a `port` for the service to listen on, the rest is optional:
|
||||
|
||||
```nix
|
||||
{
|
||||
- services.netbird.tunnels = {
|
||||
- wt1 = {
|
||||
- port = 51830;
|
||||
- };
|
||||
- };
|
||||
+ services.netbird.clients.wt1.port = 51830;
|
||||
+ services.netbird.clients.wt2.port = 51831;
|
||||
}
|
||||
```
|
||||
|
||||
-To interact with it, you will need to specify the correct daemon address:
|
||||
-
|
||||
-```bash
|
||||
-netbird --daemon-addr unix:///var/run/netbird-wt1/sock ...
|
||||
-```
|
||||
+see [clients](#opt-services.netbird.clients) option documentation for more details.
|
||||
|
||||
-The address will by default be `unix:///var/run/netbird-<name>`.
|
||||
+## Exposing services internally on the Netbird network {#module-services-netbird-firewall}
|
||||
|
||||
-It is also possible to overwrite default options passed to the service, for
|
||||
-example:
|
||||
+You can easily expose services exclusively to Netbird network by combining
|
||||
+[`networking.firewall.interfaces`](#opt-networking.firewall.interfaces) rules
|
||||
+with [`interface`](#opt-services.netbird.clients._name_.interface) names:
|
||||
|
||||
```nix
|
||||
{
|
||||
- services.netbird.tunnels.wt1.environment = {
|
||||
- NB_DAEMON_ADDR = "unix:///var/run/toto.sock";
|
||||
+ services.netbird.clients.priv.port = 51819;
|
||||
+ services.netbird.clients.work.port = 51818;
|
||||
+ networking.firewall.interfaces = {
|
||||
+ "${config.services.netbird.clients.priv.interface}" = {
|
||||
+ allowedUDPPorts = [ 1234 ];
|
||||
+ };
|
||||
+ "${config.services.netbird.clients.work.interface}" = {
|
||||
+ allowedTCPPorts = [ 8080 ];
|
||||
+ };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
-This will set the socket to interact with the netbird service to `/var/run/toto.sock`.
|
||||
+### Additional customizations {#module-services-netbird-customization}
|
||||
+
|
||||
+Each Netbird client service by default:
|
||||
+
|
||||
+- runs in a [hardened](#opt-services.netbird.clients._name_.hardened) mode,
|
||||
+- starts with the system,
|
||||
+- [opens up a firewall](#opt-services.netbird.clients._name_.openFirewall) for direct (without TURN servers)
|
||||
+ peer-to-peer communication,
|
||||
+- can be additionally configured with environment variables,
|
||||
+- automatically determines whether `netbird-ui-<name>` should be available,
|
||||
+
|
||||
+[autoStart](#opt-services.netbird.clients._name_.autoStart) allows you to start the client (an actual systemd service)
|
||||
+on demand, for example to connect to work-related or otherwise conflicting network only when required.
|
||||
+See the option description for more information.
|
||||
+
|
||||
+[environment](#opt-services.netbird.clients._name_.environment) allows you to pass additional configurations
|
||||
+through environment variables, but special care needs to be taken for overriding config location and
|
||||
+daemon address due [hardened](#opt-services.netbird.clients._name_.hardened) option.
|
||||
diff --git a/nixos/modules/services/networking/netbird.nix b/nixos/modules/services/networking/netbird.nix
|
||||
index e68c39946fe3b5..0160a8964aecad 100644
|
||||
--- a/nixos/modules/services/networking/netbird.nix
|
||||
+++ b/nixos/modules/services/networking/netbird.nix
|
||||
@@ -1,72 +1,155 @@
|
||||
-{
|
||||
- config,
|
||||
- lib,
|
||||
- pkgs,
|
||||
- ...
|
||||
+{ config
|
||||
+, lib
|
||||
+, pkgs
|
||||
+, ...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
- attrNames
|
||||
+ attrValues
|
||||
+ concatLists
|
||||
+ concatStringsSep
|
||||
+ escapeShellArgs
|
||||
+ filterAttrs
|
||||
getExe
|
||||
literalExpression
|
||||
maintainers
|
||||
+ makeBinPath
|
||||
mapAttrs'
|
||||
+ mapAttrsToList
|
||||
mkDefault
|
||||
- mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
+ mkOptionDefault
|
||||
mkPackageOption
|
||||
+ mkRemovedOptionModule
|
||||
nameValuePair
|
||||
optional
|
||||
+ optionalString
|
||||
+ toShellVars
|
||||
+ versionAtLeast
|
||||
versionOlder
|
||||
;
|
||||
|
||||
inherit (lib.types)
|
||||
attrsOf
|
||||
+ bool
|
||||
+ enum
|
||||
+ package
|
||||
port
|
||||
str
|
||||
submodule
|
||||
;
|
||||
|
||||
- kernel = config.boot.kernelPackages;
|
||||
+ inherit (config.boot) kernelPackages;
|
||||
+ inherit (config.boot.kernelPackages) kernel;
|
||||
|
||||
cfg = config.services.netbird;
|
||||
+
|
||||
+ toClientList = fn: map fn (attrValues cfg.clients);
|
||||
+ toClientAttrs = fn: mapAttrs' (_: fn) cfg.clients;
|
||||
+
|
||||
+ hardenedClients = filterAttrs (_: client: client.hardened) cfg.clients;
|
||||
+ toHardenedClientList = fn: map fn (attrValues hardenedClients);
|
||||
+ toHardenedClientAttrs = fn: mapAttrs' (_: fn) hardenedClients;
|
||||
+
|
||||
+ nixosConfig = config;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with maintainers; [
|
||||
misuzu
|
||||
+ nazarewk
|
||||
];
|
||||
meta.doc = ./netbird.md;
|
||||
|
||||
+ imports = [
|
||||
+ (mkRemovedOptionModule [ "services" "netbird" "tunnels" ]
|
||||
+ "The option `services.netbird.tunnels` has been renamed to `services.netbird.clients`")
|
||||
+ ];
|
||||
+
|
||||
options.services.netbird = {
|
||||
- enable = mkEnableOption "Netbird daemon";
|
||||
+ enable = mkOption {
|
||||
+ type = bool;
|
||||
+ default = false;
|
||||
+ description = ''
|
||||
+ Enables backwards compatible Netbird client service.
|
||||
+
|
||||
+ This is strictly equivalent to:
|
||||
+
|
||||
+ ```nix
|
||||
+ services.netbird.clients.wt0 = {
|
||||
+ port = 51820;
|
||||
+ name = "netbird";
|
||||
+ interface = "wt0";
|
||||
+ hardened = false;
|
||||
+ };
|
||||
+ ```
|
||||
+ '';
|
||||
+ };
|
||||
package = mkPackageOption pkgs "netbird" { };
|
||||
|
||||
- tunnels = mkOption {
|
||||
+ ui.enable = mkOption {
|
||||
+ type = bool;
|
||||
+ default = config.services.displayManager.sessionPackages != [ ] || config.services.xserver.enable;
|
||||
+ defaultText = literalExpression ''
|
||||
+ config.services.displayManager.sessionPackages != [ ] || config.services.xserver.enable
|
||||
+ '';
|
||||
+ description = ''
|
||||
+ Controls presence `netbird-ui` wrappers, defaults to presence of graphical sessions.
|
||||
+ '';
|
||||
+ };
|
||||
+ ui.package = mkPackageOption pkgs "netbird-ui" { };
|
||||
+
|
||||
+ clients = mkOption {
|
||||
type = attrsOf (
|
||||
submodule (
|
||||
{ name, config, ... }:
|
||||
+ let client = config; in
|
||||
{
|
||||
options = {
|
||||
port = mkOption {
|
||||
type = port;
|
||||
- default = 51820;
|
||||
+ example = literalExpression "51820";
|
||||
description = ''
|
||||
- Port for the ${name} netbird interface.
|
||||
+ Port the Netbird client listens on.
|
||||
'';
|
||||
};
|
||||
|
||||
+ name = mkOption {
|
||||
+ type = str;
|
||||
+ default = name;
|
||||
+ description = ''
|
||||
+ Primary name for use (as a suffix) in:
|
||||
+ - systemd service name,
|
||||
+ - hardened user name and group,
|
||||
+ - [systemd `*Directory=`](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory=) names,
|
||||
+ - desktop application identification,
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ interface = mkOption {
|
||||
+ type = str;
|
||||
+ default = "nb-${client.name}";
|
||||
+ description = ''
|
||||
+ Name of the network interface managed by this client.
|
||||
+ '';
|
||||
+ apply = iface:
|
||||
+ lib.throwIfNot (builtins.stringLength iface <= 15) "Network interface name must be 15 characters or less"
|
||||
+ iface;
|
||||
+ };
|
||||
+
|
||||
environment = mkOption {
|
||||
type = attrsOf str;
|
||||
defaultText = literalExpression ''
|
||||
{
|
||||
- NB_CONFIG = "/var/lib/''${stateDir}/config.json";
|
||||
- NB_LOG_FILE = "console";
|
||||
- NB_WIREGUARD_PORT = builtins.toString port;
|
||||
- NB_INTERFACE_NAME = name;
|
||||
- NB_DAMEON_ADDR = "/var/run/''${stateDir}"
|
||||
+ NB_CONFIG = "/var/lib/netbird-''${client.name}/config.json";
|
||||
+ NB_DAEMON_ADDR = "unix:///var/run/netbird-''${client.name}/sock";
|
||||
+ NB_INTERFACE_NAME = config.interface;
|
||||
+ NB_LOG_FILE = mkOptionDefault "console";
|
||||
+ NB_LOG_LEVEL = config.logLevel;
|
||||
+ NB_SERVICE = "netbird-''${client.name}";
|
||||
+ NB_WIREGUARD_PORT = toString config.port;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
@@ -74,97 +157,361 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
- stateDir = mkOption {
|
||||
- type = str;
|
||||
- default = "netbird-${name}";
|
||||
+ autoStart = mkOption {
|
||||
+ type = bool;
|
||||
+ default = true;
|
||||
+ description = ''
|
||||
+ Start the service with the system.
|
||||
+
|
||||
+ As of 2024-02-13 it is not possible to start a Netbird client daemon without immediately
|
||||
+ connecting to the network, but it is [planned for a near future](https://github.com/netbirdio/netbird/projects/2#card-91718018).
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ openFirewall = mkOption {
|
||||
+ type = bool;
|
||||
+ default = true;
|
||||
+ description = ''
|
||||
+ Opens up firewall `port` for communication between Netbird peers directly over LAN or public IP,
|
||||
+ without using (internet-hosted) TURN servers as intermediaries.
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ hardened = mkOption {
|
||||
+ type = bool;
|
||||
+ default = true;
|
||||
description = ''
|
||||
- Directory storing the netbird configuration.
|
||||
+ Hardened service:
|
||||
+ - runs as a dedicated user with minimal set of permissions (see caveats),
|
||||
+ - restricts daemon configuration socket access to dedicated user group
|
||||
+ (you can grant access to it with `users.users."<user>".extraGroups = [ "netbird-${client.name}" ]`),
|
||||
+
|
||||
+ Even though the local system resources access is restricted:
|
||||
+ - `CAP_NET_RAW`, `CAP_NET_ADMIN` and `CAP_BPF` still give unlimited network manipulation possibilites,
|
||||
+ - older kernels don't have `CAP_BPF` and use `CAP_SYS_ADMIN` instead,
|
||||
+
|
||||
+ Known security features that are not (yet) integrated into the module:
|
||||
+ - 2024-02-14: `rosenpass` is an experimental feature configurable solely
|
||||
+ through `--enable-rosenpass` flag on the `netbird up` command,
|
||||
+ see [the docs](https://docs.netbird.io/how-to/enable-post-quantum-cryptography)
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ logLevel = mkOption {
|
||||
+ type = enum [
|
||||
+ # logrus loglevels
|
||||
+ "panic"
|
||||
+ "fatal"
|
||||
+ "error"
|
||||
+ "warn"
|
||||
+ "warning"
|
||||
+ "info"
|
||||
+ "debug"
|
||||
+ "trace"
|
||||
+ ];
|
||||
+ default = "info";
|
||||
+ description = "Log level of the Netbird daemon.";
|
||||
+ };
|
||||
+
|
||||
+ ui.enable = mkOption {
|
||||
+ type = bool;
|
||||
+ default = nixosConfig.services.netbird.ui.enable;
|
||||
+ defaultText = literalExpression ''config.ui.enable'';
|
||||
+ description = ''
|
||||
+ Controls presence of `netbird-ui` wrapper for this Netbird client.
|
||||
+ '';
|
||||
+ };
|
||||
+
|
||||
+ wrapper = mkOption {
|
||||
+ type = package;
|
||||
+ internal = true;
|
||||
+ default =
|
||||
+ let
|
||||
+ makeWrapperArgs = concatLists (mapAttrsToList
|
||||
+ (key: value: [ "--set-default" key value ])
|
||||
+ config.environment
|
||||
+ );
|
||||
+ in
|
||||
+ pkgs.stdenv.mkDerivation {
|
||||
+ name = "${cfg.package.name}-wrapper-${client.name}";
|
||||
+ meta.mainProgram = "netbird-${client.name}";
|
||||
+ nativeBuildInputs = with pkgs; [ makeWrapper ];
|
||||
+ phases = [ "installPhase" ];
|
||||
+ installPhase = concatStringsSep "\n" [
|
||||
+ ''
|
||||
+ mkdir -p "$out/bin"
|
||||
+ makeWrapper ${lib.getExe cfg.package} "$out/bin/netbird-${client.name}" \
|
||||
+ ${escapeShellArgs makeWrapperArgs}
|
||||
+ ''
|
||||
+ (optionalString cfg.ui.enable ''
|
||||
+ # netbird-ui doesn't support envvars
|
||||
+ makeWrapper ${lib.getExe cfg.ui.package} "$out/bin/netbird-ui-${client.name}" \
|
||||
+ --add-flags '--daemon-addr=${config.environment.NB_DAEMON_ADDR}'
|
||||
+
|
||||
+ mkdir -p "$out/share/applications"
|
||||
+ substitute ${cfg.ui.package}/share/applications/netbird.desktop \
|
||||
+ "$out/share/applications/netbird-${client.name}.desktop" \
|
||||
+ --replace-fail 'Name=Netbird' "Name=Netbird @ netbird-${client.name}" \
|
||||
+ --replace-fail '${lib.getExe cfg.ui.package}' "$out/bin/netbird-ui-${client.name}"
|
||||
+ '')
|
||||
+ ];
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ # see https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82
|
||||
+ config = mkOption {
|
||||
+ type = (pkgs.formats.json { }).type;
|
||||
+ defaultText = literalExpression ''
|
||||
+ {
|
||||
+ DisableAutoConnect = !config.autoStart;
|
||||
+ WgIface = config.interface;
|
||||
+ WgPort = config.port;
|
||||
+ }
|
||||
+ '';
|
||||
+ description = ''
|
||||
+ Additional configuration that exists before the first start and
|
||||
+ later overrides the existing values in `config.json`.
|
||||
+
|
||||
+ It is mostly helpful to manage configuration ignored/not yet implemented
|
||||
+ outside of `netbird up` invocation.
|
||||
+
|
||||
+ WARNING: this is not an upstream feature, it could break in the future
|
||||
+ (by having lower priority) after upstream implements an equivalent.
|
||||
+
|
||||
+ It is implemented as a `preStart` script which overrides `config.json`
|
||||
+ with content of `/etc/netbird-${client.name}/config.d/*.json` files.
|
||||
+ This option manages specifically `50-nixos.json` file.
|
||||
+
|
||||
+ Consult [the source code](https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82)
|
||||
+ or inspect existing file for a complete list of available configurations.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
- config.environment = builtins.mapAttrs (_: mkDefault) {
|
||||
- NB_CONFIG = "/var/lib/${config.stateDir}/config.json";
|
||||
- NB_LOG_FILE = "console";
|
||||
- NB_WIREGUARD_PORT = builtins.toString config.port;
|
||||
- NB_INTERFACE_NAME = name;
|
||||
- NB_DAEMON_ADDR = "unix:///var/run/${config.stateDir}/sock";
|
||||
+ config.environment = {
|
||||
+ NB_CONFIG = "/var/lib/netbird-${client.name}/config.json";
|
||||
+ NB_DAEMON_ADDR = "unix:///var/run/netbird-${client.name}/sock";
|
||||
+ NB_INTERFACE_NAME = config.interface;
|
||||
+ NB_LOG_FILE = mkOptionDefault "console";
|
||||
+ NB_LOG_LEVEL = config.logLevel;
|
||||
+ NB_SERVICE = "netbird-${client.name}";
|
||||
+ NB_WIREGUARD_PORT = toString config.port;
|
||||
+ };
|
||||
+
|
||||
+ config.config = {
|
||||
+ DisableAutoConnect = !config.autoStart;
|
||||
+ WgIface = config.interface;
|
||||
+ WgPort = config.port;
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
description = ''
|
||||
- Attribute set of Netbird tunnels, each one will spawn a daemon listening on ...
|
||||
+ Attribute set of Netbird client daemons, by default each one will:
|
||||
+
|
||||
+ 1. be manageable using dedicated tooling:
|
||||
+ - `netbird-<name>` script,
|
||||
+ - `Netbird - netbird-<name>` graphical interface when appropriate (see `ui.enable`),
|
||||
+ 2. run as a `netbird-<name>.service`,
|
||||
+ 3. listen for incoming remote connections on the port `51820` (`openFirewall` by default),
|
||||
+ 4. manage the `netbird-<name>` wireguard interface,
|
||||
+ 5. use the `/var/lib/netbird-<name>/config.json` configuration file,
|
||||
+ 6. override `/var/lib/netbird-<name>/config.json` with values from `/etc/netbird-<name>/config.d/*.json`,
|
||||
+ 7. (`hardened`) be locally manageable by `netbird-<name>` system group,
|
||||
+
|
||||
+ With following caveats:
|
||||
+
|
||||
+ - multiple daemons will interfere with each other's DNS resolution of `netbird.cloud`, but
|
||||
+ should remain fully operational otherwise.
|
||||
+ Setting up custom (non-conflicting) DNS zone is currently possible only when self-hosting.
|
||||
+ '';
|
||||
+ example = lib.literalExpression ''
|
||||
+ {
|
||||
+ services.netbird.clients.wt0.port = 51820;
|
||||
+ services.netbird.clients.personal.port = 51821;
|
||||
+ services.netbird.clients.work1.port = 51822;
|
||||
+ }
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
- (mkIf cfg.enable {
|
||||
- # For backwards compatibility
|
||||
- services.netbird.tunnels.wt0.stateDir = "netbird";
|
||||
- })
|
||||
+ (mkIf cfg.enable (
|
||||
+ let name = "wt0"; client = cfg.clients."${name}"; in {
|
||||
+ services.netbird.clients."${name}" = {
|
||||
+ port = mkDefault 51820;
|
||||
+ name = mkDefault "netbird";
|
||||
+ interface = mkDefault "wt0";
|
||||
+ hardened = mkDefault false;
|
||||
+ };
|
||||
|
||||
- (mkIf (cfg.tunnels != { }) {
|
||||
- boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
|
||||
+ environment.systemPackages = [
|
||||
+ (lib.hiPrio (pkgs.runCommand "${client.name}-as-default" { } ''
|
||||
+ mkdir -p "$out/bin"
|
||||
+ for binary in netbird ${optionalString cfg.ui.enable "netbird-ui"} ; do
|
||||
+ ln -s "${client.wrapper}/bin/$binary-${client.name}" "$out/bin/$binary"
|
||||
+ done
|
||||
+ ''))
|
||||
+ ];
|
||||
+ }
|
||||
+ ))
|
||||
+ {
|
||||
+ boot.extraModulePackages = optional
|
||||
+ (cfg.clients != { } && (versionOlder kernel.version "5.6"))
|
||||
+ kernelPackages.wireguard;
|
||||
|
||||
- environment.systemPackages = [ cfg.package ];
|
||||
+ environment.systemPackages =
|
||||
+ toClientList (client: client.wrapper)
|
||||
+ # omitted due to https://github.com/netbirdio/netbird/issues/1562
|
||||
+ #++ optional (cfg.clients != { }) cfg.package
|
||||
+ # omitted due to https://github.com/netbirdio/netbird/issues/1581
|
||||
+ #++ optional (cfg.clients != { } && cfg.ui.enable) cfg.ui.package
|
||||
+ ;
|
||||
|
||||
- networking.dhcpcd.denyInterfaces = attrNames cfg.tunnels;
|
||||
+ networking.dhcpcd.denyInterfaces = toClientList (client: client.interface);
|
||||
+ networking.networkmanager.unmanaged = toClientList (client: "interface-name:${client.interface}");
|
||||
|
||||
- systemd.network.networks = mkIf config.networking.useNetworkd (
|
||||
- mapAttrs'
|
||||
- (
|
||||
- name: _:
|
||||
- nameValuePair "50-netbird-${name}" {
|
||||
- matchConfig = {
|
||||
- Name = name;
|
||||
- };
|
||||
- linkConfig = {
|
||||
- Unmanaged = true;
|
||||
- ActivationPolicy = "manual";
|
||||
- };
|
||||
- }
|
||||
- )
|
||||
- cfg.tunnels
|
||||
- );
|
||||
+ networking.firewall.allowedUDPPorts = concatLists (toClientList (client: optional client.openFirewall client.port));
|
||||
|
||||
- systemd.services =
|
||||
- mapAttrs'
|
||||
- (
|
||||
- name:
|
||||
- { environment, stateDir, ... }:
|
||||
- nameValuePair "netbird-${name}" {
|
||||
- description = "A WireGuard-based mesh network that connects your devices into a single private network";
|
||||
+ systemd.network.networks = mkIf config.networking.useNetworkd (toClientAttrs (client:
|
||||
+ nameValuePair "50-netbird-${client.interface}" {
|
||||
+ matchConfig = {
|
||||
+ Name = client.interface;
|
||||
+ };
|
||||
+ linkConfig = {
|
||||
+ Unmanaged = true;
|
||||
+ ActivationPolicy = "manual";
|
||||
+ };
|
||||
+ }
|
||||
+ ));
|
||||
|
||||
- documentation = [ "https://netbird.io/docs/" ];
|
||||
+ environment.etc = toClientAttrs (client: nameValuePair "netbird-${client.name}/config.d/50-nixos.json" {
|
||||
+ text = builtins.toJSON client.config;
|
||||
+ mode = "0444";
|
||||
+ });
|
||||
|
||||
- after = [ "network.target" ];
|
||||
- wantedBy = [ "multi-user.target" ];
|
||||
+ systemd.services = toClientAttrs (client: nameValuePair "netbird-${client.name}" {
|
||||
+ description = "A WireGuard-based mesh network that connects your devices into a single private network";
|
||||
|
||||
- path = with pkgs; [ openresolv ];
|
||||
+ documentation = [ "https://netbird.io/docs/" ];
|
||||
|
||||
- inherit environment;
|
||||
+ after = [ "network.target" ];
|
||||
+ wantedBy = [ "multi-user.target" ];
|
||||
|
||||
- serviceConfig = {
|
||||
- ExecStart = "${getExe cfg.package} service run";
|
||||
- Restart = "always";
|
||||
- RuntimeDirectory = stateDir;
|
||||
- StateDirectory = stateDir;
|
||||
- StateDirectoryMode = "0700";
|
||||
- WorkingDirectory = "/var/lib/${stateDir}";
|
||||
- };
|
||||
+ path = optional (!config.services.resolved.enable) pkgs.openresolv;
|
||||
|
||||
- unitConfig = {
|
||||
- StartLimitInterval = 5;
|
||||
- StartLimitBurst = 10;
|
||||
- };
|
||||
+ serviceConfig = {
|
||||
+ ExecStart = "${getExe client.wrapper} service run";
|
||||
+ Restart = "always";
|
||||
+
|
||||
+ RuntimeDirectory = "netbird-${client.name}";
|
||||
+ RuntimeDirectoryMode = mkDefault "0755";
|
||||
+ ConfigurationDirectory = "netbird-${client.name}";
|
||||
+ StateDirectory = "netbird-${client.name}";
|
||||
+ StateDirectoryMode = "0700";
|
||||
+
|
||||
+ WorkingDirectory = "/var/lib/netbird-${client.name}";
|
||||
+ };
|
||||
+
|
||||
+ unitConfig = {
|
||||
+ StartLimitInterval = 5;
|
||||
+ StartLimitBurst = 10;
|
||||
+ };
|
||||
+
|
||||
+ stopIfChanged = false;
|
||||
+ });
|
||||
+ }
|
||||
+ # Hardening section
|
||||
+ (mkIf (hardenedClients != { }) {
|
||||
+ users.groups = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" { });
|
||||
+ users.users = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" {
|
||||
+ isSystemUser = true;
|
||||
+ home = "/var/lib/netbird-${client.name}";
|
||||
+ group = "netbird-${client.name}";
|
||||
+ });
|
||||
+
|
||||
+ systemd.services = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" (mkIf client.hardened {
|
||||
+ serviceConfig = {
|
||||
+ RuntimeDirectoryMode = "0750";
|
||||
+
|
||||
+ User = "netbird-${client.name}";
|
||||
+ Group = "netbird-${client.name}";
|
||||
+
|
||||
+ # settings implied by DynamicUser=true, without actully using it,
|
||||
+ # see https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser=
|
||||
+ RemoveIPC = true;
|
||||
+ PrivateTmp = true;
|
||||
+ ProtectSystem = "strict";
|
||||
+ ProtectHome = "yes";
|
||||
|
||||
- stopIfChanged = false;
|
||||
- }
|
||||
- )
|
||||
- cfg.tunnels;
|
||||
+ AmbientCapabilities = [
|
||||
+ # see https://man7.org/linux/man-pages/man7/capabilities.7.html
|
||||
+ # see https://docs.netbird.io/how-to/installation#running-net-bird-in-docker
|
||||
+ #
|
||||
+ # seems to work fine without CAP_SYS_ADMIN and CAP_SYS_RESOURCE
|
||||
+ # CAP_NET_BIND_SERVICE could be added to allow binding on low ports, but is not required,
|
||||
+ # see https://github.com/netbirdio/netbird/pull/1513
|
||||
+
|
||||
+ # failed creating tunnel interface wt-priv: [operation not permitted
|
||||
+ "CAP_NET_ADMIN"
|
||||
+ # failed to pull up wgInterface [wt-priv]: failed to create ipv4 raw socket: socket: operation not permitted
|
||||
+ "CAP_NET_RAW"
|
||||
+ ]
|
||||
+ # required for eBPF filter, used to be subset of CAP_SYS_ADMIN
|
||||
+ ++ optional (versionAtLeast kernel.version "5.8") "CAP_BPF"
|
||||
+ ++ optional (versionOlder kernel.version "5.8") "CAP_SYS_ADMIN"
|
||||
+ ;
|
||||
+ };
|
||||
+ }));
|
||||
+
|
||||
+ # see https://github.com/systemd/systemd/blob/17f3e91e8107b2b29fe25755651b230bbc81a514/src/resolve/org.freedesktop.resolve1.policy#L43-L43
|
||||
+ security.polkit.extraConfig = mkIf config.services.resolved.enable ''
|
||||
+ // systemd-resolved access for Netbird clients
|
||||
+ polkit.addRule(function(action, subject) {
|
||||
+ var actions = [
|
||||
+ "org.freedesktop.resolve1.set-dns-servers",
|
||||
+ "org.freedesktop.resolve1.set-domains",
|
||||
+ ];
|
||||
+ var users = ${builtins.toJSON (toHardenedClientList (client: "netbird-${client.name}"))};
|
||||
+
|
||||
+ if (actions.indexOf(action.id) >= 0 && users.indexOf(subject.user) >= 0 ) {
|
||||
+ return polkit.Result.YES;
|
||||
+ }
|
||||
+ });
|
||||
+ '';
|
||||
})
|
||||
+ # migration & temporary fixups section
|
||||
+ {
|
||||
+ systemd.services = toClientAttrs (client: nameValuePair "netbird-${client.name}" {
|
||||
+ preStart = ''
|
||||
+ set -eEuo pipefail
|
||||
+ ${optionalString (client.logLevel == "trace" || client.logLevel == "debug") "set -x"}
|
||||
+
|
||||
+ PATH="${makeBinPath (with pkgs; [coreutils jq diffutils])}:$PATH"
|
||||
+ export ${toShellVars client.environment}
|
||||
+
|
||||
+ # merge /etc/netbird-${client.name}/config.d' into "$NB_CONFIG"
|
||||
+ {
|
||||
+ test -e "$NB_CONFIG" || echo -n '{}' > "$NB_CONFIG"
|
||||
+
|
||||
+ # merge config.d with "$NB_CONFIG" into "$NB_CONFIG.new"
|
||||
+ jq -sS 'reduce .[] as $i ({}; . * $i)' \
|
||||
+ "$NB_CONFIG" \
|
||||
+ /etc/netbird-${client.name}/config.d/*.json \
|
||||
+ > "$NB_CONFIG.new"
|
||||
+
|
||||
+ echo "Comparing $NB_CONFIG with $NB_CONFIG.new ..."
|
||||
+ if ! diff <(jq -S <"$NB_CONFIG") "$NB_CONFIG.new" ; then
|
||||
+ echo "Updating $NB_CONFIG ..."
|
||||
+ mv "$NB_CONFIG.new" "$NB_CONFIG"
|
||||
+ else
|
||||
+ echo "Files are the same, not doing anything."
|
||||
+ rm "$NB_CONFIG.new"
|
||||
+ fi
|
||||
+ }
|
||||
+ '';
|
||||
+ });
|
||||
+ }
|
||||
];
|
||||
}
|
||||
diff --git a/nixos/tests/netbird.nix b/nixos/tests/netbird.nix
|
||||
index 7342e8d04a39c3..063fff6d42f031 100644
|
||||
--- a/nixos/tests/netbird.nix
|
||||
+++ b/nixos/tests/netbird.nix
|
||||
@@ -12,10 +12,32 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||
};
|
||||
};
|
||||
|
||||
+ # TODO: confirm the whole solution is working end-to-end when netbird server is implemented
|
||||
testScript = ''
|
||||
start_all()
|
||||
- node.wait_for_unit("netbird-wt0.service")
|
||||
+ node.wait_for_unit("netbird.service")
|
||||
node.wait_for_file("/var/run/netbird/sock")
|
||||
- node.succeed("netbird status | grep -q 'Daemon status: NeedsLogin'")
|
||||
+ output = node.succeed("netbird status")
|
||||
+ # used to print `Daemon status: NeedsLogin`, but not anymore `Management: Disconnected`
|
||||
+ assert "Disconnected" in output or "NeedsLogin" in output
|
||||
'';
|
||||
+
|
||||
+ /*
|
||||
+ `netbird status` used to print `Daemon status: NeedsLogin`
|
||||
+ https://github.com/netbirdio/netbird/blob/23a14737974e3849fa86408d136cc46db8a885d0/client/cmd/status.go#L154-L164
|
||||
+ as the first line, but now it is just:
|
||||
+
|
||||
+ Daemon version: 0.26.3
|
||||
+ CLI version: 0.26.3
|
||||
+ Management: Disconnected
|
||||
+ Signal: Disconnected
|
||||
+ Relays: 0/0 Available
|
||||
+ Nameservers: 0/0 Available
|
||||
+ FQDN:
|
||||
+ NetBird IP: N/A
|
||||
+ Interface type: N/A
|
||||
+ Quantum resistance: false
|
||||
+ Routes: -
|
||||
+ Peers count: 0/0 Connected
|
||||
+ */
|
||||
})
|
@ -1,24 +1,24 @@
|
||||
diff --git a/nixos/modules/services/security/vaultwarden/default.nix b/nixos/modules/services/security/vaultwarden/default.nix
|
||||
index b2920931f..443b8421b 100644
|
||||
index 41f7de5d8..31c183ed5 100644
|
||||
--- a/nixos/modules/services/security/vaultwarden/default.nix
|
||||
+++ b/nixos/modules/services/security/vaultwarden/default.nix
|
||||
@@ -23,7 +23,7 @@ let
|
||||
@@ -25,7 +25,7 @@ let
|
||||
configEnv = lib.concatMapAttrs (name: value: lib.optionalAttrs (value != null) {
|
||||
${nameToEnvVar name} = if lib.isBool value then lib.boolToString value else toString value;
|
||||
}) cfg.config;
|
||||
- in { DATA_FOLDER = "/var/lib/bitwarden_rs"; } // lib.optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED) || configEnv.WEB_VAULT_ENABLED == "true") {
|
||||
- in { DATA_FOLDER = "/var/lib/${StateDirectory}"; } // lib.optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED) || configEnv.WEB_VAULT_ENABLED == "true") {
|
||||
+ in { DATA_FOLDER = cfg.dataDir; } // lib.optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED) || configEnv.WEB_VAULT_ENABLED == "true") {
|
||||
WEB_VAULT_FOLDER = "${cfg.webVaultPackage}/share/vaultwarden/vault";
|
||||
} // configEnv;
|
||||
|
||||
@@ -163,6 +163,16 @@ in {
|
||||
|
||||
@@ -157,6 +157,16 @@ in {
|
||||
defaultText = lib.literalExpression "pkgs.vaultwarden.webvault";
|
||||
description = "Web vault package to use.";
|
||||
};
|
||||
+
|
||||
+ dataDir = lib.mkOption {
|
||||
+ type = lib.types.str;
|
||||
+ default = "/var/lib/bitwarden_rs";
|
||||
+ default = "/var/lib/${StateDirectory}";
|
||||
+ description = ''
|
||||
+ The directury in which vaultwarden will keep its state. If left as the default value
|
||||
+ this directory will automatically be created before the vaultwarden server starts, otherwise
|
||||
@ -26,53 +26,13 @@ index b2920931f..443b8421b 100644
|
||||
+ '';
|
||||
+ };
|
||||
};
|
||||
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
@@ -180,28 +190,32 @@ in {
|
||||
systemd.services.vaultwarden = {
|
||||
after = [ "network.target" ];
|
||||
path = with pkgs; [ openssl ];
|
||||
- serviceConfig = {
|
||||
- User = user;
|
||||
- Group = group;
|
||||
- EnvironmentFile = [ configFile ] ++ lib.optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
- ExecStart = "${vaultwarden}/bin/vaultwarden";
|
||||
- LimitNOFILE = "1048576";
|
||||
- PrivateTmp = "true";
|
||||
- PrivateDevices = "true";
|
||||
- ProtectHome = "true";
|
||||
- ProtectSystem = "strict";
|
||||
- AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||
- StateDirectory = "bitwarden_rs";
|
||||
- StateDirectoryMode = "0700";
|
||||
- Restart = "always";
|
||||
- };
|
||||
+ serviceConfig = lib.mkMerge [
|
||||
+ (lib.mkIf (cfg.dataDir == "/var/lib/bitwarden_rs") {
|
||||
+ StateDirectory = "bitwarden_rs";
|
||||
+ StateDirectoryMode = "0700";
|
||||
+ })
|
||||
+ {
|
||||
+ User = user;
|
||||
+ Group = group;
|
||||
+ EnvironmentFile = [ configFile ] ++ lib.optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
+ ExecStart = "${vaultwarden}/bin/vaultwarden";
|
||||
+ LimitNOFILE = "1048576";
|
||||
+ PrivateTmp = "true";
|
||||
+ PrivateDevices = "true";
|
||||
+ ProtectHome = "true";
|
||||
+ ProtectSystem = "strict";
|
||||
+ AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||
+ Restart = "always";
|
||||
+ }
|
||||
+ ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
@@ -224,7 +234,7 @@ in {
|
||||
systemd.services.backup-vaultwarden = lib.mkIf (cfg.backupDir != null) {
|
||||
description = "Backup vaultwarden";
|
||||
environment = {
|
||||
- DATA_FOLDER = "/var/lib/bitwarden_rs";
|
||||
- DATA_FOLDER = "/var/lib/${StateDirectory}";
|
||||
+ DATA_FOLDER = cfg.dataDir;
|
||||
BACKUP_FOLDER = cfg.backupDir;
|
||||
};
|
||||
|
@ -1,24 +1,15 @@
|
||||
diff --git a/pkgs/os-specific/linux/kernel/zen-kernels.nix b/pkgs/os-specific/linux/kernel/zen-kernels.nix
|
||||
index 072416007e72..89c776e611e5 100644
|
||||
index 9d1566216..c3113eb5c 100644
|
||||
--- a/pkgs/os-specific/linux/kernel/zen-kernels.nix
|
||||
+++ b/pkgs/os-specific/linux/kernel/zen-kernels.nix
|
||||
@@ -4,16 +4,16 @@ let
|
||||
# comments with variant added for update script
|
||||
# ./update-zen.py zen
|
||||
zenVariant = {
|
||||
- version = "6.9.3"; #zen
|
||||
+ version = "6.9.2"; #zen
|
||||
suffix = "zen1"; #zen
|
||||
- sha256 = "0vgy249zrzm6kn8wqisnbgbq8h6sffmk1zs6cx57annab9w0sb57"; #zen
|
||||
+ sha256 = "1fsmpryk7an6xqppvilcf3bmxs41mqpc3v4f4c81jgrikg21gxbb"; #zen
|
||||
isLqx = false;
|
||||
@@ -11,9 +11,9 @@ let
|
||||
};
|
||||
# ./update-zen.py lqx
|
||||
lqxVariant = {
|
||||
- version = "6.9.3"; #lqx
|
||||
- version = "6.9.5"; #lqx
|
||||
+ version = "6.8.11"; #lqx
|
||||
suffix = "lqx1"; #lqx
|
||||
- sha256 = "1wfjw5fq7myvhfb6srina0b7b76a08ib9x8hd8bdfr4zr6al8zq8"; #lqx
|
||||
- sha256 = "0r3pgjfyza3vkvp7kw1s7sn1gf4hxq6r6qs5wvv76gmff7s399yz"; #lqx
|
||||
+ sha256 = "1dj4znir4wp6jqs680dcxn8z6p02d518993rmrx54ch04jyy5brj"; #lqx
|
||||
isLqx = true;
|
||||
};
|
||||
|
@ -1,22 +1,20 @@
|
||||
{ pkgs, config, ... }:
|
||||
with config.deviceSpecific; {
|
||||
|
||||
hardware.cpu.${devInfo.cpu.vendor}.updateMicrocode = true;
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
|
||||
hardware.opengl = {
|
||||
hardware.graphics = {
|
||||
enable = true;
|
||||
driSupport = true;
|
||||
driSupport32Bit = true;
|
||||
enable32Bit = true;
|
||||
extraPackages = if devInfo.gpu.vendor == "intel" then [
|
||||
pkgs.intel-media-driver
|
||||
pkgs.intel-vaapi-driver
|
||||
pkgs.libvdpau-va-gl
|
||||
] else if devInfo.gpu.vendor == "amd" then [
|
||||
pkgs.rocm-opencl-icd
|
||||
pkgs.rocm-opencl-runtime
|
||||
pkgs.rocmPackages.clr.icd
|
||||
] else [ ];
|
||||
};
|
||||
|
||||
environment.sessionVariables = if (devInfo.gpu.vendor == "intel") then {
|
||||
GST_VAAPI_ALL_DRIVERS = "1";
|
||||
LIBVA_DRIVER_NAME = "iHD";
|
||||
@ -24,6 +22,7 @@ with config.deviceSpecific; {
|
||||
} else if (devInfo.gpu.vendor == "amd") then {
|
||||
AMD_VULKAN_ICD = "RADV";
|
||||
} else {};
|
||||
|
||||
boot.initrd.kernelModules = if devInfo.gpu.vendor == "amd" then [
|
||||
"amdgpu"
|
||||
] else if devInfo.gpu.vendor == "intel" then [
|
||||
|
@ -13,7 +13,7 @@ in
|
||||
with lib; {
|
||||
nixpkgs.overlays = [
|
||||
inputs.ataraxiasjel-nur.overlays.default
|
||||
inputs.ataraxiasjel-nur.overlays.grub2-argon2
|
||||
inputs.ataraxiasjel-nur.overlays.grub2-unstable-argon2
|
||||
inputs.deploy-rs.overlay
|
||||
(final: prev:
|
||||
{
|
||||
@ -33,6 +33,7 @@ with lib; {
|
||||
steam = prev.steam.override {
|
||||
extraPkgs = pkgs: with pkgs; [ mono libkrb5 keyutils ];
|
||||
};
|
||||
wine = prev.wineWow64Packages.stagingFull;
|
||||
intel-vaapi-driver = prev.intel-vaapi-driver.override { enableHybridCodec = true; };
|
||||
|
||||
neatvnc = prev.neatvnc.overrideAttrs (oa: {
|
||||
|
79
profiles/servers/coturn.nix
Normal file
79
profiles/servers/coturn.nix
Normal file
@ -0,0 +1,79 @@
|
||||
{ config, lib, inputs, ... }:
|
||||
let
|
||||
external-ip = "91.202.204.123";
|
||||
coturn-denied-ips = [
|
||||
"0.0.0.0-0.255.255.255"
|
||||
"10.0.0.0-10.255.255.255"
|
||||
"100.64.0.0-100.127.255.255"
|
||||
"127.0.0.0-127.255.255.255"
|
||||
"169.254.0.0-169.254.255.255"
|
||||
"172.16.0.0-172.31.255.255"
|
||||
"192.0.0.0-192.0.0.255"
|
||||
"192.0.2.0-192.0.2.255"
|
||||
"192.88.99.0-192.88.99.255"
|
||||
"192.168.0.0-192.168.255.255"
|
||||
"198.18.0.0-198.19.255.255"
|
||||
"198.51.100.0-198.51.100.255"
|
||||
"203.0.113.0-203.0.113.255"
|
||||
"240.0.0.0-255.255.255.255"
|
||||
"::1"
|
||||
"64:ff9b::-64:ff9b::ffff:ffff"
|
||||
"::ffff:0.0.0.0-::ffff:255.255.255.255"
|
||||
"100::-100::ffff:ffff:ffff:ffff"
|
||||
"2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||
"2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||
"fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||
"fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||
];
|
||||
cert-fqdn = "ataraxiadev.com";
|
||||
in {
|
||||
sops.secrets.auth-secret = {
|
||||
sopsFile = inputs.self.secretsDir + /home-hypervisor/coturn.yaml;
|
||||
restartUnits = [ "coturn.service" ];
|
||||
owner = config.users.users.turnserver.name;
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
services.coturn = {
|
||||
enable = true;
|
||||
use-auth-secret = true;
|
||||
static-auth-secret-file = config.sops.secrets.auth-secret.path;
|
||||
realm = "turn.ataraxiadev.com";
|
||||
min-port = 49152;
|
||||
max-port = 49262;
|
||||
no-cli = true;
|
||||
cert = "${config.security.acme.certs.${cert-fqdn}.directory}/fullchain.pem";
|
||||
pkey = "${config.security.acme.certs.${cert-fqdn}.directory}/key.pem";
|
||||
no-tcp-relay = true;
|
||||
extraConfig = ''
|
||||
fingerprint
|
||||
external-ip=${external-ip}
|
||||
userdb=/var/lib/coturn/turnserver.db
|
||||
no-tlsv1
|
||||
no-tlsv1_1
|
||||
no-rfc5780
|
||||
no-stun-backward-compatibility
|
||||
response-origin-only-with-rfc5780
|
||||
no-multicast-peers
|
||||
'' + lib.strings.concatMapStringsSep "\n" (x: "denied-peer-ip=${x}")
|
||||
coturn-denied-ips;
|
||||
};
|
||||
systemd.services.coturn.serviceConfig.StateDirectory = "coturn";
|
||||
systemd.services.coturn.serviceConfig.Group = lib.mkForce "acme";
|
||||
|
||||
networking = let
|
||||
turn-ports = with config.services.coturn; [
|
||||
listening-port tls-listening-port
|
||||
alt-listening-port alt-tls-listening-port
|
||||
];
|
||||
in {
|
||||
firewall = {
|
||||
allowedUDPPortRanges = with config.services.coturn; [{
|
||||
from = min-port;
|
||||
to = max-port;
|
||||
}];
|
||||
allowedUDPPorts = turn-ports;
|
||||
allowedTCPPorts = turn-ports;
|
||||
};
|
||||
};
|
||||
}
|
102
profiles/servers/netbird-server.nix
Normal file
102
profiles/servers/netbird-server.nix
Normal file
@ -0,0 +1,102 @@
|
||||
{ config, lib, inputs, ... }:
|
||||
let
|
||||
svc-pass = config.sops.secrets.netbird-svc-pass.path;
|
||||
store-key = config.sops.secrets.netbird-store-key.path;
|
||||
|
||||
domain = "net.ataraxiadev.com";
|
||||
client-id = "GI2nPUZfBoAOgYWoQpWHopE4awUz3Tx3W5LYOaz1";
|
||||
issuer = "https://auth.ataraxiadev.com/application/o/netbird";
|
||||
scopes = "openid profile email offline_access api groups";
|
||||
in {
|
||||
sops.secrets = let
|
||||
cfg = {
|
||||
sopsFile = inputs.self.secretsDir + /home-hypervisor/netbird.yaml;
|
||||
restartUnits = [ "netbird-management.service" ];
|
||||
};
|
||||
in {
|
||||
netbird-store-key = cfg;
|
||||
netbird-svc-pass = cfg;
|
||||
};
|
||||
|
||||
services.netbird.server = {
|
||||
enable = true;
|
||||
inherit domain;
|
||||
enableNginx = true;
|
||||
coturn.enable = false;
|
||||
signal.logLevel = "INFO";
|
||||
dashboard.settings = {
|
||||
AUTH_AUTHORITY = issuer;
|
||||
AUTH_CLIENT_ID = client-id;
|
||||
AUTH_SUPPORTED_SCOPES = scopes;
|
||||
};
|
||||
management = {
|
||||
disableAnonymousMetrics = lib.mkForce true;
|
||||
logLevel = "INFO";
|
||||
dnsDomain = "netbird.local";
|
||||
singleAccountModeDomain = "netbird.local";
|
||||
oidcConfigEndpoint = "${issuer}/.well-known/openid-configuration";
|
||||
|
||||
turnDomain = config.services.coturn.realm;
|
||||
turnPort = config.services.coturn.listening-port;
|
||||
settings = {
|
||||
DataStoreEncryptionKey._secret = store-key;
|
||||
DeviceAuthorizationFlow = {
|
||||
Provider = "hosted";
|
||||
ProviderConfig = {
|
||||
Audience = client-id;
|
||||
ClientID = client-id;
|
||||
DeviceAuthEndpoint = "https://auth.ataraxiadev.com/application/o/device/";
|
||||
RedirectURLs = null;
|
||||
Scope = "openid";
|
||||
TokenEndpoint = "https://auth.ataraxiadev.com/application/o/token/";
|
||||
UseIDToken = false;
|
||||
};
|
||||
};
|
||||
HttpConfig = {
|
||||
AuthAudience = client-id;
|
||||
AuthIssuer = "https://auth.ataraxiadev.com/application/o/netbird/";
|
||||
AuthKeysLocation = "https://auth.ataraxiadev.com/application/o/netbird/jwks/";
|
||||
# AuthUserIDClaim = "";
|
||||
IdpSignKeyRefreshEnabled = false;
|
||||
};
|
||||
IdpManagerConfig = {
|
||||
ManagerType = "authentik";
|
||||
ClientConfig = {
|
||||
ClientID = client-id;
|
||||
GrantType = "client_credentials";
|
||||
Issuer = "https://auth.ataraxiadev.com/application/o/netbird/";
|
||||
TokenEndpoint = "https://auth.ataraxiadev.com/application/o/token/";
|
||||
};
|
||||
ExtraConfig = {
|
||||
Password._secret = svc-pass;
|
||||
Username = "Netbird";
|
||||
};
|
||||
};
|
||||
PKCEAuthorizationFlow = {
|
||||
ProviderConfig = {
|
||||
Audience = client-id;
|
||||
AuthorizationEndpoint = "https://auth.ataraxiadev.com/application/o/authorize/";
|
||||
ClientID = client-id;
|
||||
Scope = scopes;
|
||||
TokenEndpoint = "https://auth.ataraxiadev.com/application/o/token/";
|
||||
UseIDToken = false;
|
||||
};
|
||||
};
|
||||
TURNConfig = {
|
||||
Secret._secret = config.sops.secrets.auth-secret.path;
|
||||
TimeBasedCredentials = true;
|
||||
# Not used, supress nix warnind about world-readable password
|
||||
# Password._secret = config.sops.secrets.auth-secret.path;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts.${domain} = {
|
||||
useACMEHost = "ataraxiadev.com";
|
||||
enableACME = false;
|
||||
forceSSL = true;
|
||||
};
|
||||
|
||||
persist.state.directories = [ "/var/lib/netbird-mgmt" ];
|
||||
}
|
@ -1,39 +1,74 @@
|
||||
{ config, lib, ... }:
|
||||
{ config, lib, pkgs, inputs, ... }:
|
||||
let
|
||||
gpu = config.deviceSpecific.devInfo.gpu.vendor;
|
||||
ollama-port = toString config.services.ollama.port;
|
||||
searx-port = toString config.services.searx.settings.server.port;
|
||||
in {
|
||||
sops.secrets.searx-env.sopsFile = inputs.self.secretsDir + /searx.yaml;
|
||||
|
||||
services.ollama = {
|
||||
enable = true;
|
||||
host = "127.0.0.1";
|
||||
port = 11434;
|
||||
sandbox = false;
|
||||
openFirewall = false;
|
||||
acceleration =
|
||||
if gpu == "amd" then
|
||||
"rocm"
|
||||
else if gpu == "nvidia" then
|
||||
"cuda"
|
||||
else false;
|
||||
openFirewall = false;
|
||||
rocmOverrideGfx = lib.mkIf (gpu == "amd") "10.3.0";
|
||||
environmentVariables = {
|
||||
HSA_OVERRIDE_GFX_VERSION = "10.3.0";
|
||||
OLLAMA_KEEP_ALIVE = "-1";
|
||||
# OLLAMA_LLM_LIBRARY = "";
|
||||
# OLLAMA_KEEP_ALIVE = "-1";
|
||||
};
|
||||
};
|
||||
services.open-webui = {
|
||||
enable = true;
|
||||
host = "127.0.0.1";
|
||||
port = 8081;
|
||||
port = 8080;
|
||||
openFirewall = false;
|
||||
environment = {
|
||||
ANONYMIZED_TELEMETRY = "False";
|
||||
DO_NOT_TRACK = "True";
|
||||
SCARF_NO_ANALYTICS = "True";
|
||||
OLLAMA_API_BASE_URL = "http://127.0.0.1:11434";
|
||||
OLLAMA_API_BASE_URL = "http://127.0.0.1:${ollama-port}";
|
||||
# Disable authentication
|
||||
WEBUI_AUTH = "False";
|
||||
ENABLE_SIGNUP = "False";
|
||||
WEBUI_URL = "http://localhost:8080";
|
||||
# Search
|
||||
ENABLE_RAG_WEB_SEARCH = "True";
|
||||
RAG_WEB_SEARCH_ENGINE = "searxng";
|
||||
SEARXNG_QUERY_URL = "http://127.0.0.1:${searx-port}/search?q=<query>";
|
||||
|
||||
};
|
||||
};
|
||||
services.searx = {
|
||||
enable = true;
|
||||
package = pkgs.searxng;
|
||||
runInUwsgi = false;
|
||||
settings = {
|
||||
general.enable_metrics = false;
|
||||
search = {
|
||||
safe_search = 0;
|
||||
formats = [ "html" "csv" "json" "rss" ];
|
||||
};
|
||||
server = {
|
||||
port = 8081;
|
||||
bind_address = "127.0.0.1";
|
||||
public_instance = false;
|
||||
limiter = false;
|
||||
http_protocol_version = "1.1";
|
||||
secret_key = "@SEARX_SECRET_KEY@";
|
||||
};
|
||||
ui = {
|
||||
default_locale = "en";
|
||||
theme_args.simple_style = "dark";
|
||||
};
|
||||
};
|
||||
environmentFile = config.sops.secrets.searx-env.path;
|
||||
};
|
||||
|
||||
users.groups.ollama = { };
|
||||
users.users.ollama = {
|
||||
|
@ -1,39 +1,7 @@
|
||||
{ config, lib, inputs, ... }:
|
||||
{ config, ... }:
|
||||
let
|
||||
external-ip = "91.202.204.123";
|
||||
coturn-denied-ips = [
|
||||
"0.0.0.0-0.255.255.255"
|
||||
"10.0.0.0-10.255.255.255"
|
||||
"100.64.0.0-100.127.255.255"
|
||||
"127.0.0.0-127.255.255.255"
|
||||
"169.254.0.0-169.254.255.255"
|
||||
"172.16.0.0-172.31.255.255"
|
||||
"192.0.0.0-192.0.0.255"
|
||||
"192.0.2.0-192.0.2.255"
|
||||
"192.88.99.0-192.88.99.255"
|
||||
"192.168.0.0-192.168.255.255"
|
||||
"198.18.0.0-198.19.255.255"
|
||||
"198.51.100.0-198.51.100.255"
|
||||
"203.0.113.0-203.0.113.255"
|
||||
"240.0.0.0-255.255.255.255"
|
||||
"::1"
|
||||
"64:ff9b::-64:ff9b::ffff:ffff"
|
||||
"::ffff:0.0.0.0-::ffff:255.255.255.255"
|
||||
"100::-100::ffff:ffff:ffff:ffff"
|
||||
"2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||
"2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||
"fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||
"fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||
];
|
||||
cert-fqdn = "ataraxiadev.com";
|
||||
in {
|
||||
sops.secrets.auth-secret = {
|
||||
sopsFile = inputs.self.secretsDir + /home-hypervisor/coturn.yaml;
|
||||
restartUnits = [ "coturn.service" ];
|
||||
owner = config.users.users.turnserver.name;
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
virtualisation.libvirt.guests.debian-matrix = {
|
||||
autoStart = true;
|
||||
user = config.mainuser;
|
||||
@ -41,49 +9,12 @@ in {
|
||||
xmlFile = ./vm.xml;
|
||||
};
|
||||
|
||||
services.coturn = {
|
||||
enable = true;
|
||||
use-auth-secret = true;
|
||||
static-auth-secret-file = config.sops.secrets.auth-secret.path;
|
||||
realm = "turn.ataraxiadev.com";
|
||||
min-port = 49152;
|
||||
max-port = 49262;
|
||||
no-cli = true;
|
||||
cert = "${config.security.acme.certs.${cert-fqdn}.directory}/fullchain.pem";
|
||||
pkey = "${config.security.acme.certs.${cert-fqdn}.directory}/key.pem";
|
||||
no-tcp-relay = true;
|
||||
extraConfig = ''
|
||||
external-ip=${external-ip}
|
||||
userdb=/var/lib/coturn/turnserver.db
|
||||
no-tlsv1
|
||||
no-tlsv1_1
|
||||
no-rfc5780
|
||||
no-stun-backward-compatibility
|
||||
response-origin-only-with-rfc5780
|
||||
no-multicast-peers
|
||||
'' + lib.strings.concatMapStringsSep "\n" (x: "denied-peer-ip=${x}")
|
||||
coturn-denied-ips;
|
||||
};
|
||||
systemd.services.coturn.serviceConfig.StateDirectory = "coturn";
|
||||
systemd.services.coturn.serviceConfig.Group = lib.mkForce "acme";
|
||||
|
||||
networking = let
|
||||
libvirt-ifname = "virbr0";
|
||||
guest-ip = "192.168.122.11";
|
||||
synapse-ports = [ 8081 8448 8766 ];
|
||||
turn-ports = with config.services.coturn; [
|
||||
listening-port tls-listening-port
|
||||
alt-listening-port alt-tls-listening-port
|
||||
];
|
||||
in {
|
||||
firewall = {
|
||||
allowedUDPPortRanges = with config.services.coturn; [{
|
||||
from = min-port;
|
||||
to = max-port;
|
||||
}];
|
||||
allowedUDPPorts = turn-ports;
|
||||
allowedTCPPorts = turn-ports ++ synapse-ports;
|
||||
};
|
||||
firewall.allowedTCPPorts = synapse-ports;
|
||||
nat = {
|
||||
enable = true;
|
||||
internalInterfaces = [ "br0" ];
|
||||
|
23
profiles/servers/tg-bot.nix
Normal file
23
profiles/servers/tg-bot.nix
Normal file
@ -0,0 +1,23 @@
|
||||
{ config, ... }:
|
||||
let
|
||||
cert-fqdn = "tg.ataraxiadev.com";
|
||||
in {
|
||||
security.acme.certs = {
|
||||
${cert-fqdn} = {
|
||||
dnsResolver = "1.1.1.1:53";
|
||||
dnsProvider = "cloudflare";
|
||||
credentialFiles."CF_DNS_API_TOKEN_FILE" = config.sops.secrets.cf-dns-api.path;
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = {
|
||||
${cert-fqdn} = {
|
||||
useACMEHost = cert-fqdn;
|
||||
enableACME = false;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://192.168.0.100:3456";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -39,4 +39,6 @@
|
||||
builtins.readFile ./easyeffects/noise_reduction.json;
|
||||
};
|
||||
};
|
||||
|
||||
persist.state.homeDirectories = [ ".local/state/wireplumber" ];
|
||||
}
|
@ -13,32 +13,18 @@ with config.deviceSpecific; {
|
||||
podman = {
|
||||
enable = true;
|
||||
defaultNetwork.settings.dns_enabled = true;
|
||||
dockerSocket.enable = !config.virtualisation.docker.enable;
|
||||
};
|
||||
containers.registries.search = [
|
||||
"docker.io" "gcr.io" "quay.io"
|
||||
];
|
||||
containers.storage.settings = {
|
||||
storage = {
|
||||
driver = "overlay2";
|
||||
driver = "overlay";
|
||||
graphroot = "/var/lib/containers/storage";
|
||||
runroot = "/run/containers/storage";
|
||||
};
|
||||
};
|
||||
lxd = lib.mkIf (!isContainer) {
|
||||
enable = true;
|
||||
zfsSupport = devInfo.fileSystem == "zfs";
|
||||
recommendedSysctlSettings = true;
|
||||
};
|
||||
lxc = {
|
||||
enable = true;
|
||||
lxcfs.enable = true;
|
||||
systemConfig = ''
|
||||
lxc.lxcpath = /var/lib/lxd/containers
|
||||
${if devInfo.fileSystem == "zfs" then ''
|
||||
lxc.bdev.zfs.root = rpool/persistent/lxd
|
||||
'' else ""}
|
||||
'';
|
||||
};
|
||||
libvirtd = {
|
||||
enable = true;
|
||||
qemu = {
|
||||
@ -56,7 +42,7 @@ with config.deviceSpecific; {
|
||||
onShutdown = "shutdown";
|
||||
};
|
||||
|
||||
spiceUSBRedirection.enable = true;
|
||||
spiceUSBRedirection.enable = !isServer;
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.virtiofsd ];
|
||||
@ -79,7 +65,7 @@ with config.deviceSpecific; {
|
||||
'';
|
||||
};
|
||||
|
||||
programs.extra-container.enable = true;
|
||||
programs.extra-container.enable = !isServer;
|
||||
programs.virt-manager.enable = !isServer;
|
||||
|
||||
persist.state.homeDirectories = [
|
||||
@ -90,18 +76,19 @@ with config.deviceSpecific; {
|
||||
"/var/lib/docker"
|
||||
"/var/lib/libvirt"
|
||||
"/var/lib/containers"
|
||||
"/var/lib/lxd"
|
||||
];
|
||||
|
||||
networking.firewall.interfaces."podman+".allowedUDPPorts = [ 53 5353 ];
|
||||
|
||||
# cross compilation of aarch64 uefi currently broken
|
||||
# link existing extracted from fedora package
|
||||
system.activationScripts.aarch64-ovmf.text = ''
|
||||
rm -f /run/libvirt/nix-ovmf/AAVMF_*
|
||||
mkdir -p /run/libvirt/nix-ovmf || true
|
||||
${pkgs.zstd}/bin/zstd -d ${../misc/AAVMF_CODE.fd.zst} -o /run/libvirt/nix-ovmf/AAVMF_CODE.fd
|
||||
${pkgs.zstd}/bin/zstd -d ${../misc/AAVMF_VARS.fd.zst} -o /run/libvirt/nix-ovmf/AAVMF_VARS.fd
|
||||
'';
|
||||
system.activationScripts.aarch64-ovmf = lib.mkIf (!isServer) {
|
||||
text = ''
|
||||
rm -f /run/libvirt/nix-ovmf/AAVMF_*
|
||||
mkdir -p /run/libvirt/nix-ovmf || true
|
||||
${pkgs.zstd}/bin/zstd -d ${../misc/AAVMF_CODE.fd.zst} -o /run/libvirt/nix-ovmf/AAVMF_CODE.fd
|
||||
${pkgs.zstd}/bin/zstd -d ${../misc/AAVMF_VARS.fd.zst} -o /run/libvirt/nix-ovmf/AAVMF_VARS.fd
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,19 +1,17 @@
|
||||
{ cfg }: { config, pkgs, ... }: {
|
||||
{ cfg }: { config, pkgs, lib, ... }: {
|
||||
home-manager.users.${config.mainuser} = rec {
|
||||
gtk = {
|
||||
enable = true;
|
||||
theme = {
|
||||
name = "Catppuccin-${cfg.flavorUpper}-${cfg.sizeUpper}-${cfg.accentUpper}-${cfg.gtkTheme}";
|
||||
theme = let
|
||||
gtkTweaks = lib.concatStringsSep "," cfg.tweaks;
|
||||
in {
|
||||
name = "catppuccin-${cfg.flavor}-${cfg.accent}-${cfg.size}+${gtkTweaks}";
|
||||
package = pkgs.catppuccin-gtk.override {
|
||||
inherit (cfg) tweaks;
|
||||
accents = [ cfg.accent ];
|
||||
variant = cfg.flavor;
|
||||
};
|
||||
};
|
||||
cursorTheme = {
|
||||
name = "catppuccin-${cfg.flavor}-${cfg.accent}-cursors";
|
||||
package = pkgs.catppuccin-cursors.${cfg.flavor + cfg.accentUpper};
|
||||
};
|
||||
iconTheme = {
|
||||
name = "Papirus-${cfg.gtkTheme}";
|
||||
package = pkgs.catppuccin-papirus-folders.override { inherit (cfg) accent flavor; };
|
||||
@ -30,5 +28,12 @@
|
||||
};
|
||||
};
|
||||
home.sessionVariables.GTK_THEME = gtk.theme.name;
|
||||
xdg.configFile = let
|
||||
gtk4Dir = "${gtk.theme.package}/share/themes/${gtk.theme.name}/gtk-4.0";
|
||||
in {
|
||||
"gtk-4.0/assets".source = "${gtk4Dir}/assets";
|
||||
"gtk-4.0/gtk.css".source = "${gtk4Dir}/gtk.css";
|
||||
"gtk-4.0/gtk-dark.css".source = "${gtk4Dir}/gtk-dark.css";
|
||||
};
|
||||
};
|
||||
}
|
@ -5,7 +5,7 @@ let
|
||||
gsettings = "${pkgs.glib}/bin/gsettings";
|
||||
gnomeSchema = "org.gnome.desktop.interface";
|
||||
importGsettings = pkgs.writeShellScript "import_gsettings.sh" ''
|
||||
config="/home/${config.mainuser}/.config/gtk-3.0/settings.ini"
|
||||
config="/home/${config.mainuser}/.config/gtk-4.0/settings.ini"
|
||||
if [ ! -f "$config" ]; then exit 1; fi
|
||||
gtk_theme="$(grep 'gtk-theme-name' "$config" | sed 's/.*\s*=\s*//')"
|
||||
icon_theme="$(grep 'gtk-icon-theme-name' "$config" | sed 's/.*\s*=\s*//')"
|
||||
|
@ -20,8 +20,11 @@ with config.lib.base16.theme; {
|
||||
"/run/current-system/sw:/run/current-system/sw/share/kservices5:/run/current-system/sw/share/kservicetypes5:/run/current-system/sw/share/kxmlgui5";
|
||||
};
|
||||
home-manager.users.${config.mainuser} = {
|
||||
qt.enable = true;
|
||||
qt.style.name = "kvantum";
|
||||
qt = {
|
||||
enable = true;
|
||||
style.name = "kvantum";
|
||||
platformTheme.name = "kvantum";
|
||||
};
|
||||
|
||||
xdg.configFile."kdeglobals".text = lib.generators.toGitINI {
|
||||
General = {
|
||||
|
@ -6,7 +6,7 @@ let
|
||||
ie = "en_IE.UTF-8";
|
||||
ru = "ru_RU.UTF-8";
|
||||
us = "en_US.UTF-8";
|
||||
lang = "en_IE:en:C:ru_RU";
|
||||
lang = "en_IE:en_US:en:C:ru_RU";
|
||||
in {
|
||||
i18n.defaultLocale = ie;
|
||||
i18n.extraLocaleSettings = {
|
||||
|
@ -57,10 +57,9 @@ with config.deviceSpecific; {
|
||||
tooltip-format = "<tt>{calendar}</tt>";
|
||||
calendar = {
|
||||
mode = "month";
|
||||
mode-mon-col = 4;
|
||||
mode-mon-col = 3;
|
||||
weeks-pos = "right";
|
||||
on-scroll = 1;
|
||||
on-click-right = "mode";
|
||||
format = {
|
||||
months = "<span color='#c0caf5'><b>{}</b></span>";
|
||||
days = "<span color='#c0caf5'><b>{}</b></span>";
|
||||
@ -69,6 +68,12 @@ with config.deviceSpecific; {
|
||||
today = "<span color='#f7768e'><b><u>{}</u></b></span>";
|
||||
};
|
||||
};
|
||||
actions = {
|
||||
on-click-right = "mode";
|
||||
on-click-middle = "shift_reset";
|
||||
on-scroll-up = "shift_up";
|
||||
on-scroll-down = "shift_down";
|
||||
};
|
||||
};
|
||||
cpu = {
|
||||
interval = 4;
|
||||
@ -76,7 +81,7 @@ with config.deviceSpecific; {
|
||||
};
|
||||
disk = {
|
||||
interval = 60;
|
||||
format = "<span color=\"#7aa2f7\"> </span>{free}%";
|
||||
format = "<span color=\"#7aa2f7\"> </span>{free}";
|
||||
path = "/home";
|
||||
};
|
||||
"hyprland/window" = {
|
||||
|
4
scripts/json-to-nix.sh
Executable file
4
scripts/json-to-nix.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i bash -p nixfmt-rfc-style
|
||||
|
||||
nix-instantiate --eval -E "builtins.fromJSON (builtins.readFile "$(realpath $1)")" | nixfmt
|
49
secrets/home-hypervisor/netbird.yaml
Normal file
49
secrets/home-hypervisor/netbird.yaml
Normal file
@ -0,0 +1,49 @@
|
||||
netbird-store-key: ENC[AES256_GCM,data:hTT3ggwgbp4ioozh/HJ+zB9A+l2ZH/mPe3HPtWe63YuV7NfM1Gu+C8vZ/4w=,iv:Uvuk+AESXhDjQ1/qfb7T/qgJopL+f3NJr0j80S6Gsuc=,tag:iM40VvO8Ir73JZVckjuwGg==,type:str]
|
||||
netbird-svc-pass: ENC[AES256_GCM,data:it+Wgt73w1QO89xpy2NGxOZy46RgGpNwdFaspcfW3ZMI9maZTwEZF9CE0fuaFPcrCBVDabG9RpRqWJAG,iv:kJBz8mKbmwatJFnoFnOj9EkCnRFzA0OfrSEGfcuyk1A=,tag:B3Rg7Pg4dwA0TPj/0anQJQ==,type:str]
|
||||
netbird-client-id: ENC[AES256_GCM,data:g+4/d0tPqGITND56MFaTrr3AZlNIvmeHVgB1J/PYI6GPf8HzD6M4/Q==,iv:fljPA983TjTnISE9HmyieK9lzdQDc3wvEXIvvu8vI0A=,tag:aPPMf66EyUZK0qHJrquX0g==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age: []
|
||||
lastmodified: "2024-06-29T16:49:33Z"
|
||||
mac: ENC[AES256_GCM,data:lLhXyjhsUSg2OGuwPgyNI6u9KKJrtE2G7/uBynu/Iw/cmqBBPGTArzFZRMBjLY7Pit9ZN0YWPLTL2fH8AdNXc6Hq1LgArR29WRgaN0A8sw+HfyVgH2wX79Rvh1ddInOkXRLm8LQYr/Iy9M9N3eWhIZc7jmgj0Vx0Jfhne0atO34=,iv:padr7hsmHMSf+YXhSxN4NyNxNN2fX98oGgVvhfPCsLY=,tag:YydiCnuPvpvI7oou5TQfyw==,type:str]
|
||||
pgp:
|
||||
- created_at: "2024-06-29T14:21:49Z"
|
||||
enc: |-
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQEMAwcagTG/Fm6AAQf8DQg7f6Qw6JSjyEgi63R0TaCi5MpM/OOWPym7zBoVyyO7
|
||||
MM7KQVcaG3nAFyaQZutg1wk+VtiJXA5fjsbQiVJ+VPO2csb8HU6uq7Xtbripu0mP
|
||||
C+KL6HaKlzsRBSKexjGYXn5Pu5/ZVcnigQiq5Ih56tHIE0FUx+LdHJ2m1IQ0lNXJ
|
||||
56PdHNUQNd/qRRyJDw8x+vro0uZljR7cmZPV6TaglxdtBO668JzU7NfEBwbfQMmf
|
||||
0Z6XTE6+1c+N4KWSU1zvko5qcA1UhSLB21CkQcMvs71pkWobDbInEDaYkyhyy0UP
|
||||
Bn8cSpHMOOv3XaanHCNwPACNKDE6J9UkXYA/By2ky9JYAcVH0H4slVsTePOIMjtm
|
||||
LvHvpj9PSwvhJrgiEb2aNQ7QdLmghmkkuZSGmCDdHStV2a4I+t7PzVOzJ/RGnTiu
|
||||
6aJRFW1XRQr26CeW5OozmMat1z3iZm0O3w==
|
||||
=OdzC
|
||||
-----END PGP MESSAGE-----
|
||||
fp: ad382d058c964607b7bbf01b071a8131bf166e80
|
||||
- created_at: "2024-06-29T14:21:49Z"
|
||||
enc: |-
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQIMA187ia82lSDGAQ/7BdvWFd8kzGcCSHU3C1wHVmTr73X7vfYnnk5jAdD1iuEd
|
||||
lizTw+pT4pv76Qp+y/VWhPutY3ZsfchsMQ1cZDYfcaVk3ozq3gx4+DnZMEtXc7FK
|
||||
Y933+ru70L3XPQJ1daAwJogNJosq5icovGirPUc6f4a23ix0h7whkv+TwB5jrF/Z
|
||||
cHTVCxth0B9Ol3Q+pvIlf3dH7LntYJOmtDR4rICRE6LILxTAV23fVCJPEqXy9Fbm
|
||||
J+/i9vKOOtc6qP5wwMpIUeQu7rTeELjV32WaaCAOf/rfNDtnatNScmWjcqlQ3/0a
|
||||
XNipo+ptcrj+3UxmVGHLvHuPg7mrRaAYFHA5oEeQHPWklfsjSwQgknqpRSQ+7vmY
|
||||
4rQaI5Yrx0D/a3S8zWY5t51X6YLFu7jSeSu8uZ3ToBmAUWmSZmcWgHV60oONlkE8
|
||||
Orsw3c4yNfGl/GY27yUrRGCFMeVsDiCTKkXUQgii+m4cPoxzDS/IS3QvPULV42u9
|
||||
rj9u1853WsbDUDsf9lyFYfgmU6E1Az5KhtQXhdifL9SZtdEmJmfApbrlOcmx1QCS
|
||||
jwP/3tgF8KR7vmfU+XN1BXZt71fY27Qysc+JNXVT2bAIpfBS/XJGHyFAeRuYne/S
|
||||
syPX6O+SA6+oHjA/tGrrekVUsD98NG+3bL0NJUckIlkjPYnUZ1FnpVqnIcGFdZXS
|
||||
WAEMP2QAkpnNDEYnYufQmzGU3XWscN8iQcBSLkfwTvRYh9gt0yEKdGnR9yDoxa40
|
||||
/0nIV7JgPvv/CRHFO7lcQtKP97SJC5UDjWYSPS2XL5bPA4gSvVWEN1c=
|
||||
=OlmE
|
||||
-----END PGP MESSAGE-----
|
||||
fp: a32018133c7afbfd05d5b2795f3b89af369520c6
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
107
secrets/searx.yaml
Normal file
107
secrets/searx.yaml
Normal file
@ -0,0 +1,107 @@
|
||||
searx-env: ENC[AES256_GCM,data:SV4yIJevpr9GY2LgeDJa5AKhitDg37ypmmZIQQWFEh6gAVomohaBGSLO8kShP4eazlsfnef6pFtohbSCQBoJGdMtneh6FpA9jdfwULA3JgEnhw==,iv:Ocv6FRnFZbOMBMp0c2IpeTRXiUFWxJyFlwDNu8JrCdw=,tag:hVboEK3nwLfxlVTm8rB+sA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age: []
|
||||
lastmodified: "2024-06-28T10:01:20Z"
|
||||
mac: ENC[AES256_GCM,data:DzYvaWafYkBCXeRvYuNmeTCH6ILn0IXI15F9E91JS5cWQ3icRZUIUn33uJBjR0Lb//ocECoSuCy4IQ3eM1pBD+Ii8P6cBui02Vob2blNLaD9Yf4a/xeXpXTOUZtFi0aRGdbefc9Ozg8XIwUTCkATzlYzhmWbKw9B/8I7NZ1quok=,iv:7shAhYF2bj5F23wbyKkS6vKdiimkW/Im+ZE1M/UmIcY=,tag:/n+B+qVCZmr/eJFzetaVQg==,type:str]
|
||||
pgp:
|
||||
- created_at: "2024-06-28T10:00:35Z"
|
||||
enc: |-
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQEMAwcagTG/Fm6AAQf9H6+6CVfKxaKoUrJWghbvCRnKmSDqaIXm8LvjWNKdoJOS
|
||||
Pqg3oJ/uQRIZFV68nyQcSa6Wq0K/9W0Jh0s7/E1W2ItEn+DeBiazzDGlOa46bOUl
|
||||
abVcQhvkoaMuqmvIGFRgUGMGmfd81EUdYojBIdRnqpHvFDhpNhRS3uKiN69Qccqc
|
||||
sbVWnZb7/U+RgdhK5bkruPGHLu5bIRiauQHmZg3Tu+FvJIVZza+Jem0YEKoMnWZW
|
||||
qgWE10k6C8hNZ975UmOZxoK/aumSd5sMLngNFz9psXU+joNy4ROACM7KuJoJBNL9
|
||||
UHRHXHg2NIY1Y3tgWl6fmh2h1Weso8IqrgXRXNEu/9JYAcsGvAKrn/HwLW488kGS
|
||||
A3wNnwfkWKNxGRKpqyVwP+fgPwnt5KnVFytiWVdWwPkdnhf8iKX9MTHQ0oqCcs7U
|
||||
xeX3dmBLtXddD+AcoO2mR+344r+qEfuQwg==
|
||||
=1v3C
|
||||
-----END PGP MESSAGE-----
|
||||
fp: ad382d058c964607b7bbf01b071a8131bf166e80
|
||||
- created_at: "2024-06-28T10:00:35Z"
|
||||
enc: |-
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQIMAzTK+524Lx1AAQ//c6fwYMjC3xxf6pLHU+35Jyfl9Zw3zhhKGR0epO9vqnW4
|
||||
SC9d2rLiBlPSujqkGfcg+LqUtjZ91zoZfG334CvdmroqWfaBT7bMd26HsPcFXWG/
|
||||
yLH9hXagDbXoFgR1xck8OqOYHs8nh2/RkoKlWZXJe0WbN4DUZNt9ywViRX+DdPUT
|
||||
leNDcsTR4Lg7tkjuBvQLgOHzTf1hKk+9R/ql92J+hqkXuV0J1oSWJDT+6jjkXW/N
|
||||
aZUYbQ/GbS6sa4Z3cAfWAx3nta7bF6nsf/1hF7lgzwGnHH6Zz9D+iYEiawi9avNc
|
||||
JzkmCy0aoFGZrwvPMt/tx0wZzgtD+ETMFUw27IXMsp6mG3gTnr7EaYOQjQGRzMid
|
||||
ESnZpV8JLSA/dd2HjmZpOy7rOIXjn86OjAX++X6c2Wgypr8gIN3aH/V2EVht09Z5
|
||||
E/WtWK2V+bOUBX4dlI9c17r1Xl96liodhuxhwENCZzqaNnsNHw15SUSnXtVaDiA9
|
||||
DUJey5JqNKjECv3rNd1PcEDrAQGmd0fikoY2td2yyoMIifOd2RSscDT9lv9Wrdxg
|
||||
ERmtwno4qp3YkFHMupxylFMuw6gBGTrJ14NTvApwahnbnqVLpxATK5eAL8X9mNmY
|
||||
9RmTo/sSqepET/xzDj2YYkhzlmFWWbDnBm2ZjlnMc4yNLwYkq40bbpPM0owS0QvS
|
||||
WAHVO9oEp8n96ABSS7i7hK7fN/1n+od1Ey/Lr2heuQnb5N+sMkocWnUQGFkdw9UM
|
||||
NioXKLz/VSC7ZGVJl1RFRUnnxLGor8PpYhREvG6Zpgy8nDpXTK9xLio=
|
||||
=i8J2
|
||||
-----END PGP MESSAGE-----
|
||||
fp: 20d2e2b90c6aa179585b6b6b34cafb9db82f1d40
|
||||
- created_at: "2024-06-28T10:00:35Z"
|
||||
enc: |-
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQIMA187ia82lSDGARAAxfytOLeeuvQS287ELpA65cRoqGcr2OCy5traQjutUH7x
|
||||
vyskZh+h1RWilM3P4g5vuQbkCc+yZS+K9sbtvCDNoj7N08HrEGXczdEJJLERWOyE
|
||||
Gde1Gn3HHO1fMr6HNk3twfJZ0ogp9KvZvR/n9AV+56x1TOG1p5aAT3d9KuUcsHJW
|
||||
v8jHpWqJAEAaR/HzMb+jg/n/IsPxs5n1it+8Y/nHzNDb0hLvGB2DSscW7sJgKMcF
|
||||
byckamGVNEV3JvlX+tYB8ziEeqiDEywB3Gbr5avQmyHLXdDkk1omEWuyh3Tqmhbo
|
||||
8dkDxp9ulkPqxR4l4QOtXrYsWSISxA6le4GiqltGQ8d5jAbquG0WhiIgm5WnXczn
|
||||
MwkgIoqwtpl+I103MXoAn8tNgxE0WB2/D4OrdUo/6aeWoVn07D9x1qqQMxkmuQjr
|
||||
2aKCO1HKYMs7ZA+l1vuKIr08iJ3VEvMBqe39Wro97fzSlOsPYn1bj9mghyD8Dj58
|
||||
7dLvzfgWKSDy2ZGBfdc5JVRkNeGzh1ZnlRuIBSFKBbUGWrkh1VlxrsAh0wMw89Xv
|
||||
KasNKU2V2Z8Ob+oPcZRPzNtLYRaLkWRvsSB/zBbp0Li2xXb+WLxpUAO0M+EDNena
|
||||
tyPPOJrL2DfD12ur7v620Mh/uT+PkZ+ntPcfA8YHBFN7CYNk+wm5PvVe824sPobS
|
||||
WAFZDv1soB1zKilVuVjxOpWd4YFbo/dk2TttyCyzrBkkxEZxSF6ScwF5hqZ3qy0X
|
||||
hrHJ7/TV5pCai/PStB8kNyNLQZ66QKwC3L7ErlA/5dvJVEkLkjrLEcY=
|
||||
=dErp
|
||||
-----END PGP MESSAGE-----
|
||||
fp: a32018133c7afbfd05d5b2795f3b89af369520c6
|
||||
- created_at: "2024-06-28T10:00:35Z"
|
||||
enc: |-
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQIMA4NImSg+4iqHARAAyBzXIOrRpPBvg8OauOAjDhSgTd4G5mzpZGmvfhYmpFG2
|
||||
jdhsVnhVAuSkLpET3JpDhlWHL2DnsmuJLWSiwBDYy4jwbSfa/z3efXIg9HWKyQaU
|
||||
Ty3lxE3PxA0n4GYg7T7hh2WMTDNO7ByVbCswXpCmutrSLLW6uMDIxEjLN3o6euhP
|
||||
QJNRO1+Vg7Tyr7kVQZK0GMwRYVDAv3SqkvjO282sh0gYfKVqb4y0VysRDsIZy3HZ
|
||||
8FxyyR1NTlbYlzvd+Ny6g3D5NQukNy6bTowN+Vt8hVfSKYE5wYZye42pe9Zh0tjW
|
||||
NFiJ1S0UbRvJO/F2JxnAnG1CuvLV5PETVbVBP8jjshuKYD1cZ7eM0AAuTLErGEZ0
|
||||
5HVWcU9ZjM0RJZ8H4BvFFR0YBXXwze7F1E0x61I/7g+kUEKf9wPAicljFNxZ8mSW
|
||||
vxZx9c5Lh9QXeTt//n1ZrpjiZtzqSwK0OKfdSkv5TqVH8WOiXI4uF4yznjZ1vhQJ
|
||||
49wu+vQz2skWQS1S67VhCmN2BdptasuCXsbksZewWa6OIyXszj2YthCyLe0jvhUo
|
||||
qYV/Y0371DxMnq8QVcm4kjGVnc5DbM9Lwa8zFtJ6BLyxm3hBlhwnXWDLsXKoi6UL
|
||||
K7bStqhnVeL4IKZWCs3gqn/FvBV4IOBHNWwngFo0sktm9P0MSsjil9/1Vj4okdXS
|
||||
WAE7kJC0vd1NOXPkmnnkI6KsbusW+x1RXdp6w/lD+/a0AAEXcxyGjuf5n7AzO8CH
|
||||
fkjQOFj7mBFz1/rLCY8iP+5YoYfBJeUhZ+J2G4QfKJauM0w8cxiSJxU=
|
||||
=LXTZ
|
||||
-----END PGP MESSAGE-----
|
||||
fp: 78fa8fb95e85b2b89f1dd4f0834899283ee22a87
|
||||
- created_at: "2024-06-28T10:00:35Z"
|
||||
enc: |-
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQIMA9T+KNkhS2haAQ//RRHjVJzoVSitcEKTfCACD1t9Uyx6wWe7eRn+oKqPCcZn
|
||||
LP7NU8qmcpFjqZCu/9IZJP6xa7m1ac2tJCwLiARL1qOO9l6dWFCo5J0nH0uVrC9h
|
||||
b0twCRulktE0AlYGK25yuaZl/Rmw4wv1hc/NIMyw8jx6PmOdXrL/vsmz/CZ60wNw
|
||||
fdrfljYWCk1cPXLHmfVtYKht8B7Jx4o9Ivq6XTQXdO9nCNKu9YNxOrvzSjQYI87Y
|
||||
oTU3zUwM7jfrjLOBtYlB9EXeFkKdDZQE4EYBQO+8FD7KM5fXdr5YQVzFjY4Sz6uV
|
||||
7WdER2oHoX/NfQ/2eLCVkbQ/4oyTCV963mELM7hWQyqKxpX0H41puJICsQzuhyh3
|
||||
9FdELO9nZwQUrr788YAO3fgYlE0pFwh80gD+yo2Ke0h1R8+OzPvwD6yChD+yi6kA
|
||||
Jtq4J2hUT2NmKZPbk3cRK4etz3srKvwd5nMaBhv9wQAQUMaIIXMVCQvSudgj0Idf
|
||||
E/GXlvVPyP2Scqw00eU7emAJCldUYzxh4nZpnWBq9U/f8h9YDooww3riM5YTGfKJ
|
||||
liZf5x4/Zwy+0AteC8LuFiEa6Izsy92Iwc2WtWnaCx0d6xfazLA/vfUwcXxICr7L
|
||||
UwUveyd4BQFYqWEESgqvO072myvff6pqS9LIJreHskUidv582wIpuXhwwL1mp5rS
|
||||
WAE0Y1rLT7ZqWfZziPAIE+yZatV33zHHGX5u1x3jwEpsgn7xVshxJmSxSurF4Lop
|
||||
Lk6FhNvg+n7UGD0xwVOisvT/SD0jrdkL0BI6vQ1qYM9TSJHKYt/9V9w=
|
||||
=hH+U
|
||||
-----END PGP MESSAGE-----
|
||||
fp: 05588f4245256f75a8da42e5d4fe28d9214b685a
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
Loading…
x
Reference in New Issue
Block a user