initial retooling
This commit is contained in:
108
modules/core/caddy.nix
Normal file
108
modules/core/caddy.nix
Normal file
@@ -0,0 +1,108 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
user = "caddy";
|
||||
group = "root";
|
||||
configFile = "/run/caddy/Caddyfile";
|
||||
};
|
||||
|
||||
systemd.services.caddy-generate-config = {
|
||||
description = "Generate Caddyfile from /var/lib/domains at runtime";
|
||||
before = [ "caddy.service" ];
|
||||
requiredBy = [ "caddy.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
RuntimeDirectory = "caddy";
|
||||
};
|
||||
path = [ pkgs.coreutils ];
|
||||
script = ''
|
||||
MATRIX=$(cat /var/lib/domains/matrix)
|
||||
WORDPRESS=$(cat /var/lib/domains/wordpress)
|
||||
NEXTCLOUD=$(cat /var/lib/domains/nextcloud)
|
||||
BTCPAY=$(cat /var/lib/domains/btcpayserver)
|
||||
VAULTWARDEN=$(cat /var/lib/domains/vaultwarden)
|
||||
HAVEN=$(cat /var/lib/domains/haven)
|
||||
ACME_EMAIL=$(cat /var/lib/domains/sslemail)
|
||||
|
||||
# Start with global config
|
||||
cat > /run/caddy/Caddyfile <<EOF
|
||||
{
|
||||
email $ACME_EMAIL
|
||||
}
|
||||
EOF
|
||||
|
||||
# If element-calling is enabled, it wrote a snippet with
|
||||
# enhanced Matrix vhosts (.well-known, element-calling routes)
|
||||
if [ -f /run/caddy/element-calling.snippet ]; then
|
||||
cat /run/caddy/element-calling.snippet >> /run/caddy/Caddyfile
|
||||
else
|
||||
# Fallback: basic Matrix vhosts without element-calling
|
||||
cat >> /run/caddy/Caddyfile <<EOF
|
||||
|
||||
$MATRIX {
|
||||
reverse_proxy /_matrix/* http://localhost:8008
|
||||
reverse_proxy /_synapse/client/* http://localhost:8008
|
||||
}
|
||||
|
||||
$MATRIX:8448 {
|
||||
reverse_proxy http://localhost:8008
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Append remaining vhosts
|
||||
cat >> /run/caddy/Caddyfile <<EOF
|
||||
|
||||
$WORDPRESS {
|
||||
encode gzip zstd
|
||||
root * /var/lib/www/wordpress
|
||||
php_fastcgi unix//run/phpfpm/mypool.sock
|
||||
file_server browse
|
||||
}
|
||||
|
||||
$NEXTCLOUD {
|
||||
encode gzip zstd
|
||||
root * /var/lib/www/nextcloud
|
||||
php_fastcgi unix//run/phpfpm/mypool.sock {
|
||||
trusted_proxies private_ranges
|
||||
}
|
||||
file_server
|
||||
redir /.well-known/carddav /remote.php/dav/ 301
|
||||
redir /.well-known/caldav /remote.php/dav/ 301
|
||||
header {
|
||||
Strict-Transport-Security max-age=31536000;
|
||||
}
|
||||
}
|
||||
|
||||
$BTCPAY {
|
||||
reverse_proxy http://localhost:23000
|
||||
encode gzip zstd
|
||||
}
|
||||
|
||||
$VAULTWARDEN {
|
||||
reverse_proxy http://localhost:8777
|
||||
encode gzip zstd
|
||||
}
|
||||
|
||||
$HAVEN {
|
||||
reverse_proxy localhost:3355 {
|
||||
header_up Host {host}
|
||||
header_up X-Real-IP {remote_host}
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
transport http {
|
||||
versions 1.1
|
||||
}
|
||||
}
|
||||
request_body {
|
||||
max_size 100MB
|
||||
}
|
||||
}
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
}
|
||||
68
modules/core/njalla-ddns.nix
Normal file
68
modules/core/njalla-ddns.nix
Normal file
@@ -0,0 +1,68 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
# The cron job scans /var/lib/njalla/hooks.d/ for DDNS URLs
|
||||
systemd.services.njalla-ddns = {
|
||||
description = "Njalla Dynamic DNS Updater";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
IP=$(${pkgs.dig}/bin/dig @resolver4.opendns.com myip.opendns.com +short -4)
|
||||
|
||||
if [ -z "$IP" ]; then
|
||||
echo "Failed to resolve external IP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Only update if IP changed
|
||||
LAST_IP_FILE="/var/lib/njalla/.last_ip"
|
||||
LAST_IP=""
|
||||
[ -f "$LAST_IP_FILE" ] && LAST_IP=$(cat "$LAST_IP_FILE")
|
||||
|
||||
if [ "$IP" = "$LAST_IP" ]; then
|
||||
echo "IP unchanged ($IP), skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -n "$IP" > "$LAST_IP_FILE"
|
||||
echo "IP changed to $IP, updating DNS records..."
|
||||
|
||||
# Update external_ip secret
|
||||
echo -n "$IP" > /var/lib/secrets/external_ip
|
||||
|
||||
# Process each DDNS hook
|
||||
HOOKS_DIR="/var/lib/njalla/hooks.d"
|
||||
mkdir -p "$HOOKS_DIR"
|
||||
|
||||
for hook in "$HOOKS_DIR"/*; do
|
||||
[ -f "$hook" ] || continue
|
||||
DDNS_URL=$(cat "$hook")
|
||||
SERVICE=$(basename "$hook")
|
||||
echo "Updating $SERVICE..."
|
||||
${pkgs.curl}/bin/curl -s "''${DDNS_URL}''${IP}" || echo "Failed: $SERVICE"
|
||||
done
|
||||
|
||||
echo "Done."
|
||||
'';
|
||||
};
|
||||
|
||||
# Run every 15 minutes
|
||||
systemd.timers.njalla-ddns = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*:0/15";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Ensure directory exists
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/njalla 0700 root root -"
|
||||
"d /var/lib/njalla/hooks.d 0700 root root -"
|
||||
];
|
||||
}
|
||||
37
modules/core/role-logic.nix
Executable file
37
modules/core/role-logic.nix
Executable file
@@ -0,0 +1,37 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
config = lib.mkMerge [
|
||||
|
||||
# Server-Desktop Role most services enabled
|
||||
(lib.mkIf config.sovran_systemsOS.roles.server-desktop {
|
||||
sovran_systemsOS.features = {
|
||||
synapse = true;
|
||||
bitcoin = true;
|
||||
coturn = true;
|
||||
vaultwarden = true;
|
||||
haven = false;
|
||||
mempool = false;
|
||||
bip110 = false;
|
||||
element-calling = false;
|
||||
bitcoin-core = false;
|
||||
rdp = false;
|
||||
};
|
||||
})
|
||||
|
||||
# Desktop role
|
||||
(lib.mkIf config.sovran_systemsOS.roles.desktop {
|
||||
services.xserver.enable = true;
|
||||
services.desktopManager.gnome.enable = true;
|
||||
})
|
||||
|
||||
# Bitcoin node role
|
||||
(lib.mkIf config.sovran_systemsOS.roles.node {
|
||||
sovran_systemsOS.features = {
|
||||
bitcoin = true;
|
||||
bip110 = false;
|
||||
};
|
||||
})
|
||||
|
||||
];
|
||||
}
|
||||
33
modules/core/roles.nix
Executable file
33
modules/core/roles.nix
Executable file
@@ -0,0 +1,33 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
options.sovran_systemsOS = {
|
||||
roles = {
|
||||
server-desktop = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = !config.sovran_systemsOS.roles.desktop && !config.sovran_systemsOS.roles.node;
|
||||
};
|
||||
desktop = lib.mkEnableOption "Desktop Role";
|
||||
node = lib.mkEnableOption "Bitcoin Node Only Role";
|
||||
};
|
||||
|
||||
features = {
|
||||
coturn = lib.mkEnableOption "TURN server";
|
||||
synapse = lib.mkEnableOption "Matrix Synapse";
|
||||
bitcoin = lib.mkEnableOption "Bitcoin Ecosystem";
|
||||
vaultwarden = lib.mkEnableOption "Vaultwarden";
|
||||
haven = lib.mkEnableOption "Haven NOSTR relay";
|
||||
bip110 = lib.mkEnableOption "BIP-110 Bitcoin Better Money";
|
||||
mempool = lib.mkEnableOption "Bitcoin Mempool Explorer";
|
||||
element-calling = lib.mkEnableOption "Element Video and Audio Calling";
|
||||
bitcoin-core = lib.mkEnableOption "Bitcoin Core";
|
||||
rdp = lib.mkEnableOption "Gnome Remote Desktop";
|
||||
};
|
||||
|
||||
nostr_npub = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "Nostr public key (npub1...) for Haven relay";
|
||||
};
|
||||
};
|
||||
}
|
||||
13
modules/core/sovran-manage.nix
Normal file
13
modules/core/sovran-manage.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
sovran-manage = pkgs.writeShellScriptBin "sovran-manage" (builtins.readFile ../../scripts/sovran-manage.sh);
|
||||
in
|
||||
{
|
||||
environment.systemPackages = [
|
||||
sovran-manage
|
||||
pkgs.pwgen
|
||||
pkgs.dig
|
||||
pkgs.curl
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user