blob: 4cceeca69546718d419e82154d6712fe2d1b9a14 [file] [log] [blame]
# 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:*" ];
}
];
};
};
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";
};
};
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";
};
}