This commit is contained in:
nora 2025-08-03 16:37:18 +02:00
parent beb86b7ea9
commit a4e5e3720b
12 changed files with 134 additions and 176 deletions

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>nora's server</title>
</head>
<body>
<h1>congrats, you landed on my server (0% NixOS) directly!?</h1>
<p>sorry, but there isn't anything cool here. this is <b>my</b> infra, you are not allowed here.</p>
<p>if you do want to be allowed here, then uh.. still no.</p>
<p>:3</p>
</body>
</html>

View file

@ -1,7 +1,7 @@
{ pkgs, lib, does-it-build, my-projects-versions, ... }: { pkgs, lib, my-projects-versions, ... }:
let let
does-it-build-base = does-it-build { inherit pkgs; }; does-it-build-base = (import (fetchTarball "https://github.com/Noratrieb/does-it-build/archive/${my-projects-versions.does-it-build}.tar.gz")) { inherit pkgs; };
does-it-build-with-commit = does-it-build-base.overrideAttrs (finalAttrs: previousAttrs: { does-it-build = does-it-build-base.overrideAttrs (finalAttrs: previousAttrs: {
DOES_IT_BUILD_OVERRIDE_VERSION = my-projects-versions.does-it-build; DOES_IT_BUILD_OVERRIDE_VERSION = my-projects-versions.does-it-build;
}); });
in in
@ -15,7 +15,7 @@ in
serviceConfig = { serviceConfig = {
User = "does-it-build"; User = "does-it-build";
Group = "does-it-build"; Group = "does-it-build";
ExecStart = "${lib.getExe' (does-it-build-with-commit) "does-it-build" }"; ExecStart = "${lib.getExe' (does-it-build) "does-it-build" }";
Environment = "DB_PATH=/var/lib/does-it-build/db.sqlite"; Environment = "DB_PATH=/var/lib/does-it-build/db.sqlite";
}; };
}; };

View file

@ -0,0 +1,29 @@
{ lib, pkgs, my-projects-versions, ... }:
let cluelessh = import (fetchTarball "https://github.com/Noratrieb/cluelessh/archive/${my-projects-versions.cluelessh}.tar.gz");
in
{
systemd.services.fakessh = {
description = "cluelessh-faked ssh honeypot";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Restart = "on-failure";
RestartSec = "5s";
ExecStart = "${lib.getExe' (cluelessh {inherit pkgs;}) "cluelessh-faked" }";
# i really don't trust this.
DynamicUser = true;
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
MemoryHigh = "100M";
MemoryMax = "200M";
# config
Environment = [
"FAKESSH_LISTEN_ADDR=0.0.0.0:22"
"RUST_LOG=debug"
#"FAKESSH_JSON_LOGS=1"
];
};
};
networking.firewall.allowedTCPPorts = [ 22 ];
}

View file

@ -1,4 +1,6 @@
{ upload-files, pkgs, lib, config, ... }: { { my-projects-versions, pkgs, lib, config, ... }:
let upload-files = import (fetchTarball "https://github.com/Noratrieb/upload.files.noratrieb.dev/archive/${my-projects-versions."upload.files.noratrieb.dev"}.tar.gz"); in
{
age.secrets.upload_files_s3_secret.file = ../../secrets/upload_files_s3_secret.age; age.secrets.upload_files_s3_secret.file = ../../secrets/upload_files_s3_secret.age;
systemd.services.upload-files = { systemd.services.upload-files = {

View file

@ -1,7 +1,6 @@
{ {
meta = meta =
let let
my-projects-versions = builtins.fromJSON (builtins.readFile ./my-projects.json);
nixpkgs-version = builtins.fromJSON (builtins.readFile ./nixpkgs.json); nixpkgs-version = builtins.fromJSON (builtins.readFile ./nixpkgs.json);
nixpkgs-path = (fetchTarball "https://github.com/NixOS/nixpkgs/archive/${nixpkgs-version.commit}.tar.gz"); nixpkgs-path = (fetchTarball "https://github.com/NixOS/nixpkgs/archive/${nixpkgs-version.commit}.tar.gz");
in in
@ -14,15 +13,7 @@
nixpkgs = import nixpkgs-path; nixpkgs = import nixpkgs-path;
specialArgs = { specialArgs = {
website = import (fetchTarball "https://github.com/Noratrieb/website/archive/${my-projects-versions.website}.tar.gz"); my-projects-versions = builtins.fromJSON (builtins.readFile ./my-projects.json);
blog = fetchTarball "https://github.com/Noratrieb/blog/archive/${my-projects-versions.blog}.tar.gz";
slides = fetchTarball "https://github.com/Noratrieb/slides/archive/${my-projects-versions.slides}.tar.gz";
pretense = import (fetchTarball "https://github.com/Noratrieb/pretense/archive/${my-projects-versions.pretense}.tar.gz");
quotdd = import (fetchTarball "https://github.com/Noratrieb/quotdd/archive/${my-projects-versions.quotdd}.tar.gz");
does-it-build = import (fetchTarball "https://github.com/Noratrieb/does-it-build/archive/${my-projects-versions.does-it-build}.tar.gz");
upload-files = import (fetchTarball "https://github.com/Noratrieb/upload.files.noratrieb.dev/archive/${my-projects-versions."upload.files.noratrieb.dev"}.tar.gz");
inherit my-projects-versions;
inherit nixpkgs-path; inherit nixpkgs-path;
@ -35,6 +26,7 @@
publicKey = "7jy2q93xYBHG5yKqLmNuMWSuFMnUGWXVuKQ1yMmxoV4="; publicKey = "7jy2q93xYBHG5yKqLmNuMWSuFMnUGWXVuKQ1yMmxoV4=";
peers = [ "vps3" ]; peers = [ "vps3" ];
}; };
tags = [ "dns" ];
}; };
dns2 = { dns2 = {
publicIPv4 = "128.140.3.7"; publicIPv4 = "128.140.3.7";
@ -46,6 +38,7 @@
publicKey = "yfOc/q5M+2DWPoZ4ZgwrTYYkviQxGxRWpcBCDcauDnc="; publicKey = "yfOc/q5M+2DWPoZ4ZgwrTYYkviQxGxRWpcBCDcauDnc=";
peers = [ "vps3" ]; peers = [ "vps3" ];
}; };
tags = [ "dns" ];
}; };
vps1 = { vps1 = {
publicIPv4 = "161.97.165.1"; publicIPv4 = "161.97.165.1";
@ -55,6 +48,7 @@
publicKey = "5tg3w/TiCuCeKIBJCd6lHUeNjGEA76abT1OXnhNVyFQ="; publicKey = "5tg3w/TiCuCeKIBJCd6lHUeNjGEA76abT1OXnhNVyFQ=";
peers = [ "vps2" "vps3" "vps4" "vps5" ]; peers = [ "vps2" "vps3" "vps4" "vps5" ];
}; };
tags = [ "apps" ];
}; };
vps2 = { vps2 = {
publicIPv4 = "184.174.32.252"; publicIPv4 = "184.174.32.252";
@ -64,6 +58,7 @@
publicKey = "SficHHJ0ynpZoGah5heBpNKnEVIVrgs72Z5HEKd3jHA="; publicKey = "SficHHJ0ynpZoGah5heBpNKnEVIVrgs72Z5HEKd3jHA=";
peers = [ "vps1" "vps3" "vps4" "vps5" ]; peers = [ "vps1" "vps3" "vps4" "vps5" ];
}; };
tags = [ "apps" ];
}; };
vps3 = { vps3 = {
publicIPv4 = "134.255.181.139"; publicIPv4 = "134.255.181.139";
@ -73,6 +68,7 @@
publicKey = "pdUxG1vhmYraKzIIEFxTRAMhGwGztBL/Ly5icJUV3g0="; publicKey = "pdUxG1vhmYraKzIIEFxTRAMhGwGztBL/Ly5icJUV3g0=";
peers = [ "vps1" "vps2" "vps4" "vps5" "dns1" "dns2" ]; peers = [ "vps1" "vps2" "vps4" "vps5" "dns1" "dns2" ];
}; };
tags = [ "apps" ];
}; };
vps4 = { vps4 = {
publicIPv4 = "195.201.147.17"; publicIPv4 = "195.201.147.17";
@ -84,6 +80,7 @@
publicKey = "+n2XKKaSFdCanEGRd41cvnuwJ0URY0HsnpBl6ZrSBRs="; publicKey = "+n2XKKaSFdCanEGRd41cvnuwJ0URY0HsnpBl6ZrSBRs=";
peers = [ "vps1" "vps2" "vps3" "vps5" ]; peers = [ "vps1" "vps2" "vps3" "vps5" ];
}; };
tags = [ "apps" ];
}; };
vps5 = { vps5 = {
publicIPv4 = "45.94.209.30"; publicIPv4 = "45.94.209.30";
@ -93,6 +90,7 @@
publicKey = "r1cwt63fcOR+FTqMTUpZdK4/MxpalkDYRHXyy7osWUk="; publicKey = "r1cwt63fcOR+FTqMTUpZdK4/MxpalkDYRHXyy7osWUk=";
peers = [ "vps1" "vps2" "vps3" "vps4" ]; peers = [ "vps1" "vps2" "vps3" "vps4" ];
}; };
tags = [ "apps" ];
}; };
}; };
}; };
@ -120,9 +118,6 @@
./modules/wg-mesh ./modules/wg-mesh
]; ];
# The name and nodes parameters are supported in Colmena,
# allowing you to reference configurations in other nodes.
deployment.tags = [ "dns" "us" ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
}; };
dns2 = { name, nodes, modulesPath, lib, ... }: { dns2 = { name, nodes, modulesPath, lib, ... }: {
@ -132,7 +127,6 @@
./modules/wg-mesh ./modules/wg-mesh
]; ];
deployment.tags = [ "dns" "eu" "hetzner" ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
boot.loader.grub.device = "/dev/sda"; boot.loader.grub.device = "/dev/sda";
@ -196,7 +190,6 @@
./apps/upload-files ./apps/upload-files
]; ];
deployment.tags = [ "caddy" "eu" "apps" "website" ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
}; };
# VPS2 exists # VPS2 exists
@ -209,7 +202,6 @@
./modules/garage ./modules/garage
]; ];
deployment.tags = [ "caddy" "eu" "apps" ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
}; };
# VPS3 is the primary monitoring/metrics server. # VPS3 is the primary monitoring/metrics server.
@ -223,7 +215,6 @@
./modules/prometheus ./modules/prometheus
]; ];
deployment.tags = [ "eu" "apps" "website" ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
}; };
# VPS4 exists. It's useful for garage replication and runs does-it-build which uses some CPU. # VPS4 exists. It's useful for garage replication and runs does-it-build which uses some CPU.
@ -239,7 +230,6 @@
./apps/does-it-build ./apps/does-it-build
]; ];
deployment.tags = [ "eu" "apps" "hetzner" "website" ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
boot.loader.grub.device = "/dev/sda"; boot.loader.grub.device = "/dev/sda";
@ -282,10 +272,6 @@
}; };
# VPS5 is the primary test server, where new things are being deployed that could break stuff maybe. # VPS5 is the primary test server, where new things are being deployed that could break stuff maybe.
vps5 = { name, nodes, modulesPath, config, pkgs, lib, ... }: vps5 = { name, nodes, modulesPath, config, pkgs, lib, ... }:
let
commit = "5f203d0f5ba2639043bd5bd1c3687c406d6abac1";
cluelessh = import (fetchTarball "https://github.com/Noratrieb/cluelessh/archive/${commit}.tar.gz");
in
{ {
imports = [ imports = [
(modulesPath + "/profiles/qemu-guest.nix") (modulesPath + "/profiles/qemu-guest.nix")
@ -293,37 +279,12 @@
./modules/caddy ./modules/caddy
./modules/wg-mesh ./modules/wg-mesh
./modules/garage ./modules/garage
./apps/fakessh
]; ];
services.openssh.ports = [ 2000 ]; services.openssh.ports = [ 2000 ];
systemd.services.fakessh = {
description = "cluelessh-faked ssh honeypot";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Restart = "on-failure";
RestartSec = "5s";
ExecStart = "${lib.getExe' (cluelessh {inherit pkgs;}) "cluelessh-faked" }";
# i really don't trust this.
DynamicUser = true;
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
MemoryHigh = "100M";
MemoryMax = "200M";
# config
Environment = [
"FAKESSH_LISTEN_ADDR=0.0.0.0:22"
"RUST_LOG=debug"
#"FAKESSH_JSON_LOGS=1"
];
};
};
networking.firewall.allowedTCPPorts = [ 22 ];
deployment.targetPort = 2000; deployment.targetPort = 2000;
deployment.tags = [ "eu" "apps" ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
}; };
} }

View file

@ -1,4 +1,4 @@
{ pkgs, config, lib, name, website, slides, blog, ... }: { pkgs, config, lib, name, my-projects-versions, ... }:
let let
caddy = pkgs.callPackage ./caddy-build.nix { caddy = pkgs.callPackage ./caddy-build.nix {
@ -11,6 +11,10 @@ let
]; ];
vendorHash = "sha256-KP9bYitM/Pocw4DxOXPVBigWh4IykNf8yKJiBlTFZmI="; vendorHash = "sha256-KP9bYitM/Pocw4DxOXPVBigWh4IykNf8yKJiBlTFZmI=";
}; };
website = import (fetchTarball "https://github.com/Noratrieb/website/archive/${my-projects-versions.website}.tar.gz");
blog = fetchTarball "https://github.com/Noratrieb/blog/archive/${my-projects-versions.blog}.tar.gz";
slides = fetchTarball "https://github.com/Noratrieb/slides/archive/${my-projects-versions.slides}.tar.gz";
website-build = website { inherit pkgs slides blog; };
in in
{ {
environment.systemPackages = [ caddy ]; environment.systemPackages = [ caddy ];
@ -62,7 +66,7 @@ in
header -Last-Modified header -Last-Modified
root * ${import ./caddy-static-prepare { root * ${import ./caddy-static-prepare {
name = "website"; name = "website";
src = website { inherit pkgs slides blog; }; src = website-build;
inherit pkgs lib; inherit pkgs lib;
}} }}
file_server { file_server {

View file

@ -1,5 +1,10 @@
{ pkgs, lib, config, name, pretense, quotdd, nixpkgs-path, ... }: { { pkgs, lib, name, my-projects-versions, networkingConfig, nixpkgs-path, ... }:
deployment.targetHost = "${config.networking.hostName}.infra.noratrieb.dev"; let
pretense = import (fetchTarball "https://github.com/Noratrieb/pretense/archive/${my-projects-versions.pretense}.tar.gz");
quotdd = import (fetchTarball "https://github.com/Noratrieb/quotdd/archive/${my-projects-versions.quotdd}.tar.gz");
in
{
deployment.targetHost = "${name}.infra.noratrieb.dev";
imports = [ imports = [
"${builtins.fetchTarball "https://github.com/ryantm/agenix/archive/de96bd907d5fbc3b14fc33ad37d1b9a3cb15edc6.tar.gz"}/modules/age.nix" # main 2024-07-26 "${builtins.fetchTarball "https://github.com/ryantm/agenix/archive/de96bd907d5fbc3b14fc33ad37d1b9a3cb15edc6.tar.gz"}/modules/age.nix" # main 2024-07-26
@ -107,7 +112,7 @@
}; };
services.cadvisor = { services.cadvisor = {
enable = true; enable = true;
listenAddress = "0.0.0.0"; # todo: $wg-ip listenAddress = "0.0.0.0";
}; };
services.promtail = { services.promtail = {
enable = true; enable = true;
@ -169,4 +174,6 @@
]; ];
}; };
}; };
deployment.tags = networkingConfig."${name}".tags;
} }

View file

@ -1,4 +1,6 @@
{ pkgs, lib, networkingConfig, ... }: { { pkgs, lib, networkingConfig, ... }:
let metricsPort = 9433; in
{
# get the package for the debugging tools # get the package for the debugging tools
environment.systemPackages = with pkgs; [ knot-dns ]; environment.systemPackages = with pkgs; [ knot-dns ];
@ -40,9 +42,9 @@
}; };
}; };
networking.firewall.interfaces.wg0.allowedTCPPorts = [ 9433 ]; # metrics networking.firewall.interfaces.wg0.allowedTCPPorts = [ metricsPort ];
services.prometheus.exporters.knot = { services.prometheus.exporters.knot = {
enable = true; enable = true;
port = 9433; port = metricsPort;
}; };
} }

View file

@ -1,4 +1,9 @@
{ config, pkgs, name, ... }: { { config, pkgs, name, ... }:
let
rpcPort = 3901;
adminPort = 3903;
in
{
age.secrets.garage_secrets.file = ../../secrets/garage_secrets.age; age.secrets.garage_secrets.file = ../../secrets/garage_secrets.age;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
@ -6,8 +11,8 @@
]; ];
networking.firewall.interfaces.wg0.allowedTCPPorts = [ networking.firewall.interfaces.wg0.allowedTCPPorts = [
3901 # RPC rpcPort
3903 # admin for metrics adminPort
]; ];
services.garage = { services.garage = {
@ -24,8 +29,8 @@
# arbitrary, but a bit higher as disk space matters more than time. she says, cluelessly. # arbitrary, but a bit higher as disk space matters more than time. she says, cluelessly.
compression-level = 5; compression-level = 5;
rpc_bind_addr = "[::]:3901"; rpc_bind_addr = "[::]:${toString rpcPort}";
rpc_public_addr = "${name}.local:3901"; rpc_public_addr = "${name}.local:${toString rpcPort}";
s3_api = { s3_api = {
s3_region = "garage"; s3_region = "garage";
@ -40,7 +45,7 @@
}; };
admin = { admin = {
api_bind_addr = "[::]:3903"; api_bind_addr = "[::]:${toString adminPort}";
}; };
}; };
environmentFile = config.age.secrets.garage_secrets.path; environmentFile = config.age.secrets.garage_secrets.path;

View file

@ -1,96 +1,52 @@
{ config, lib, ... }: { { config, lib, networkingConfig, ... }: {
services.prometheus = { services.prometheus = {
enable = true; enable = true;
globalConfig = { }; globalConfig = { };
scrapeConfigs = [ scrapeConfigs =
{ let hostsWithTag = tag: map (entry: entry.name) (builtins.filter (entry: builtins.elem tag entry.value.tags) (lib.attrsToList networkingConfig)); in
job_name = "prometheus"; [
static_configs = [ {
{ targets = [ "localhost:9090" ]; } job_name = "prometheus";
]; static_configs = [
} { targets = [ "localhost:9090" ]; }
{ ];
job_name = "node"; }
static_configs = [ {
{ targets = [ "dns1.local:9100" ]; } job_name = "node";
{ targets = [ "dns2.local:9100" ]; } static_configs = [{ targets = map (name: "${name}.local:9100") (builtins.attrNames networkingConfig); }];
{ targets = [ "vps1.local:9100" ]; } }
{ targets = [ "vps2.local:9100" ]; } {
{ targets = [ "vps3.local:9100" ]; } job_name = "cadvisor";
{ targets = [ "vps4.local:9100" ]; } static_configs = [{ targets = map (name: "${name}.local:8080") (builtins.attrNames networkingConfig); }];
{ targets = [ "vps5.local:9100" ]; }
]; }
} {
{ job_name = "systemd";
job_name = "cadvisor"; static_configs = [{ targets = map (name: "${name}.local:9558") (builtins.attrNames networkingConfig); }];
static_configs = [ }
{ targets = [ "dns1.local:8080" ]; } {
{ targets = [ "dns2.local:8080" ]; } job_name = "caddy";
{ targets = [ "vps1.local:8080" ]; } static_configs = [{ targets = map (name: "${name}.local:9010") (hostsWithTag "apps"); }];
{ targets = [ "vps2.local:8080" ]; } }
{ targets = [ "vps3.local:8080" ]; } {
{ targets = [ "vps4.local:8080" ]; } job_name = "docker-registry";
{ targets = [ "vps5.local:8080" ]; } static_configs = [
]; { targets = [ "vps1.local:9011" ]; }
} ];
{ }
job_name = "systemd"; {
static_configs = [ job_name = "garage";
{ targets = [ "dns1.local:9558" ]; } static_configs = [{ targets = map (name: "${name}.local:3903") (hostsWithTag "apps"); }];
{ targets = [ "dns2.local:9558" ]; } }
{ targets = [ "vps1.local:9558" ]; } {
{ targets = [ "vps2.local:9558" ]; } job_name = "knot";
{ targets = [ "vps3.local:9558" ]; } static_configs = [{ targets = map (name: "${name}.local:9433") (hostsWithTag "dns"); }];
{ targets = [ "vps4.local:9558" ]; } }
{ targets = [ "vps5.local:9558" ]; } {
]; job_name = "pretense";
} static_configs = [{ targets = map (name: "${name}.local:9150") (builtins.attrNames networkingConfig); }];
{ }
job_name = "caddy"; ];
static_configs = [
{ targets = [ "vps1.local:9010" ]; }
{ targets = [ "vps2.local:9010" ]; }
{ targets = [ "vps3.local:9010" ]; }
{ targets = [ "vps4.local:9010" ]; }
{ targets = [ "vps5.local:9010" ]; }
];
}
{
job_name = "docker-registry";
static_configs = [
{ targets = [ "vps1.local:9011" ]; }
];
}
{
job_name = "garage";
static_configs = [
{ targets = [ "vps1.local:3903" ]; }
{ targets = [ "vps2.local:3903" ]; }
{ targets = [ "vps3.local:3903" ]; }
{ targets = [ "vps4.local:3903" ]; }
{ targets = [ "vps5.local:3903" ]; }
];
}
{
job_name = "knot";
static_configs = [
{ targets = [ "dns1.local:9433" ]; }
{ targets = [ "dns2.local:9433" ]; }
];
}
{
job_name = "pretense";
static_configs = [
{ targets = [ "dns1.local:9150" ]; }
{ targets = [ "dns2.local:9150" ]; }
{ targets = [ "vps1.local:9150" ]; }
{ targets = [ "vps2.local:9150" ]; }
{ targets = [ "vps3.local:9150" ]; }
{ targets = [ "vps4.local:9150" ]; }
{ targets = [ "vps5.local:9150" ]; }
];
}
];
}; };
age.secrets.grafana_admin_password.file = ../../secrets/grafana_admin_password.age; age.secrets.grafana_admin_password.file = ../../secrets/grafana_admin_password.age;
@ -132,7 +88,7 @@
}; };
}; };
networking.firewall.interfaces.wg0.allowedTCPPorts = [ 3100 ]; # loki networking.firewall.interfaces.wg0.allowedTCPPorts = [ config.services.loki.configuration.server.http_listen_port ];
age.secrets.loki_env.file = ../../secrets/loki_env.age; age.secrets.loki_env.file = ../../secrets/loki_env.age;
systemd.services.loki.serviceConfig.EnvironmentFile = config.age.secrets.loki_env.path; systemd.services.loki.serviceConfig.EnvironmentFile = config.age.secrets.loki_env.path;
services.loki = { services.loki = {

View file

@ -10,9 +10,14 @@
}; };
}; };
networking.firewall.interfaces.wg0.allowedTCPPorts = [ 9011 ]; # metrics networking.firewall.interfaces.wg0.allowedTCPPorts = [ 9011 ];
systemd.services.docker-registry.serviceConfig.EnvironmentFile = config.age.secrets.registry_s3_key_secret.path; systemd.services.docker-registry = {
serviceConfig.EnvironmentFile = config.age.secrets.registry_s3_key_secret.path;
environment = {
OTEL_TRACES_EXPORTER = "none";
};
};
services.dockerRegistry = { services.dockerRegistry = {
enable = true; enable = true;
storagePath = null; storagePath = null;

View file

@ -5,5 +5,6 @@
"pretense": "270b01fc1118dfd713c1c41530d1a7d98f04527d", "pretense": "270b01fc1118dfd713c1c41530d1a7d98f04527d",
"quotdd": "e922229e1d9e055be35dabd112bafc87a0686548", "quotdd": "e922229e1d9e055be35dabd112bafc87a0686548",
"does-it-build": "81790825173d87f89656f66f12a123bc99e2f6f1", "does-it-build": "81790825173d87f89656f66f12a123bc99e2f6f1",
"upload.files.noratrieb.dev": "0124fa5ba5446cb463fb6b3c4f52e7e6b84e5077" "upload.files.noratrieb.dev": "0124fa5ba5446cb463fb6b3c4f52e7e6b84e5077",
"cluelessh": "5f203d0f5ba2639043bd5bd1c3687c406d6abac1"
} }