From 355e35b9f6cda972b995b581f80a7117b86b04f3 Mon Sep 17 00:00:00 2001 From: naturallaw77 Date: Thu, 1 Jun 2023 05:47:05 -0700 Subject: [PATCH] initial add --- For_NEW_Sovran_Pros_Upload/flake.nix | 14 + For_NEW_Sovran_Pros_Upload/sp | 197 ++++++++++++ README.md | 30 +- flake.lock | 122 ++++++++ flake.nix | 28 ++ modules/bitcoinecosystem.nix | 76 +++++ modules/configuration.nix | 434 +++++++++++++++++++++++++++ modules/coturn.nix | 51 ++++ modules/modules.nix | 13 + modules/personalization.nix | 17 ++ modules/synapse.nix | 75 +++++ modules/vaultwarden.nix | 21 ++ sovran_systems.png | Bin 0 -> 23137 bytes 13 files changed, 1076 insertions(+), 2 deletions(-) create mode 100644 For_NEW_Sovran_Pros_Upload/flake.nix create mode 100644 For_NEW_Sovran_Pros_Upload/sp create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 modules/bitcoinecosystem.nix create mode 100644 modules/configuration.nix create mode 100644 modules/coturn.nix create mode 100644 modules/modules.nix create mode 100644 modules/personalization.nix create mode 100644 modules/synapse.nix create mode 100644 modules/vaultwarden.nix create mode 100644 sovran_systems.png diff --git a/For_NEW_Sovran_Pros_Upload/flake.nix b/For_NEW_Sovran_Pros_Upload/flake.nix new file mode 100644 index 0000000..7d9c4e8 --- /dev/null +++ b/For_NEW_Sovran_Pros_Upload/flake.nix @@ -0,0 +1,14 @@ +{ + description = "The Ultimate Sovran Pro Configuration from Sovran Systems"; + + inputs = { + Sovran_Systems.url = "git+https://git.sovransystems.com/Sovran_Systems/Sovran_Pro"; + }; + + outputs = { self, Sovran_Systems, ... }@inputs: { + nixosConfigurations."nixos" = Sovran_Systems.inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ Sovran_Systems.nixosModules.Sovran_Pro ]; + }; + }; +} \ No newline at end of file diff --git a/For_NEW_Sovran_Pros_Upload/sp b/For_NEW_Sovran_Pros_Upload/sp new file mode 100644 index 0000000..701e52e --- /dev/null +++ b/For_NEW_Sovran_Pros_Upload/sp @@ -0,0 +1,197 @@ +#!/usr/bin/env bash + +GREEN="\e[32m" +LIGHTBLUE="\e[94m" +ENDCOLOR="\e[0m" + +# + +pushd /etc/nixos/ + +sudo wget https://git.sovransystems.com/Sovran_Systems/Sovran_Pro/raw/branch/main/For_NEW_Sovran_Pros_Upload/flake.nix + +sudo chown root:root /etc/nixos/ -R + +sudo chmod 770 /etc/nixos/ -R + +popd + +# + +sudo rsync -av -e "ssh -i /root/sovransystems" root@192.168.1.32:/home/ /home + +sudo rsync -av -e "ssh -i /root/sovransystems" root@192.168.1.32:/var/lib/www/ /var/lib/www + +sudo rsync -av -e "ssh -i /root/sovransystems" root@192.168.1.32:/var/lib/domains/ /var/lib/domains + +sudo rsync -av -e "ssh -i /root/sovransystems" root@192.168.1.32:/var/lib/nextcloudaddition/ /var/lib/nextcloudaddition + +sudo rsync -av -e "ssh -i /root/sovransystems" root@192.168.1.32:/var/lib/njalla/ /var/lib/njalla + +sudo rsync -av -e "ssh -i /root/sovransystems" root@192.168.1.32:/var/lib/external_ip/ /var/lib/external_ip + +sudo rsync -av -e "ssh -i /root/sovransystems" root@192.168.1.32:/var/lib/secrets/ /var/lib/secrets + +# + +nixos-rebuild switch --flake '/etc/nixos/#' --impure --update-input Sovran_Systems --commit-lock-file + +# + +sudo chown root:root /var/lib/secrets/main -R + +sudo chown matrix-synapse:matrix-synapse /var/lib/secrets/matrix_reg_secret -R + +sudo chown matrix-synapse:matrix-synapse /var/lib/secrets/matrixdb -R + +sudo chown postgres:postgres /var/lib/secrets/nextclouddb -R + +sudo chown turnserver:turnserver /var/lib/secrets/turn -R + +sudo chown mysql:mysql /var/lib/secrets/wordpressdb -R + +sudo chmod 770 /var/lib/secrets/ -R + +# + +sudo echo -e "${GREEN}What is your New Matrix (Element Chat) domain name?${ENDCOLOR}" +read +sudo echo -n $REPLY > /var/lib/domains/matrix + +sudo echo -e "${GREEN}What is your New Wordpress domain name?${ENDCOLOR}" +read +sudo echo -n $REPLY > /var/lib/domains/wordpress + +sudo echo -e "${GREEN}What is your New Nextcloud domain name?${ENDCOLOR}" +read +sudo echo -n $REPLY > /var/lib/domains/nextcloud + +sudo echo -e "${GREEN}What is your New BTCPayserver domain name?${ENDCOLOR}" +read +sudo echo -n $REPLY > /var/lib/domains/btcpayserver + +sudo echo -e "${GREEN}What is your New Vaultwarden domain name?${ENDCOLOR}" +read +sudo echo -n $REPLY > /var/lib/domains/vaultwarden + +sudo echo -e "${GREEN}What is the email you would like to use to manage the SSL certificates for your domains?${ENDCOLOR}" +read +sudo echo -n $REPLY > /var/lib/domains/sslemail + + +sudo chown caddy:php /var/lib/domains -R + +sudo chmod 770 /var/lib/domains -R + +# + +set -x + + +sudo rm -rf /home/free/.config/BraveSoftware + +sudo rm -rf /home/free/.local/share/fish/fish_history + +# + +sudo rm -rf /var/lib/www/wordpress/wp-config.php + +sudo rm -rf /var/lib/www/nextcloud/config/config.php + +sudo touch /var/lib/www/nextcloud/config/CAN_INSTALL + +sudo sed -i '$e cat /var/lib/nextcloudaddition/nextcloudaddition' /var/lib/www/nextcloud/config/config.php + + +sudo chown caddy:php /var/lib/www -R + +sudo chmod 770 /var/lib/www -R + +# + +sudo mkdir /var/lib/nextcloud + +sudo chown caddy:php /var/lib/nextcloud -R + +sudo chmod 770 /var/lib/nextcloud -R + +# + +sudo mkdir /var/lib/coturn + +sudo chown turnserver:turnserver /var/lib/coturn -R + +sudo chmod 770 /var/lib/coturn -R + +# + +sudo touch /var/lib/vaultwarden.env + +sudo chown vaultwarden:vaultwarden /var/lib/vaultwarden.env + +sudo chmod 770 /var/lib/vaultwarden.env + +# + +sudo echo -n $(pwgen -s 17 -1) > /var/lib/secrets/nextclouddb +sudo echo -n $(pwgen -s 17 -1) > /var/lib/secrets/wordpressdb +sudo echo -n $(pwgen -s 17 -1) > /var/lib/secrets/matrixdb +sudo echo -n $(pwgen -s 17 -1) > /var/lib/secrets/turn +sudo echo -n $(pwgen -s 17 -1) > /var/lib/secrets/matrix_reg_secret +sudo echo -n $(pwgen -s 17 -1) > /var/lib/secrets/main +sudo echo -n ADMIN_TOKEN=$(openssl rand -base64 48 +) > /var/lib/vaultwarden.env + +# + +sudo echo "root:$(cat /var/lib/secrets/main)" | chpasswd -c SHA512 + +# + +flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo +flatpak update + +# + +sudo echo "free:a" | chpasswd -c SHA512 + +# + +sudo rm -rf /root/sp + +sudo rm -rf /root/Step_2_psp + +sudo rm -rf /root/.ssh + +sudo rm -rf /home/free/.ssh + +sudo rm -rf /root/sovransystems + + +sudo chown bitcoin:bitcoin /run/media/Second_Drive/BTCEcoandBackup/Bitcoin_Node -R + +sudo chmod 770 /run/media/Second_Drive/BTCEcoandBackup/Bitcoin_Node -R + +sudo chown electrs:electrs /run/media/Second_Drive/BTCEcoandBackup/Electrs_Data -R + +sudo chmod 770 /run/media/Second_Drive/BTCEcoandBackup/Electrs_Data -R + +nixos-rebuild switch --flake '/etc/nixos/#' --impure --update-input Sovran_Systems --commit-lock-file + + +# + +set +x + +sudo echo -e "${GREEN}These four passwords are generated for convenience to use for the Web front end setup UI accounts for Nextcloud, Wordpress, VaultWarden, and BTCPayserver (if you want to use them).${ENDCOLOR} \n" + +sudo echo -e "$(pwgen -s 17 -1) \n" +sudo echo -e "$(pwgen -s 17 -1) \n" +sudo echo -e "$(pwgen -s 17 -1) \n" +sudo echo -e "$(pwgen -s 17 -1) \n" + +# + +sudo echo -e "${LIGHTBLUE}One last thing, you need to put the Njalla DDNS info from Njalla into njalla.sh.${ENDCOLOR} \n" + +sudo echo -e "${GREEN}All Finished! Please Reboot then Enjoy your New Sovran Pro!${ENDCOLOR} \n" \ No newline at end of file diff --git a/README.md b/README.md index b8fcfa8..62621c7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,29 @@ -# Sovran_SystemsOS +
+
-The Official Repository of Sovran_SystemsOS. \ No newline at end of file +
drawing
+ +
+
+
+# Complete Configuration for Sovran_SystemsOS and the Sovran Pro +________________________________________________________ + +A Nix Flake Implementation + +Thanks to all the NixOS creators and developers for creating what is the future of computing. + +https://www.sovransystems.com + +Connect on Matrix here: https://matrix.to/#/#sovran-systems:anarchyislove.xyz + +_________________________________________________________ +GNU GPL 3.0+ + +All Open Source Software Used Falls Under Its Specific Open Source License. + +Created, Handcrafted, and Headquartered in Southern California – 2022-2023 🏖️. + +This Gitea is Proudly Powered by a Sovran Pro 💚. + +All Is Love. Fear Is Illusion. All Beings Are Free. Truth Can Never Be Destroyed. \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..8a39b31 --- /dev/null +++ b/flake.lock @@ -0,0 +1,122 @@ +{ + "nodes": { + "extra-container": { + "inputs": { + "flake-utils": [ + "nix-bitcoin", + "flake-utils" + ], + "nixpkgs": [ + "nix-bitcoin", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1678566036, + "narHash": "sha256-dq+gCYplCTkbHOH1ERCzuTnwY/RvwMyw/kijPy7C3vE=", + "owner": "erikarvstedt", + "repo": "extra-container", + "rev": "a4fe3227bf63bf8479938e1457ebe1c04fe51ef5", + "type": "github" + }, + "original": { + "owner": "erikarvstedt", + "repo": "extra-container", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1678901627, + "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nix-bitcoin": { + "inputs": { + "extra-container": "extra-container", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "nixpkgs-unstable": "nixpkgs-unstable" + }, + "locked": { + "lastModified": 1679384842, + "narHash": "sha256-SMJW+QZt3iRuoezjE12sopBsdLHDihXe/RerLfRpqoI=", + "owner": "fort-nix", + "repo": "nix-bitcoin", + "rev": "481050bdf75106bff652016bfe5c39736bdd03ef", + "type": "github" + }, + "original": { + "owner": "fort-nix", + "ref": "release", + "repo": "nix-bitcoin", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1679139072, + "narHash": "sha256-Gtw2Yj8DfETie3u7iHv1y5Wt+plGRmp6nTQ0EEfaPho=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "08ef7dc8334521605a5c8b7086cc248e74ee338b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1679198465, + "narHash": "sha256-VfXpHpniNWgg7pBzxb20pRX7kqn80LApPDQYTReiFCw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5a05160f7671434e1c833b1b01284b876e04eca4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1681217261, + "narHash": "sha256-RbxCHWN3Vhyv/WEsXcJlDwF7bpvZ9NxDjfSouQxXEKo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3fb8eedc450286d5092e4953118212fa21091b3b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nix-bitcoin": "nix-bitcoin", + "nixpkgs": "nixpkgs_2" + } + } + }, + "root": "root", + "version": 7 +} \ No newline at end of file diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..243b4e3 --- /dev/null +++ b/flake.nix @@ -0,0 +1,28 @@ +{ + description = "The Ultimate Sovran Pro Configuration from Sovran Systems"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + nix-bitcoin.url = "github:fort-nix/nix-bitcoin/release"; + }; + + outputs = { self, nixpkgs, nix-bitcoin, ... }: + { + + nixosConfigurations.nixos = nixpkgs.lib.nixosSystem { + system ="x86_64-linux"; + }; + + nixosModules.Sovran_Pro = { pkgs, ... }: { + + imports = [ + + ./modules/modules.nix + + nix-bitcoin.nixosModules.default + + ]; + }; + }; +} \ No newline at end of file diff --git a/modules/bitcoinecosystem.nix b/modules/bitcoinecosystem.nix new file mode 100644 index 0000000..0f8e45d --- /dev/null +++ b/modules/bitcoinecosystem.nix @@ -0,0 +1,76 @@ +{ config, pkgs, lib, ... }: + +{ + nix-bitcoin.generateSecrets = true; + + services.bitcoind = { + enable = true; + dataDir = "/run/media/Second_Drive/BTCEcoandBackup/Bitcoin_Node"; + txindex = true; + tor.proxy = true; + disablewallet = true; + extraConfig = '' + peerbloomfilters=1 + server=1 + ''; + }; + + nix-bitcoin.onionServices.bitcoind.enable = true; + nix-bitcoin.onionServices.electrs.enable = true; + + services.lnd = { + enable = true; + }; + + services.lightning-loop = { + enable = true; + }; + + services.lightning-pool = { + enable = true; + }; + + services.rtl = { + enable = true; + port = 3050; + nightTheme = true; + nodes = { + lnd = { + enable = true; + loop = true; + }; + reverseOrder = true; + }; + }; + + nix-bitcoin.onionServices.lnd.public = true; + services.lnd.lndconnect = { + enable = true; + onion = true; + }; + services.charge-lnd.enable = true; + + services.btcpayserver.lightningBackend = "lnd"; + + + services.electrs = { + enable = true; + tor.enforce = true; + dataDir = "/run/media/Second_Drive/BTCEcoandBackup/Electrs_Data"; + }; + + + services.btcpayserver = { + enable = true; + }; + + + nix-bitcoin.nodeinfo.enable = true; + + + nix-bitcoin.operator = { + enable = true; + name = "free"; + }; + +} diff --git a/modules/configuration.nix b/modules/configuration.nix new file mode 100644 index 0000000..bf43b2e --- /dev/null +++ b/modules/configuration.nix @@ -0,0 +1,434 @@ +{ config, pkgs, lib, ... }: + + +let + personalization = import ./personalization.nix; + + + custom-php = pkgs.php81.buildEnv { + extensions = { enabled, all }: enabled ++ (with all; [ apcu imagick memcached ]); + extraConfig = '' + display_errors = On + display_startup_errors = On + max_execution_time = 6000 + max_input_time = 3000 + memory_limit = 8G; + opcache.enable=1; + opcache.memory_consumption=512; + opcache_revalidate_freq = 240; + opcache.max_accelerated_files=4000; + auto_prepend_file = '/var/lib/www/wordpress/wordfence-waf.php' + post_max_size = 2048M + upload_max_filesize = 2048M + opcache.interned_strings_buffer = 32 + apc.enable_cli=1 + ''; + }; +in +{ + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + boot.loader.efi.efiSysMountPoint = "/boot/efi"; + boot.kernelPackages = pkgs.linuxPackages_latest; + + # Enable Automount without Fail for Internal Drive. + fileSystems."/run/media/Second_Drive" = { + device = "LABEL=BTCEcoandBackup"; + fsType = "ext4"; + options = [ "nofail" ]; + }; + + nix = { + package = pkgs.nixUnstable; + extraOptions = '' + experimental-features = nix-command flakes + ''; + }; + + networking.hostName = "nixos"; # Define your hostname. + # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. + + # Enable networking + networking.networkmanager.enable = true; + + # Set your time zone. + time.timeZone = "America/Los_Angeles"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + # Enable the X11 windowing system. + services.xserver.enable = true; + + # Enable the GNOME Desktop Environment. + services.xserver.displayManager.gdm.enable = true; + services.xserver.desktopManager.gnome.enable = true; + + # Configure keymap in X11 + services.xserver = { + layout = "us"; + xkbVariant = ""; + }; + + # Enable CUPS to print documents. + services.printing.enable = true; + + # Systemd Settings + systemd.enableEmergencyMode = false; + + # Enable sound with pipewire. + sound.enable = true; + hardware.pulseaudio.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + }; + + users.users = { + free = { + isNormalUser = true; + description = "free"; + extraGroups = [ "networkmanager" ]; + }; + + +####### PHP user for PHPFPM ####### + php = { + isSystemUser = true; + createHome = false; + uid = 7777; + }; + }; + + users.users.php.group = "php"; + users.groups.php = {}; + + + + # Enable automatic login for the user. + services.xserver.displayManager.autoLogin.enable = true; + services.xserver.displayManager.autoLogin.user = "free"; + + # Workaround for GNOME autologin: https://github.com/NixOS/nixpkgs/issues/103746#issuecomment-945091229 + systemd.services."getty@tty1".enable = true; + systemd.services."autovt@tty1".enable = true; + + # Allow Flatpak + services.flatpak.enable = true; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + git + wget + librewolf + fish + htop + gnomeExtensions.dash-to-dock-for-cosmic + gnomeExtensions.vitals + gnomeExtensions.pop-shell + gnomeExtensions.transparent-top-bar + gnomeExtensions.just-perfection + gnomeExtensions.appindicator + gnomeExtensions.systemd-manager + gnome.gnome-tweaks + papirus-icon-theme + ranger + gnome.gnome-tweaks + sparrow + bisq-desktop + neofetch + gnome.gedit + matrix-synapse + openssl + pwgen + aspell + aspellDicts.en + lm_sensors + hunspell + hunspellDicts.en_US + custom-php + matrix-synapse-tools.synadm + brave + ncdu_2 + bitwarden + gparted + pv + unzip + parted + screen + gnome.zenity + + ]; + + nixpkgs.config.permittedInsecurePackages = [ + "nodejs-16.20.0" + "nodejs-slim-16.20.0" + ]; + + + programs.bash.promptInit = "fish"; + programs.fish = { + enable = true; + promptInit = "neofetch"; + }; + + +####### PHPFMP ####### + services.phpfpm.pools = { + mypool = { + user = "caddy"; + group = "php"; + phpPackage = custom-php; + settings = { + "pm" = "dynamic"; + "pm.max_children" = 75; + "pm.start_servers" = 10; + "pm.min_spare_servers" = 5; + "pm.max_spare_servers" = 20; + "pm.max_requests" = 500; + "clear_env" = "no"; + }; + }; + }; + + + +####### CADDY ####### + services.caddy = { + enable = true; + package = pkgs.caddy; + user = "caddy"; + group = "root"; + email = "${personalization.caddy_email_for_zerossl}"; + acmeCA = "https://acme.zerossl.com/v2/DV90"; + virtualHosts = { + "${personalization.wordpress_url}" = { + extraConfig = '' + encode gzip zstd + root * /var/lib/www/wordpress + php_fastcgi unix//run/phpfpm/mypool.sock + file_server browse + ''; + }; + + "www.${personalization.wordpress_url}" = { + extraConfig = '' + encode gzip zstd + root * /var/lib/www/wordpress + php_fastcgi unix//run/phpfpm/mypool.sock + file_server browse + ''; + }; + + "${personalization.nextcloud_url}" = { + extraConfig = '' + encode gzip zstd + root * /var/lib/www/nextcloud + php_fastcgi unix//run/phpfpm/mypool.sock + file_server + redir /.well-known/carddav /remote.php/carddav 301 + redir /.well-known/caldav /remote.php/caldav 301 + header { + Strict-Transport-Security max-age=31536000; + } + ''; + }; + + "${personalization.matrix_url}" = { + extraConfig = '' + reverse_proxy /_matrix/* http://localhost:8008 + reverse_proxy /_synapse/client/* http://localhost:8008 + ''; + }; + + "${personalization.matrix_url}:8448" = { + extraConfig = '' + reverse_proxy http://localhost:8008 + ''; + }; + + "${personalization.btcpayserver_url}" = { + extraConfig = '' + reverse_proxy http://localhost:23000 + encode gzip zstd + ''; + }; + + "https://${personalization.vaultwarden_url}" = { + extraConfig = '' + reverse_proxy http://localhost:8777 + encode gzip zstd + ''; + }; + + ":3051" = { + extraConfig = '' + reverse_proxy :3050 + encode gzip zstd + tls internal + ''; + }; + }; + }; + + +###### CREATE DATABASE (WORDPRESS, MATRIX_SYNAPSE, AND NEXTCLOUD) ####### + services.postgresql = { + enable = true; + package = pkgs.postgresql_14; + }; + + services.postgresql.authentication = lib.mkForce '' + # Generated file; do not edit! + # TYPE DATABASE USER ADDRESS METHOD + local all all trust + host all all 127.0.0.1/32 trust + host all all ::1/128 trust + ''; + + + services.mysql = { + enable = true; + package = pkgs.mariadb_1011; + }; + + services.postgresql.initialScript = pkgs.writeText "begin-init.sql" '' + CREATE ROLE "ncusr" WITH LOGIN PASSWORD '${personalization.nextclouddb_pass}'; + CREATE DATABASE "nextclouddb" WITH OWNER "ncusr" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + + + CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD '${personalization.matrix-synapsedb_pass}'; + CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + + '' + ; + + services.mysql.initialScript = pkgs.writeText "wordpress-init.sql" '' + CREATE DATABASE wordpressdb; + GRANT ALL ON *.* TO 'wpusr'@'localhost' IDENTIFIED BY '${personalization.wordpressdb_pass}'; + FLUSH PRIVILEGES; + '' + ; + + + +####### KEEP AWAKE for DISPLAY and HEADLESS ####### + services.xserver.displayManager.gdm.autoSuspend = false; + + + +####### BACKUP TO INTERNAL DRIVE ####### + services.rsnapshot = { + enable = true; + extraConfig = '' +snapshot_root /run/media/Second_Drive/BTCEcoandBackup/NixOS_Snapshot_Backup +retain hourly 12 +retain daily 12 +backup /home/ localhost/ +backup /var/lib/ localhost/ +backup /etc/nixos/ localhost/ +backup /etc/nix-bitcoin-secrets/ localhost/ + ''; + cronIntervals = { + daily = "50 21 * * *"; + hourly = "0 * * * *"; + }; + }; + + + +####### CRON ####### + services.cron = { + enable = true; + systemCronJobs = [ + "*/5 * * * * caddy /run/current-system/sw/bin/php -f /var/lib/www/nextcloud/cron.php" + "15 * * * * root /var/lib/njalla/njalla.sh" + "0 */2 * * * root /var/lib/external_ip/external_ip.sh" + ]; + }; + + +####### TOR ####### + services.tor = { + enable = true; + client.enable = true; + torsocks.enable = true; + }; + services.privoxy.enableTor = true; + + + + +####### Enable the OpenSSH daemon ####### + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + PermitRootLogin = "yes"; + }; + }; + + +#######FailtoBan####### + services.fail2ban = { + enable = true; + ignoreIP = [ + "127.0.0.0/8" + "10.0.0.0/8" + "172.16.0.0/12" + "192.168.0.0/16" + "8.8.8.8" + ]; + }; + + +####### Open ports in the firewall ####### + networking.firewall.allowedTCPPorts = [ 80 443 5349 8448 3050 3051 ]; + networking.firewall.allowedUDPPorts = [ 80 443 5349 8448 3050 3051 ]; + networking.firewall.allowedUDPPortRanges = [ + { from=49152; to=65535; } # TURN relay + ]; + + # Or disable the firewall altogether. + networking.firewall.enable = true; + + + + +####### AUTO UPDATE ####### +# system.autoUpgrade = { +# enable = true; +# flags = [ "--impure" "--update-input" "Sovran_Systems" "--commit-lock-file" ]; +# flake = "/etc/nixos"; +# persistent = true; +# allowReboot = true; +# rebootWindow = { lower = "02:00"; upper = "05:00"; }; +# }; + + + +####### AUTO COLLECT GARABAGE ####### + nix.gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 7d"; + }; + + system.stateVersion = "22.05"; + +} diff --git a/modules/coturn.nix b/modules/coturn.nix new file mode 100644 index 0000000..d6de653 --- /dev/null +++ b/modules/coturn.nix @@ -0,0 +1,51 @@ +{config, pkgs, lib, ...}: + +let + personalization = import ./personalization.nix; + in +{ + systemd.services.sslcoturn = { + script = '' + cp -n /var/lib/caddy/.local/share/caddy/certificates/acme.zerossl.com-v2-dv90/${personalization.matrix_url}/${personalization.matrix_url}.crt /var/lib/coturn/${personalization.matrix_url}.crt.pem + + cp -n /var/lib/caddy/.local/share/caddy/certificates/acme.zerossl.com-v2-dv90/${personalization.matrix_url}/${personalization.matrix_url}.key /var/lib/coturn/${personalization.matrix_url}.key.pem + + chown turnserver:turnserver /var/lib/coturn -R + + chmod 770 /var/lib/coturn -R + + systemctl restart coturn + ''; + + unitConfig = { + Type = "simple"; + After = "NetworkManager.service"; + Requires = "network-online.target"; + }; + + serviceConfig = { + RemainAfterExit = "yes"; + Type = "oneshot"; + }; + + wantedBy = [ "multi-user.target" ]; + }; + + + services.coturn = { + enable = true; + use-auth-secret = true; + static-auth-secret = "${personalization.turn_shared}"; + realm = personalization.matrix_url; + cert = "/var/lib/coturn/${personalization.matrix_url}.crt.pem"; + pkey = "/var/lib/coturn/${personalization.matrix_url}.key.pem"; + min-port = 49152; + max-port = 65535; + no-cli = true; + #listening-ips = [ "127.0.0.1" ]; + extraConfig = '' + verbose + external-ip=${personalization.external_ip_secret} + ''; + }; +} diff --git a/modules/modules.nix b/modules/modules.nix new file mode 100644 index 0000000..518304e --- /dev/null +++ b/modules/modules.nix @@ -0,0 +1,13 @@ +{ config, pkgs, lib, ... }: + +{ + + imports = [ + ./configuration.nix + ./synapse.nix + ./coturn.nix + ./bitcoinecosystem.nix + ./vaultwarden.nix + /etc/nixos/hardware-configuration.nix + ]; +} \ No newline at end of file diff --git a/modules/personalization.nix b/modules/personalization.nix new file mode 100644 index 0000000..3310da5 --- /dev/null +++ b/modules/personalization.nix @@ -0,0 +1,17 @@ +{ + +matrix_url = builtins.readFile /var/lib/domains/matrix; +wordpress_url = builtins.readFile /var/lib/domains/wordpress; +nextcloud_url = builtins.readFile /var/lib/domains/nextcloud; +btcpayserver_url = builtins.readFile /var/lib/domains/btcpayserver; +caddy_email_for_zerossl = builtins.readFile /var/lib/domains/sslemail; +vaultwarden_url = builtins.readFile /var/lib/domains/vaultwarden; + +wordpressdb_pass = builtins.readFile /var/lib/secrets/wordpressdb; +matrix-synapsedb_pass = builtins.readFile /var/lib/secrets/matrixdb; +nextclouddb_pass = builtins.readFile /var/lib/secrets/nextclouddb; +turn_shared = builtins.readFile /var/lib/secrets/turn; +matrix_reg_secret = builtins.readFile /var/lib/secrets/matrix_reg_secret; +external_ip_secret = builtins.readFile /var/lib/secrets/external_ip; + +} diff --git a/modules/synapse.nix b/modules/synapse.nix new file mode 100644 index 0000000..76839ae --- /dev/null +++ b/modules/synapse.nix @@ -0,0 +1,75 @@ +{ config, pkgs, lib, ... }: + + +####### CREATE NEW USER (ADMIN OR NOT) VIA TERMINAL ####### + +# (Run as root in terminal) matrix-synapse-register_new_matrix_user # + +####### ####### + +let + personalization = import ./personalization.nix; +in +{ + services.matrix-synapse = { + enable = true; + settings = { + include_content = false; + group_unread_count_by_room = false; + encryption_enabled_by_default_for_room_type = "invite"; + allow_profile_lookup_over_federation = false; + allow_device_name_lookup_over_federation = false; + server_name = personalization.matrix_url; + url_preview_enabled = true; + max_upload_size = "1024M"; + url_preview_ip_range_blacklist = [ + "10.0.0.0/8" + "100.64.0.0/10" + "169.254.0.0/16" + "172.16.0.0/12" + "192.0.0.0/24" + "192.0.2.0/24" + "192.168.0.0/16" + "192.88.99.0/24" + "198.18.0.0/15" + "198.51.100.0/24" + "2001:db8::/32" + "203.0.113.0/24" + "224.0.0.0/4" + "::1/128" + "fc00::/7" + "fe80::/10" + "fec0::/10" + "ff00::/8" + ]; + url_preview_ip_ranger_whitelist = [ "127.0.0.1" ]; + turn_shared_secret = "${personalization.turn_shared}"; + turn_uris = [ + "turn:${personalization.matrix_url}:5349?transport=udp" + "turn:${personalization.matrix_url}:5349?transport=tcp" + "turns:${personalization.matrix_url}:5349?transport=udp" + "turns:${personalization.matrix_url}:5349?transport=tcp" + ]; + presence.enabled = true; + enable_registration = false; + registration_shared_secret = "${personalization.matrix_reg_secret}"; + listeners = [ + { + port = 8008; + bind_addresses = [ "::1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ { + names = [ "client" ]; + compress = true; + } + { + names = [ "federation" ]; + compress = false; + } ]; + } + ]; + }; + }; +} diff --git a/modules/vaultwarden.nix b/modules/vaultwarden.nix new file mode 100644 index 0000000..46b0678 --- /dev/null +++ b/modules/vaultwarden.nix @@ -0,0 +1,21 @@ +{ config, pkgs, lib, ... }: + +let + personalization = import ./personalization.nix; +in +{ + + services.vaultwarden = { + enable = true; + config = { + + DOMAIN = "https://${personalization.vaultwarden_url}"; + SIGNUPS_ALLOWED = false; + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = 8777; + ROCKET_LOG = "critical"; + }; + dbBackend = "sqlite"; + environmentFile = "/var/lib/vaultwarden.env"; + }; +} \ No newline at end of file diff --git a/sovran_systems.png b/sovran_systems.png new file mode 100644 index 0000000000000000000000000000000000000000..618f61e62581d9214459805f1f7a35bc1f977514 GIT binary patch literal 23137 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 bIXr>o*UDwLFWIYt5q#ILm>H7{5z+q#La)6? literal 0 HcmV?d00001