feat: forgejo backups

feat: maddy
This commit is contained in:
Patrick Großmann 2024-01-27 23:21:42 +01:00
parent b4db6868e8
commit 04c127e144
Signed by: patrick
GPG key ID: 451F95EFB8BECD0F
16 changed files with 133 additions and 41 deletions

View file

@ -19,8 +19,6 @@
../../modules/hardware/physical.nix
../../modules/hardware/zfs.nix
../../modules/services/acme.nix
./net.nix
./fs.nix
]

View file

@ -39,4 +39,36 @@
interface = "lan01";
mode = "bridge";
};
age.secrets.cloudflare_token_acme = {
rekeyFile = ./secrets/cloudflare_api_token.age;
mode = "440";
group = "acme";
};
security.acme = {
acceptTerms = true;
defaults = {
email = config.secrets.secrets.global.devEmail;
dnsProvider = "cloudflare";
dnsPropagationCheck = true;
reloadServices = ["nginx"];
credentialFiles = {
"CF_DNS_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
"CF_ZONE_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
};
};
};
security.acme.certs.web = {
domain = config.secrets.secrets.global.domains.web;
extraDomainNames = ["*.${config.secrets.secrets.global.domains.web}"];
};
users.groups.acme.members = ["nginx"];
environment.persistence."/state".directories = [
{
directory = "/var/lib/acme";
user = "acme";
group = "acme";
mode = "0755";
}
];
}

View file

@ -0,0 +1,13 @@
age-encryption.org/v1
-> X25519 j1vdwUZ+o5coMFAaOCyiS42rLq7FPX6xwuWmoHcN61U
m1QEYj4NW5IdNsFh26Uhwe2Sg1ggkvTYB92S4B2lC8M
-> piv-p256 XTQkUA AhjsxoVBz3h/1Sj+cwnT7gpcE6SDMhNOBMU9nP+gfC5G
a7E3dolF4QaxTVpJBOKA314INK32eTdDykDyRT+/8XQ
-> piv-p256 ZFgiIw Ah49xwjTzvroi4R90URbbE0yY15w+OvUsWZ2cQdYHs/w
4i6XZ8lwOeWinlU1IiCgUBTSWMzxuPyvYKRbz6GqNUk
-> piv-p256 ZFgiIw A49Cv751h0WJYL6qPceFVwjbGVpF668SGKVjHq/lQ4Rs
AAGD0jOCHIOAIBk872SJwe2mCx69xn/1ZjiswebgU0w
-> K("0$@8-grease z`/W }"_xiVH <~Bj._
--- /NUrs98fD72LqCIYVOzrUhFNhxGivAEOZ9pob65I2fI
:(#­¥aô[8@BÊ4èÝ|ÍC7!³>Ù?¬Œ›`5á‰o‡Þr õB´ˆ°y`óAIJ;)÷Å&“)@ÝÎB²¹Ï¡ñ´¾Q

View file

@ -7,6 +7,7 @@
[
../../modules/config
../../modules/optional/initrd-ssh.nix
../../modules/services/maddy.nix
../../modules/hardware/zfs.nix

View file

@ -28,7 +28,6 @@
fileSystems."/state".neededForBoot = true;
fileSystems."/persist".neededForBoot = true;
boot.initrd.luks.devices.enc-rpool.allowDiscards = true;
boot.loader.grub.devices = [
"/dev/disk/by-id/${config.secrets.secrets.local.disko.drive}"
];

View file

@ -30,4 +30,35 @@
linkConfig.RequiredForOnline = "routable";
};
};
age.secrets.cloudflare_token_acme = {
rekeyFile = ./secrets/cloudflare_api_token.age;
mode = "440";
group = "acme";
};
security.acme = {
acceptTerms = true;
defaults = {
email = config.secrets.secrets.global.devEmail;
dnsProvider = "cloudflare";
dnsPropagationCheck = true;
reloadServices = ["nginx"];
credentialFiles = {
"CF_DNS_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
"CF_ZONE_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
};
};
};
security.acme.certs.mail = {
domain = config.secrets.secrets.global.domains.mail;
extraDomainNames = ["*.${config.secrets.secrets.global.domains.mail}"];
};
users.groups.acme.members = ["maddy"];
environment.persistence."/state".directories = [
{
directory = "/var/lib/acme";
user = "acme";
group = "acme";
mode = "0755";
}
];
}

View file

@ -0,0 +1,15 @@
age-encryption.org/v1
-> X25519 uhnRibm92XSz2UcJWT43CrsZfOrSzUyqVFU8nWiYEXs
QNxh6YGDCgSSoCWLthZlou7F7i9OJpunB+/6J4ogk2k
-> piv-p256 XTQkUA AzTDTMXLU5jTp54ysvnVIDo5lIb5ED1zkP8659tTH2JJ
VLO6rtfY5poFGVH/eeD+T/xrlNdPGnlLQ6mK1HytT8A
-> piv-p256 ZFgiIw AnwL/t0GNZI3/y7KlatHLebToW1pJLfOasODGQ7ogriz
Wl7xm6+a1qmqLeTZszpO0XG96BcDRO5l8wvpc0atW0Y
-> piv-p256 5vmPtQ AzC3t9sPdKF/IPkJSqhldnx3Mnkc84DCD13l8tYqZIWd
GaNzRxPoSOy/kEuLzbXpiRDo5F2hZT8KriXpgqZkQ5Y
-> piv-p256 ZFgiIw ApFdJVoW4zoWq38fE27TR/OFEDs4Wub1g3q6RiF+fDTR
IypnQqeluntk31gez5I6eYtlKiY/8sy+dXNkpWhdwPs
-> wX-grease
neAQttCOcpQWsfSpI38jdOjODJYK8uOhqjWsZOLWlHZaRUQtoyXI
--- r44AgWizs6H92oY6hKMs67ARXqr8Je0Z0cIJr9xidBg
°ß¦Ñ¨â<>Ÿî̪øÙ¤Ph\œdv úí¥]’ÀÓšÆÜŠÚ˜ùÄE<C384>ʃ´¯æewIé‡t.¬²WÃÂ6ZFi

View file

@ -25,6 +25,7 @@
vaultwarden = uidGid 215;
redis-paperless = uidGid 216;
microvm = uidGid 217;
maddy = uidGid 218;
paperless = uidGid 315;
systemd-oom = uidGid 300;
systemd-coredump = uidGid 301;

View file

@ -1,37 +0,0 @@
{
config,
lib,
...
}: {
age.secrets.cloudflare_token_acme = {
rekeyFile = ../../secrets/cloudflare/api_token.age;
mode = "440";
group = "acme";
};
security.acme = {
acceptTerms = true;
defaults = {
email = config.secrets.secrets.global.devEmail;
dnsProvider = "cloudflare";
dnsPropagationCheck = true;
reloadServices = ["nginx"];
credentialFiles = {
"CF_DNS_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
"CF_ZONE_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
};
};
};
security.acme.certs = lib.flip lib.mapAttrs config.secrets.secrets.global.domains (_: value: {
domain = value;
extraDomainNames = ["*.${value}"];
});
users.groups.acme.members = ["nginx"];
environment.persistence."/state".directories = [
{
directory = "/var/lib/acme";
user = "acme";
group = "acme";
mode = "0755";
}
];
}

View file

@ -1,6 +1,6 @@
{config, ...}: {
age.secrets.cloudflare_token_dns = {
rekeyFile = ../../secrets/cloudflare/api_token.age;
rekeyFile = "${config.node.secretsDir}/cloudflare_api_token.age";
mode = "440";
};
# So we only update the A record

View file

@ -5,6 +5,38 @@
}: let
giteaDomain = "git.${config.secrets.secrets.global.domains.web}";
in {
age.secrets.resticpasswd = {
generator.script = "alnum";
};
age.secrets.forgejoHetznerSsh = {
generator.script = "ssh-ed25519";
};
services.restic.backups = {
main = {
user = "root";
timerConfig = {
OnCalendar = "06:00";
Persistent = true;
RandomizedDelaySec = "3h";
};
initialize = true;
passwordFile = config.age.secrets.resticpasswd.path;
hetznerStorageBox = {
enable = true;
inherit (config.secrets.secrets.global.hetzner) mainUser;
inherit (config.secrets.secrets.global.hetzner.users.forgejo) subUid path;
sshAgeSecret = "forgejoHetznerSsh";
};
paths = [config.services.gitea.stateDir];
pruneOpts = [
"--keep-daily 10"
"--keep-weekly 7"
"--keep-monthly 12"
"--keep-yearly 75"
];
};
};
# Recommended by forgejo: https://forgejo.org/docs/latest/admin/recommendations/#git-over-ssh
services.openssh.settings.AcceptEnv = "GIT_PROTOCOL";
networking.firewall.allowedTCPPorts = [3000 9922];

View file

@ -0,0 +1,7 @@
{config, ...}: {
services.maddy = {
enable = true;
hostname = "mx1" + config.secrets.secrets.global.domains.mail;
primaryDomain = config.secrets.secrets.global.domains.mail;
};
}

Binary file not shown.