mirror of
https://codeberg.org/polyteknisk-radiogruppe/the_prg_server_configuration.git
synced 2026-10-21 11:25:46 +02:00
Compare commits
25 commits
2981721727
...
54a3be635b
| Author | SHA1 | Date | |
|---|---|---|---|
| 54a3be635b | |||
| c2e5f113b4 | |||
| 23fa0c1397 | |||
| 5e794336d8 | |||
| 0d903689a3 | |||
| c0e252df71 | |||
| 9a6d5cea0d | |||
| 0ad5eddb8d | |||
| 92db9f8575 | |||
| 201a1d56fd | |||
| c4fe904896 | |||
| d6af466263 | |||
| b3e83605db | |||
| 3e129f880e | |||
| b5af91bde0 | |||
| aee7f79c01 | |||
| aa38152c1c | |||
| c5a33e537e | |||
| 3ac671279a | |||
| 408745c511 | |||
| ce519b3343 | |||
| 92ab262d70 | |||
| 20e27f799c | |||
| 458d0d865a | |||
| a1a579662e |
12 changed files with 439 additions and 5 deletions
|
|
@ -2,6 +2,7 @@ keys:
|
||||||
- &admin_christine age1746rvsvsc3snxfl7cndm222wd5kck4aqj3x7nednlegq0gdjhfcqx0qv7m
|
- &admin_christine age1746rvsvsc3snxfl7cndm222wd5kck4aqj3x7nednlegq0gdjhfcqx0qv7m
|
||||||
- &server_songsheet age1la8yjuc2ws9pyx70rc83jd2084v5e08v8fvh6muvfzrl2ulp8fms6frs86
|
- &server_songsheet age1la8yjuc2ws9pyx70rc83jd2084v5e08v8fvh6muvfzrl2ulp8fms6frs86
|
||||||
- &server_traefik age1rdcs8y4fjfyagwt2q9599ax329thceersh6dg2f0p6nsghm5xufq00qu0p
|
- &server_traefik age1rdcs8y4fjfyagwt2q9599ax329thceersh6dg2f0p6nsghm5xufq00qu0p
|
||||||
|
- &server_database age1k9ddvzypz986a7dt403ja6evql2agz0gehll79mx64zceteya38smxph8m
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: nix-system-configs/secrets/songsheet/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: nix-system-configs/secrets/songsheet/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
|
|
@ -13,3 +14,8 @@ creation_rules:
|
||||||
- age:
|
- age:
|
||||||
- *admin_christine
|
- *admin_christine
|
||||||
- *server_traefik
|
- *server_traefik
|
||||||
|
- path_regex: nix-system-configs/secrets/database/[^/]+\.(yaml|json|env|ini)$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *admin_christine
|
||||||
|
- *server_database
|
||||||
|
|
|
||||||
16
README.md
16
README.md
|
|
@ -22,3 +22,19 @@ TODO HECK
|
||||||
- [ ] Figure out my life
|
- [ ] Figure out my life
|
||||||
- [ ] Setup Hardware Keys
|
- [ ] Setup Hardware Keys
|
||||||
- [ ] Setup a VPN (Likely OpenVPN)
|
- [ ] Setup a VPN (Likely OpenVPN)
|
||||||
|
|
||||||
|
|
||||||
|
## NOTES FOR FUTURE
|
||||||
|
|
||||||
|
```
|
||||||
|
ServiceException: 401 Anonymous caller does not have storage.objects.list access to the Google Cloud Storage bucket. Permission 'storage.objects.list' denied on resource (or it may not exist).
|
||||||
|
```
|
||||||
|
|
||||||
|
You need to run
|
||||||
|
```zsh
|
||||||
|
sudo gcloud init
|
||||||
|
sudo gcloud auth activate-service-account --key-file /run/secrets/gcloud_bucket
|
||||||
|
```
|
||||||
|
|
||||||
|
Cheesus Crust, document this plz Google, whyyyyyyyyy
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@
|
||||||
fastfetch
|
fastfetch
|
||||||
hyfetch
|
hyfetch
|
||||||
pgadmin4
|
pgadmin4
|
||||||
|
google-cloud-sdk
|
||||||
];
|
];
|
||||||
|
|
||||||
# Some programs need SUID wrappers, can be configured further or are
|
# Some programs need SUID wrappers, can be configured further or are
|
||||||
|
|
@ -4,7 +4,49 @@
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
# Enable the X11 windowing system.
|
||||||
services.xserver.enable = true;
|
services.xserver.enable = true;
|
||||||
|
|
||||||
|
# Enable the GNOME Desktop Environment.
|
||||||
services.xserver.displayManager.gdm.enable = true;
|
services.xserver.displayManager.gdm.enable = true;
|
||||||
services.xserver.desktopManager.gnome3.enable = true;
|
services.xserver.desktopManager.gnome.enable = true;
|
||||||
|
|
||||||
|
# Configure keymap in X11
|
||||||
|
services.xserver.xkb = {
|
||||||
|
layout = "us";
|
||||||
|
variant = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable CUPS to print documents.
|
||||||
|
services.printing.enable = true;
|
||||||
|
|
||||||
|
# Enable sound with pipewire.
|
||||||
|
services.pulseaudio.enable = false;
|
||||||
|
security.rtkit.enable = true;
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
alsa.support32Bit = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
# If you want to use JACK applications, uncomment this
|
||||||
|
#jack.enable = true;
|
||||||
|
|
||||||
|
# use the example session manager (no others are packaged yet so this is enabled by default,
|
||||||
|
# no need to redefine it in your config for now)
|
||||||
|
#media-session.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Install firefox.
|
||||||
|
programs.firefox.enable = true;
|
||||||
|
|
||||||
|
# Allow unfree packages
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
|
# Some programs need SUID wrappers, can be configured further or are
|
||||||
|
# started in user sessions.
|
||||||
|
programs.mtr.enable = true;
|
||||||
|
programs.gnupg.agent = {
|
||||||
|
enable = true;
|
||||||
|
enableSSHSupport = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,8 @@ else
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
## Todo System Conditional pulling of directories (only if it exists)
|
||||||
|
|
||||||
# Step 2.1: Sync secrets directory
|
# Step 2.1: Sync secrets directory
|
||||||
# nix-system-configs/modules/scripts /pull.zsh
|
# nix-system-configs/modules/scripts /pull.zsh
|
||||||
# nix-system-configs/secrets/songsheet/secrets.yaml
|
# nix-system-configs/secrets/songsheet/secrets.yaml
|
||||||
|
|
@ -135,6 +137,22 @@ else
|
||||||
print_warn "Secrets directory not found: ${SECRETS_DIR}"
|
print_warn "Secrets directory not found: ${SECRETS_DIR}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Step 2.2: Sync system_scripts directory
|
||||||
|
SYSTEM_SCRIPT_DIR="${SCRIPT_DIR}/../system_scripts"
|
||||||
|
SYSTEM_SCRIPT_TARGET="/etc/nixos/system_scripts"
|
||||||
|
|
||||||
|
if [[ -d "$SECRETS_DIR" ]]; then
|
||||||
|
print_info "Syncing system scripts to ${BOLD}${SYSTEM_SCRIPT_TARGET}${RESET}..."
|
||||||
|
if sudo rsync -av --delete "${SYSTEM_SCRIPT_DIR}/" "${SYSTEM_SCRIPT_TARGET}/"; then
|
||||||
|
print_success "System scripts synced"
|
||||||
|
else
|
||||||
|
print_error "Failed to sync system scripts"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_warn "System scripts directory not found: ${SYSTEM_SCRIPT_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Step 3: Copy configuration
|
# Step 3: Copy configuration
|
||||||
source_file="${SYSTEM_DIR}/${selected_system}.nix"
|
source_file="${SYSTEM_DIR}/${selected_system}.nix"
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
# sops.defaultSopsFile = "/root/.sops/secrets/example.yaml";
|
# sops.defaultSopsFile = "/root/.sops/secrets/example.yaml";
|
||||||
sops.defaultSopsFile = ../../secrets/songsheet/secrets.yaml;
|
sops.defaultSopsFile = ../../secrets/songsheet/secrets.yaml;
|
||||||
# This will automatically import SSH keys as age keys
|
# This will automatically import SSH keys as age keys
|
||||||
sops.age.sshKeyPaths = ["/home/songsheetprg/.ssh/id_ed25519.pub"];
|
#sops.age.sshKeyPaths = ["/home/songsheetprg/.ssh/id_ed25519"];
|
||||||
# This is using an age key that is expected to already be in the filesystem
|
# This is using an age key that is expected to already be in the filesystem
|
||||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||||
# This will generate a new key if the key specified above does not exist
|
# This will generate a new key if the key specified above does not exist
|
||||||
43
nix-system-configs/modules/secrets-config/sops-database.nix
Normal file
43
nix-system-configs/modules/secrets-config/sops-database.nix
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = let
|
||||||
|
# replace this with an actual commit id or tag
|
||||||
|
commit = "17eea6f3816ba6568b8c81db8a4e6ca438b30b7c";
|
||||||
|
in [
|
||||||
|
"${builtins.fetchTarball {
|
||||||
|
url = "https://github.com/Mic92/sops-nix/archive/${commit}.tar.gz";
|
||||||
|
# replace this with an actual hash
|
||||||
|
sha256 = "ktjWTq+D5MTXQcL9N6cDZXUf9kX8JBLLBLT0ZyOTSYY=";
|
||||||
|
}}/modules/sops"
|
||||||
|
];
|
||||||
|
|
||||||
|
# This will add secrets.yml to the nix store
|
||||||
|
# You can avoid this by adding a string to the full path instead, i.e.
|
||||||
|
# sops.defaultSopsFile = "/root/.sops/secrets/example.yaml";
|
||||||
|
sops.defaultSopsFile = ../../secrets/songsheet/secrets.yaml;
|
||||||
|
# This will automatically import SSH keys as age keys
|
||||||
|
#sops.age.sshKeyPaths = ["/home/nixosdd/.ssh/id_ed25519"];
|
||||||
|
# This is using an age key that is expected to already be in the filesystem
|
||||||
|
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||||
|
# This will generate a new key if the key specified above does not exist
|
||||||
|
sops.age.generateKey = true;
|
||||||
|
# Secrets key stuff
|
||||||
|
sops.secrets."backup_gpg_key" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ../../secrets/database/secrets.yaml;
|
||||||
|
owner = "root";
|
||||||
|
mode = "0400";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Declare the GCS service account secret
|
||||||
|
sops.secrets."gcloud_bucket" = {
|
||||||
|
format = "binary"; # Apparently this can make it behave as is.
|
||||||
|
sopsFile = ../../secrets/database/gcloud_bucket.json;
|
||||||
|
owner = "root";
|
||||||
|
mode = "0400";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
#
|
#
|
||||||
## Compose modules for Portainer service
|
## Compose modules for Portainer service
|
||||||
./modules/songsheet/wavelog/docker-compose.nix
|
./modules/songsheet/wavelog/docker-compose.nix
|
||||||
./modules/secrets-config/sops-nix.nix
|
./modules/secrets-config/sops-composesongsheet.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
|
||||||
104
nix-system-configs/modules/system/database.nix
Normal file
104
nix-system-configs/modules/system/database.nix
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
options.local = {
|
||||||
|
hostname = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "nixos-default";
|
||||||
|
description = "System hostname";
|
||||||
|
};
|
||||||
|
username = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "user";
|
||||||
|
description = "Primary user username";
|
||||||
|
};
|
||||||
|
userDescription = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "NixOS User";
|
||||||
|
description = "Primary user description";
|
||||||
|
};
|
||||||
|
address = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "10.1.1.100";
|
||||||
|
description = "Static IP address";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./modules/desktop-manager/gnome.nix
|
||||||
|
./modules/local/hostname_username.nix
|
||||||
|
./modules/local/networking_local.nix
|
||||||
|
./modules/lix-default.nix
|
||||||
|
./modules/secrets-config/sops-database.nix
|
||||||
|
./modules/system_scripts/gcloud_backup.nix
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
config = {
|
||||||
|
local.hostname = "nixosdd";
|
||||||
|
local.username = "nixosdd";
|
||||||
|
local.userDescription = "NixOS Dedicated Database";
|
||||||
|
local.address = "10.1.1.251";
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
5432 # PostgreSQL
|
||||||
|
3306 # MariaDB/MySQL
|
||||||
|
];
|
||||||
|
networking.firewall.allowedUDPPorts = [
|
||||||
|
5432 # PostgreSQL
|
||||||
|
3306 # MariaDB/MySQL
|
||||||
|
];
|
||||||
|
|
||||||
|
# Bootloader.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
# Enable PostgreSQL
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
enableTCPIP = true;
|
||||||
|
ensureDatabases = ["forgejo" "part_db_database"];
|
||||||
|
settings = {
|
||||||
|
listen_addresses = "*";
|
||||||
|
};
|
||||||
|
authentication = pkgs.lib.mkOverride 10 ''
|
||||||
|
local all all trust
|
||||||
|
host all all 10.1.1.4/32 scram-sha-256
|
||||||
|
host all all 10.1.1.249/32 scram-sha-256
|
||||||
|
host all all 127.0.0.1/32 trust
|
||||||
|
host all all ::1/128 trust
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable MariaDB
|
||||||
|
services.mysql = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.mariadb;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable Tailscale
|
||||||
|
services.tailscale.enable = true;
|
||||||
|
|
||||||
|
# List packages installed in system profile. To search, run:
|
||||||
|
# $ nix search wget
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
|
||||||
|
wget
|
||||||
|
helix
|
||||||
|
fastfetch
|
||||||
|
hyfetch
|
||||||
|
pgadmin4
|
||||||
|
python3
|
||||||
|
python3Packages.pip
|
||||||
|
python3Packages.setuptools
|
||||||
|
python3Packages.wheel
|
||||||
|
python3Packages.cryptography
|
||||||
|
google-cloud-sdk
|
||||||
|
];
|
||||||
|
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
};
|
||||||
|
}
|
||||||
160
nix-system-configs/modules/system_scripts/gcloud_backup.nix
Normal file
160
nix-system-configs/modules/system_scripts/gcloud_backup.nix
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
gcsBucket = "polyteknisk-db-backups-bucket";
|
||||||
|
gpgRecipient = "dtu.prg@dtu.dk";
|
||||||
|
|
||||||
|
# Embed the public key directly (not sensitive)
|
||||||
|
gpgPublicKey = pkgs.writeText "backup-public-key.asc" ''
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
DFYqkeE28Uzz52DpHGvbw4cT08w17WWrf6A=
|
||||||
|
=jpAS
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
'';
|
||||||
|
|
||||||
|
postgresBackupScript = pkgs.writeShellScript "backup-postgresql" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
export GOOGLE_APPLICATION_CREDENTIALS="${config.sops.secrets.gcloud_bucket.path}"
|
||||||
|
export PATH="${lib.makeBinPath [pkgs.postgresql pkgs.gzip pkgs.google-cloud-sdk pkgs.gnupg pkgs.coreutils pkgs.gnugrep]}:$PATH"
|
||||||
|
#gcloud auth activate-service-account --key-file="$GOOGLE_APPLICATION_CREDENTIALS"
|
||||||
|
|
||||||
|
TIMESTAMP=$(date +%Y%m%d%H%M%S)
|
||||||
|
BACKUP_DIR=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$BACKUP_DIR"' EXIT
|
||||||
|
|
||||||
|
gpg --batch --import "${gpgPublicKey}"
|
||||||
|
|
||||||
|
DATABASES=$(psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false AND datname != 'postgres';" | grep -v '^$')
|
||||||
|
|
||||||
|
for DB in $DATABASES; do
|
||||||
|
DB=$(echo "$DB" | xargs)
|
||||||
|
echo "Backing up PostgreSQL database: $DB"
|
||||||
|
FILENAME="pgsql_''${DB}_''${TIMESTAMP}.sql.gz.gpg"
|
||||||
|
if pg_dump -U postgres -d "$DB" | gzip | gpg --batch --trust-model always --encrypt --recipient "${gpgRecipient}" > "$BACKUP_DIR/$FILENAME"; then
|
||||||
|
gcloud storage cp "$BACKUP_DIR/$FILENAME" "gs://${gcsBucket}/postgresql/$FILENAME"
|
||||||
|
echo "Successfully uploaded encrypted $FILENAME"
|
||||||
|
else
|
||||||
|
echo "Failed to backup $DB" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
|
||||||
|
mariadbBackupScript = pkgs.writeShellScript "backup-mariadb" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
export GOOGLE_APPLICATION_CREDENTIALS="${config.sops.secrets.gcloud_bucket.path}"
|
||||||
|
export PATH="${lib.makeBinPath [pkgs.mariadb pkgs.gzip pkgs.google-cloud-sdk pkgs.gnupg pkgs.coreutils pkgs.gnugrep]}:$PATH"
|
||||||
|
#sudo gcloud auth activate-service-account --key-file="$GOOGLE_APPLICATION_CREDENTIALS"
|
||||||
|
|
||||||
|
TIMESTAMP=$(date +%Y%m%d%H%M%S)
|
||||||
|
BACKUP_DIR=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$BACKUP_DIR"' EXIT
|
||||||
|
|
||||||
|
gpg --batch --import "${gpgPublicKey}"
|
||||||
|
|
||||||
|
DATABASES=$(mariadb -u root -e "SHOW DATABASES;" | grep -Ev "^(Database|information_schema|performance_schema|mysql|sys)$")
|
||||||
|
|
||||||
|
for DB in $DATABASES; do
|
||||||
|
echo "Backing up MariaDB database: $DB"
|
||||||
|
FILENAME="mariadb_''${DB}_''${TIMESTAMP}.sql.gz.gpg"
|
||||||
|
if mariadb-dump -u root "$DB" | gzip | gpg --batch --trust-model always --encrypt --recipient "${gpgRecipient}" > "$BACKUP_DIR/$FILENAME"; then
|
||||||
|
gcloud storage cp "$BACKUP_DIR/$FILENAME" "gs://${gcsBucket}/mariadb/$FILENAME"
|
||||||
|
echo "Successfully uploaded encrypted $FILENAME"
|
||||||
|
else
|
||||||
|
echo "Failed to backup $DB" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
systemd.services.backup-postgresql = {
|
||||||
|
description = "Backup PostgresSQL databases to GCS";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "root";
|
||||||
|
ExecStart = "${postgresBackupScript}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.backup-postgresql = {
|
||||||
|
description = "Timer for PostgresSQL backups";
|
||||||
|
wantedBy = ["timers.target"];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "Mon,Thu,Sun 03:00";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.backup-mariadb = {
|
||||||
|
description = "Backup MariaDB databases to GCS";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "root";
|
||||||
|
ExecStart = "${mariadbBackupScript}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.backup-mariadb = {
|
||||||
|
description = "Timer for MariaDB backups";
|
||||||
|
wantedBy = ["timers.target"];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "Mon,Thu,Sun 04:00";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
19
nix-system-configs/secrets/database/gcloud_bucket.json
Normal file
19
nix-system-configs/secrets/database/gcloud_bucket.json
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"data": "ENC[AES256_GCM,data:bIh3mtzZL5Sj/jmZXg7iLnkmgngk3+1i9ZGlrc1fhilf5Dno8opjovIEof5DwzA9Pyk4KQijb4yiP/cNMSc6cBLE9X2n6ZLZb065sN9h+h2n6kItVapxwScMi4W7srpFctTs98fj95wp/MH2R43MS7QY9sIzlE5ZifEo8G4xuDmQdBHONIVhYu36A3JEOjuW80SzdIfgTqvZyLfa+NtlrqqI/Ofm63H0SOf6wzCm6dMPZQyD9KIP/adT35U45EZx0lEnaDSmvqLqkGoNAw6uDbdtQ3fd/qfs0UrGkVVi/n+uxuY355eY9Qb9PQBdz5K6gkW7d+zOmFyVKPEJ1p0AeYuIOSY8x8tOlT+97tI/6SBnMa43FBPuOMFEeujTuiUdVlI5bAkxRPk4qTCntUIzKBkZ4YBDRolHQkk38SQWCA5DIeZ6ehu1tbvVjtx0FFNqNOAGjXrmL0Jggp2cDsrHOHHPOtb+CVUcjmdmgAhhF1QIYK0tZPFNrBlOY3/OoLaXuQWIaHNKHNfoGvSPcoRRnovSgguYYBb9wLJ4r00usVLW9A5m3I464N/WHv7crsWjLrXBk7Yai1Jd8GI0K/4ICy4n6nCuwujdeMGbT/syd2RLXYYwBOs48qZHy/qzZOwHxn8lXyApNG3w5t+xqpDOa99/6IaB6G+sDOX8oadb+YfZFvhyBdsAKoDE3s+tfB8aGRClteS3bDbFjnqA/NlUVQ93Wcf070W0T8e9+E89zyWriJIdpNrN8n1MHOLp/vFi/VAIejhQ9aFcOQT51ZBULZYV/iNjZ+Ucy5y7NdTwBI2jCU6ihRn8FJMM/d0R5i+PVxOAJIKTTUqTvMs5cPTLwk0s2Ns+BWl1i934gzk8qK3QNh/Dd9QSxKSZdXEOa25J+uUZ7RpRv0YzAyehvXeioPyIRrPoAq/uk+MRKV7QVBXfNFXVyc3fWg2sObUIR/53iURpFMJjlkf/UO6zV/D1U+2d6TwSMpvtyjtB5jgnWMtIOiYOEDDUx6+xaWi2YnC3bqXd0mrWBSfx+FQjSeV32yeRCWj6kAwJHE4UqOqwi+R7YGsff2Ww0tAuX/rFWdRUZeaC2wu8Onyi/BUjfG/M9Q1p/YzVeylQZe+o4tvPN41hPvrBwNBnXLKS1GZziK+dWDlV2Xvcj6f2Ur2qwnmbOAph/L31qMEYA8doUkkDHBhgxf+OwKR+wVbsPtooidDmVLoYEB/6W8wXAUHPq4MsnS7GTTjpEgEdfn3+/9PdP94ED8Ch+Bn8weh784SknaWytG4gGJy7UJK7Jc0/7JwQO/IreZxiCVVdL/ib6PCYUoumArFtNlLxQOansZvnD4ATf4DMLjtQmAaZb6/PbBozL+fmXq4V9WrB2P1JEkdnfJu5n6rfhG+7dBLxHsjWT5w4ZHPP66WvaWN92JhzkysmrlGl3YRVDUuOyoUiqRmvyFVuRupHVnupURqpI56g7+3N9tEduZhesJ9MN7qDuFpSv3QPgyRARMRQemYhQEvKJNaFie9e81qsacYCq73V3glXY0cdPMZb4HP6Ir1Vr6dtZyFnAX8XsSTZo5RFQmLq7OmIXXE7Y3QRZRcSG+x+Qtk6GK2+nLG+FUALHWnp1YHRwGGUW9dAShGA1ZFlRpEUtpzQxBwc2OkoWKpYG2kbsMdyLmpwUA8m41JPKUI4vblJ4Xx9TP+t4b9jKFGbxeTFyHIcY5nO3hRExPhPYjwoSDFjRI5lzj6xUeQ1DYJVosYB3T03fDSIUjMqm2xLdMLUFiwLv3iNbhyyxJe1KdGwCi/oo8nInjaIu76ONy//KTTrI4qf7k4B2AuYz5gEaBOhIzR/+RmUnHR9QDQkD/rwglIXNCIgct7BqYHrTbWWggL1JUG5RZuJQvrTMH2nL5TbxWONt1/s4RcxR8ZBs+rD82q3KtIIfOHlowje9HJrAfYefMUTZP1ZjST+XmRgLpdjLzefTxrAcfy0MhBsknDICSHeiiPny8jPLZMmFDhahCmc/36lXFExTdNYxXvo8px/4ZIwYaNTrryO5PYVbBiRjIirZf6P5K0EZNbd2YAkX3YdPVEPXS7eaNG/mPUMeWFCQeXVFXkoGs8foLdPH8eBby7wjocq/xumt4Pa06rqazAj0LpdDcstvYcLcXDT+56kS6KahDuoZNB7ujaDXDLSm5HpAAlNnxKGzjPGBP38+IzXI9ggA3hoatLCU6cuTTeJxkDOraszLxENmB8qD/MFg5JIHcpGbeALEib0w3c5ZghuaDDD/r0dj6MBmYd/o2Hz0eY8LKUbD8A+i5y97qpBrHbgwKSX5XSuqhBA+SeC/UfVdDXQ9RnTGbK6ZgpY45kjkFzj/cdU4T1W5xVmm+D14MlBUrDRW/9+bAemqSxvJWiXZ+RvSxRmcnD8TwkbYrFDdidRPljQHFbbtIf/PJrV63ZKT97xawBMwgcszdm7+putFgQMgR2Vyh2cQZNJU7dtWxdji0R4x6O0HYM8bTnkSUzMyLwWGEOB0M+s8QYeMqHY5ESFCwqKeDtB8F6cQHs1nRNSjSzQ6yWnylWAGwXzT5xWBQM+qf/XJUidXxItxuf8UiBR7ffk8AmFRiCNFCEJzIvz4CE/j50GWXG5ecf+33qcCuz2Dqu/u9wjp2qWawTe/Mcrs0SiYn4y6CgJaFhaHKk1T2VHxlSqGLalJLeL/Fil9kIIWLUythh09Yy1/8e2YML8CpR9RLk7f4epv51crCpjP0Ih9ckRTWqqrKLKOSpNHezTWPlx4MrQwWr+AneG/4G5k1i8x2fLRowcW0uTKFK8cEZmgo7s7C54UMktDaPyORu39U7Vw9B29y0WAmVcYC2OA55p7D1Bj66bp2rm3auXmO8q9wBqlC+0/i6NA0+rqUgHlWxCm7tEZkbNRR4RBARskmOBqWdDJX6kJkNFIbA5JAJujX+YKLonB+K7qJcAgay9yidet/e0pfD1/vmz0cb6HpMmbbU8wTksqDTtqWaMx8l23J6f8WSiUJaA8X/PKeF7MY2h7ag/y041s4Q13Lo6KXK19lql9VwwNdaAN/nysWWYF72sbWIKTKBXRYAWH9+ZsV4+NvEmr4BZvzvhLMLOXFqCA3/ykQ4nmJPgZazUYOYWRr+6Pq+7LPEF/A9uKJNZcjHMVLiWhQw0m3IUsig4AwYeOMFLr/9juqNku5WiPpOyH5WCdHqbiAXHjD0CZDMJKWjtrlRaLaMnLkJmBDShieKgjdC/aEI+bVKx4IM=,iv:NJE8hUES+ayjQrXb4/vpp6qey6Rts2FoGwu2/H4BPsw=,tag:P+V61A1LVE45oTrteOBWiQ==,type:str]",
|
||||||
|
"sops": {
|
||||||
|
"age": [
|
||||||
|
{
|
||||||
|
"recipient": "age1746rvsvsc3snxfl7cndm222wd5kck4aqj3x7nednlegq0gdjhfcqx0qv7m",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRL0E3QnNZOCt3RHdjTzBw\nM0tuSW1JQXNzVm4wZWtaNXZnSHJYdENUTGdnCmh6UnNTSWZqSkJrOTIzMmFHWElJ\nb0o2WGRLeEZjVzlCNURVZ1Z0eDl3eWsKLS0tIHNwQUEzUXIwSmRGMTRsSU1qbUNP\ndUdWOXYzU2tHa1IveUFFSG1OTHRiRGMKc1rmeYCy0zSxiOvPd9JwUduRbdjlUs7K\nAsTkw75P9UEitnMPrZziLtkxJGl9dochdB6y5/Eh4eJg7K9zeIr9Ug==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"recipient": "age1k9ddvzypz986a7dt403ja6evql2agz0gehll79mx64zceteya38smxph8m",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVM1plZUhQUXdMTUMwZDNl\ndWM2OHV2RVRTS2hncjhjd0o4S1g5ZWNucWdVCm1PUG9kcHNXUFY3V2pJZndXZkdw\nUkhyNHdja0ZUSDU5aEgxeFhFR2VFTWcKLS0tIGl4UXp3bTJZWk1ZckJtK0M3RUFS\ncDlhV2NDSUsvVzJxYUhjT3JKUk55MkEKD13e9L1Xlh7q/a+sX4nCjlYfOpnnwodD\nMO2tDPt5odap7w9fra27BdEdBQiTdZxQXmE+7r85GEN8isk6xeqS/w==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastmodified": "2026-02-07T22:27:15Z",
|
||||||
|
"mac": "ENC[AES256_GCM,data:51vWvevuX1A2mYC6HBRmL+qgJ0Bbvi1XEfl4km/LUGzOj2weSPvV+r/UJsIOVdkOr04On0YD58JXGDQMTWyV6FaaRdng7MgM4ffg5mnLLv3sPtqwaJJNT+7pqDfVc43qixbCHL+89nq2IPBrqNwVhHxm/WlE27K+7GA+JMtKmiQ=,iv:cseRzqtJgjVkNqdZplpmIaexfmOkKm0kieE1J2KSfLw=,tag:mhKzS0NNguygaHL4jdIpmg==,type:str]",
|
||||||
|
"unencrypted_suffix": "_unencrypted",
|
||||||
|
"version": "3.11.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
25
nix-system-configs/secrets/database/secrets.yaml
Normal file
25
nix-system-configs/secrets/database/secrets.yaml
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue