blob: 8123543d9dc600e88e98b28fbe64dde07a01ea04 [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;
42
Skyler Greyf08a6192024-06-01 23:55:20 +000043 services = {
44 ssh.enable = true;
Skyler Grey61f0f852024-06-09 00:02:53 +000045 headscale = {
46 enable = true;
Skyler Greybed35f12024-07-04 00:46:44 +000047 domain = "clicks.domains";
Skyler Grey14375fe2024-06-22 14:43:44 +000048 addr = lib.clicks.constants.hosts.generic;
Skyler Grey61f0f852024-06-09 00:02:53 +000049 oidc = {
50 enable = true;
51 issuer = "https://login.clicks.codes/realms/master";
52 allowed_groups = [ "/clicks" ];
53 client_secret_path =
Skyler Grey67cf8aa2024-07-28 13:21:32 +000054 config.age.secrets."clicks.services.headscale.oidc.client_secret_path".path;
Skyler Grey61f0f852024-06-09 00:02:53 +000055 };
56 database_password_path =
Skyler Grey67cf8aa2024-07-28 13:21:32 +000057 config.age.secrets."clicks.services.headscale.database_password_path".path;
Skyler Grey61f0f852024-06-09 00:02:53 +000058 noise_private_key_path =
Skyler Grey67cf8aa2024-07-28 13:21:32 +000059 config.age.secrets."clicks.services.headscale.noise_private_key_path".path;
Skyler Grey61f0f852024-06-09 00:02:53 +000060 private_key_path =
Skyler Grey67cf8aa2024-07-28 13:21:32 +000061 config.age.secrets."clicks.services.headscale.private_key_path".path;
Skyler Grey0e05b522024-06-11 22:48:00 +000062 acl =
63 let
64 internet = [
65 "0.0.0.0/5"
66 "8.0.0.0/7"
67 "11.0.0.0/8"
68 "12.0.0.0/6"
69 "16.0.0.0/4"
70 "32.0.0.0/3"
71 "64.0.0.0/3"
72 "96.0.0.0/6"
73 "100.0.0.0/10"
74 "100.128.0.0/9"
75 "101.0.0.0/8"
76 "102.0.0.0/7"
77 "104.0.0.0/5"
78 "112.0.0.0/4"
79 "128.0.0.0/3"
80 "160.0.0.0/5"
81 "168.0.0.0/8"
82 "169.0.0.0/9"
83 "169.128.0.0/10"
84 "169.192.0.0/11"
85 "169.224.0.0/12"
86 "169.240.0.0/13"
87 "169.248.0.0/14"
88 "169.252.0.0/15"
89 "169.255.0.0/16"
90 "170.0.0.0/7"
91 "172.0.0.0/12"
92 "172.32.0.0/11"
93 "172.64.0.0/10"
94 "172.128.0.0/9"
95 "173.0.0.0/8"
96 "174.0.0.0/7"
97 "176.0.0.0/4"
98 "192.0.0.0/9"
99 "192.128.0.0/11"
100 "192.160.0.0/13"
101 "192.169.0.0/16"
102 "192.170.0.0/15"
103 "192.172.0.0/14"
104 "192.176.0.0/12"
105 "192.192.0.0/10"
106 "193.0.0.0/8"
107 "194.0.0.0/7"
108 "196.0.0.0/6"
109 "200.0.0.0/5"
110 "208.0.0.0/4"
111 "224.0.0.0/3"
112 "ipv6-internet"
113 # A nasty hack used because ipv6 colons were messing with dst
114 # ports
115 ]; # Should be replaceable with autogroup:internet in next release
116 in
117 {
118 groups."group:users" = [
Skyler Grey0e05b522024-06-11 22:48:00 +0000119 "coded"
Skyler Greyefc62522024-06-15 00:23:06 +0000120 "maddie"
121 "minion"
Skyler Grey0e05b522024-06-11 22:48:00 +0000122 "pineafan"
Skyler Greyefc62522024-06-15 00:23:06 +0000123 "zanderp25"
Skyler Grey57b0e772024-10-13 21:52:49 +0000124 "mostlyturquoise"
Skyler Grey0e05b522024-06-11 22:48:00 +0000125 ];
Skyler Grey985a6122024-07-17 22:00:16 +0000126 groups."group:friends" = [
127 "sirdigalot"
128 ];
Skyler Grey0e05b522024-06-11 22:48:00 +0000129 groups."group:areas" = [
130 # Some phonetic alphabet names are excluded here to avoid confusing
131 # them with given names
132 "alpha"
133 "bravo"
Skyler Grey0e05b522024-06-11 22:48:00 +0000134 "echo"
135 "foxtrot"
Skyler Grey0e05b522024-06-11 22:48:00 +0000136 "hotel"
137 "india"
138 "kilo"
139 "lima"
140 "november"
141 "papa"
Skyler Grey0e05b522024-06-11 22:48:00 +0000142 "sierra"
143 "tango"
144 "uniform"
145 "whiskey"
146 "xray"
147 "yankee"
148 "zulu"
149 ];
150 hosts.ipv6-internet = "2000::/3";
Skyler Grey2154d222024-06-10 17:17:51 +0000151
Skyler Grey0e05b522024-06-11 22:48:00 +0000152 acls = [
153 {
154 action = "accept";
155 src = [ "group:users" ];
156 dst = [
157 "group:users:*"
Skyler Grey985a6122024-07-17 22:00:16 +0000158 "group:friends:*"
Skyler Grey0e05b522024-06-11 22:48:00 +0000159 "group:areas:*"
160 ] ++ (lib.forEach internet (host: "${host}:*"));
161 }
162 {
163 action = "accept";
Skyler Grey985a6122024-07-17 22:00:16 +0000164 src = [ "group:friends" ];
165 dst = [
166 "group:users:*"
167 "group:friends:*"
168 ];
169 }
170 {
171 action = "accept";
Skyler Grey0e05b522024-06-11 22:48:00 +0000172 src = [ "group:areas" ];
173 dst = [ "group:areas:*" ];
174 }
Skyler Grey31fbc232024-08-22 16:34:53 +0000175 {
176 action = "accept";
177 src = [ "zulu" ];
178 dst = [ "zanderp25:3000" ];
179 }
Skyler Grey0e05b522024-06-11 22:48:00 +0000180 ];
181 };
Skyler Grey61f0f852024-06-09 00:02:53 +0000182 };
Skyler Grey0a0912a2024-07-04 00:13:40 +0000183 fava = {
184 enable = true;
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000185 extraPythonPackages = [
186 pkgs.clicks.beancount-autobean
Skyler Greydf6a6362024-08-08 22:07:15 +0000187 pkgs.clicks.beancount-beancount_share
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000188 pkgs.clicks.beancount-smart_importer
189 ];
Skyler Grey0a0912a2024-07-04 00:13:40 +0000190 tailscaleAuth = true;
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000191 credentials = {
192 truelayer_client_secret = config.age.secrets."clicks.services.fava.credentials.truelayer_client_secret".path;
193 };
Skyler Grey0a0912a2024-07-04 00:13:40 +0000194 accounts = {
Skyler Grey5e8bba22024-07-12 14:31:49 +0000195 "clicks" = lib.home-manager.hm.dag.entryAnywhere {
196 name = "Clicks Codes";
197 beancountExtraOptions.operating_currency = "GBP";
198 };
199 "coded" = lib.home-manager.hm.dag.entryBetween [ "testing" ] [ "clicks" ] {
200 name = "Samuel Shuert";
201 beancountExtraOptions.operating_currency = "USD";
202 };
203 "minion" = lib.home-manager.hm.dag.entryBetween [ "testing" ] [ "clicks" ] {
204 name = "Skyler Grey";
205 beancountExtraOptions.operating_currency = "GBP";
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000206 favaExtraOptions = {
207 invert-income-liabilities-equity = "true";
208 auto-reload = "true";
Skyler Greydf6a6362024-08-08 22:07:15 +0000209 fiscal-year-end = "04-05";
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000210 import-config = builtins.toString (pkgs.writeText "minion-imports.py" ''
211 import autobean.truelayer
212 from smart_importer import apply_hooks, PredictPayees, PredictPostings
213
214 import os
215 import pathlib
216
217 with open(pathlib.Path(os.environ["CREDENTIALS_DIRECTORY"]) / pathlib.Path("truelayer_client_secret")) as f:
218 truelayer_client_secret = f.read().strip()
219
220 CONFIG = [
221 apply_hooks(
222 autobean.truelayer.Importer(
223 "fava-228732",
224 truelayer_client_secret
225 ),
226 [
227 PredictPayees(),
228 PredictPostings(),
229 ]
230 )
231 ]
232 '');
233 import-dirs = "/var/lib/private/fava/minion/";
234 };
Skyler Greydf6a6362024-08-08 22:07:15 +0000235 extraConfig = ''
236 plugin "fava.plugins.tag_discovered_documents"
237 plugin "fava.plugins.link_documents"
238
239 plugin "beancount.plugins.pedantic"
240 plugin "beancount.plugins.unrealized" "Unrealized"
241 plugin "beancount.plugins.implicit_prices"
242
243 plugin "beancount_share.share" "{
244 'mark_name': 'share',
245 'meta_name': 'shared',
246 'account_debtors': 'Assets:People',
247 'account_creditors': 'Liabilities:People',
248 'open_date': '1970-01-01',
249 'quantize': '0.01'
250 }"
251 '';
Skyler Grey5e8bba22024-07-12 14:31:49 +0000252 };
253 "testing" = lib.home-manager.hm.dag.entryAfter [ "clicks" ] {
254 name = "Test Data - May Be Wiped At Any Time";
255 };
Skyler Grey0a0912a2024-07-04 00:13:40 +0000256 };
257 domain = "fava.clicks.codes";
258 };
Skyler Grey700577a2024-08-14 18:21:34 +0000259 silverbullet = {
260 enable = true;
261 domain = "silverbullet.clicks.codes";
262 tailscaleAuth = true;
263 };
Skyler Greyf08a6192024-06-01 23:55:20 +0000264 };
Skyler Grey40ae7a02024-06-06 21:22:25 +0000265
Skyler Grey8ef34812024-06-09 19:42:15 +0000266 networking.tailscale = {
267 enable = true;
268 authKeyFile =
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000269 config.age.secrets."clicks.networking.tailscale.authKeyFile".path;
Skyler Grey8ef34812024-06-09 19:42:15 +0000270 };
271
Skyler Grey40ae7a02024-06-06 21:22:25 +0000272 storage = {
Skyler Greyf4d05f02024-06-06 21:25:39 +0000273 raid.enable = true;
Skyler Grey40ae7a02024-06-06 21:22:25 +0000274 impermanence = {
275 enable = true;
Skyler Greyd3377402024-06-06 22:01:26 +0000276 devices = {
277 root = "/dev/disk/by-uuid/ab5c2f52-a737-4b29-a505-e3d0b9d0714c";
278 persist = "/dev/md/a1d1:persist";
279 };
Skyler Grey40ae7a02024-06-06 21:22:25 +0000280 };
281 };
Skyler Greyf08a6192024-06-01 23:55:20 +0000282 };
283
284 boot.initrd.availableKernelModules = [
285 "nvme"
286 "xhci_pci"
287 "ahci"
288 "usbhid"
289 "uas"
290 "usb_storage"
291 "sd_mod"
292 ];
293 boot.initrd.kernelModules = [ ];
294 boot.kernelModules = [ "kvm-amd" ];
295 boot.extraModulePackages = [ ];
296
Skyler Grey40ae7a02024-06-06 21:22:25 +0000297 fileSystems."/nix" = {
Skyler Greyf08a6192024-06-01 23:55:20 +0000298 device = "/dev/disk/by-uuid/ab5c2f52-a737-4b29-a505-e3d0b9d0714c";
299 fsType = "btrfs";
Skyler Grey40ae7a02024-06-06 21:22:25 +0000300 options = [ "subvol=@nix" ];
Skyler Greyf08a6192024-06-01 23:55:20 +0000301 };
302
303 fileSystems."/boot" = {
304 device = "/dev/disk/by-uuid/880D-BBAB";
305 fsType = "vfat";
306 options = [
307 "fmask=0022"
308 "dmask=0022"
309 ];
310 };
311
312 swapDevices = [ ];
313
314 networking.useDHCP = true;
315
316 system.stateVersion = "24.05";
Skyler Grey61f0f852024-06-09 00:02:53 +0000317
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000318 age.secrets."clicks.networking.tailscale.authKeyFile".rekeyFile = ./clicks.networking.tailscale.authKeyFile.age;
319
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000320 age.secrets."clicks.security.acme.defaults.environmentFile".rekeyFile = ./clicks.security.acme.defaults.environmentFile.age;
321
Skyler Grey2c9c3e72024-07-17 22:00:16 +0000322 age.secrets."clicks.services.fava.credentials.truelayer_client_secret".rekeyFile = ./clicks.services.fava.credentials.truelayer_client_secret.age;
323
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000324 age.secrets."clicks.services.headscale.oidc.client_secret_path" = {
325 rekeyFile = ./clicks.services.headscale.oidc.client_secret_path.age;
Skyler Grey61f0f852024-06-09 00:02:53 +0000326 group = "headscale";
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000327 };
328 age.secrets."clicks.services.headscale.database_password_path" = {
329 rekeyFile = ./clicks.services.headscale.database_password_path.age;
330 group = "headscale";
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000331 };
332 age.secrets."clicks.services.headscale.noise_private_key_path" = {
333 rekeyFile = ./clicks.services.headscale.noise_private_key_path.age;
334 group = "headscale";
Skyler Grey67cf8aa2024-07-28 13:21:32 +0000335 };
336 age.secrets."clicks.services.headscale.private_key_path" = {
337 rekeyFile = ./clicks.services.headscale.private_key_path.age;
338 group = "headscale";
Skyler Grey61f0f852024-06-09 00:02:53 +0000339 };
Skyler Greyf08a6192024-06-01 23:55:20 +0000340}