feat: refactor the modules/servers directory.

This commit is contained in:
CronyAkatsuki 2026-01-19 21:36:24 +01:00
parent 4e783c052b
commit 8b754d3a7e
69 changed files with 61 additions and 62 deletions

View file

@ -0,0 +1,15 @@
{...}: let
servicesDir = ./services;
serviceFiles =
builtins.filter
(name: builtins.match "^.*\\.nix$" name != null)
(builtins.attrNames (builtins.readDir servicesDir));
hostModules = map (fn: import "${servicesDir}/${fn}") serviceFiles;
in {
imports =
[
../../common
./secrets.nix
]
++ hostModules;
}

View file

@ -0,0 +1,12 @@
{
age = {
secrets = {
searx = {
file = ../../../../secrets/searx.age;
};
miniflux = {
file = ../../../../secrets/miniflux.age;
};
};
};
}

View file

@ -0,0 +1,27 @@
{
services.filebrowser = {
enable = true;
};
services.traefik.dynamicConfigOptions.http = {
services.filebrowser.loadBalancer.servers = [
{
url = "http://localhost:8080";
}
];
routers.filebrowser = {
rule = "Host(`filebrowser.cronyakatsuki.xyz`)";
tls = {
certResolver = "porkbun";
};
service = "filebrowser";
entrypoints = "websecure";
};
};
services.restic.backups = {
local.paths = ["/var/lib/filebrowser"];
server.paths = ["/var/lib/filebrowser"];
};
}

View file

@ -0,0 +1,38 @@
{config, ...}: {
services.miniflux = {
enable = true;
config = {
LISTEN_ADDR = "127.0.0.1:8000";
BASE_URL = "https://feed.cronyakatsuki.xyz";
FETCH_YOUTUBE_WATCH_TIME = "1";
};
adminCredentialsFile = "${config.age.secrets.miniflux.path}";
};
services.traefik.dynamicConfigOptions.http = {
services.miniflux.loadBalancer.servers = [
{
url = "http://localhost:8000";
}
];
routers.miniflux = {
rule = "Host(`feed.cronyakatsuki.xyz`)";
tls = {
certResolver = "porkbun";
};
service = "miniflux";
entrypoints = "websecure";
};
};
services.postgresqlBackup = {
enable = true;
databases = ["miniflux"];
};
services.restic.backups = {
local.paths = ["/var/backup/postgresql"];
server.paths = ["/var/backup/postgresql"];
};
}

View file

@ -0,0 +1,34 @@
{config, ...}: {
services.searx = {
enable = true;
settings = {
general.instance_name = "Crony's SearXNG";
server.port = "8090";
server.bind_address = "127.0.0.1";
server.secret_key = "@SEARX_SECRET_KEY@";
};
uwsgiConfig = {
http = ":8090";
};
redisCreateLocally = true;
configureUwsgi = true;
environmentFile = "${config.age.secrets.searx.path}";
};
services.traefik.dynamicConfigOptions.http = {
services.searx.loadBalancer.servers = [
{
url = "http://localhost:8090";
}
];
routers.searx = {
rule = "Host(`searx.cronyakatsuki.xyz`)";
tls = {
certResolver = "porkbun";
};
service = "searx";
entrypoints = "websecure";
};
};
}

View file

@ -0,0 +1,37 @@
{...}: {
virtualisation.oci-containers.containers.syncyomi = {
image = "ghcr.io/syncyomi/syncyomi:latest";
autoStart = true;
ports = [
"8282:8282"
];
labels = {
"io.containers.autoupdate" = "registry";
};
volumes = [
"/var/lib/syncyomi:/config"
];
};
services.traefik.dynamicConfigOptions.http = {
services.syncyomi.loadBalancer.servers = [
{
url = "http://localhost:8282";
}
];
routers.syncyomi = {
rule = "Host(`syncyomi.cronyakatsuki.xyz`)";
tls = {
certResolver = "porkbun";
};
service = "syncyomi";
entrypoints = "websecure";
};
};
services.restic.backups = {
local.paths = ["/var/lib/syncyomi"];
server.paths = ["/var/lib/syncyomi"];
};
}

View file

@ -0,0 +1,47 @@
instance="http://127.0.0.1:8383"
files=$(curl -s "$instance"/files/)
# Check for keygens on server
if echo "$files" | grep -i "keygen" >> /dev/null; then
for file in $(echo "$files" | grep -i "keygen"); do
echo "Deleting file $file"
curl -X DELETE "$instance/files/$file"
done
fi
# Check for common payload names on server
if echo "$files" | grep -iE "dorpxy|mner|mnpxy" >> /dev/null; then
for file in $(echo "$files" | grep -iE "dorpxy|mner|mnpxy"); do
echo "Deleting file $file"
curl -X DELETE "$instance/files/$file"
done
fi
# Delete common php payloads
if echo "$files" | grep -i ".php" >> /dev/null; then
for file in $(echo "$files" | grep -i ".php"); do
if curl -s "$instance/files/$file" | grep -i "base64_decode" >> /dev/null; then
echo "Found payload, deleting file $file"
curl -X DELETE "$instance/files/$file"
fi
done
fi
# Delete all shell scripts that make direct mention of my upfast instance
if echo "$files" | grep -i ".sh" >> /dev/null; then
for file in $(echo "$files" | grep -i ".sh"); do
if curl -s "$instance/files/$file" | grep -i "upfast.cronyakatsuki.xyz/files" >> /dev/null; then
echo "Found payload, deleting file $file"
curl -X DELETE "$instance/files/$file"
fi
done
fi
# Delete kernel object files
if echo "$files" | grep -iE ".*.ko" >> /dev/null; then
for file in $(echo "$files" | grep -iE ".*.ko"); do
echo "Deleting file $file"
curl -X DELETE "$instance/files/$file"
done
fi

View file

@ -0,0 +1,98 @@
{
inputs,
pkgs,
lib,
...
}: let
upfast-cleaner = pkgs.writeShellApplication {
name = "upfast-cleaner";
runtimeInputs = with pkgs; [curl];
text = ./upfast-cleaner.sh;
};
in {
fileSystems."/var/lib/upfast" = {
device = "/root/10gb";
fsType = "ext4";
options = [
"loop"
"rw"
"usrquota"
"grpquota"
];
};
users = {
users.upfast = {
isSystemUser = true;
home = "/var/lib/upfast";
group = "upfast";
};
groups.upfast = {};
};
systemd.services.upfast = {
enable = true;
description = "SelfHosted file upload and share service like 0x0.st";
serviceConfig = {
Type = "simple";
User = "upfast";
Group = "upfast";
WorkingDirectory = "/var/lib/upfast";
Restart = "on-failure";
};
script = "${inputs.upfast.packages.aarch64-linux.default}/bin/upfast -p 8383 -d https://upfast.cronyakatsuki.xyz";
after = ["var-lib-upfast.mount"];
bindsTo = ["var-lib-upfast.mount"];
wantedBy = ["multi-user.target"];
};
systemd.services.upfast-cleaner = {
description = "Script to automatically delete common types of payloads/keygens.";
requires = ["upfast.service"];
after = ["upfast.service"];
serviceConfig = {
Type = "oneshot";
User = "upfast";
Group = "upfast";
WorkingDirectory = "/var/lib/upfast";
};
script = "${lib.getExe upfast-cleaner}";
};
systemd.timers.upfast-cleaner = {
enable = true;
timerConfig = {
OnBootSec = "1m";
OnUnitActiveSec = "1m";
};
wantedBy = ["timers.target"];
};
services.traefik.dynamicConfigOptions.http = {
services.upfast.loadBalancer.servers = [
{
url = "http://localhost:8383";
}
];
routers.upfast = {
rule = "Host(`upfast.cronyakatsuki.xyz`)";
tls = {
certResolver = "porkbun";
};
service = "upfast";
entrypoints = "websecure";
};
};
services.restic.backups = {
local.paths = ["/var/lib/upfast"];
server.paths = ["/var/lib/upfast"];
};
}

View file

@ -0,0 +1,41 @@
{...}: {
virtualisation.oci-containers.containers.wallabag = {
image = "docker.io/wallabag/wallabag:latest";
autoStart = true;
ports = [
"8181:80"
];
environment = {
"SYMFONY__ENV__DOMAIN_NAME" = "https://wallabag.cronyakatsuki.xyz";
};
labels = {
"io.containers.autoupdate" = "registry";
};
volumes = [
"/var/lib/wallabag/data:/var/www/wallabag/data"
"/var/lib/wallabag/images:/var/www/wallabag/web/assets/images"
];
};
services.traefik.dynamicConfigOptions.http = {
services.wallabag.loadBalancer.servers = [
{
url = "http://localhost:8181";
}
];
routers.wallabag = {
rule = "Host(`wallabag.cronyakatsuki.xyz`)";
tls = {
certResolver = "porkbun";
};
service = "wallabag";
entrypoints = "websecure";
};
};
services.restic.backups = {
local.paths = ["/var/lib/wallabag"];
server.paths = ["/var/lib/wallabag"];
};
}

View file

@ -0,0 +1,32 @@
{...}: {
virtualisation.oci-containers.containers.website = {
image = "docker.io/nginx:alpine";
autoStart = true;
ports = [
"8001:80"
];
labels = {
"io.containers.autoupdate" = "registry";
};
volumes = [
"/var/lib/website:/usr/share/nginx/html:ro"
];
};
services.traefik.dynamicConfigOptions.http = {
services.website.loadBalancer.servers = [
{
url = "http://localhost:8001";
}
];
routers.website = {
rule = "Host(`cronyakatsuki.xyz`)";
tls = {
certResolver = "porkbun";
};
service = "website";
entrypoints = "websecure";
};
};
}