| # SPDX-FileCopyrightText: 2024 Auxolotl Infrastructure Contributors |
| # SPDX-FileCopyrightText: 2024 Clicks Codes |
| # |
| # SPDX-License-Identifier: GPL-3.0-only |
| |
| { |
| pkgs, |
| modulesPath, |
| lib, |
| config, |
| ... |
| }: |
| { |
| age.rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPkKdPSPxsLdx3GUjjyibRLjLl3XfaXmfrrvemDFkjI3"; |
| |
| boot.loader.systemd-boot.enable = true; |
| boot.loader.efi.canTouchEfiVariables = true; |
| |
| time.timeZone = "Etc/UTC"; |
| |
| environment.systemPackages = with pkgs; [ neovim ]; |
| |
| clicks = { |
| nix.enable = true; |
| |
| backups.key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHYH3yYKcrsDz8U45HF6201BN1nBDQIr4qsGeKh94K6T root@vermilion"; |
| |
| security = { |
| doas.enable = true; |
| |
| acme = { |
| enable = true; |
| defaults = { |
| email = "minion@clicks.codes"; |
| dnsProvider = "cloudflare"; |
| environmentFile = config.age.secrets."clicks.security.acme.defaults.environmentFile".path; |
| }; |
| }; |
| }; |
| |
| sites."docs.auxolotl.org".enable = true; |
| |
| services = { |
| ssh.enable = true; |
| headscale = { |
| enable = true; |
| domain = "clicks.domains"; |
| addr = lib.clicks.constants.hosts.generic; |
| oidc = { |
| enable = true; |
| issuer = "https://login.clicks.codes/realms/master"; |
| allowed_groups = [ "/clicks" ]; |
| client_secret_path = |
| config.age.secrets."clicks.services.headscale.oidc.client_secret_path".path; |
| }; |
| database_password_path = |
| config.age.secrets."clicks.services.headscale.database_password_path".path; |
| noise_private_key_path = |
| config.age.secrets."clicks.services.headscale.noise_private_key_path".path; |
| private_key_path = |
| config.age.secrets."clicks.services.headscale.private_key_path".path; |
| acl = |
| let |
| internet = [ |
| "0.0.0.0/5" |
| "8.0.0.0/7" |
| "11.0.0.0/8" |
| "12.0.0.0/6" |
| "16.0.0.0/4" |
| "32.0.0.0/3" |
| "64.0.0.0/3" |
| "96.0.0.0/6" |
| "100.0.0.0/10" |
| "100.128.0.0/9" |
| "101.0.0.0/8" |
| "102.0.0.0/7" |
| "104.0.0.0/5" |
| "112.0.0.0/4" |
| "128.0.0.0/3" |
| "160.0.0.0/5" |
| "168.0.0.0/8" |
| "169.0.0.0/9" |
| "169.128.0.0/10" |
| "169.192.0.0/11" |
| "169.224.0.0/12" |
| "169.240.0.0/13" |
| "169.248.0.0/14" |
| "169.252.0.0/15" |
| "169.255.0.0/16" |
| "170.0.0.0/7" |
| "172.0.0.0/12" |
| "172.32.0.0/11" |
| "172.64.0.0/10" |
| "172.128.0.0/9" |
| "173.0.0.0/8" |
| "174.0.0.0/7" |
| "176.0.0.0/4" |
| "192.0.0.0/9" |
| "192.128.0.0/11" |
| "192.160.0.0/13" |
| "192.169.0.0/16" |
| "192.170.0.0/15" |
| "192.172.0.0/14" |
| "192.176.0.0/12" |
| "192.192.0.0/10" |
| "193.0.0.0/8" |
| "194.0.0.0/7" |
| "196.0.0.0/6" |
| "200.0.0.0/5" |
| "208.0.0.0/4" |
| "224.0.0.0/3" |
| "ipv6-internet" |
| # A nasty hack used because ipv6 colons were messing with dst |
| # ports |
| ]; # Should be replaceable with autogroup:internet in next release |
| in |
| { |
| groups."group:users" = [ |
| "coded" |
| "maddie" |
| "minion" |
| "pineafan" |
| "zanderp25" |
| ]; |
| groups."group:friends" = [ |
| "sirdigalot" |
| ]; |
| groups."group:areas" = [ |
| # Some phonetic alphabet names are excluded here to avoid confusing |
| # them with given names |
| "alpha" |
| "bravo" |
| "echo" |
| "foxtrot" |
| "hotel" |
| "india" |
| "kilo" |
| "lima" |
| "november" |
| "papa" |
| "sierra" |
| "tango" |
| "uniform" |
| "whiskey" |
| "xray" |
| "yankee" |
| "zulu" |
| ]; |
| hosts.ipv6-internet = "2000::/3"; |
| |
| acls = [ |
| { |
| action = "accept"; |
| src = [ "group:users" ]; |
| dst = [ |
| "group:users:*" |
| "group:friends:*" |
| "group:areas:*" |
| ] ++ (lib.forEach internet (host: "${host}:*")); |
| } |
| { |
| action = "accept"; |
| src = [ "group:friends" ]; |
| dst = [ |
| "group:users:*" |
| "group:friends:*" |
| ]; |
| } |
| { |
| action = "accept"; |
| src = [ "group:areas" ]; |
| dst = [ "group:areas:*" ]; |
| } |
| { |
| action = "accept"; |
| src = [ "zulu" ]; |
| dst = [ "zanderp25:3000" ]; |
| } |
| ]; |
| }; |
| }; |
| fava = { |
| enable = true; |
| extraPythonPackages = [ |
| pkgs.clicks.beancount-autobean |
| pkgs.clicks.beancount-smart_importer |
| ]; |
| tailscaleAuth = true; |
| credentials = { |
| truelayer_client_secret = config.age.secrets."clicks.services.fava.credentials.truelayer_client_secret".path; |
| }; |
| accounts = { |
| "clicks" = lib.home-manager.hm.dag.entryAnywhere { |
| name = "Clicks Codes"; |
| beancountExtraOptions.operating_currency = "GBP"; |
| }; |
| "coded" = lib.home-manager.hm.dag.entryBetween [ "testing" ] [ "clicks" ] { |
| name = "Samuel Shuert"; |
| beancountExtraOptions.operating_currency = "USD"; |
| }; |
| "minion" = lib.home-manager.hm.dag.entryBetween [ "testing" ] [ "clicks" ] { |
| name = "Skyler Grey"; |
| beancountExtraOptions.operating_currency = "GBP"; |
| favaExtraOptions = { |
| invert-income-liabilities-equity = "true"; |
| auto-reload = "true"; |
| import-config = builtins.toString (pkgs.writeText "minion-imports.py" '' |
| import autobean.truelayer |
| from smart_importer import apply_hooks, PredictPayees, PredictPostings |
| |
| import os |
| import pathlib |
| |
| with open(pathlib.Path(os.environ["CREDENTIALS_DIRECTORY"]) / pathlib.Path("truelayer_client_secret")) as f: |
| truelayer_client_secret = f.read().strip() |
| |
| CONFIG = [ |
| apply_hooks( |
| autobean.truelayer.Importer( |
| "fava-228732", |
| truelayer_client_secret |
| ), |
| [ |
| PredictPayees(), |
| PredictPostings(), |
| ] |
| ) |
| ] |
| ''); |
| import-dirs = "/var/lib/private/fava/minion/"; |
| }; |
| }; |
| "testing" = lib.home-manager.hm.dag.entryAfter [ "clicks" ] { |
| name = "Test Data - May Be Wiped At Any Time"; |
| }; |
| }; |
| domain = "fava.clicks.codes"; |
| }; |
| silverbullet = { |
| enable = true; |
| domain = "silverbullet.clicks.codes"; |
| tailscaleAuth = true; |
| }; |
| }; |
| |
| networking.tailscale = { |
| enable = true; |
| authKeyFile = |
| config.age.secrets."clicks.networking.tailscale.authKeyFile".path; |
| }; |
| |
| storage = { |
| raid.enable = true; |
| impermanence = { |
| enable = true; |
| devices = { |
| root = "/dev/disk/by-uuid/ab5c2f52-a737-4b29-a505-e3d0b9d0714c"; |
| persist = "/dev/md/a1d1:persist"; |
| }; |
| }; |
| }; |
| }; |
| |
| boot.initrd.availableKernelModules = [ |
| "nvme" |
| "xhci_pci" |
| "ahci" |
| "usbhid" |
| "uas" |
| "usb_storage" |
| "sd_mod" |
| ]; |
| boot.initrd.kernelModules = [ ]; |
| boot.kernelModules = [ "kvm-amd" ]; |
| boot.extraModulePackages = [ ]; |
| |
| fileSystems."/nix" = { |
| device = "/dev/disk/by-uuid/ab5c2f52-a737-4b29-a505-e3d0b9d0714c"; |
| fsType = "btrfs"; |
| options = [ "subvol=@nix" ]; |
| }; |
| |
| fileSystems."/boot" = { |
| device = "/dev/disk/by-uuid/880D-BBAB"; |
| fsType = "vfat"; |
| options = [ |
| "fmask=0022" |
| "dmask=0022" |
| ]; |
| }; |
| |
| swapDevices = [ ]; |
| |
| networking.useDHCP = true; |
| |
| system.stateVersion = "24.05"; |
| |
| age.secrets."clicks.networking.tailscale.authKeyFile".rekeyFile = ./clicks.networking.tailscale.authKeyFile.age; |
| |
| age.secrets."clicks.security.acme.defaults.environmentFile".rekeyFile = ./clicks.security.acme.defaults.environmentFile.age; |
| |
| age.secrets."clicks.services.fava.credentials.truelayer_client_secret".rekeyFile = ./clicks.services.fava.credentials.truelayer_client_secret.age; |
| |
| age.secrets."clicks.services.headscale.oidc.client_secret_path" = { |
| rekeyFile = ./clicks.services.headscale.oidc.client_secret_path.age; |
| group = "headscale"; |
| }; |
| age.secrets."clicks.services.headscale.database_password_path" = { |
| rekeyFile = ./clicks.services.headscale.database_password_path.age; |
| group = "headscale"; |
| }; |
| age.secrets."clicks.services.headscale.noise_private_key_path" = { |
| rekeyFile = ./clicks.services.headscale.noise_private_key_path.age; |
| group = "headscale"; |
| }; |
| age.secrets."clicks.services.headscale.private_key_path" = { |
| rekeyFile = ./clicks.services.headscale.private_key_path.age; |
| group = "headscale"; |
| }; |
| } |