more renaming + some new software

This commit is contained in:
xunuwu 2024-10-26 13:14:03 +02:00
parent d94b4723d4
commit 02738e65ab
Signed by: xun
SSH key fingerprint: SHA256:Uot/1WoAjWAeqLOHA5vYy4phhVydsH7jCPmBjaPZfgI
27 changed files with 42 additions and 16 deletions

View file

@ -1,150 +0,0 @@
{
pkgs,
lib,
config,
...
}: {
networking.firewall.allowedTCPPorts = [
# 4444
];
systemd.services."static-web-server".after = ["brawlstats.timer"];
services.static-web-server = {
enable = true;
root = "/var/lib/brawlstats";
listen = "[::]:3434";
};
systemd.sockets."brawlstats-web" = {
wantedBy = ["sockets.target"];
socketConfig = {
ListenStream = "4444";
TriggerLimitIntervalSec = 0;
Accept = "yes";
};
};
systemd.services."brawlstats-web@" = {
serviceConfig = {
StandardInput = "socket";
ExecStart = "${pkgs.writeShellScript "brawlstats-web.sh" ''
parameters=$(head -n1 | ${lib.getExe pkgs.gawk} '{print $2}' | ${lib.getExe pkgs.gnused} 's/,/ /g')
response=""
tosvg() {
${lib.getExe pkgs.gnuplot} -c ${pkgs.writeText "gnuplotcmds" ''
set xdata time
set timefmt '%Y%m%dT%H%M%S.000Z'
set format x '%m/%d-%H:%M'
set xlabel 'Time'
set ylabel 'Trophies'
set term svg
plot "/dev/stdin" u 1:2 w lines notitle
''}
}
rm /tmp/brawlstatslog
case ''${parameters:1} in
total*)
id=$(echo $parameters | ${lib.getExe pkgs.gawk} '{print $2}')
trophies=$(cat "/var/lib/brawlstats/$id-player.json" | ${lib.getExe pkgs.jq} '.trophies')
response=$(${lib.getExe pkgs.jq} -r \
"sort_by(.battleTime)
| reverse | .[]
| .battleTime, .battle.trophyChange" "/var/lib/brawlstats/$id-log.json" \
| paste - - \
| ${lib.getExe pkgs.gawk} -v total=$trophies '{total -= $2; $2 = total}2' \
| tosvg)
;;
brawler*)
id=$(echo $parameters | ${lib.getExe pkgs.gawk} '{print $2}')
brawler=$(echo $parameters | ${lib.getExe pkgs.gawk} '{print $3}' | ${lib.getExe pkgs.gnused} 's/%20/ /g')
response=$(${lib.getExe pkgs.jq} -r \
"sort_by(.battleTime)
| reverse
| map (select (.. | .tag? == \"#$id\" and .brawler.name == \"$brawler\")).[]
| select (.battle.type == \"ranked\")
| .battleTime,
(.battle | (.teams[]?,.players) | select(.)[] | select(.tag == \"#$id\") | .brawler.trophies) + .battle.trophyChange" "/var/lib/brawlstats/$id-log.json" \
| paste - - \
| tosvg)
;;
*)
response="parameters: $parameters | firstparam: $(echo "$parameters" | ${lib.getExe pkgs.gawk} '{print $1}')"
;;
esac
echo -e "HTTP/1.1 200 OK\r\nContent-Length: $(echo "$response" | wc -c)\r\nContent-Type: text/html\r\n\r\n$response"
''}";
};
};
systemd.timers."brawlstats" = {
wantedBy = ["timers.target"];
timerConfig = {
OnCalendar = "*:0/30";
Unit = "brawlstats.service";
};
};
systemd.services."brawlstats" = {
serviceConfig = {
Type = "oneshot";
User = "root";
StateDirectory = "brawlstats";
PrivateTmp = true;
LoadCredential = "apitoken:${config.sops.secrets.brawlstars-api-key.path}";
Environment = "TOKEN=%d/apitoken";
ExecStart = pkgs.writers.writeBash "brawlstats.sh" ''
TOKEN=$(cat $TOKEN)
cd "$STATE_DIRECTORY"
ids=("VLJY22GY" "VLJV2CYL")
for id in ''${ids[@]}; do
echo "id: $id"
sleep 1
battlelogout=$(mktemp)
${lib.getExe pkgs.curl} -H "Authorization: Bearer $TOKEN" "https://api.brawlstars.com/v1/players/%23$id/battlelog" | ${lib.getExe pkgs.jq} '[.items[]]' > "$battlelogout"
sleep 1
${lib.getExe pkgs.curl} -H "Authorization: Bearer $TOKEN" "https://api.brawlstars.com/v1/players/%23$id" > "$id-player.json"
if [ ! -s "$battlelogout" ]; then
echo "battlelogout is empty"
rm "$battlelogout"
continue
fi
if [ ! -s "$id-player.json" ]; then
echo "$id-player.json is empty"
continue
fi
tmplog=$(mktemp)
cat "$battlelogout" "$id-log.json" | ${lib.getExe pkgs.jq} -s 'add | unique' > "$tmplog"
cat "$tmplog" > "$id-log.json"
rm -f "$tmplog"
rm -f "$battlelogout"
# create backup
cp "$id-log.json" "$id-log-$(date +'%s').json"
# remove old backups
find . -type f -name "$id-log-*.json" | sort | head -n -5 | xargs -r rm
done
'';
};
};
}

View file

@ -1,20 +0,0 @@
{inputs, ...}: {
imports = with inputs.hardware.nixosModules; [
common-cpu-intel
inputs.vpn-confinement.nixosModules.default
./hardware.nix
./brawlstats.nix
./lab.nix
./hardening.nix
];
networking.hostName = "hopper";
swapDevices = [];
networking.interfaces.eno1.wakeOnLan.enable = true;
system.stateVersion = "23.11";
}

View file

@ -1,5 +0,0 @@
{
fileSystems."/".options = ["noexec"];
fileSystems."/home".options = ["noexec"];
fileSystems."/boot".options = ["noexec"];
}

View file

@ -1,58 +0,0 @@
{config, ...}: {
nixpkgs.hostPlatform.system = "x86_64-linux";
## nvidia gpu
#services.xserver.videoDrivers = ["nvidia"];
#hardware.nvidia = {
# modesetting.enable = true;
# package = config.boot.kernelPackages.nvidiaPackages.stable;
#};
boot = {
blacklistedKernelModules = [
# "xhci_pci" # was causing issues (100% udevd cpu usage)
];
initrd = {
availableKernelModules = [
"ehci_pci"
"ahci"
"usb_storage"
"usbhid"
"sd_mod"
];
kernelModules = [];
};
kernelModules = ["kvm-intel" "wireguard"];
extraModulePackages = [];
loader = {
systemd-boot = {
enable = true;
configurationLimit = 10;
};
efi.canTouchEfiVariables = true;
};
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/1297e638-f2ff-49a2-a362-314ac7eeaabc";
fsType = "btrfs";
options = ["subvol=root" "compress=zstd" "autodefrag" "noatime"];
};
"/home" = {
device = "/dev/disk/by-uuid/1297e638-f2ff-49a2-a362-314ac7eeaabc";
fsType = "btrfs";
options = ["subvol=home" "compress=zstd"];
};
"/nix" = {
device = "/dev/disk/by-uuid/1297e638-f2ff-49a2-a362-314ac7eeaabc";
fsType = "btrfs";
options = ["subvol=nix" "compress=zstd" "noatime"];
};
"/boot" = {
device = "/dev/disk/by-uuid/8D4C-2F05";
fsType = "vfat";
};
};
}

View file

@ -1,305 +0,0 @@
## TODO look into sops-nix placeholders
## reference: https://github.com/javigomezo/nixos/blob/b3ebe8d570ea9b37aea8bb3a343f6e16e054e322/services/network/authelia/user_database.nix
{
pkgs,
inputs,
config,
lib,
...
}: let
domain = "xunuwu.xyz";
caddyPort = 8336;
autheliaPort = 24637;
in {
## TODO use impermanence
## TODO setup fail2ban mayb
imports = [inputs.vpn-confinement.nixosModules.default];
security.acme = {
acceptTerms = true;
certs.${domain} = {
domain = "*.${domain}";
dnsProvider = "cloudflare";
email = "xunuwu@gmail.com";
reloadServices = ["caddy.service"];
credentialFiles.CF_DNS_API_TOKEN_FILE = config.sops.secrets.cloudflare.path;
extraDomainNames = [domain];
};
};
vpnNamespaces."wg" = {
enable = true;
wireguardConfigFile = config.sops.secrets.wireguard-config.path;
accessibleFrom = [
"192.168.0.0/24"
];
# Forwarded to my vpn, for making things accessible from outside
openVPNPorts = [
{
port = caddyPort;
protocol = "tcp";
}
];
# From inside of the vpn namespace to outside of it, for making things inside accessible to LAN
portMappings = [
{
to = caddyPort;
from = caddyPort;
}
{
to = 7359; # Jellyfin auto-discovery
from = 7359;
}
{
to = 1900; # Jellyfin auto-discovery, TODO check if this actually works and dont forward these if it doesnt
from = 1900;
}
];
};
networking.firewall = {
allowedTCPPorts = [config.services.navidrome.settings.Port];
allowedUDPPorts = [1900 7359]; # Jellyfin auto-discovery
};
systemd.services.caddy.vpnConfinement = {
enable = true;
vpnNamespace = "wg";
};
services.caddy = {
enable = true;
# extraConfig = let
# gensub = x: "${x}.${domain}:${toString caddyPort}";
# tls = "tls /var/lib/acme/${domain}/cert.pem /var/lib/acme/${domain}/key.pem";
# rpPort = port: "reverse_proxy localhost:${toString port}";
# in ''
# ${gensub "navidrome"} {
# ${tls}
# ${rpPort config.services.navidrome.settings.Port}
# }
# '';
virtualHosts = let
authelia = "localhost:${toString autheliaPort}";
in
builtins.mapAttrs (n: v:
{
useACMEHost = domain;
hostName = "${n}.${domain}:${toString caddyPort}";
}
// v) {
navidrome.extraConfig = ''
reverse_proxy localhost:${toString config.services.navidrome.settings.Port}
'';
auth.extraConfig = "reverse_proxy ${authelia}";
#jellyfin.extraConfig = "reverse_proxy localhost:8096"; # TODO tmp off since i dont have proper auth yet
other = {
hostName = ":${toString caddyPort}";
extraConfig = ''
respond 404 {
body "no such route you dummy"
}
'';
};
};
};
systemd.services.navidrome = {
vpnConfinement = {
enable = true;
vpnNamespace = "wg";
};
serviceConfig = {
PrivateTmp = true;
NoNewPrivileges = true;
RestrictSUIDSGID = true;
ProtectProc = "invisible";
};
};
## TODO might be unnecessary with authelia but specifying a custom PasswordEncryptionKey is recommended
services.navidrome = {
enable = true;
settings = {
Address = "localhost";
MusicFolder = "/media/library/music";
ReverseProxyWhitelist = "0.0.0.0/0"; # cant be accessed from outside since the navidrome port isnt mapped to outside of the wireguard namespace
};
};
systemd.services.authelia-main = {
vpnConfinement = {
enable = true;
vpnNamespace = "wg";
};
# serviceConfig.LoadCredential = [
# "users.yaml:${}"
# ];
};
services.authelia.instances.main = {
enable = true;
secrets = {
jwtSecretFile = config.sops.secrets.authelia_jwt_secret.path;
storageEncryptionKeyFile = config.sops.secrets.authelia_encryption_key.path;
sessionSecretFile = config.sops.secrets.authelia_session_secret.path;
};
settings = {
# might change this to info in the future, for now its nice seeing debug messages if something goes wrong
log.level = "debug";
access_control = {
default_policy = "deny";
rules = [
{
domain = "*.${domain}";
policy = "one_factor"; # using totp requires me to set up smtp support :(
}
];
};
theme = "auto";
default_2fa_method = "totp";
## use ldap backend, not yaml file
## https://www.authelia.com/configuration/first-factor/ldap/
# default_redirection_url = "https://auth.${domain}/";
notifier.filesystem.filename = "/tmp/authelia-notifier.txt"; ## TODO change this to something reasonable
authentication_backend = {
password_reset.disable = true;
file.path = pkgs.writers.writeYAML "users.yaml" {
users.xun = {
disabled = false;
displayname = "xun";
password = "$argon2id$v=19$m=65536,t=3,p=4$cwYrForToKZn7+urMrSXuQ$PStkqPlo/7/GZ+hMsJXfOyZ0WijNtuZpaHWyZUuBWBY";
email = "xunuwu@gmail.com";
groups = ["admin"];
};
};
};
storage.postgres = {
address = "unix:///run/postgresql";
database = "authelia-main";
# this isnt used, ensureDBOwnership allows us to auth to postgres using unix users
username = "authelia-main";
password = "unused";
};
session.cookies = [
{
domain = domain;
authelia_url = "https://auth.${domain}";
default_redirection_url = "https://invalid.${domain}"; # TODO replace with overview thing mayb
}
];
## TODO: https://www.authelia.com/integration/proxies/forwarded-headers/#cloudflare
server = {
address = "127.0.0.1:${toString autheliaPort}";
endpoints.authz.forward-auth.implementation = "ForwardAuth";
};
};
};
services.postgresql = let
databases = ["authelia-main"];
in {
enable = true;
ensureDatabases = databases;
ensureUsers = lib.singleton {
name = "authelia-main";
ensureDBOwnership = true;
};
};
systemd.services.jellyfin.vpnConfinement = {
enable = true;
vpnNamespace = "wg";
};
services.jellyfin = {
enable = true;
};
services.prometheus = {
enable = true;
port = 9001;
extraFlags = ["--storage.tsdb.retention.time=30d"];
scrapeConfigs = [
{
job_name = config.networking.hostName;
static_configs = [
{
targets = ["127.0.0.1:${toString config.services.prometheus.exporters.node.port}"];
}
];
}
];
};
services.prometheus.exporters = {
node = {
enable = true;
enabledCollectors = ["systemd"];
};
};
# services.grafana = {
# enable = true;
# domain = "grafana.hopper";
# addr = "127.0.0.1";
# security = {
# adminUser = "admin";
# adminPasswordFile = config.sops.secrets.grafana-pass.path;
# };
# };
## TODO: add forgejo
## ignore this its cringe and ill prob remove it later idk, its also pasted from someone else, idk who tho ##
systemd.services.vpn-test-service = {
enable = true;
vpnConfinement = {
enable = true;
vpnNamespace = "wg";
};
script = "${pkgs.writeShellApplication {
name = "vpn-test";
runtimeInputs = with pkgs; [util-linux unixtools.ping coreutils curl bash libressl netcat-gnu openresolv dig];
text = ''
cd "$(mktemp -d)"
# DNS information
dig google.com
# Print resolv.conf
echo "/etc/resolv.conf contains:"
cat /etc/resolv.conf
# Query resolvconf
# echo "resolvconf output:"
# resolvconf -l
# echo ""
# Get ip
echo "Getting IP:"
curl -s ipinfo.io
echo -ne "DNS leak test:"
curl -s https://raw.githubusercontent.com/macvk/dnsleaktest/b03ab54d574adbe322ca48cbcb0523be720ad38d/dnsleaktest.sh -o dnsleaktest.sh
chmod +x dnsleaktest.sh
./dnsleaktest.sh
'';
}}/bin/vpn-test";
};
}