I don't know if i like this

This commit is contained in:
Gerg-L 2025-01-17 19:18:32 -05:00
parent c6a9144ffe
commit 1b62d16ddc
Signed by: gerg-l
SSH key fingerprint: SHA256:FPYDHIkvMocr4wdmZXpgpJjsb2Tw6rASs2ISPbOb0KI
63 changed files with 369 additions and 294 deletions

View file

@ -0,0 +1,31 @@
{
config,
pkgs,
_dir,
}:
{
sops.secrets.cloudflare = { };
systemd.services.ddns = {
reloadIfChanged = false;
restartIfChanged = false;
stopIfChanged = false;
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
startAt = "hourly";
serviceConfig = {
EnvironmentFile = config.sops.secrets.cloudflare.path;
DynamicUser = true;
};
path = [
pkgs.netcat
pkgs.jq
pkgs.curl
];
script = builtins.readFile "${_dir}/ddns_script.sh";
};
}

View file

@ -0,0 +1,56 @@
#!/usr/bin/env bash
if ! nc -zw1 api.cloudflare.com 443 &>/dev/null; then
echo No Internet access... bailing early
exit 0
fi
IP=$(grep -oP '^((?!fe80).).{22}ffee.{5}' /proc/net/if_inet6 | sed -E 's/(.{4})/\1:/g; s/.$//')
func () {
RECORD="$1"
ZONE="$2"
PROXY="${3:-"true"}"
REQ=$(curl --silent \
--request GET \
--url "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $AUTH"
)
readarray -t AR < <(jq -r '.result[].name' <<< "$REQ")
for i in "${!AR[@]}"; do
if [ "${AR[i]}" == "$RECORD" ]; then
ID=$(jq -r ".result[$i].id" <<< "$REQ")
if [ "$(jq -r ".result[$i].content" <<< "$REQ")" == "$IP" ]; then
echo "IP was the same, returing early"
return 0
fi
break
fi
done
curl --silent \
--request PATCH \
--url "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records/$ID" \
--header "Authorization: Bearer $AUTH" \
--header "Content-Type: application/json" \
--data '{
"content": "'"$IP"'",
"name": "'"$RECORD"'",
"proxied": '"$PROXY"',
"type": "AAAA",
"comment": "",
"tags": [],
"ttl": 1
}'
}
func "*.gerg-l.com" "8f76f071c5edbc0f947a5c5f9c5df9f8"
func "gerg-l.com" "8f76f071c5edbc0f947a5c5f9c5df9f8" "false"
func "ipv6.gerg-l.com" "8f76f071c5edbc0f947a5c5f9c5df9f8" "false"

View file

@ -0,0 +1,40 @@
{ config }:
{
users = {
groups.${config.services.forgejo.group} = { };
users = {
${config.services.forgejo.user} = {
isSystemUser = true;
inherit (config.services.forgejo) group;
extraGroups = [ "postgres" ];
openssh.authorizedKeys.keys = [ config.local.keys.gerg_gerg-desktop ];
};
${config.services.nginx.user}.extraGroups = [ config.services.forgejo.group ];
};
};
services.forgejo = {
enable = true;
stateDir = "/persist/services/forgejo";
settings = {
DEFAULT.APP_NAME = "Powered by NixOS";
server = {
DOMAIN = "git.gerg-l.com";
ROOT_URL = "https://git.gerg-l.com/";
LANDING_PAGE = "/explore/repos";
HTTP_ADDR = "/run/forgejo/forgejo.sock";
PROTOCOL = "http+unix";
UNIX_SOCKET_PERMISSION = "660";
};
ui.DEFAULT_THEME = "forgejo-dark";
service.DISABLE_REGISTRATION = true;
};
database = {
type = "postgres";
createDatabase = true;
};
};
local.nginx.proxyVhosts."git.gerg-l.com" =
"http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}";
}

View file

@ -0,0 +1,20 @@
{ config, ... }:
{
users.users.${config.services.immich.user}.extraGroups = [ "postgres" ];
services.immich = {
enable = true;
openFirewall = true;
database = {
enable = true;
createDB = true;
};
mediaLocation = "/persist/services/immich";
machine-learning.enable = true;
settings = null;
port = 2283;
host = "0.0.0.0";
};
local.nginx.proxyVhosts."photos.gerg-l.com" =
"http://localhost:${toString config.services.immich.port}";
}

View file

@ -0,0 +1,94 @@
{ lib, self' }:
{
# I manually switch this sometimes
config = lib.mkIf false {
networking.firewall = {
allowedUDPPorts = [ 24454 ];
allowedTCPPorts = [
25565
25575
];
};
users = {
users.minecraft = {
home = "/persist/minecraft2";
createHome = true;
isSystemUser = true;
group = "minecraft";
};
groups.minecraft = { };
};
systemd.services.minecraft-server = {
description = "Minecraft";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
script = ''
${lib.getExe self'.packages.fabric} \
-Xms12G \
-Xmx12G \
-XX:+UnlockExperimentalVMOptions \
-XX:+UnlockDiagnosticVMOptions \
-XX:+AlwaysActAsServerClassMachine \
-XX:+AlwaysPreTouch \
-XX:+DisableExplicitGC \
-XX:+UseNUMA \
-XX:NmethodSweepActivity=1 \
-XX:ReservedCodeCacheSize=400M \
-XX:NonNMethodCodeHeapSize=12M \
-XX:ProfiledCodeHeapSize=194M \
-XX:NonProfiledCodeHeapSize=194M \
-XX:-DontCompileHugeMethods \
-XX:MaxNodeLimit=240000 \
-XX:NodeLimitFudgeFactor=8000 \
-XX:+UseVectorCmov \
-XX:+PerfDisableSharedMem \
-XX:+UseFastUnorderedTimeStamps \
-XX:+UseCriticalJavaThreadPriority \
-XX:ThreadPriorityPolicy=1 \
-XX:AllocatePrefetchStyle=3
'';
serviceConfig = {
Restart = "always";
User = "minecraft";
WorkingDirectory = "/persist/minecraft2";
StandardInput = "journal";
StandardOutput = "journal";
StandardError = "journal";
# Hardening
CapabilityBoundingSet = [ "" ];
DeviceAllow = [ "" ];
LockPersonality = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
UMask = "0077";
};
preStart = ''
if [ ! -e "eula.txt" ]; then
echo "eula=true" > eula.txt
fi
'';
};
};
}

View file

@ -0,0 +1,38 @@
{
config,
lib,
}:
{
sops.secrets.minifluxenv = { };
services.miniflux = {
enable = true;
config = {
BASE_URL = "https://flux.gerg-l.com";
LISTEN_ADDR = "/run/miniflux/miniflux.sock";
};
adminCredentialsFile = config.sops.secrets.minifluxenv.path;
createDatabaseLocally = true;
};
users = {
groups.miniflux.gid = 377;
users = {
miniflux = {
group = "miniflux";
extraGroups = [ "postgres" ];
isSystemUser = true;
uid = 377;
};
${config.services.nginx.user}.extraGroups = [ "miniflux" ];
};
};
systemd.services.miniflux.serviceConfig = {
RuntimeDirectoryMode = lib.mkForce "0770";
DynamicUser = lib.mkForce false;
};
local.nginx.proxyVhosts."flux.gerg-l.com" =
"http://unix:${config.services.miniflux.config.LISTEN_ADDR}";
}

View file

@ -0,0 +1,70 @@
{ config, lib }:
{
options.local.nginx = {
proxyVhosts = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
};
defaultVhosts = lib.mkOption {
type = lib.types.attrs;
};
};
config = {
local.nginx.defaultVhosts = builtins.mapAttrs (_: v: {
locations."/".proxyPass = v;
}) config.local.nginx.proxyVhosts;
sops.secrets = {
gerg_ssl_key.owner = config.services.nginx.user;
gerg_ssl_cert.owner = config.services.nginx.user;
};
security.acme = {
acceptTerms = true;
certs."gerg-l.com" = {
email = "GregLeyda@proton.me";
webroot = "/var/lib/acme/acme-challenge";
extraDomainNames = builtins.attrNames config.local.nginx.defaultVhosts;
};
};
systemd.tmpfiles.rules = [ "L+ /var/lib/acme - - - - /persist/services/acme" ];
users.users.${config.services.nginx.user}.extraGroups = [ "acme" ];
services.nginx = {
enable = true;
recommendedZstdSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
# For immich
clientMaxBodySize = "50000M";
proxyTimeout = "600s";
virtualHosts =
builtins.mapAttrs
(
_: v:
{
forceSSL = true;
useACMEHost = "gerg-l.com";
}
// v
)
(
config.local.nginx.defaultVhosts
// {
"_" = {
default = true;
locations."/".return = "404";
};
}
);
};
networking.firewall.allowedTCPPorts = [
80
443
];
};
}

View file

@ -0,0 +1,77 @@
{ config, pkgs }:
{
sops.secrets.store_key.owner = "nix-serve";
users = {
groups = {
builder = { };
nix-serve = { };
};
users = {
${config.services.nginx.user}.extraGroups = [ "nix-serve" ];
builder = {
isSystemUser = true;
openssh.authorizedKeys.keys = [ config.local.keys.root_media-laptop ];
group = "builder";
shell = pkgs.bashInteractive;
};
nix-serve = {
isSystemUser = true;
group = "nix-serve";
};
};
};
services.openssh.extraConfig = ''
Match User builder
AllowAgentForwarding no
AllowTcpForwarding no
PermitTTY no
PermitTunnel no
X11Forwarding no
Match All
'';
nix.settings = {
trusted-users = [ "builder" ];
allowed-users = [ "nix-serve" ];
keep-outputs = true;
keep-derivations = true;
secret-key-files = config.sops.secrets.store_key.path;
};
systemd.services.nix-serve = {
description = "nix-serve binary cache server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
path = [
config.nix.package
pkgs.bzip2
pkgs.nix-serve-ng
];
environment = {
NIX_REMOTE = "daemon";
NIX_SECRET_KEY_FILE = config.sops.secrets.store_key.path;
};
script = ''
nix-serve --socket /run/nix-serve/nix-serve.sock &
PID=$!
sleep 1
chmod 660 /run/nix-serve/nix-serve.sock
wait "$PID"
'';
serviceConfig = {
Restart = "always";
RestartSec = "5s";
User = "nix-serve";
Group = "nix-serve";
};
};
systemd.tmpfiles.rules = [ "d /run/nix-serve - nix-serve nix-serve - -" ];
local.nginx.proxyVhosts."cache.gerg-l.com" = "http://unix:/run/nix-serve/nix-serve.sock";
}

View file

@ -0,0 +1,23 @@
{
pkgs,
config,
lib,
}:
{
sops.secrets.discordenv = { };
systemd.services.parrot = {
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
environment.SETTINGS_PATH = "/persist/services/parrot";
serviceConfig = {
ExecStart = lib.getExe pkgs.parrot;
EnvironmentFile = config.sops.secrets.discordenv.path;
Restart = "on-failure";
RestartSec = "30s";
};
};
}

View file

@ -0,0 +1,9 @@
{ pkgs }:
{
services.postgresql = {
enable = true;
package = pkgs.postgresql_16;
dataDir = "/persist/services/postgresql";
settings.unix_socket_permissions = "0770";
};
}

View file

@ -0,0 +1,22 @@
{
config,
lib,
reboot-bot,
}:
{
sops.secrets.reboot_token = { };
systemd.services.reboot_bot = {
enable = false;
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
serviceConfig = {
ExecStart = lib.getExe reboot-bot.packages.default;
EnvironmentFile = config.sops.secrets.reboot_token.path;
Restart = "on-failure";
RestartSec = "30s";
};
};
}

View file

@ -0,0 +1,43 @@
{ config, pkgs }:
{
sops.secrets.searxngenv = { };
users.users.${config.services.nginx.user}.extraGroups = [ "searx" ];
services.searx = {
enable = true;
package = pkgs.searxng;
runInUwsgi = true;
uwsgiConfig = {
socket = "/run/searx/searx.sock";
chmod-socket = "660";
disable-logging = true;
};
environmentFile = config.sops.secrets.searxngenv.path;
settings = {
general.instance_name = "Gerg search";
server = {
secret_key = "@SEARXNG_SECRET@";
base_url = "https://search.gerg-l.com";
};
search.formats = [
"html"
"json"
];
engines = [
{
name = "bing";
disabled = true;
}
{
name = "brave";
disabled = true;
}
];
ui.theme_args.simple_style = "dark";
};
};
local.nginx.defaultVhosts."search.gerg-l.com" = {
locations."/".extraConfig = "uwsgi_pass unix:${config.services.searx.uwsgiConfig.socket};";
extraConfig = "access_log off;";
};
}