1
1
Fork 1
mirror of https://github.com/oddlama/nix-config.git synced 2025-10-10 14:50:40 +02:00

feat: switch from actual -> firefly-iii

This commit is contained in:
oddlama 2025-04-26 10:28:33 +02:00
parent 4adf28a442
commit ced72fb7bb
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
34 changed files with 193 additions and 128 deletions

View file

@ -12,7 +12,7 @@ let
# FIXME: new entry here? make new firezone gateway on ward entry too.
homeDomains = [
globals.services.grafana.domain
globals.services.actual.domain
globals.services.firefly.domain
globals.services.immich.domain
globals.services.influxdb.domain
globals.services.loki.domain

View file

@ -18,6 +18,11 @@
group = "oauth2-proxy";
};
# FIXME: switch to loadcredential + start wrapper.
# TODO: define nixos option to do this for us, it's recurring. like systemd.services.a.secretEnv = {
# ABC = ./path.to.secret.file; # or runtime path.
# };
# Mirror the original oauth2 secret, but prepend OAUTH2_PROXY_CLIENT_SECRET=
# so it can be used as an EnvironmentFile
age.secrets.oauth2-client-secret = {

View file

@ -134,7 +134,6 @@
in
lib.mkIf (!minimal) (
{ }
// mkMicrovm "actual" { }
// mkMicrovm "samba" {
enableStorageDataset = true;
enableBunkerDataset = true;

View file

@ -1,96 +0,0 @@
{
config,
globals,
lib,
pkgs,
nodes,
...
}:
let
actualDomain = "finance.${globals.domains.me}";
# client_id = "actual";
in
{
wireguard.proxy-home = {
client.via = "ward";
firewallRuleForNode.ward-web-proxy.allowedTCPPorts = [ config.services.actual.settings.port ];
};
# Mirror the original oauth2 secret
age.secrets.actual-oauth2-client-secret = {
inherit (nodes.ward-kanidm.config.age.secrets.kanidm-oauth2-actual) rekeyFile;
};
environment.persistence."/persist".directories = [
{
directory = "/var/lib/private/actual";
mode = "0700";
}
];
services.actual = {
enable = true;
settings.trustedProxies = [ nodes.ward-web-proxy.config.wireguard.proxy-home.ipv4 ];
};
# NOTE: state: to enable openid, we need to call their enable-openid script once
# which COPIES this data to the database :( so changing these values later will
# require manual intervention.
systemd.services.actual = {
serviceConfig.ExecStart = lib.mkForce [
(pkgs.writeShellScript "start-actual" ''
export ACTUAL_OPENID_CLIENT_SECRET=$(< "$CREDENTIALS_DIRECTORY"/oauth2-client-secret)
exec ${lib.getExe config.services.actual.package}
'')
];
serviceConfig.LoadCredential = [
"oauth2-client-secret:${config.age.secrets.actual-oauth2-client-secret.path}"
];
# NOTE: openid is disabled for now. too experimental, many rough edges.
# only admins can use sync, every admin can open anyones finances. not good enough yet.
# environment = {
# ACTUAL_OPENID_ENFORCE = "true";
# ACTUAL_TOKEN_EXPIRATION = "openid-provider";
#
# ACTUAL_OPENID_DISCOVERY_URL = "https://${globals.services.kanidm.domain}/oauth2/openid/${client_id}/.well-known/openid-configuration";
# ACTUAL_OPENID_CLIENT_ID = client_id;
# ACTUAL_OPENID_SERVER_HOSTNAME = "https://${actualDomain}";
# };
};
globals.services.actual.domain = actualDomain;
# FIXME: monitor from internal network
# globals.monitoring.http.actual = {
# url = "https://${actualDomain}/";
# expectedBodyRegex = "Actual";
# network = "local-${config.node.name}";
# };
nodes.ward-web-proxy = {
services.nginx = {
upstreams.actual = {
servers."${config.wireguard.proxy-home.ipv4}:${toString config.services.actual.settings.port}" =
{ };
extraConfig = ''
zone actual 64k;
keepalive 2;
'';
monitoring = {
enable = true;
expectedBodyRegex = "Actual";
};
};
virtualHosts.${actualDomain} = {
forceSSL = true;
useACMEWildcardHost = true;
extraConfig = ''
client_max_body_size 256M;
'';
locations."/" = {
proxyPass = "http://actual";
proxyWebsockets = true;
};
};
};
};
}

View file

@ -1 +0,0 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIARJ59yifkMFmcWWM4sAwhQN6u+H4Bv+VVboPBslHqZj

View file

@ -13,7 +13,7 @@ let
# FIXME: new entry here? make new firezone entry too.
homeDomains = [
globals.services.grafana.domain
globals.services.actual.domain
globals.services.firefly.domain
globals.services.immich.domain
globals.services.influxdb.domain
globals.services.loki.domain
@ -135,6 +135,7 @@ in
lib.mkIf (!minimal) (
{ }
// mkMicrovm "adguardhome"
// mkMicrovm "firefly"
// mkMicrovm "forgejo"
// mkMicrovm "kanidm"
// mkMicrovm "radicale"

View file

@ -112,7 +112,7 @@ in
# FIXME: new entry here? make new firezone entry too.
# FIXME: new entry here? make new firezone gateway on ward entry too.
globals.services.grafana.domain
globals.services.actual.domain
globals.services.firefly.domain
globals.services.immich.domain
globals.services.influxdb.domain
globals.services.loki.domain

View file

@ -0,0 +1,87 @@
{
config,
globals,
nodes,
...
}:
let
fireflyDomain = "firefly.${globals.domains.me}";
wardWebProxyCfg = nodes.ward-web-proxy.config;
in
{
wireguard.proxy-home = {
client.via = "ward";
firewallRuleForNode.sausebiene.allowedTCPPorts = [ config.services.firefly.port ];
};
globals.services.firefly.domain = fireflyDomain;
globals.monitoring.http.firefly = {
url = "https://${fireflyDomain}";
expectedBodyRegex = "Firefly-III";
network = "home-lan.vlans.services";
};
age.secrets.firefly-app-key = {
generator.script = _: ''
echo "base64:$(head -c 32 /dev/urandom | base64)"
'';
owner = "firefly-iii";
};
environment.persistence."/persist".directories = [
{
directory = "/var/lib/firefly-iii";
user = "firefly-iii";
}
];
i18n.supportedLocales = [ "all" ];
services.firefly-iii = {
enable = true;
enableNginx = true;
virtualHost = globals.services.firefly.domain;
settings = {
APP_URL = "https://${globals.services.firefly.domain}";
TZ = "Europe/Berlin";
TRUSTED_PROXIES = wardWebProxyCfg.wireguard.proxy-home.ipv4;
SITE_OWNER = "admin@${globals.domains.me}";
APP_KEY_FILE = config.age.secrets.firefly-app-key.path;
AUTHENTICATION_GUARD = "remote_user_guard";
AUTHENTICATION_GUARD_HEADER = "X-User";
AUTHENTICATION_GUARD_EMAIL = "X-Email";
};
};
nodes.ward-web-proxy = {
services.nginx = {
upstreams.firefly = {
servers."${config.wireguard.proxy-home.ipv4}:${toString config.services.firefly.settings.server.http_port}" =
{ };
extraConfig = ''
zone firefly 64k;
keepalive 2;
'';
monitoring = {
enable = true;
expectedBodyRegex = "Firefly";
};
};
virtualHosts.${fireflyDomain} = {
forceSSL = true;
useACMEWildcardHost = true;
locations."/" = {
proxyPass = "http://firefly";
proxyWebsockets = true;
};
extraConfig = ''
allow ${globals.net.home-lan.vlans.home.cidrv4};
allow ${globals.net.home-lan.vlans.home.cidrv6};
# Firezone traffic
allow ${globals.net.home-lan.vlans.services.hosts.ward.ipv4};
allow ${globals.net.home-lan.vlans.services.hosts.ward.ipv6};
deny all;
'';
};
};
};
}

View file

@ -35,7 +35,6 @@ in
age.secrets.kanidm-admin-password = mkRandomSecret;
age.secrets.kanidm-idm-admin-password = mkRandomSecret;
age.secrets.kanidm-oauth2-actual = mkRandomSecret;
age.secrets.kanidm-oauth2-forgejo = mkRandomSecret;
age.secrets.kanidm-oauth2-grafana = mkRandomSecret;
age.secrets.kanidm-oauth2-immich = mkRandomSecret;
@ -137,23 +136,6 @@ in
];
};
# Actual
groups."actual.access" = { };
systems.oauth2.actual = {
displayName = "Actual Budget";
originUrl = "https://${globals.services.actual.domain}/openid/callback";
originLanding = "https://${globals.services.actual.domain}/";
basicSecretFile = config.age.secrets.kanidm-oauth2-actual.path;
preferShortUsername = true;
# XXX: RS256 is used instead of ES256 so additionally we need legacy crypto
enableLegacyCrypto = true;
scopeMaps."actual.access" = [
"openid"
"email"
"profile"
];
};
# Firezone
groups."firezone.access" = { };
systems.oauth2.firezone = {

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDI93VlzePCcQnAF3MmgcvfJPhWrLmT+9uWCzgVl3YV+