updated pdf creator and overall theme
This commit is contained in:
@@ -49,6 +49,7 @@
|
|||||||
services.desktopManager.gnome.enable = true;
|
services.desktopManager.gnome.enable = true;
|
||||||
services.printing.enable = true;
|
services.printing.enable = true;
|
||||||
systemd.enableEmergencyMode = false;
|
systemd.enableEmergencyMode = false;
|
||||||
|
environment.gnome.excludePackages = [ pkgs.gnome-tour gnome-initial-setup ];
|
||||||
|
|
||||||
# ── Audio ──────────────────────────────────────────────────
|
# ── Audio ──────────────────────────────────────────────────
|
||||||
services.pulseaudio.enable = false;
|
services.pulseaudio.enable = false;
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ in
|
|||||||
boot.plymouth.theme = "sovran";
|
boot.plymouth.theme = "sovran";
|
||||||
boot.plymouth.themePackages = [ theme ];
|
boot.plymouth.themePackages = [ theme ];
|
||||||
boot.kernelParams = [ "quiet" "splash" ];
|
boot.kernelParams = [ "quiet" "splash" ];
|
||||||
}
|
boot.initrd.systemd.enable = true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
image.fileName = "Sovran_SystemsOS.iso";
|
image.fileName = "Sovran_SystemsOS.iso";
|
||||||
|
|
||||||
|
isoImage.splashImage = ./assets/splash-logo.png;
|
||||||
|
|
||||||
users.users.free = {
|
users.users.free = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
@@ -29,6 +31,7 @@ in
|
|||||||
installer
|
installer
|
||||||
zenity
|
zenity
|
||||||
util-linux
|
util-linux
|
||||||
|
disko
|
||||||
parted
|
parted
|
||||||
dosfstools
|
dosfstools
|
||||||
e2fsprogs
|
e2fsprogs
|
||||||
@@ -37,6 +40,8 @@ in
|
|||||||
git
|
git
|
||||||
curl
|
curl
|
||||||
];
|
];
|
||||||
|
|
||||||
|
environment.etc."sovran/logo.png".source = ./assets/splash-logo.png;
|
||||||
|
|
||||||
environment.etc."sovran/flake".source = sovranSource;
|
environment.etc."sovran/flake".source = sovranSource;
|
||||||
|
|
||||||
|
|||||||
62
iso/disko.nix
Normal file
62
iso/disko.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{ device ? "/dev/sda", dataDevice ? "", ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
disko.devices = {
|
||||||
|
disk = {
|
||||||
|
main = {
|
||||||
|
type = "disk";
|
||||||
|
device = builtins.toString device;
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
ESP = {
|
||||||
|
priority = 1;
|
||||||
|
name = "ESP";
|
||||||
|
start = "1M";
|
||||||
|
end = "512M";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot/efi";
|
||||||
|
mountOptions = [ "umask=0077" "defaults" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
name = "root";
|
||||||
|
start = "512M";
|
||||||
|
end = "100%";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "ext4";
|
||||||
|
mountpoint = "/";
|
||||||
|
extraArgs = [ "-L" "sovran_systemsos" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // (if dataDevice != "" then {
|
||||||
|
data = {
|
||||||
|
type = "disk";
|
||||||
|
device = builtins.toString dataDevice;
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
primary = {
|
||||||
|
name = "primary";
|
||||||
|
start = "1M";
|
||||||
|
end = "100%";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "ext4";
|
||||||
|
mountpoint = "/run/media/Second_Drive";
|
||||||
|
extraArgs = [ "-L" "BTCEcoandBackup" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} else {});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -6,17 +6,21 @@ exec > >(tee -a "$LOG") 2>&1
|
|||||||
|
|
||||||
export PATH=/run/current-system/sw/bin:$PATH
|
export PATH=/run/current-system/sw/bin:$PATH
|
||||||
|
|
||||||
BYTES_4TB=$((4 * 1024 * 1024 * 1024 * 1024))
|
# Changed to 2TB cutoff
|
||||||
|
BYTES_2TB=$((2 * 1024 * 1024 * 1024 * 1024))
|
||||||
|
LOGO="/etc/sovran/logo.png"
|
||||||
|
|
||||||
human_size() {
|
human_size() {
|
||||||
numfmt --to=iec --suffix=B "$1"
|
numfmt --to=iec --suffix=B "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
zenity --info --width=500 --text="Sovran SystemsOS Installer\n\nWARNING:\nThis installer will ERASE ALL DATA on selected disks.\n\nPress OK to continue."
|
zenity --info --window-icon="$LOGO" --text="Sovran SystemsOS Installer\n\nWARNING:\nThis installer will ERASE ALL DATA on selected disks.\n\nPress OK to continue."
|
||||||
|
|
||||||
|
# Filter out USB drives and loop/cdrom devices so it doesn't try to install to the installation media
|
||||||
|
mapfile -t DISKS < <(lsblk -b -dno NAME,SIZE,TYPE,RO,TRAN -e 7,11 | awk '$3=="disk" && $4=="0" && $5!="usb" {print $1":"$2}')
|
||||||
|
|
||||||
mapfile -t DISKS < <(lsblk -b -dno NAME,SIZE,TYPE | awk '$3=="disk"{print $1":"$2}')
|
|
||||||
if [ "${#DISKS[@]}" -eq 0 ]; then
|
if [ "${#DISKS[@]}" -eq 0 ]; then
|
||||||
zenity --error --text="No disks found."
|
zenity --error --window-icon="$LOGO" --text="No valid internal drives found. (USB drives are ignored)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -34,8 +38,9 @@ if [ "${#DISKS_SORTED[@]}" -ge 2 ]; then
|
|||||||
DATA_SIZE="${DISKS_SORTED[-1]##*:}"
|
DATA_SIZE="${DISKS_SORTED[-1]##*:}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$DATA_DISK" ] && [ "$DATA_SIZE" -lt "$BYTES_4TB" ]; then
|
# Updated to check against 2TB
|
||||||
zenity --warning --width=500 --text="Second disk detected (${DATA_DISK}), but it is smaller than 4TB.\n\nIt will NOT be used."
|
if [ -n "$DATA_DISK" ] && [ "$DATA_SIZE" -lt "$BYTES_2TB" ]; then
|
||||||
|
zenity --warning --window-icon="$LOGO" --text="Second disk detected (${DATA_DISK}), but it is smaller than 2TB.\n\nIt will NOT be used."
|
||||||
DATA_DISK=""
|
DATA_DISK=""
|
||||||
DATA_SIZE=""
|
DATA_SIZE=""
|
||||||
fi
|
fi
|
||||||
@@ -47,7 +52,8 @@ else
|
|||||||
SUMMARY="${SUMMARY}\nData disk: none"
|
SUMMARY="${SUMMARY}\nData disk: none"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ROLE=$(zenity --list --radiolist --width=500 --height=250 \
|
ROLE=$(zenity --list --radiolist \
|
||||||
|
--window-icon="$LOGO" \
|
||||||
--title="Choose Install Role" \
|
--title="Choose Install Role" \
|
||||||
--column="" --column="Role" \
|
--column="" --column="Role" \
|
||||||
TRUE "Server-Desktop (default)" \
|
TRUE "Server-Desktop (default)" \
|
||||||
@@ -58,52 +64,21 @@ if [ -z "$ROLE" ]; then
|
|||||||
ROLE="Server-Desktop (default)"
|
ROLE="Server-Desktop (default)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CONFIRM=$(zenity --entry --width=500 --text="WARNING: This will ERASE ALL DATA on:\n\n${SUMMARY}\n\nType ERASE to continue.")
|
CONFIRM=$(zenity --entry --window-icon="$LOGO" --text="WARNING: This will ERASE ALL DATA on:\n\n${SUMMARY}\n\nType ERASE to continue.")
|
||||||
if [ "$CONFIRM" != "ERASE" ]; then
|
if [ "$CONFIRM" != "ERASE" ]; then
|
||||||
zenity --error --text="Install cancelled."
|
zenity --error --window-icon="$LOGO" --text="Install cancelled."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
BOOT_PATH="/dev/${BOOT_DISK}"
|
BOOT_PATH="/dev/${BOOT_DISK}"
|
||||||
PART_SUFFIX=""
|
DATA_PATH=""
|
||||||
if [[ "$BOOT_DISK" =~ ^(nvme|mmcblk) ]]; then
|
|
||||||
PART_SUFFIX="p"
|
|
||||||
fi
|
|
||||||
|
|
||||||
parted --script "$BOOT_PATH" mklabel gpt
|
|
||||||
parted --script "$BOOT_PATH" mkpart ESP fat32 1MiB 512MiB
|
|
||||||
parted --script "$BOOT_PATH" set 1 esp on
|
|
||||||
parted --script "$BOOT_PATH" mkpart primary ext4 512MiB 100%
|
|
||||||
|
|
||||||
partprobe "$BOOT_PATH"
|
|
||||||
udevadm settle
|
|
||||||
|
|
||||||
mkfs.fat -F 32 -n boot "${BOOT_PATH}${PART_SUFFIX}1"
|
|
||||||
mkfs.ext4 -F -L sovran_systemsos "${BOOT_PATH}${PART_SUFFIX}2"
|
|
||||||
|
|
||||||
if [ -n "$DATA_DISK" ]; then
|
if [ -n "$DATA_DISK" ]; then
|
||||||
DATA_PATH="/dev/${DATA_DISK}"
|
DATA_PATH="/dev/${DATA_DISK}"
|
||||||
part_suffix_data=""
|
|
||||||
if [[ "$DATA_DISK" =~ ^(nvme|mmcblk) ]]; then
|
|
||||||
part_suffix_data="p"
|
|
||||||
fi
|
|
||||||
|
|
||||||
parted --script "$DATA_PATH" mklabel gpt
|
|
||||||
parted --script "$DATA_PATH" mkpart primary ext4 1MiB 100%
|
|
||||||
partprobe "$DATA_PATH"
|
|
||||||
udevadm settle
|
|
||||||
mkfs.ext4 -F -L BTCEcoandBackup "${DATA_PATH}${part_suffix_data}1"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p /mnt
|
# Run Disko to partition and format drives
|
||||||
mount /dev/disk/by-label/sovran_systemsos /mnt
|
echo "Running Disko to partition and format drives..."
|
||||||
mkdir -p /mnt/boot/efi
|
disko --mode disko /etc/sovran/flake/iso/disko.nix --argstr device "$BOOT_PATH" --argstr dataDevice "$DATA_PATH"
|
||||||
mount /dev/disk/by-label/boot /mnt/boot/efi
|
|
||||||
|
|
||||||
if [ -n "$DATA_DISK" ]; then
|
|
||||||
mkdir -p /mnt/run/media/Second_Drive
|
|
||||||
mount /dev/disk/by-label/BTCEcoandBackup /mnt/run/media/Second_Drive
|
|
||||||
fi
|
|
||||||
|
|
||||||
nixos-generate-config --root /mnt
|
nixos-generate-config --root /mnt
|
||||||
|
|
||||||
@@ -123,5 +98,21 @@ EOF
|
|||||||
|
|
||||||
nixos-install --root /mnt --flake /mnt/etc/nixos#nixos
|
nixos-install --root /mnt --flake /mnt/etc/nixos#nixos
|
||||||
|
|
||||||
zenity --info --text="Install complete. Rebooting..."
|
EOF
|
||||||
reboot
|
|
||||||
|
nixos-install --root /mnt --flake /mnt/etc/nixos#nixos
|
||||||
|
|
||||||
|
zenity --warning --width=600 --title="INSTALLATION COMPLETE! 🚨 PLEASE READ" --text="<b><span size='large'>Installation Successful!</span></b>
|
||||||
|
|
||||||
|
Before you reboot, please write down your main login details:
|
||||||
|
|
||||||
|
<b>Username:</b> free
|
||||||
|
<b>Password:</b> free
|
||||||
|
|
||||||
|
🚨 <b>CRITICAL:</b> Do not lose this password! If you forget this, you will be permanently locked out of your computer.
|
||||||
|
|
||||||
|
📁 <b>Other Passwords:</b> Once the system reboots, it will finish building your forts and generate all the passwords for your apps (Nextcloud, Bitcoin, Matrix, etc.). It will save them in a secure PDF in your <b>Documents</b> folder.
|
||||||
|
|
||||||
|
Click OK to reboot into your new system!"
|
||||||
|
|
||||||
|
reboot
|
||||||
|
|||||||
156
modules/core/sovran_systemsos-desktop.nix
Normal file
156
modules/core/sovran_systemsos-desktop.nix
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
customWallpaper = pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
pname = "sovran-systemsos-wallpaper";
|
||||||
|
version = "1.0";
|
||||||
|
src = pkgs.fetchurl {
|
||||||
|
url = "https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS_iso/raw/branch/main/post-install-scripts/Wallpaper_Dark_Wide.png";
|
||||||
|
sha256 = "0609gy0vp92fywl7pcr4y3mg05ca6pwxsnlsax14jd371fj4y7fn"; # Make sure this hash is correct!
|
||||||
|
};
|
||||||
|
dontUnpack = true;
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/share/backgrounds/sovran
|
||||||
|
cp $src $out/share/backgrounds/sovran/Wallpaper_Dark_Wide.png
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# 1. Install the wallpaper package
|
||||||
|
environment.systemPackages = [ customWallpaper ];
|
||||||
|
|
||||||
|
# 2. Enable dconf
|
||||||
|
programs.dconf.enable = true;
|
||||||
|
|
||||||
|
# 3. Apply system-wide default GNOME settings
|
||||||
|
programs.dconf.profiles.user.databases = [{
|
||||||
|
settings = with lib.gvariant; {
|
||||||
|
"org/gnome/desktop/background" = {
|
||||||
|
picture-uri = "file:///run/current-system/sw/share/backgrounds/sovran/Wallpaper_Dark_Wide.png";
|
||||||
|
picture-uri-dark = "file:///run/current-system/sw/share/backgrounds/sovran/Wallpaper_Dark_Wide.png";
|
||||||
|
picture-options = "zoom";
|
||||||
|
primary-color = "#000000";
|
||||||
|
secondary-color = "#000000";
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/desktop/input-sources" = {
|
||||||
|
sources = [ (mkTuple [ "xkb" "us" ]) ];
|
||||||
|
xkb-options = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/desktop/interface" = {
|
||||||
|
color-scheme = "prefer-dark";
|
||||||
|
enable-animations = true;
|
||||||
|
icon-theme = "Papirus-Dark";
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/evolution-data-server" = {
|
||||||
|
migrated = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/mutter" = {
|
||||||
|
edge-tiling = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/nautilus/icon-view" = {
|
||||||
|
default-zoom-level = "large";
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/nautilus/preferences" = {
|
||||||
|
default-folder-viewer = "icon-view";
|
||||||
|
migrated-gtk-settings = true;
|
||||||
|
search-filter-time-type = "last_modified";
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/shell" = {
|
||||||
|
disabled-extensions = [ "just-perfection-desktop@just-perfection" ];
|
||||||
|
enabled-extensions = [
|
||||||
|
"appindicatorsupport@rgcjonas.gmail.com"
|
||||||
|
"dash-to-dock-cosmic-@halfmexicanhalfamazing@gmail.com"
|
||||||
|
"Vitals@CoreCoding.com"
|
||||||
|
"dash-to-dock@micxgx.gmail.com"
|
||||||
|
"pop-shell@system76.com"
|
||||||
|
"date-menu-formatter@marcinjakubowski.github.com"
|
||||||
|
"systemd-manager@hardpixel.eu"
|
||||||
|
"light-style@gnome-shell-extensions.gcampax.github.com"
|
||||||
|
];
|
||||||
|
favorite-apps = [
|
||||||
|
"brave-browser.desktop"
|
||||||
|
"org.gnome.Settings.desktop"
|
||||||
|
"org.gnome.Nautilus.desktop"
|
||||||
|
"Sovran_SystemsOS_Updater.desktop"
|
||||||
|
"org.gnome.Software.desktop"
|
||||||
|
"org.gnome.Geary.desktop"
|
||||||
|
"org.gnome.Contacts.desktop"
|
||||||
|
"org.gnome.Calendar.desktop"
|
||||||
|
"sparrow-desktop.desktop"
|
||||||
|
"Bisq.desktop"
|
||||||
|
"bisq2.desktop"
|
||||||
|
];
|
||||||
|
welcome-dialog-last-shown-version = "48.4";
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/shell/extensions/dash-to-dock" = {
|
||||||
|
background-color = "rgb(0,0,0)";
|
||||||
|
background-opacity = 0.5;
|
||||||
|
custom-background-color = true;
|
||||||
|
dash-max-icon-size = 47;
|
||||||
|
dock-position = "BOTTOM";
|
||||||
|
height-fraction = 0.9;
|
||||||
|
preferred-monitor = -2;
|
||||||
|
preferred-monitor-by-connector = "Virtual-1";
|
||||||
|
show-trash = false;
|
||||||
|
transparency-mode = "FIXED";
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/shell/extensions/date-menu-formatter" = {
|
||||||
|
font-size = 12;
|
||||||
|
pattern = "EEEE, MMM d h:mm a";
|
||||||
|
text-align = "center";
|
||||||
|
update-level = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/shell/extensions/just-perfection" = {
|
||||||
|
support-notifier-showed-version = 34;
|
||||||
|
support-notifier-type = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/shell/extensions/pop-shell" = {
|
||||||
|
tile-by-default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/shell/extensions/systemd-manager" = {
|
||||||
|
command-method = "systemctl";
|
||||||
|
systemd = [
|
||||||
|
"{\"name\":\"Bitcoind\",\"service\":\"bitcoind.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"Electrs\",\"service\":\"electrs.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"CLN\",\"service\":\"clightning.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"LND\",\"service\":\"lnd.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"Ride The Lightning\",\"service\":\"rtl.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"BTCPayserver\",\"service\":\"btcpayserver.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"Matrix-Synapse\",\"service\":\"matrix-synapse.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"Coturn\",\"service\":\"coturn.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"VaultWarden\",\"service\":\"vaultwarden.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"Caddy\",\"service\":\"caddy.service\",\"type\":\"system\"}"
|
||||||
|
"{\"name\":\"Tor\",\"service\":\"tor.service\",\"type\":\"system\"}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/shell/extensions/vitals" = {
|
||||||
|
hot-sensors = [
|
||||||
|
"_storage_free_"
|
||||||
|
"_processor_usage_"
|
||||||
|
"_memory_usage_"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gnome/software" = {
|
||||||
|
first-run = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
"org/gtk/gtk4/settings/color-chooser" = {
|
||||||
|
selected-color = mkTuple [ true 0.0 0.0 0.0 1.0 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
}
|
||||||
234
modules/credentials-pdf.nix
Normal file
234
modules/credentials-pdf.nix
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# ── 1. Auto-Generate Root Password (Runs once) ─────────────
|
||||||
|
systemd.services.root-password-setup = {
|
||||||
|
description = "Generate and set a random root password";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
path = [ pkgs.pwgen pkgs.shadow pkgs.coreutils ];
|
||||||
|
script = ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SECRET_FILE="/var/lib/secrets/root-password"
|
||||||
|
|
||||||
|
if [ ! -f "$SECRET_FILE" ]; then
|
||||||
|
mkdir -p /var/lib/secrets
|
||||||
|
ROOT_PASS=$(pwgen -s 20 1)
|
||||||
|
|
||||||
|
# Apply the password to the root user
|
||||||
|
echo "root:$ROOT_PASS" | chpasswd
|
||||||
|
|
||||||
|
# Save it for the PDF generator to read
|
||||||
|
echo "$ROOT_PASS" > "$SECRET_FILE"
|
||||||
|
chmod 600 "$SECRET_FILE"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# ── 2. The Path Watcher (The Magic Trigger!) ───────────────
|
||||||
|
# This tells NixOS: "If any files inside these folders change,
|
||||||
|
# instantly run the generate-credentials-pdf service."
|
||||||
|
systemd.paths.generate-credentials-pdf-trigger = {
|
||||||
|
description = "Watch for new secret files to regenerate Magic Keys PDF";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
pathConfig = {
|
||||||
|
# Watch these directories for new passwords
|
||||||
|
PathChanged = [
|
||||||
|
"/var/lib/secrets"
|
||||||
|
"/var/lib/gnome-remote-desktop"
|
||||||
|
"/var/lib/domains"
|
||||||
|
"/etc/nix-bitcoin-secrets"
|
||||||
|
];
|
||||||
|
# Watch for these specific Tor links to be generated
|
||||||
|
PathExists = [
|
||||||
|
"/var/lib/tor/onion/rtl/hostname"
|
||||||
|
"/var/lib/tor/onion/electrs/hostname"
|
||||||
|
"/var/lib/tor/onion/bitcoind/hostname"
|
||||||
|
];
|
||||||
|
Unit = "generate-credentials-pdf.service";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# ── 3. Generate the Magic Keys PDF ─────────────────────────
|
||||||
|
systemd.services.generate-credentials-pdf = {
|
||||||
|
description = "Generate Magic Keys PDF for Sovran_SystemsOS";
|
||||||
|
# We remove RemainAfterExit so this service can be triggered over and over again!
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
|
||||||
|
path = [ pkgs.pandoc pkgs.typst pkgs.coreutils ];
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Give it a tiny delay so multiple files being created at once don't trigger it 10 times in a row
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
DOC_DIR="/home/free/Documents"
|
||||||
|
mkdir -p "$DOC_DIR"
|
||||||
|
FILE="/tmp/magic_keys.md"
|
||||||
|
|
||||||
|
ROOT_PASS="Generating..."
|
||||||
|
if [ -f "/var/lib/secrets/root-password" ]; then
|
||||||
|
ROOT_PASS=$(cat /var/lib/secrets/root-password)
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat << 'EOF' > "$FILE"
|
||||||
|
# Your Sovran SystemsOS Magic Keys! 🗝️
|
||||||
|
|
||||||
|
Welcome to your new computer! We have built a lot of cool secret forts (services) for you. To get into your forts, you need your magic keys (passwords).
|
||||||
|
|
||||||
|
Here are all of your keys in one place. **Keep this document safe and do not share it with strangers!**
|
||||||
|
|
||||||
|
## 🖥️ Your Computer
|
||||||
|
These are the master keys to the actual machine.
|
||||||
|
|
||||||
|
### 1. Main Screen Unlock (The 'free' account)
|
||||||
|
When you turn the computer on, it usually logs you in automatically. However, if the screen goes to sleep, or **if you enable Remote Desktop (RDP)**, you will need this to log in:
|
||||||
|
- **Username:** `free`
|
||||||
|
- **Password:** `free`
|
||||||
|
|
||||||
|
🚨 **VERY IMPORTANT:** You MUST write this password down and keep it safe! If you lose it, you will be locked out of your computer!
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat << EOF >> "$FILE"
|
||||||
|
|
||||||
|
### 2. The Big Boss (Root)
|
||||||
|
Sometimes a pop-up box might ask for an Administrator (Root) password to change a setting. We created a super-secret password just for this!
|
||||||
|
- **Root Password:** \`$ROOT_PASS\`
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat << 'EOF' >> "$FILE"
|
||||||
|
|
||||||
|
### 3. The Hacker Terminal (`ssh root@localhost`)
|
||||||
|
Because your main account is so safe, you cannot just type normal commands to become the boss. If you open a black terminal box and want to make big changes, you must use your special factory key!
|
||||||
|
|
||||||
|
Type this exact command into the terminal:
|
||||||
|
`ssh root@localhost`
|
||||||
|
|
||||||
|
When it asks for a passphrase, type:
|
||||||
|
- **Terminal Password:** `gosovransystems`
|
||||||
|
|
||||||
|
---
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# --- BITCOIN ECOSYSTEM ---
|
||||||
|
if [ -f "/etc/nix-bitcoin-secrets/rtl-password" ] || [ -f "/var/lib/tor/onion/rtl/hostname" ]; then
|
||||||
|
echo "## ⚡ Your Bitcoin & Lightning Node" >> "$FILE"
|
||||||
|
echo "Your computer is a real Bitcoin node! It talks to the network secretly using Tor. Here is how to connect your wallet apps to it:" >> "$FILE"
|
||||||
|
|
||||||
|
RTL_ONION="Not generated yet"
|
||||||
|
if [ -f "/var/lib/tor/onion/rtl/hostname" ]; then
|
||||||
|
RTL_ONION=$(cat /var/lib/tor/onion/rtl/hostname)
|
||||||
|
fi
|
||||||
|
RTL_PASS="Not found"
|
||||||
|
if [ -f "/etc/nix-bitcoin-secrets/rtl-password" ]; then
|
||||||
|
RTL_PASS=$(cat /etc/nix-bitcoin-secrets/rtl-password)
|
||||||
|
fi
|
||||||
|
|
||||||
|
ELECTRS_ONION="Not generated yet"
|
||||||
|
if [ -f "/var/lib/tor/onion/electrs/hostname" ]; then
|
||||||
|
ELECTRS_ONION=$(cat /var/lib/tor/onion/electrs/hostname)
|
||||||
|
fi
|
||||||
|
|
||||||
|
BITCOIN_ONION="Not generated yet"
|
||||||
|
if [ -f "/var/lib/tor/onion/bitcoind/hostname" ]; then
|
||||||
|
BITCOIN_ONION=$(cat /var/lib/tor/onion/bitcoind/hostname)
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat << BITCOIN >> "$FILE"
|
||||||
|
### 1. Ride The Lightning (RTL)
|
||||||
|
*This is the control panel for your Lightning Node.*
|
||||||
|
Open the **Tor Browser** and go to this website. Use this password to log in:
|
||||||
|
- **Website:** \`http://$RTL_ONION\`
|
||||||
|
- **Password:** \`$RTL_PASS\`
|
||||||
|
|
||||||
|
### 2. Electrs (Your Private Bank Teller)
|
||||||
|
*If you use a wallet app on your phone or computer (like Sparrow or BlueWallet), tell it to connect here so nobody can spy on your money!*
|
||||||
|
- **Tor Address:** \`$ELECTRS_ONION\`
|
||||||
|
- **Port:** \`50001\`
|
||||||
|
|
||||||
|
### 3. Bitcoin Core
|
||||||
|
*This is the heartbeat of your node. It uses this address to talk to other Bitcoiners securely.*
|
||||||
|
- **Tor Address:** \`$BITCOIN_ONION\`
|
||||||
|
|
||||||
|
---
|
||||||
|
BITCOIN
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- MATRIX / ELEMENT ---
|
||||||
|
if [ -f "/var/lib/secrets/matrix-users" ]; then
|
||||||
|
echo "## 💬 Your Private Chat (Matrix / Element)" >> "$FILE"
|
||||||
|
echo "This is your very own private messaging app! We created an Admin account for you, and a Test account you can give to a friend to try it out. Log in using an app like Element with these details:" >> "$FILE"
|
||||||
|
echo '```text' >> "$FILE"
|
||||||
|
cat /var/lib/secrets/matrix-users >> "$FILE"
|
||||||
|
echo '```' >> "$FILE"
|
||||||
|
echo "---" >> "$FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- GNOME RDP ---
|
||||||
|
if [ -f "/var/lib/gnome-remote-desktop/rdp-credentials" ]; then
|
||||||
|
echo "## 🌎 Connect from Far Away (Remote Desktop)" >> "$FILE"
|
||||||
|
echo "This lets you control your computer screen from another device! Open your Remote Desktop app and type in these keys:" >> "$FILE"
|
||||||
|
echo '```text' >> "$FILE"
|
||||||
|
cat /var/lib/gnome-remote-desktop/rdp-credentials >> "$FILE"
|
||||||
|
echo '```' >> "$FILE"
|
||||||
|
echo "---" >> "$FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- NEXTCLOUD ---
|
||||||
|
if [ -f "/var/lib/secrets/nextcloud-admin" ]; then
|
||||||
|
echo "## ☁️ Your Personal Cloud (Nextcloud)" >> "$FILE"
|
||||||
|
echo "This is like your own private Google Drive! You can save photos and files here. Go to the URL below and use these keys:" >> "$FILE"
|
||||||
|
echo '```text' >> "$FILE"
|
||||||
|
cat /var/lib/secrets/nextcloud-admin >> "$FILE"
|
||||||
|
echo '```' >> "$FILE"
|
||||||
|
echo "---" >> "$FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- WORDPRESS ---
|
||||||
|
if [ -f "/var/lib/secrets/wordpress-admin" ]; then
|
||||||
|
echo "## 📝 Your Website (WordPress)" >> "$FILE"
|
||||||
|
echo "This is your very own website where you can write blogs or make pages. Go to the URL below to log in:" >> "$FILE"
|
||||||
|
echo '```text' >> "$FILE"
|
||||||
|
cat /var/lib/secrets/wordpress-admin >> "$FILE"
|
||||||
|
echo '```' >> "$FILE"
|
||||||
|
echo "---" >> "$FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- VAULTWARDEN ---
|
||||||
|
if [ -f "/var/lib/domains/vaultwarden" ]; then
|
||||||
|
DOMAIN=$(cat /var/lib/domains/vaultwarden)
|
||||||
|
echo "## 🔐 Your Password Manager (Vaultwarden)" >> "$FILE"
|
||||||
|
echo "This keeps all your other passwords safe! Go to this website to use it:" >> "$FILE"
|
||||||
|
echo "- **Website:** https://$DOMAIN" >> "$FILE"
|
||||||
|
echo "*(Note: You get to make up your own Master Password the very first time you visit this website!)*" >> "$FILE"
|
||||||
|
echo "---" >> "$FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- BTCPAY SERVER ---
|
||||||
|
if [ -f "/var/lib/domains/btcpayserver" ]; then
|
||||||
|
DOMAIN=$(cat /var/lib/domains/btcpayserver)
|
||||||
|
echo "## ₿ Your Bitcoin Store (BTCPay Server)" >> "$FILE"
|
||||||
|
echo "This lets you accept Bitcoin like a real shop! Go to this website to set it up:" >> "$FILE"
|
||||||
|
echo "- **Website:** https://$DOMAIN" >> "$FILE"
|
||||||
|
echo "*(Note: You get to make up your own Admin Password the very first time you visit this website!)*" >> "$FILE"
|
||||||
|
echo "---" >> "$FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Convert the Markdown text into a beautiful PDF!
|
||||||
|
pandoc "$FILE" -o "$DOC_DIR/Sovran_SystemsOS_Magic_Keys.pdf" --pdf-engine=typst
|
||||||
|
|
||||||
|
# Make sure the 'free' user owns the file so they can open it
|
||||||
|
chown -R free:users "$DOC_DIR"
|
||||||
|
|
||||||
|
# Secure the markdown file
|
||||||
|
chmod 600 "$FILE"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -9,10 +9,12 @@
|
|||||||
./core/njalla.nix
|
./core/njalla.nix
|
||||||
./core/ssh-bootstrap.nix
|
./core/ssh-bootstrap.nix
|
||||||
./core/sovran-manage-domains.nix
|
./core/sovran-manage-domains.nix
|
||||||
|
./core/sovran_systemsos-desktop.nix
|
||||||
|
|
||||||
# ── Always on (no flag) ───────────────────────────────────
|
# ── Always on (no flag) ───────────────────────────────────
|
||||||
./php.nix
|
./php.nix
|
||||||
./Sovran_SystemsOS_File_Fixes_And_New_Services.nix
|
./Sovran_SystemsOS_File_Fixes_And_New_Services.nix
|
||||||
|
./credentials-pdf.nix
|
||||||
|
|
||||||
# ── Services (default ON — disable in custom.nix) ─────────
|
# ── Services (default ON — disable in custom.nix) ─────────
|
||||||
./synapse.nix
|
./synapse.nix
|
||||||
|
|||||||
@@ -139,6 +139,72 @@ EOF
|
|||||||
|
|
||||||
systemd.services.matrix-synapse.after = [ "matrix-synapse-secret-init.service" ];
|
systemd.services.matrix-synapse.after = [ "matrix-synapse-secret-init.service" ];
|
||||||
systemd.services.matrix-synapse.wants = [ "matrix-synapse-secret-init.service" ];
|
systemd.services.matrix-synapse.wants = [ "matrix-synapse-secret-init.service" ];
|
||||||
|
|
||||||
|
|
||||||
|
# ── Auto-generate Admin and Test users ──────────────────────
|
||||||
|
systemd.services.matrix-synapse-create-users = {
|
||||||
|
description = "Create Admin and Test users for Matrix Synapse";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "matrix-synapse.service" ];
|
||||||
|
requires = [ "matrix-synapse.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
path = [ pkgs.pwgen pkgs.matrix-synapse pkgs.curl pkgs.coreutils pkgs.jq ];
|
||||||
|
script = ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Wait for Synapse to be fully responsive
|
||||||
|
for i in {1..30}; do
|
||||||
|
if curl -s http://localhost:8008/_matrix/client/versions > /dev/null; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
DOMAIN=$(cat /var/lib/domains/matrix)
|
||||||
|
CREDS_FILE="/var/lib/secrets/matrix-users"
|
||||||
|
SECRET=$(cat /var/lib/matrix-synapse/registration-secret)
|
||||||
|
|
||||||
|
# Only run if we haven't already generated the file
|
||||||
|
if [ ! -f "$CREDS_FILE" ]; then
|
||||||
|
mkdir -p /var/lib/secrets
|
||||||
|
|
||||||
|
ADMIN_USER="admin"
|
||||||
|
ADMIN_PASS=$(pwgen -s 24 1)
|
||||||
|
|
||||||
|
TEST_USER="test"
|
||||||
|
TEST_PASS=$(pwgen -s 24 1)
|
||||||
|
|
||||||
|
# Create Admin user
|
||||||
|
register_new_matrix_user -c /run/matrix-synapse/runtime-config.yaml \
|
||||||
|
-u "$ADMIN_USER" -p "$ADMIN_PASS" -a -S "$SECRET" http://localhost:8008
|
||||||
|
|
||||||
|
# Create Test user (non-admin)
|
||||||
|
register_new_matrix_user -c /run/matrix-synapse/runtime-config.yaml \
|
||||||
|
-u "$TEST_USER" -p "$TEST_PASS" --no-admin -S "$SECRET" http://localhost:8008
|
||||||
|
|
||||||
|
# Save the credentials
|
||||||
|
cat > "$CREDS_FILE" << CREDS
|
||||||
|
Matrix (Element) Credentials
|
||||||
|
════════════════════════════
|
||||||
|
Homeserver URL: https://$DOMAIN
|
||||||
|
|
||||||
|
[ Admin Account ]
|
||||||
|
Username: @$ADMIN_USER:$DOMAIN
|
||||||
|
Password: $ADMIN_PASS
|
||||||
|
|
||||||
|
[ Test Account ]
|
||||||
|
Username: @$TEST_USER:$DOMAIN
|
||||||
|
Password: $TEST_PASS
|
||||||
|
CREDS
|
||||||
|
|
||||||
|
chmod 600 "$CREDS_FILE"
|
||||||
|
echo "Matrix users created successfully."
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
sovran_systemsOS.domainRequirements = [
|
sovran_systemsOS.domainRequirements = [
|
||||||
{ name = "matrix"; label = "Matrix Synapse"; example = "matrix.yourdomain.com"; }
|
{ name = "matrix"; label = "Matrix Synapse"; example = "matrix.yourdomain.com"; }
|
||||||
|
|||||||
Reference in New Issue
Block a user