blob: 8ccb0778ed03536758efaa0481cfe40f7e7dd80d [file] [log] [blame]
Skyler Greyf08a6192024-06-01 23:55:20 +00001# SPDX-FileCopyrightText: 2024 Auxolotl Infrastructure Contributors
2# SPDX-FileCopyrightText: 2024 Clicks Codes
3#
4# SPDX-License-Identifier: GPL-3.0-only
5
Skyler Grey61f0f852024-06-09 00:02:53 +00006{
7 pkgs,
8 modulesPath,
9 lib,
10 config,
11 ...
12}:
Skyler Greyf08a6192024-06-01 23:55:20 +000013{
Skyler Grey67cf8aa2024-07-28 13:21:32 +000014 age.rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPkKdPSPxsLdx3GUjjyibRLjLl3XfaXmfrrvemDFkjI3";
15
Skyler Greyf08a6192024-06-01 23:55:20 +000016 boot.loader.systemd-boot.enable = true;
17 boot.loader.efi.canTouchEfiVariables = true;
18
19 time.timeZone = "Etc/UTC";
20
21 environment.systemPackages = with pkgs; [ neovim ];
22
23 clicks = {
24 nix.enable = true;
25
Skyler Grey05e11c12024-06-15 00:02:15 +000026 backups.key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHYH3yYKcrsDz8U45HF6201BN1nBDQIr4qsGeKh94K6T root@vermilion";
27
Skyler Greyf08a6192024-06-01 23:55:20 +000028 security = {
29 doas.enable = true;
30
31 acme = {
32 enable = true;
Skyler Greyd7e1acd2024-06-22 14:42:11 +000033 defaults = {
34 email = "minion@clicks.codes";
35 dnsProvider = "cloudflare";
Skyler Grey67cf8aa2024-07-28 13:21:32 +000036 environmentFile = config.age.secrets."clicks.security.acme.defaults.environmentFile".path;
Skyler Greyd7e1acd2024-06-22 14:42:11 +000037 };
Skyler Greyf08a6192024-06-01 23:55:20 +000038 };
39 };
40
Skyler Grey3299e4f2024-07-04 00:33:43 +000041 sites."docs.auxolotl.org".enable = true;
Samuel Shuertc6f63032024-12-31 11:09:23 -050042 sites."a.starrysky.blog".enable = true;
43 # sites."blog.thecoded.prof".enable = true;
Skyler Grey3299e4f2024-07-04 00:33:43 +000044
Skyler Greyf08a6192024-06-01 23:55:20 +000045 services = {
46 ssh.enable = true;
Skyler Grey61f0f852024-06-09 00:02:53 +000047 headscale = {
48 enable = true;
Skyler Greybed35f12024-07-04 00:46:44 +000049 domain = "clicks.domains";
Samuel Shuertc6f63032024-12-31 11:09:23 -050050 server_url = "vpn.clicks.codes";
Skyler Grey14375fe2024-06-22 14:43:44 +000051 addr = lib.clicks.constants.hosts.generic;
Skyler Grey61f0f852024-06-09 00:02:53 +000052 oidc = {
53 enable = true;
54 issuer = "https://login.clicks.codes/realms/master";
55 allowed_groups = [ "/clicks" ];
56 client_secret_path =
Skyler Grey67cf8aa2024-07-28 13:21:32 +000057 config.age.secrets."clicks.services.headscale.oidc.client_secret_path".path;
Skyler Grey61f0f852024-06-09 00:02:53 +000058 };
Skyler Grey61f0f852024-06-09 00:02:53 +000059 noise_private_key_path =
Skyler Grey67cf8aa2024-07-28 13:21:32 +000060 config.age.secrets."clicks.services.headscale.noise_private_key_path".path;
Samuel Shuertc6f63032024-12-31 11:09:23 -050061 acl = let
62 permitted_area_names = [
63 # Some phonetic alphabet names are excluded here to avoid confusing
64 # them with given names
65 "alpha"
66 "bravo"
67 "delta"
68 "echo"
69 "foxtrot"
70 "golf"
71 "hotel"
72 "india"
73 "kilo"
74 "lima"
75 "november"
76 "papa"
77 "quebec"
78 "sierra"
79 "tango"
80 "uniform"
81 "whiskey"
82 "xray"
83 "yankee"
84 "zulu"
85 ];
86
87 assigned_areas = {
88 "alpha" = "coded";
89 "bravo" = "minion";
90 "echo" = "maddie";
91 "sierra" = "pineafan";
92 "tango" = "mostlyturquoise";
93 "zulu" = "zanderp25";
94 };
95
96 users = [
97 "coded"
98 "maddie"
99 "minion"
100 "pineafan"
101 "zanderp25"
102 "mostlyturquoise"
103 ];
104
105 friends = [
106 "sirdigalot"
107 ];
108 in
Skyler Grey0e05b522024-06-11 22:48:00 +0000109 {
Samuel Shuertc6f63032024-12-31 11:09:23 -0500110 groups."group:maintainer" = [
Skyler Grey0e05b522024-06-11 22:48:00 +0000111 "coded"
Skyler Greyefc62522024-06-15 00:23:06 +0000112 "minion"
Skyler Grey0e05b522024-06-11 22:48:00 +0000113 ];
Samuel Shuertc6f63032024-12-31 11:09:23 -0500114 groups."group:users" = users;
115 groups."group:friends" = friends;
Skyler Grey2154d222024-06-10 17:17:51 +0000116
Skyler Grey0e05b522024-06-11 22:48:00 +0000117 acls = [
118 {
119 action = "accept";
120 src = [ "group:users" ];
121 dst = [
122 "group:users:*"
Skyler Grey985a6122024-07-17 22:00:16 +0000123 "group:friends:*"
Samuel Shuertc6f63032024-12-31 11:09:23 -0500124 "autogroup:internet:*"
125 ] ++ (map (tag: "tag:${tag}:*") permitted_area_names);
Skyler Grey0e05b522024-06-11 22:48:00 +0000126 }
127 {
128 action = "accept";
Skyler Grey985a6122024-07-17 22:00:16 +0000129 src = [ "group:friends" ];
130 dst = [
131 "group:users:*"
132 "group:friends:*"
133 ];
134 }
135 {
136 action = "accept";
Samuel Shuertc6f63032024-12-31 11:09:23 -0500137 src = (map (tag: "tag:${tag}") permitted_area_names);
138 dst = (map (tag: "tag:${tag}:*") permitted_area_names);
Skyler Grey0e05b522024-06-11 22:48:00 +0000139 }
Skyler Grey31fbc232024-08-22 16:34:53 +0000140 {
141 action = "accept";
142 src = [ "zulu" ];
143 dst = [ "zanderp25:3000" ];
144 }
Skyler Grey0e05b522024-06-11 22:48:00 +0000145 ];
Samuel Shuertc6f63032024-12-31 11:09:23 -0500146
147 ssh = [
148 {
149 action = "check";
150 src = ["group:users"];
151 dst = (map (tag: "tag:${tag}") permitted_area_names);
152 checkPeriod = "8h";
153 acceptEnv = [
154 "BAT_THEME"
155 "COLORTERM"
156 "JQ_COLORS"
157 "LANG"
158 "LS_COLORS"
159 "LSCOLORS"
160 "TERM"
161 ];
162 }
163 ] ++ (lib.attrsets.mapAttrsToList (area: user: {
164 action = "check";
165 src = [ user ];
166 dst = [ "tag:${area}" ];
167 checkPeriod = "2h";
168 users = [ "root" "autogroup:nonroot" ];
169 acceptEnv = [ "*" ];
170 }) assigned_areas) ++ (map (user: {
171 action = "check";
172 src = [ user ];
173 dst = [ user ];
174 checkPeriod = "2h";
175 users = [ "root" "autogroup:nonroot" ];
176 acceptEnv = [ "*" ];
177 }) (users ++ friends));
178
179 tagOwners = (lib.pipe permitted_area_names [
180 (map (area: {
181 name = "tag:${area}";
182 value = [ "group:maintainer" ];
183 }))
184 lib.listToAttrs
185 ]) // (lib.attrsets.mapAttrs' (area: user: {
186 name = "tag:${area}";
187 value = [ "group:maintainer" user ];
188 }) assigned_areas);
Skyler Grey0e05b522024-06-11 22:48:00 +0000189 };
Skyler Grey61f0f852024-06-09 00:02:53 +0000190 };
Skyler Grey0a0912a2024-07-04 00:13:40 +0000191 fava = {
192 enable = true;
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000193 extraPythonPackages = [
194 pkgs.clicks.beancount-autobean
Skyler Greydf6a6362024-08-08 22:07:15 +0000195 pkgs.clicks.beancount-beancount_share
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000196 pkgs.clicks.beancount-smart_importer
197 ];
Skyler Grey0a0912a2024-07-04 00:13:40 +0000198 tailscaleAuth = true;
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000199 credentials = {
200 truelayer_client_secret = config.age.secrets."clicks.services.fava.credentials.truelayer_client_secret".path;
201 };
Skyler Grey0a0912a2024-07-04 00:13:40 +0000202 accounts = {
Skyler Grey5e8bba22024-07-12 14:31:49 +0000203 "clicks" = lib.home-manager.hm.dag.entryAnywhere {
204 name = "Clicks Codes";
205 beancountExtraOptions.operating_currency = "GBP";
206 };
207 "coded" = lib.home-manager.hm.dag.entryBetween [ "testing" ] [ "clicks" ] {
208 name = "Samuel Shuert";
209 beancountExtraOptions.operating_currency = "USD";
210 };
211 "minion" = lib.home-manager.hm.dag.entryBetween [ "testing" ] [ "clicks" ] {
212 name = "Skyler Grey";
213 beancountExtraOptions.operating_currency = "GBP";
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000214 favaExtraOptions = {
215 invert-income-liabilities-equity = "true";
216 auto-reload = "true";
Skyler Greydf6a6362024-08-08 22:07:15 +0000217 fiscal-year-end = "04-05";
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000218 import-config = builtins.toString (pkgs.writeText "minion-imports.py" ''
219 import autobean.truelayer
220 from smart_importer import apply_hooks, PredictPayees, PredictPostings
221
222 import os
223 import pathlib
224
225 with open(pathlib.Path(os.environ["CREDENTIALS_DIRECTORY"]) / pathlib.Path("truelayer_client_secret")) as f:
226 truelayer_client_secret = f.read().strip()
227
228 CONFIG = [
229 apply_hooks(
230 autobean.truelayer.Importer(
231 "fava-228732",
232 truelayer_client_secret
233 ),
234 [
235 PredictPayees(),
236 PredictPostings(),
237 ]
238 )
239 ]
240 '');
241 import-dirs = "/var/lib/private/fava/minion/";
242 };
Skyler Greydf6a6362024-08-08 22:07:15 +0000243 extraConfig = ''
244 plugin "fava.plugins.tag_discovered_documents"
245 plugin "fava.plugins.link_documents"
246
247 plugin "beancount.plugins.pedantic"
248 plugin "beancount.plugins.unrealized" "Unrealized"
249 plugin "beancount.plugins.implicit_prices"
250
251 plugin "beancount_share.share" "{
252 'mark_name': 'share',
253 'meta_name': 'shared',
254 'account_debtors': 'Assets:People',
255 'account_creditors': 'Liabilities:People',
256 'open_date': '1970-01-01',
257 'quantize': '0.01'
258 }"
259 '';
Skyler Grey5e8bba22024-07-12 14:31:49 +0000260 };
261 "testing" = lib.home-manager.hm.dag.entryAfter [ "clicks" ] {
262 name = "Test Data - May Be Wiped At Any Time";
263 };
Skyler Grey0a0912a2024-07-04 00:13:40 +0000264 };
265 domain = "fava.clicks.codes";
266 };
Skyler Grey700577a2024-08-14 18:21:34 +0000267 silverbullet = {
268 enable = true;
269 domain = "silverbullet.clicks.codes";
270 tailscaleAuth = true;
271 };
Skyler Greyf08a6192024-06-01 23:55:20 +0000272 };
Skyler Grey40ae7a02024-06-06 21:22:25 +0000273
Skyler Grey8ef34812024-06-09 19:42:15 +0000274 networking.tailscale = {
275 enable = true;
276 authKeyFile =
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000277 config.age.secrets."clicks.networking.tailscale.authKeyFile".path;
Skyler Grey8ef34812024-06-09 19:42:15 +0000278 };
279
Skyler Grey40ae7a02024-06-06 21:22:25 +0000280 storage = {
Skyler Greyf4d05f02024-06-06 21:25:39 +0000281 raid.enable = true;
Skyler Grey40ae7a02024-06-06 21:22:25 +0000282 impermanence = {
283 enable = true;
Skyler Greyd3377402024-06-06 22:01:26 +0000284 devices = {
285 root = "/dev/disk/by-uuid/ab5c2f52-a737-4b29-a505-e3d0b9d0714c";
286 persist = "/dev/md/a1d1:persist";
287 };
Skyler Grey40ae7a02024-06-06 21:22:25 +0000288 };
289 };
Skyler Greyf08a6192024-06-01 23:55:20 +0000290 };
291
292 boot.initrd.availableKernelModules = [
293 "nvme"
294 "xhci_pci"
295 "ahci"
296 "usbhid"
297 "uas"
298 "usb_storage"
299 "sd_mod"
300 ];
301 boot.initrd.kernelModules = [ ];
302 boot.kernelModules = [ "kvm-amd" ];
303 boot.extraModulePackages = [ ];
304
Skyler Grey40ae7a02024-06-06 21:22:25 +0000305 fileSystems."/nix" = {
Skyler Greyf08a6192024-06-01 23:55:20 +0000306 device = "/dev/disk/by-uuid/ab5c2f52-a737-4b29-a505-e3d0b9d0714c";
307 fsType = "btrfs";
Skyler Grey40ae7a02024-06-06 21:22:25 +0000308 options = [ "subvol=@nix" ];
Skyler Greyf08a6192024-06-01 23:55:20 +0000309 };
310
311 fileSystems."/boot" = {
312 device = "/dev/disk/by-uuid/880D-BBAB";
313 fsType = "vfat";
314 options = [
315 "fmask=0022"
316 "dmask=0022"
317 ];
318 };
319
320 swapDevices = [ ];
321
322 networking.useDHCP = true;
323
324 system.stateVersion = "24.05";
Skyler Grey61f0f852024-06-09 00:02:53 +0000325
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000326 age.secrets."clicks.networking.tailscale.authKeyFile".rekeyFile = ./clicks.networking.tailscale.authKeyFile.age;
327
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000328 age.secrets."clicks.security.acme.defaults.environmentFile".rekeyFile = ./clicks.security.acme.defaults.environmentFile.age;
329
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000330 age.secrets."clicks.services.fava.credentials.truelayer_client_secret".rekeyFile = ./clicks.services.fava.credentials.truelayer_client_secret.age;
331
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000332 age.secrets."clicks.services.headscale.oidc.client_secret_path" = {
333 rekeyFile = ./clicks.services.headscale.oidc.client_secret_path.age;
Skyler Grey61f0f852024-06-09 00:02:53 +0000334 group = "headscale";
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000335 };
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000336 age.secrets."clicks.services.headscale.noise_private_key_path" = {
337 rekeyFile = ./clicks.services.headscale.noise_private_key_path.age;
338 group = "headscale";
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000339 };
Skyler Greyf08a6192024-06-01 23:55:20 +0000340}