initial retooling

This commit is contained in:
2026-03-27 14:23:08 -05:00
commit 5057ed2a05
46 changed files with 4969 additions and 0 deletions

251
DIY Install Sovran_SystemsOS.md Executable file
View File

@@ -0,0 +1,251 @@
# Sovran Systems offers limited support of a DIY install of Sovran_SystemsOS. You can reach out to others in the matrix room https://matrix.to/#/#DIY_Sovran_SystemsOS:anarchyislove.xyz.
# These instructions will change over time due to new software development and Sovran Systems creator finding more efficient ways to install Sovran_SystemsOS. 9-12-2024
# Also, to fully complete the install, the Bitcoin blockchain will have to download. This could take up to 3 weeks.
# Lastly, if you gift to the computer movement <https://zaps.sovransystems.com> to receive a Sovran Pro, you do not have to do any of this. It is all done for you. On top of that, the Bitcoin blockchain is already installed. 😉
### Requirements
1. First computer with Linux OS already installed (like NixOS, Ubuntu, Arch, etc.) to download and burn the NixOS image to a USB thumb drive.
2. USB thumb drive 16GB or larger
3. Second computer that is ready to have Sovran_SystemsOS installed (Safe Boot turned off in the UEFI[BIOS] and be prepared for the entire storage drive to be ERASED!).
4. Second computer needs the following hardware specs:
- Intel or AMD processor (NO ARM processors)
- 32GB of RAM or Larger
- First main NVME internal drive to install Sovran_SystemsOS (500GB or larger)
- Second NVME internal drive to store the Bitcoin blockchain and the automatic backups (NVME 4TB or larger)
- Also, the second NVME internal drive needs to be installed FIRST into a USB enclosure. You will need a NVME USB enclosure. The USB enclosure will be plugged into the first Linux machine.
5. Working Internet connection for both computers
6. Personalized Domain names already purchased from Njal.la. See the explanation here: https://sovransystems.com/how-to-setup/
7. Your Router with ports open (Port Forwarding) to your second machine's internal IP address. This will usually be `192.168.1.(some number)` You will complete this at the end.
- Port 80
- Port 443
- Port 22
- Port 5349
- Port 8448
## Preparing the Second Internal Drive
1. Install the second NVME internal drive into the USB enclosure, NOT into the Second computer yet.
2. Plug in the USB enclosure into the first computer with Linux OS already installed into one of its available USB ports.
3. **Please Make Sure You Know The Existing Storage Names On This First Linux Computer. If You Run The Script Below And You Do Not Know What You Are Doing, You Could Potentially Erase Your First Linux Computer's Data. I Am Not Responsibly For Your Errors**
4. Open a terminal in the first Linux computer and log in as root.
5. Type in or copy and paste:
```bash
wget https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/sdpsp.sh
```
then press enter.
6. Now, type `bash sdpsp.sh` then press enter.
7. Then the screen will ask for "what block..." which will be the drive in the list that is not mounted, which will be the drive you just plugged in. It might be labeled `sda`, or `sdb` etc. Type in the drive name and press `enter`.
8. Then the screen will ask for "what partition...,"which will be whatever you typed into the first prompt, but with a "1" on it. For example, `sda1` or `sdb1`. Type it into the terminal and press `enter`.
9. Since the script is made to copy the blockchain from another Sovran Pro that already has the full blockchain installed it will throw an error. However, it should complete the setup just fine.
10. Once complete, remove the second drive from the USB enclosure and install it into your second computer in which you are installing Sovran_SystemsOS.
## Preparing the First Main Internal Drive
### Procedure One - Installing base NixOS
1. Still on the first computer with Linux OS already installed, download the latest NixOS <u>minimal</u> (64-bit Intel/AMD) image from here: https://nixos.org/download
2. Burn that ISO image onto the USB thumb drive.
3. Insert the newly created USB thumb drive with the ISO image into the second computer (the one you are installing Sovran_SystemsOS).
4. Reboot the second computer while the USB thumb drive is inserted and boot into the USB thumb drive. This may require you to press the F7 or F12 key at boot. (Also, make sure the second computer has "safe boot" turned off in the UEFI[BIOS]).
5. Proceed with the NixOS boot menu
6. Once at the command prompt type in `sudo su` to move to the root user
7. Once logged into the root user type in `passwd` then set the root user password to `a`
8. Type in `ip a` to get your internal IP address. It will usually be `192.1681.1.(somenumber)` make a note of this IP as you will need it later.
9. Now, that you are logged in as the root user type in or copy and paste:
```bash
curl https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/psp_physical_ram.sh -o psp_physical_ram.sh
```
the command to install the base NixOS and press enter.
10. Now, type `bash psp_physical_ram.sh` then press enter.
11. The script will ask for name of first main internal drive. It usually will be `nvme0n1`. Basically, it will be the drive without any data and it will not be mounted per the list on the screen. Type in the name and press enter on the keyboard.
12. Then the script will ask for the 'Boot' partition. It will be the SMALLER partition and usually named `nvme0n1p1`. Type in the name and press enter on the keyboard.
13. Then it will ask for the 'Primary' partition. It will be the LARGER partition usually named `nvme0n1p2`. Type in the name and press enter on the keyboard.
14. The script will finish installing the base NixOS. At the end it will ask for a root password. Type `a` and press enter and type `a` again to confirm and press enter.
15. The machine will reboot into a very basic install of NixOS command prompt.
16. Remove the USB thumb drive from the second computer.
### Procedure Two - Opening The Ports on Your Router - Internal IP
1. Go to port forwarding on your router and open the above mentioned ports to the internal IP (the one you found above) of your new Sovran_SystemsOS machine
### Procedure Three - Installing Sovran_SystemsOS
1. Now at the basic install of NixOS from Procedure One, type `root` to log into root and type the password `a` when asked then press enter.
2. Now you are logged in as `root`.
3. Now type in or copy and paste:
```bash
wget https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/sp.sh
```
then press enter.
4. Type in `bash sp.sh` then press enter.
5. Next the script will ask for your domain names from Njal.la. Type them in the corresponding prompts and then press enter for each prompt.
6. Then it will ask for an email for the SSL certificates. Type it in and press enter.
7. The script is long so it will take some time.
8. It will finish by stating `All Finished! Please Reboot then Enjoy your New Sovran Pro!`
9. Press the power button on the machine for it to turn off THEN press it again to power the machine
## Finishing the Install
### Putting the External IP of your New DIY Sovran Pro into your new domain names you just bought at [njal.la](https://njal.la)
1. On your New DIY Sovran Pro, log into your [njal.la](https://njal.la) account
2. Make a "dynamic" record for each subdomain
3. Njal.la will now display a `curl` command for each sub-domain.
4. Open the `Terminal` on your New DIY Sovran Pro and type in or copy and paste:
```bash
ssh root@localhost
```
It will as you for a password which is `gosovransystems` as this is the default temporary password from Sovran Systems.
Now you will be logged in as root.
5. Now type:
`nano /var/lib/njalla/njalla.sh`
and press enter.
3. Paste the `curl` commands from njal.la's website for each sub-domain. Each `curl` command gets a new line. For example:
```bash
...
curl "https://njal.la/update/?h=test.testsovransystems.com&k=8n7vk3afj-jkyg37&a=${IP}"
curl "https://njal.la/update/?h=zap.testsovransystems.com&k=8no*73afj-jkygi2ea=${IP}"
...
```
##### Make sure the default `&auto` from njal.la is replaced by `&a=${IP}` at the end of each `curl` command in the `/var/lib/njalla/njalla.sh` as in the example above.
7. After you have added all the sub-domins into `/var/lib/njalla/njalla.sh`, press `ctrl + s` then press `ctrl + x` to save and exit `nano`.
8. Close the `Terminal`.
### Setting the Desktop
1. Open the `Terminal` again and type in: `dconf load / < /home/free/Downloads/Sovran_SystemsOS-Desktop`. Do NOT log in as root.
2. Close the `Terminal`.
### Setting Up Nextcloud and Wordpress
#### Nextcloud
1. Open a web browser and navigate to your domain name you bought from [njal.la](https://njal.la) for example "cloud.myfreedomsite.com" you attributed to your Nextcloud instance.
2. Nextcloud will as you to set up a new account to be used as a log in. Do so.
3. Nextcloud will also ask you where you want the data directory. Type in `/var/lib/nextcloud/data`
4. Nextcloud will ask you to connect the database:
1. Choose `Postgresql` from the optoins.
2. Database username is `ncusr`
3. Database name is `nextclouddb`
4. Database password is found by doing this:
1. Open the `Terminal` again, then type in or copy and paste:
```bash
ssh root@localhost
```
Now you will be logged in as root.
2. Now type:
`cat /var/lib/secrets/nextclouddb`
and press enter.
3. Your database password will be displayed in the `Terminal` window.
4. Type that into the password field
5. Now, press `Install` on the Nextcloud website and Nextcloud will be installed. It will take a few minutes. Follow the on screen prompts.
#### Wordpress
1. Open a web browser and navigate to your domain name you bought from [njal.la](https://njal.la) for example "myfreedomsite.com" you attributed to your Wordpress instance.
2. Wordpress will ask you to connect the database:
1. Database username is `wpusr`
2. Database name is `wordpressdb`
4. Database password is found by doing this:
1. Open the `Terminal` again, then type in or copy and paste:
```bash
ssh root@localhost
```
Now you will be logged in as root.
2. Now type:
`cat /var/lib/secrets/wordpressdb`
and press enter.
3. Your database password will be displayed in the `Terminal` window.
4. Type that into the password field
5. Now, press `Install` on the Wordpress website and Wordpress will be installed. It will take a few minutes. Follow the on screen prompts.
### Final Install for Coturn, Flatpak, and Nextcloud
1. Staying in the `Terminal` type in or copy and paste:
```bash
sed -i '$e cat /var/lib/nextcloudaddition/nextcloudaddition' /var/lib/www/nextcloud/config/config.php
chown caddy:php /var/lib/www -R
chmod 700 /var/lib/www R
```
and press enter.
2. Now type or copy and paste:
```bash
set DOMAIN $(cat /var/lib/domains/matrix) && cp -n /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/{$DOMAIN}/{$DOMAIN}.crt /var/lib/coturn/{$DOMAIN}.crt.pem && cp -n /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/{$DOMAIN}/{$DOMAIN}.key /var/lib/coturn/{$DOMAIN}.key.pem && chown turnserver:turnserver /var/lib/coturn -R && chmod 770 /var/lib/coturn -R && systemctl restart coturn
```
and press enter.
3. Now type or copy and paste:
```bash
sudo -u free flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
```
and press enter.
It will ask for your `Administrator` password and to get the password open a new `Terminal` window and type:
```bash
ssh root@localhost
```
press enter.
Now you will be logged in as root.
Now type:
```bash
cat /var/lib/secrets/main
```
Then the `Administrator`'s password will be displayed. Copy and paste the password into the other `Terminal` window that is open. Then press enter.
Now you can close the `Terminal`.
### Everything now will be installed regarding Sovran_SystemsOS. The remaining setup will be only for the front-end user account creations for BTCpayserver, Vaultwarden, connecting the node to Sparrow wallet and Bisq.
### Congratulations! 🎉

202
LICENSE Executable file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

193
README.md Executable file
View File

@@ -0,0 +1,193 @@
<br />
<br />
<p align="center">
<img width="600" src="sovran_systems_grey.png">
</p>
<br />
<br />
<br />
# Sovran_SystemsOS
### The Officaly Repository of Sovran_SystemsOS and the Sovran Pro
**A declarative, self-hosted server and desktop operating system built on NixOS by [Sovran Systems](https://sovransystems.com)**
---
## Overview
Sovran_SystemsOS is a fully integrated NixOS configuration that transforms a single machine into a personal cloud, communications hub, Bitcoin node, web server, and **daily-use desktop** — all managed declaratively.
**It comes preinstalled on The Sovran Pro**
Every service is pre-wired: reverse proxy routing, database initialization, firewall rules, automated backups, and inter-service communication are handled out of the box. Moreover, you can activate the other custom packages; the system does the rest.
---
## Architecture
Sovran_SystemsOS is structured as a set of NixOS modules exposed via a flake. A remote machine consumes the flake and selectively enables features through a simple configuration interface.
```
Repository Main Flake (flake.nix)
└── Sovran_SystemsOS flake (nixosModules.Sovran_SystemsOS)
├── configuration.nix/ # Base system
│ ├── gnome Desktop # Gnome Desktop Interface
│ ├── caddy # Reverse proxy + HTTPS
│ ├── nextcloud # Cloud storage
│ ├── wordpress # CMS / publishing
│ ├── element # Matrix Synapse via Element Messaging App
├── modules/
│ ├── bitcoinecosystem.nix # Bitcoin Core / Knots / BTCPay Server / Bitcoin Lightning
│ ├── bip110.nix # Bip110 Node Consensus Policy
│ ├── element-calling.nix # Matrix Synapse via Element + Element Voice and Video Calling
│ ├── haven.nix # Nostr relay
│ ├── mempool.nix # Mempool explorer
│ ├── rdp.nix # Remote desktop (RDP)
│ ├── vaultwarden.nix # Password management
├── nix-bitcoin integration
├── bitcoin clients integration
│ ├── sparrow wallet # Trusted and Standard Open Source Bitcoin Wallet
│ ├── bisq/bisq2 # Non KYC Bitcoin Buying and Selling
├── agenix (secrets management)
└── nixvim
```
## Features
### Feature Toggles
[Custom Add-On Guide](custom-add-ons.md)
Every major service is gated behind a feature flag. Enable only what you need:
```nix
# custom.nix
{ config, pkgs, lib, ... }:
{
sovran_systemsOS = {
features = {
bip110 = lib.mkForce true;
element-calling = lib.mkForce true;
haven = lib.mkForce true;
mempool = lib.mkForce true;
rdp = lib.mkForce true;
};
nostr_npub = "pasteyournpubhere";
};
}
```
No unnecessary services run. No wasted resources.
---
### Service Stack
| Category | Service | Description |
|---|---|---|
| **Web** | Caddy | Automatic HTTPS, reverse proxy for all services |
| **Cloud** | Nextcloud | File storage, sync, and collaboration |
| **CMS** | WordPress | Self-hosted publishing and content management |
| **Passwords** | Vaultwarden | Bitwarden-compatible password vault |
| **Messaging** | Element/Matrix Synapse | Federated, decentralized messaging backend |
| **Video/Voice Calling** | Element Video and Voice Calling | Decentralized Voice Over IP for Matrix with optional TURN/STUN |
| **Bitcoin** | Bitcoin Core / Knots | **Full node with optional BIP-110 consensus policy** |
| **Bitcoin Lightning** | LND | Full LND Node Connected over Tor intergrated into BTCPay Server |
| **Payments** | BTCPay Server | Self-hosted Bitcoin payment processor |
| **Explorer** | Mempool | Bitcoin mempool visualizer and block explorer |
| **Nostr** | Haven | Nostr relay server |
| **Remote Access** | GNOME Remote Desktop | RDP access with auto-generated TLS and credentials |
---
### Security
- **SSH hardened** — password authentication disabled by default
- **Fail2ban** — active on https
- **Agenix** — encrypted secrets management integrated into the flake
- **Tor** — integration into the bitcoin ecosystem
- **Firewall** — ports managed per-module; only enabled services are exposed
### Reliability
- **Automated backups** via rsnapshot
- **Scheduled maintenance** via systemd timers
- **Database initialization** handled declaratively
- **Reproducible builds** — the main system is defined in code and can be rebuilt to match most systems
---
### Network Configuration
Sovran_SystemsOS hosts public-facing services (Wordpress, Element/Element Calling, Nextcloud, BTCPayserver, Haven Relay, and Vaultwarden) that require inbound connections from the internet. To make these services accessible outside your local network, you must configure **port forwarding** on your home router.
**Before deploying, ensure you have:**
- Access to your router's administration interface (typically at `192.168.1.1` or `192.168.0.1`)
- The ability to create port forwarding rules
- The local/private IP address of the machine running Sovran_SystemsOS
- The external public IP address of the machine running Sovran_SystemsOS
**Required port forwards (depending on enabled features):**
Forward each port to the **private IP address** of your Sovran_SystemsOS machine. Only forward ports for services you have enabled.
> **Tip:** Assign a static IP or DHCP reservation to your Sovran_SystemsOS machine so the forwarding rules remain valid after reboots.
> **Note:** If your ISP uses CGNAT (Carrier-Grade NAT), standard port forwarding will not work. Contact your ISP to request a public IP address.
---
## Installation
### Full Guide (A bit outdated as of now... will be working on a smoother DIY soon)
👉 [DIY Install Sovran_SystemsOS](https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/src/branch/main/DIY%20Install%20Sovran_SystemsOS.md)
---
## Requirements
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 4 cores | 8+ cores |
| RAM | 16 GB | 32+ GB |
| Storage | 512 GB SSD + 4 TB SSD | 2GB SSD + 4+ TB SSD (Bitcoin node requires significant disk) |
| Network | 100 Mbs Down/20 Mbs Up + No need for DDNS if domains are brought through https://njal.la | 1 Gbs Down/1 Gbs Up + No need for DDNS if domains are brought through https://njal.la |
---
## Community
| Channel | Link |
|---|---|
| General Chat | [#sovran-systems:anarchyislove.xyz](https://matrix.to/#/#sovran-systems:anarchyislove.xyz) |
| DIY Support | [#DIY_Sovran_SystemsOS:anarchyislove.xyz](https://matrix.to/#/#DIY_Sovran_SystemsOS:anarchyislove.xyz) |
---
## License
See [LICENSE](LICENSE) for details.
---
## Project Philosophy
Sovran_SystemsOS exists to provide a complete, self-hosted infrastructure stack that eliminates dependency on third-party platforms. It is opinionated by design — services are pre-integrated so you spend time using your system, not assembling it.
This is not a toolkit. It is a working system.
You retain full visibility into every module, every service definition, and every configuration choice. Nothing is hidden. Everything is reproducible.
---
**Be Digitally Sovereign**

191
configuration.nix Normal file
View File

@@ -0,0 +1,191 @@
{ config, pkgs, lib, ... }:
{
imports = [
./modules/modules.nix
];
# ── Boot ────────────────────────────────────────────────────
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.efi.efiSysMountPoint = "/boot/efi";
boot.kernelPackages = pkgs.linuxPackages_latest;
# ── Filesystems ──────────────────────────────────<E29480><E29480>──────────
fileSystems."/run/media/Second_Drive" = {
device = "LABEL=BTCEcoandBackup";
fsType = "ext4";
options = [ "nofail" ];
};
fileSystems."/boot/efi".options = [ "umask=0077" "defaults" ];
# ── Nix Settings ────────────────────────────────────────────
nix.settings = {
experimental-features = [ "nix-command" "flakes" ];
download-buffer-size = 524288000;
};
# ── Networking ──────────────────────────────────────────────
networking.hostName = "nixos";
networking.networkmanager.enable = true;
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [ 80 443 8448 3051 ];
networking.firewall.allowedUDPPorts = [ 80 443 8448 3051 ];
networking.firewall.allowedUDPPortRanges = [
{ from = 49152; to = 65535; }
];
# ── Locale / Time ──────────────────────────────────────────
time.timeZone = "America/Los_Angeles";
i18n.defaultLocale = "en_US.UTF-8";
# ── Desktop ────────────────────────────────────────────────
services.xserver.enable = true;
services.displayManager.gdm.enable = true;
services.displayManager.gdm.autoSuspend = false;
services.desktopManager.gnome.enable = true;
services.xserver.xkb = { layout = "us"; variant = ""; };
services.printing.enable = true;
systemd.enableEmergencyMode = false;
# ── Audio ──────────────────────────────────────────────────
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
# ── Users ──────────────────────────────────────────────────
users.users.free = {
isNormalUser = true;
description = "free";
extraGroups = [ "networkmanager" ];
};
services.displayManager.autoLogin.enable = true;
services.displayManager.autoLogin.user = "free";
# ── Flatpak ────────────────────────────────────────────────
services.flatpak.enable = true;
systemd.services.flatpak-repo = {
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
path = [ pkgs.flatpak ];
script = ''
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
'';
};
# ── Packages ───────────────────────────────────────────────
nixpkgs.config.allowUnfree = true;
nixpkgs.config.permittedInsecurePackages = [ "jitsi-meet-1.0.8043" ];
environment.systemPackages = with pkgs; [
git wget fish htop btop
gnomeExtensions.transparent-top-bar-adjustable-transparency
gnomeExtensions.systemd-manager
gnomeExtensions.dash-to-dock
gnomeExtensions.vitals
gnomeExtensions.pop-shell
gnomeExtensions.just-perfection
gnomeExtensions.appindicator
gnomeExtensions.date-menu-formatter
gnome-tweaks papirus-icon-theme
ranger fastfetch gedit openssl pwgen
aspell aspellDicts.en lm_sensors
hunspell hunspellDicts.en_US
synadm brave dua bitwarden-desktop
gparted pv unzip parted screen zenity
libargon2 gnome-terminal libreoffice-fresh
dig firefox element-desktop wp-cli axel
lk-jwt-service livekit-libwebrtc livekit-cli livekit
matrix-synapse
];
# ── Shell ──────────────────────────────────────────────────
programs.nixvim = {
enable = true;
colorschemes.catppuccin.enable = true;
plugins.lualine.enable = true;
};
programs.bash.promptInit = "fish";
programs.fish = { enable = true; promptInit = "fastfetch"; };
# ── PostgreSQL base ────────────────────────────────────────
services.postgresql = {
enable = true;
authentication = lib.mkForce ''
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
'';
};
# ── Agenix ─────────────────────────────────────────────────
age.identityPaths = [ "/root/.ssh/agenix/agenix-secret-keys" ];
age.secrets.matrix_reg_secret = {
file = ./secrets/matrix_reg_secret.age;
mode = "0440";
owner = "matrix-synapse";
group = "matrix-synapse";
};
# ── Backups ────────────────────────────────────────────────
services.rsnapshot = {
enable = true;
extraConfig = ''
snapshot_root /run/media/Second_Drive/BTCEcoandBackup/NixOS_Snapshot_Backup
retain hourly 5
retain daily 5
backup /home/ localhost/
backup /var/lib/ localhost/
backup /etc/nixos/ localhost/
backup /etc/nix-bitcoin-secrets/ localhost/
'';
cronIntervals = {
daily = "50 21 * * *";
hourly = "0 * * * *";
};
};
# ── Cron (base system crons only) ─────────────────────────
services.cron = {
enable = true;
systemCronJobs = [
"*/15 * * * * root /run/current-system/sw/bin/bash /var/lib/njalla/njalla.sh"
"*/15 * * * * root /run/current-system/sw/bin/bash /var/lib/external_ip/external_ip.sh"
"0 0 * * 0 docker-user yes | /run/current-system/sw/bin/docker system prune -a"
];
};
# ── Tor ────────────────────────────────────────────────────
services.tor = { enable = true; client.enable = true; torsocks.enable = true; };
services.privoxy.enableTor = true;
# ── SSH ────────────────────────────────────────────────────
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
PermitRootLogin = "yes";
};
};
# ── Fail2Ban ───────────────────────────────────────────────
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" ];
};
# ── Garbage Collection ─────────────────────────────────────
nix.gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 7d"; };
system.stateVersion = "22.05";
}

124
custom-add-ons.md Normal file
View File

@@ -0,0 +1,124 @@
## Custom Add-ons for Sovran_SystemsOS and The Sovran Pro
Add-ons are extra features you can have enabled before your Sovran Pro is shipped to you or you can enable them yourself.
## The information about each Feature
1. Since Sovran_SystemsOS runs Bitcoin Knots by default as opposed to Bitcion Core, you can customize your Sovran Pro's Bitcoin node to run Bitcoin Core.
https://github.com/bitcoin/bitcoin
2. BIP-110 keeps Bitcoin more efficient as Peer to Peer Cash and you can run it along side your Bitocoin node.
https://github.com/bitcoin/bips/blob/master/bip-0110.mediawiki
3. The Bitcoin Mempool can be added and can be accessed via Tor or on your local network.
https://github.com/mempool/mempool
4. The Haven Relay for NOSTR (NOTES AND OTHER STUFF TRANSMITED BY RELAYS) is a Decenterized Social Media/File Sharing.
https://github.com/barrydeen/haven
5. You can run the new Element Voice and Video calling backend.
https://github.com/element-hq/element-call
6. You can run the Gnome Remote Desktop to view your desktop from another computer in the nextwork.
https://gitlab.gnome.org/GNOME/gnome-remote-desktop
---
## The DIY for each Feature
All code belongs in the `custom.nix` file located at `/etc/nixos/custom.nix`.
If you would like to enable these features yourself after you have received your Sovran Pro, then open the *terminal* app and type or paste in
```bash
ssh root@localhost
```
Type in the password in the diaolog box if necessary. It is the same password to run the Sovran_Systems_Updater app.
Then press enter.
Next, type or paste in
```bash
nano /etc/nixos/custom.nix
```
Then press enter.
Next type or paste the codes below *(Code for each Feature)* each on their own line into the termainl/nano window right above the last `}`
Once done, press `ctr s` then `ctr x` to save and exit.
Last, type or paste in
```bash
nixos-rebuild switch --impure
```
Then press enter.
After it is done bulding, reboot your Sovran Pro typeing or pasting in
```bash
reboot
```
---
## The code for each Feature (All Features are disabled by default)
1. The code to enable Bitcoin Core is as follows:
```nix
sovran_systemsOS.features.bitcoin-core = lib.mkForce true;
```
2. The code to enable BIP-110 is as follows:
```nix
sovran_systemsOS.features.bip110 = lib.mkForce true;
```
3. The code to enable Mempool is as follows:
```nix
sovran_systemsOS.features.mempool = lib.mkForce true;
```
4. The code to enable Haven Relay is as follows (also Haven will need a new domain to work):
```nix
sovran_systemsOS.features.haven = lib.mkForce true;
sovran_systemsOS.nostr_npub = "pasteyournpubhere";
```
5. The code to enable Element Calling is as follows (also Element Calling will need a new domain to work):
```nix
sovran_systemsOS.features.element-calling = lib.mkForce true;
```
6. The code to enable Gnome Remote Desktop is as follows:
```nix
sovran_systemsOS.features.rdp = lib.mkForce true;
```
Next, in a open the terminal app and in the new window paste this in:
```bash
ssh root@localhost
```
Press enter
Type in the password if required. It will be the same password to run the Sovran_SystemsOS_Updater app.
Last, paste in this command to see the log in information to log in from any RDP client software (i.e. Remmina) from any computer on your home network
```bash
cat /var/lib/gnome-remote-desktop/rdp-credentials
```

8
custom.nix Normal file
View File

@@ -0,0 +1,8 @@
{ config, pkgs, lib, ... }:
{
# Only enable what this machine needs
sovran_systemsOS.services.wordpress.enable = true;
sovran_systemsOS.services.nextcloud.enable = true;
sovran_systemsOS.services.synapse.enable = true;
# btcpayserver is NOT enabled — no domain file needed, no vhost created
}

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env bash
cd /home/free/Downloads
#### SCRIPT 1 ####
/run/current-system/sw/bin/wget "https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/file_fixes_and_new_services/sovran-pro-flake-update.sh"
/run/current-system/sw/bin/bash /home/free/Downloads/sovran-pro-flake-update.sh
rm -rf /home/free/Downloads/sovran-pro-flake-update.sh
#### SCRIPT 2 ####
/run/current-system/sw/bin/wget "https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/file_fixes_and_new_services/add-custom-nix.sh"
/run/current-system/sw/bin/bash /home/free/Downloads/add-custom-nix.sh
rm -rf /home/free/Downloads/add-custom-nix.sh
#### SCRIPT 3 ####
/run/current-system/sw/bin/wget "https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/file_fixes_and_new_services/sovran-pro-flake-update2.sh"
/run/current-system/sw/bin/bash /home/free/Downloads/sovran-pro-flake-update2.sh
rm -rf /home/free/Downloads/sovran-pro-flake-update2.sh
#### SCRIPT 4 ####
/run/current-system/sw/bin/wget "https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/file_fixes_and_new_services/nextcloud_maintenance_window_fix.sh"
/run/current-system/sw/bin/bash /home/free/Downloads/nextcloud_maintenance_window_fix.sh
rm -rf /home/free/Downloads/nextcloud_maintenance_window_fix.sh
#### SCRIPT 5 ####
/run/current-system/sw/bin/wget "https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/file_fixes_and_new_services/add_external_backup_app.sh"
/run/current-system/sw/bin/bash /home/free/Downloads/add_external_backup_app.sh
rm -rf /home/free/Downloads/add_external_backup_app.sh
#### SCRIPT 6 ####
/run/current-system/sw/bin/wget "https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/file_fixes_and_new_services/update-agenix.sh"
/run/current-system/sw/bin/bash /home/free/Downloads/update-agenix.sh
rm -rf /home/free/Downloads/update-agenix.sh
#### SCRIPT 7 ####
/run/current-system/sw/bin/wget "https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/file_fixes_and_new_services/element-calling_haven"
/run/current-system/sw/bin/bash /home/free/Downloads/element-calling_haven.sh
rm -rf /home/free/Downloads/element-calling_haven.sh
#### REMOVAL OF MAIN SCRIPT ####
rm -rf /home/free/Downloads/Sovran_SystemsOS_File_Fixes_And_New_Services.sh

View File

@@ -0,0 +1,81 @@
#!/usr/bin/env bash
function log_console () {
echo "`date` :: $1" >> /var/lib/beacons/awesome.log
echo $1
}
#### CHECK TO SEE IF IT HAS BEEN RUN BEFORE ####
FILE=/var/lib/beacons/file_fixes_and_new_services/add-custom-nix/completed
if [ -e $FILE ]; then
/run/current-system/sw/bin/echo "File Found :), No Need to Run ... Exiting"
exit 1
fi
#### CREATE INITIAL TAG ####
/run/current-system/sw/bin/mkdir -p /var/lib/beacons/file_fixes_and_new_services/add-custom-nix ; touch /var/lib/beacons/file_fixes_and_new_services/add-custom-nix/started
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Initial Tag"
exit 1
fi
#### MAIN SCRIPT ####
touch /etc/nixos/custom.nix
/run/current-system/sw/bin/cat > /etc/nixos/custom.nix <<- "EOF"
{config, pkgs, lib, ...}:
# Add custom NixOS modules here.
let
personalization = import ./personalization.nix;
in
{
}
EOF
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Run add-custom-nix"
exit 1
fi
#### CREATE COMPELETE TAG ####
/run/current-system/sw/bin/touch /var/lib/beacons/file_fixes_and_new_services/add-custom-nix/completed
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Completed Tag"
exit 1
fi
exit 0

View File

@@ -0,0 +1,66 @@
#!/usr/bin/env bash
function log_console () {
echo "`date` :: $1" >> /var/lib/beacons/awesome.log
echo $1
}
#### CHECK TO SEE IF IT HAS BEEN RUN BEFORE ####
FILE=/var/lib/beacons/file_fixes_and_new_services/add_external_backup_app/completed
if [ -e $FILE ]; then
/run/current-system/sw/bin/echo "File Found :), No Need to Run ... Exiting"
exit 1
fi
#### CREATE INITIAL TAG ####
/run/current-system/sw/bin/mkdir -p /var/lib/beacons/file_fixes_and_new_services/add_external_backup_app ; touch /var/lib/beacons/file_fixes_and_new_services/add_external_backup_app/started
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Initial Tag"
exit 1
fi
#### MAIN SCRIPT ####
cd /home/free/Downloads
/run/current-system/sw/bin/wget "https://git.sovransystems.com/Sovran_Systems/Software/raw/branch/main/Sovran_SystemsOS_External_Backup/sovran_systemsOS_external_backup_local_installer/sovran_systemsOS_external_backup_install.sh"
/run/current-system/sw/bin/bash "sovran_systemsOS_external_backup_install.sh"
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Run add_external_backup_app"
exit 1
fi
#### CREATE COMPELETE TAG ####
/run/current-system/sw/bin/touch /var/lib/beacons/file_fixes_and_new_services/add_external_backup_app/completed
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Completed Tag"
exit 1
fi
exit 0

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env bash
function log_console () {
echo "`date` :: $1" >> /var/lib/beacons/awesome.log
echo $1
}
#### CHECK TO SEE IF IT HAS BEEN RUN BEFORE ####
FILE=/var/lib/beacons/file_fixes_and_new_services/element-calling_haven/completed
if [ -e $FILE ]; then
/run/current-system/sw/bin/echo "File Found :), No Need to Run ... Exiting"
exit 1
fi
#### CREATE INITIAL TAG ####
/run/current-system/sw/bin/mkdir -p /var/lib/beacons/file_fixes_and_new_services/element-calling_haven ; touch /var/lib/beacons/file_fixes_and_new_services/element-calling_haven/started
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Initial Tag"
exit 1
fi
#### MAIN SCRIPT ####
touch /var/lib/domains/haven
touch /var/lib/domains/element-calling
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Run element-calling_haven"
exit 1
fi
#### CREATE COMPELETE TAG ####
/run/current-system/sw/bin/touch /var/lib/beacons/file_fixes_and_new_services/element-calling_haven/completed
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Completed Tag"
exit 1
fi
exit 0

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env bash
function log_console () {
echo "`date` :: $1" >> /var/lib/beacons/awesome.log
echo $1
}
#### CHECK TO SEE IF IT HAS BEEN RUN BEFORE ####
FILE=/var/lib/beacons/file_fixes_and_new_services/nextcloud_maintenance_window_fix/completed
if [ -e $FILE ]; then
/run/current-system/sw/bin/echo "File Found :), No Need to Run ... Exiting"
exit 1
fi
#### CREATE INITIAL TAG ####
/run/current-system/sw/bin/mkdir -p /var/lib/beacons/file_fixes_and_new_services/nextcloud_maintenance_window_fix ; touch /var/lib/beacons/file_fixes_and_new_services/nextcloud_maintenance_window_fix/started
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Initial Tag"
exit 1
fi
#### MAIN SCRIPT ####
/run/wrappers/bin/sudo -u caddy /run/current-system/sw/bin/php /var/lib/www/nextcloud/occ config:system:set maintenance_window_start --type=integer --value=1
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Run add-custom-nix"
exit 1
fi
#### CREATE COMPELETE TAG ####
/run/current-system/sw/bin/touch /var/lib/beacons/file_fixes_and_new_services/nextcloud_maintenance_window_fix/completed
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Completed Tag"
exit 1
fi
exit 0

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env bash
function log_console () {
echo "`date` :: $1" >> /var/lib/beacons/awesome.log
echo $1
}
#### CHECK TO SEE IF IT HAS BEEN RUN BEFORE ####
FILE=/var/lib/beacons/file_fixes_and_new_services/sovran-pro-flake-update/completed
if [ -e $FILE ]; then
/run/current-system/sw/bin/echo "File Found :), No Need to Run ... Exiting"
exit 1
fi
#### CREATE INITIAL TAG ####
/run/current-system/sw/bin/mkdir -p /var/lib/beacons/file_fixes_and_new_services/sovran-pro-flake-update ; touch /var/lib/beacons/file_fixes_and_new_services/sovran-pro-flake-update/started
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Initial Tag"
exit 1
fi
#### MAIN SCRIPT ####
/run/current-system/sw/bin/rm /etc/nixos/flake.nix
/run/current-system/sw/bin/cat > /etc/nixos/flake.nix <<- "EOF"
{
description = "Sovran_SystemsOS for the Sovran Pro from Sovran Systems";
inputs = {
Sovran_Systems.url = "git+https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS";
};
outputs = { self, Sovran_Systems, ... }@inputs: {
nixosConfigurations."nixos" = Sovran_Systems.inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./hardware-configuration.nix
Sovran_Systems.nixosModules.Sovran_SystemsOS
];
};
};
}
EOF
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Run sovran-pro-flake-update"
exit 1
fi
#### CREATE COMPELETE TAG ####
/run/current-system/sw/bin/touch /var/lib/beacons/file_fixes_and_new_services/sovran-pro-flake-update/completed
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Completed Tag"
exit 1
fi
exit 0

View File

@@ -0,0 +1,98 @@
#!/usr/bin/env bash
function log_console () {
echo "`date` :: $1" >> /var/lib/beacons/awesome.log
echo $1
}
#### CHECK TO SEE IF IT HAS BEEN RUN BEFORE ####
FILE=/var/lib/beacons/file_fixes_and_new_services/sovran-pro-flake-update2/completed
if [ -e $FILE ]; then
/run/current-system/sw/bin/echo "File Found :), No Need to Run ... Exiting"
exit 1
fi
#### CREATE INITIAL TAG ####
/run/current-system/sw/bin/mkdir -p /var/lib/beacons/file_fixes_and_new_services/sovran-pro-flake-update2 ; touch /var/lib/beacons/file_fixes_and_new_services/sovran-pro-flake-update2/started
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Initial Tag"
exit 1
fi
#### MAIN SCRIPT ####
/run/current-system/sw/bin/rm /etc/nixos/flake.nix
/run/current-system/sw/bin/cat > /etc/nixos/flake.nix <<- "EOF"
{
description = "Sovran_SystemsOS for the Sovran Pro from Sovran Systems";
inputs = {
Sovran_Systems.url = "git+https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS";
};
outputs = { self, Sovran_Systems, ... }@inputs: {
nixosConfigurations."nixos" = Sovran_Systems.inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./custom.nix
./hardware-configuration.nix
Sovran_Systems.nixosModules.Sovran_SystemsOS
];
};
};
}
EOF
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Run sovran-pro-flake-update2"
exit 1
fi
#### CREATE COMPELETE TAG ####
/run/current-system/sw/bin/touch /var/lib/beacons/file_fixes_and_new_services/sovran-pro-flake-update2/completed
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Completed Tag"
exit 1
fi
exit 0

View File

@@ -0,0 +1,83 @@
#!/usr/bin/env bash
#### CHECK TO SEE IF IT HAS BEEN RUN BEFORE ####
FILE=/var/lib/beacons/file_fixes_and_new_services/update-agenix/completed
if [ -e $FILE ]; then
/run/current-system/sw/bin/echo "File Found :), No Need to Run ... Exiting"
exit 1
fi
#### CREATE INITIAL TAG ####
/run/current-system/sw/bin/mkdir -p /var/lib/beacons/file_fixes_and_new_services/update-agenix ; touch /var/lib/beacons/file_fixes_and_new_services/update-agenix/started
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Initial Tag"
exit 1
fi
#### MAIN SCRIPT ####
/run/current-system/sw/bin/rm -rf /var/lib/agenix-secrets/nextclouddb.age
/run/current-system/sw/bin/rm -rf /var/lib/agenix-secrets/wordpressdb.age
/run/current-system/sw/bin/rm -rf /var/lib/agenix-secrets/turn.age
/run/current-system/sw/bin/rm -rf /var/lib/agenix-secrets/matrixdb.age
/run/current-system/sw/bin/rm -rf /var/lib/agenix-secrets/matrix_reg_secret.age
pushd /var/lib/agenix-secrets/
/run/current-system/sw/bin/echo -n $(/run/current-system/sw/bin/cat /var/lib/secrets/wordpressdb) | EDITOR='/run/current-system/sw/bin/cp /dev/stdin' /run/current-system/sw/bin/nix run github:ryantm/agenix -- -e wordpressdb.age -i /root/.ssh/agenix/agenix-secret-keys
/run/current-system/sw/bin/echo -n $(/run/current-system/sw/bin/cat /var/lib/secrets/nextclouddb) | EDITOR='/run/current-system/sw/bin/cp /dev/stdin' /run/current-system/sw/bin/nix run github:ryantm/agenix -- -e nextclouddb.age -i /root/.ssh/agenix/agenix-secret-keys
/run/current-system/sw/bin/echo -n $(/run/current-system/sw/bin/cat /var/lib/secrets/matrixdb) | EDITOR='/run/current-system/sw/bin/cp /dev/stdin' /run/current-system/sw/bin/nix run github:ryantm/agenix -- -e matrixdb.age -i /root/.ssh/agenix/agenix-secret-keys
/run/current-system/sw/bin/echo -n $(/run/current-system/sw/bin/cat /var/lib/secrets/turn) | EDITOR='/run/current-system/sw/bin/cp /dev/stdin' /run/current-system/sw/bin/nix run github:ryantm/agenix -- -e turn.age -i /root/.ssh/agenix/agenix-secret-keys
/run/current-system/sw/bin/echo -n $(/run/current-system/sw/bin/cat /var/lib/secrets/matrix_reg_secret) | EDITOR='/run/current-system/sw/bin/cp /dev/stdin' /run/current-system/sw/bin/nix run github:ryantm/agenix -- -e matrix_reg_secret.age -i /root/.ssh/agenix/agenix-secret-keys
popd
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Run update-agenix"
exit 1
fi
#### CREATE COMPELETE TAG ####
/run/current-system/sw/bin/touch /var/lib/beacons/file_fixes_and_new_services/update-agenix/completed
if [[ $? != 0 ]]; then
/run/current-system/sw/bin/echo "Could Not Create Completed Tag"
exit 1
fi
exit 0

408
flake.lock generated Executable file
View File

@@ -0,0 +1,408 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": [],
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
"systems": "systems"
},
"locked": {
"lastModified": 1770165109,
"narHash": "sha256-9VnK6Oqai65puVJ4WYtCTvlJeXxMzAp/69HhQuTdl/I=",
"owner": "ryantm",
"repo": "agenix",
"rev": "b027ee29d959fda4b60b57566d64c98a202e0feb",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"bip110": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1773169138,
"narHash": "sha256-6X41z8o2z8KjF4gMzLTPD41WjvCDGXTc0muPGmwcOMk=",
"owner": "emmanuelrosa",
"repo": "bitcoin-knots-bip-110-nix",
"rev": "b9d018b71e20ce8c1567cbc2401b6edc2c1c7793",
"type": "github"
},
"original": {
"owner": "emmanuelrosa",
"repo": "bitcoin-knots-bip-110-nix",
"type": "github"
}
},
"btc-clients": {
"inputs": {
"nixpkgs": "nixpkgs_3",
"oldNixpkgs": "oldNixpkgs"
},
"locked": {
"lastModified": 1774138208,
"narHash": "sha256-a0jEd8Q9DI0uSWKQcDRRLfYvQUWojKtyY61jZ5W+6Js=",
"owner": "emmanuelrosa",
"repo": "btc-clients-nix",
"rev": "8671254e14ed042384729662c8ab8e970b4a6d87",
"type": "github"
},
"original": {
"owner": "emmanuelrosa",
"repo": "btc-clients-nix",
"type": "github"
}
},
"extra-container": {
"inputs": {
"flake-utils": [
"nix-bitcoin",
"flake-utils"
],
"nixpkgs": [
"nix-bitcoin",
"nixpkgs"
]
},
"locked": {
"lastModified": 1766155727,
"narHash": "sha256-XGp4HHH6D6ZKiO5RnMzqYJYnZB538EnEflvlTsOKpvo=",
"owner": "erikarvstedt",
"repo": "extra-container",
"rev": "b450bdb24fca1076973c852d87bcb49b8eb5fd49",
"type": "github"
},
"original": {
"owner": "erikarvstedt",
"ref": "0.14",
"repo": "extra-container",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1769996383,
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1745494811,
"narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nix-bitcoin": {
"inputs": {
"extra-container": "extra-container",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_4",
"nixpkgs-25_05": "nixpkgs-25_05",
"nixpkgs-unstable": "nixpkgs-unstable"
},
"locked": {
"lastModified": 1767721199,
"narHash": "sha256-UzRxDiJlopBGPTjyhCdMP+QdTwXK+l+y45urXCyH69A=",
"owner": "fort-nix",
"repo": "nix-bitcoin",
"rev": "5b532698ce9e8bd79b07d77ab4fc60e1a8408f73",
"type": "github"
},
"original": {
"owner": "fort-nix",
"ref": "release",
"repo": "nix-bitcoin",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1754028485,
"narHash": "sha256-IiiXB3BDTi6UqzAZcf2S797hWEPCRZOwyNThJIYhUfk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "59e69648d345d6e8fef86158c555730fa12af9de",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-25_05": {
"locked": {
"lastModified": 1767051569,
"narHash": "sha256-0MnuWoN+n1UYaGBIpqpPs9I9ZHW4kynits4mrnh1Pk4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "40ee5e1944bebdd128f9fbada44faefddfde29bd",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1751274312,
"narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1767364772,
"narHash": "sha256-fFUnEYMla8b7UKjijLnMe+oVFOz6HjijGGNS1l7dYaQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "16c7794d0a28b5a37904d55bcca36003b9109aaa",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1772380631,
"narHash": "sha256-FhW0uxeXjefINP0vUD4yRBB52Us7fXZPk9RiPAopfiY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6d3b61b190a899042ce82a5355111976ba76d698",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "master",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1772380631,
"narHash": "sha256-FhW0uxeXjefINP0vUD4yRBB52Us7fXZPk9RiPAopfiY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6d3b61b190a899042ce82a5355111976ba76d698",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1767480499,
"narHash": "sha256-8IQQUorUGiSmFaPnLSo2+T+rjHtiNWc+OAzeHck7N48=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "30a3c519afcf3f99e2c6df3b359aec5692054d92",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1774106199,
"narHash": "sha256-US5Tda2sKmjrg2lNHQL3jRQ6p96cgfWh3J1QBliQ8Ws=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1770380644,
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ae67888ff7ef9dff69b3cf0cc0fbfbcd3a722abe",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixvim": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_6",
"systems": "systems_3"
},
"locked": {
"lastModified": 1774309640,
"narHash": "sha256-8oWL7YLwElBY9ebYri1LlSlhf/gd1Qoqj0nbBwG2yso=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "28c58bf023bf537354f78d6e496a349d7a0ed554",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixvim",
"type": "github"
}
},
"oldNixpkgs": {
"locked": {
"lastModified": 1727619874,
"narHash": "sha256-a4Jcd+vjQAzF675/7B1LN3U2ay22jfDAVA8pOml5J/0=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "6710d0dd013f55809648dfb1265b8f85447d30a6",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "6710d0dd013f55809648dfb1265b8f85447d30a6",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"bip110": "bip110",
"btc-clients": "btc-clients",
"nix-bitcoin": "nix-bitcoin",
"nixpkgs": "nixpkgs_5",
"nixpkgs-stable": "nixpkgs-stable",
"nixvim": "nixvim"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

74
flake.nix Executable file
View File

@@ -0,0 +1,74 @@
{
description = "The Ultimate Sovran_SystemsOS Configuration from Sovran Systems";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix-bitcoin.url = "github:fort-nix/nix-bitcoin/release";
agenix.url = "github:ryantm/agenix";
agenix.inputs.darwin.follows = "";
nixvim.url = "github:nix-community/nixvim";
btc-clients.url = "github:emmanuelrosa/btc-clients-nix";
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11";
bip110.url = "github:emmanuelrosa/bitcoin-knots-bip-110-nix";
};
outputs = { self, nixpkgs, nix-bitcoin, nixvim, agenix, btc-clients, nixpkgs-stable, bip110, ... }:
let
overlay-stable = final: prev: {
stable = import nixpkgs-stable {
system = prev.stdenv.hostPlatform.system;
config.allowUnfree = true;
};
};
in
{
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
modules = [
{ nixpkgs.hostPlatform = "x86_64-linux"; }
];
};
nixosModules.Sovran_SystemsOS = { pkgs, lib, config, ... }: {
imports = [
({ config, pkgs, ... }: {
nixpkgs.overlays = [ overlay-stable ];
})
./configuration.nix
nix-bitcoin.nixosModules.default
agenix.nixosModules.default
nixvim.nixosModules.nixvim
];
config = {
environment.systemPackages = with pkgs; [
btc-clients.packages.${pkgs.system}.bisq
btc-clients.packages.${pkgs.system}.bisq2
btc-clients.packages.${pkgs.system}.sparrow
];
sovran_systemsOS.packages.bip110 = bip110.packages.${pkgs.system}.bitcoind-knots-bip-110;
};
};
};
}

View File

@@ -0,0 +1,472 @@
[com/ftpix/transparentbar]
dark-full-screen=false
[org/gnome/Connections]
first-run=false
[org/gnome/Console]
font-scale=1.6000000000000005
last-window-size=(1912, 1037)
[org/gnome/Geary]
migrated-config=true
window-height=516
window-width=954
[org/gnome/TextEditor]
last-save-directory='file:///home/free/Downloads'
[org/gnome/Totem]
active-plugins=['mpris', 'vimeo', 'screenshot', 'movie-properties', 'autoload-subtitles', 'screensaver', 'apple-trailers', 'save-file', 'rotation', 'open-directory', 'recent', 'variable-rate', 'skipto']
subtitle-encoding='UTF-8'
[org/gnome/baobab/ui]
is-maximized=false
window-size=(1912, 1037)
[org/gnome/calculator]
accuracy=9
angle-units='degrees'
base=10
button-mode='basic'
number-format='automatic'
show-thousands=false
show-zeroes=false
source-currency=''
source-units='degree'
target-currency=''
target-units='radian'
word-size=64
[org/gnome/calendar]
active-view='month'
window-maximized=false
window-size=(1912, 1037)
[org/gnome/control-center]
last-panel='background'
window-state=(1912, 1040, false)
[org/gnome/desktop/app-folders]
folder-children=['Utilities', 'YaST', 'd737daeb-6dbb-4a5d-9ec7-e674398539ce', '7d66e46a-a135-4e42-91bb-d438e499d251', '3fea025e-f5e4-4905-9912-e70e38cd0419', '83d8148a-1f0b-4f83-814a-11c33ab8debc', '68c075b1-a254-4b7c-ba63-c45f88bc2a58', '534e2716-83c7-4a2a-9678-8144999213ed', '4acaa2d8-d284-4efd-bba3-40f150f1ace5', '1e62b69b-d9bb-4e80-be8d-5e9b4d777fc8']
[org/gnome/desktop/app-folders/folders/1e62b69b-d9bb-4e80-be8d-5e9b4d777fc8]
apps=['math.desktop', 'writer.desktop', 'impress.desktop', 'draw.desktop', 'calc.desktop', 'base.desktop', 'startcenter.desktop']
name='Office'
[org/gnome/desktop/app-folders/folders/3fea025e-f5e4-4905-9912-e70e38cd0419]
apps=['cups.desktop', 'simple-scan.desktop']
name='Printing'
translate=false
[org/gnome/desktop/app-folders/folders/4acaa2d8-d284-4efd-bba3-40f150f1ace5]
apps=['org.gnome.DiskUtility.desktop', 'org.gnome.baobab.desktop', 'gparted.desktop', 'gnome-system-monitor.desktop']
name='Utilities'
[org/gnome/desktop/app-folders/folders/534e2716-83c7-4a2a-9678-8144999213ed]
apps=['org.gnome.Epiphany.desktop', 'librewolf.desktop', 'io.lbry.lbry-app.desktop', 'bitwarden.desktop', 'com.nextcloud.desktopclient.nextcloud.desktop', 'brave-browser.desktop', 'chromium-browser.desktop']
name='Internet'
[org/gnome/desktop/app-folders/folders/68c075b1-a254-4b7c-ba63-c45f88bc2a58]
apps=['org.gnome.Extensions.desktop', 'org.gnome.tweaks.desktop']
name='Customize Look'
translate=false
[org/gnome/desktop/app-folders/folders/7d66e46a-a135-4e42-91bb-d438e499d251]
apps=['org.gnome.Photos.desktop', 'org.gnome.Music.desktop', 'org.gnome.Totem.desktop', 'org.gnome.Cheese.desktop', 'org.gnome.Loupe.desktop', 'org.gnome.Snapshot.desktop']
name='Media'
translate=false
[org/gnome/desktop/app-folders/folders/83d8148a-1f0b-4f83-814a-11c33ab8debc]
apps=['org.gnome.Tour.desktop', 'yelp.desktop', 'nixos-manual.desktop']
name='Help'
translate=false
[org/gnome/desktop/app-folders/folders/Utilities]
apps=['gnome-abrt.desktop', 'gnome-system-log.desktop', 'nm-connection-editor.desktop', 'org.gnome.Connections.desktop', 'org.gnome.DejaDup.desktop', 'org.gnome.Dictionary.desktop', 'org.gnome.eog.desktop', 'org.gnome.Evince.desktop', 'org.gnome.FileRoller.desktop', 'org.gnome.fonts.desktop', 'org.gnome.seahorse.Application.desktop', 'org.gnome.Usage.desktop', 'vinagre.desktop', 'org.gnome.TextEditor.desktop', 'org.gnome.gedit.desktop', 'org.gnome.SystemMonitor.desktop']
categories=['X-GNOME-Utilities']
excluded-apps=['org.gnome.Console.desktop', 'org.gnome.tweaks.desktop', 'org.gnome.DiskUtility.desktop', 'org.gnome.baobab.desktop']
name='X-GNOME-Utilities.directory'
translate=true
[org/gnome/desktop/app-folders/folders/YaST]
categories=['X-SuSE-YaST']
name='suse-yast.directory'
translate=true
[org/gnome/desktop/app-folders/folders/d737daeb-6dbb-4a5d-9ec7-e674398539ce]
apps=['fish.desktop', 'org.gnome.Console.desktop', 'htop.desktop', 'ranger.desktop', 'xterm.desktop', 'org.gnome.Terminal.desktop']
name='Terminal Fun'
translate=false
[org/gnome/desktop/background]
color-shading-type='solid'
picture-options='zoom'
picture-uri='file:///run/current-system/sw/share/backgrounds/gnome/amber-l.jxl'
picture-uri-dark='file:///run/current-system/sw/share/backgrounds/gnome/amber-d.jxl'
primary-color='#ff7800'
secondary-color='#000000'
[org/gnome/desktop/calendar]
show-weekdate=false
[org/gnome/desktop/input-sources]
sources=[('xkb', 'us')]
xkb-options=['terminate:ctrl_alt_bksp']
[org/gnome/desktop/interface]
clock-format='12h'
clock-show-seconds=false
clock-show-weekday=false
color-scheme='prefer-dark'
enable-animations=true
font-antialiasing='rgba'
font-hinting='full'
gtk-theme='Adwaita-dark'
icon-theme='Papirus-Dark'
text-scaling-factor=1.0
[org/gnome/desktop/notifications]
application-children=['gnome-power-panel', 'org-gnome-nautilus', 'org-gnome-software', 'gnome-network-panel', 'sparrow', 'org-gnome-settings', 'org-gnome-console', 'gnome-printers-panel', 'org-gnome-epiphany', 'com-obsproject-studio', 'io-github-seadve-kooha', 'xdg-desktop-portal-gnome', 'org-gnome-baobab', 'org-gnome-geary', 'sparrow-desktop', 'impress', 'brave-browser', 'org-gnome-connections']
show-in-lock-screen=false
[org/gnome/desktop/notifications/application/brave-browser]
application-id='brave-browser.desktop'
[org/gnome/desktop/notifications/application/com-obsproject-studio]
application-id='com.obsproject.Studio.desktop'
[org/gnome/desktop/notifications/application/gnome-network-panel]
application-id='gnome-network-panel.desktop'
[org/gnome/desktop/notifications/application/gnome-power-panel]
application-id='gnome-power-panel.desktop'
[org/gnome/desktop/notifications/application/gnome-printers-panel]
application-id='gnome-printers-panel.desktop'
[org/gnome/desktop/notifications/application/impress]
application-id='impress.desktop'
[org/gnome/desktop/notifications/application/io-github-seadve-kooha]
application-id='io.github.seadve.Kooha.desktop'
[org/gnome/desktop/notifications/application/org-gnome-baobab]
application-id='org.gnome.baobab.desktop'
[org/gnome/desktop/notifications/application/org-gnome-connections]
application-id='org.gnome.Connections.desktop'
[org/gnome/desktop/notifications/application/org-gnome-console]
application-id='org.gnome.Console.desktop'
[org/gnome/desktop/notifications/application/org-gnome-epiphany]
application-id='org.gnome.Epiphany.desktop'
[org/gnome/desktop/notifications/application/org-gnome-geary]
application-id='org.gnome.Geary.desktop'
[org/gnome/desktop/notifications/application/org-gnome-nautilus]
application-id='org.gnome.Nautilus.desktop'
[org/gnome/desktop/notifications/application/org-gnome-settings]
application-id='org.gnome.Settings.desktop'
[org/gnome/desktop/notifications/application/org-gnome-software]
application-id='org.gnome.Software.desktop'
[org/gnome/desktop/notifications/application/sparrow-desktop]
application-id='sparrow-desktop.desktop'
[org/gnome/desktop/notifications/application/sparrow]
application-id='Sparrow.desktop'
[org/gnome/desktop/notifications/application/xdg-desktop-portal-gnome]
application-id='xdg-desktop-portal-gnome.desktop'
[org/gnome/desktop/peripherals/keyboard]
numlock-state=false
[org/gnome/desktop/peripherals/mouse]
natural-scroll=true
speed=-0.63779527559055116
[org/gnome/desktop/peripherals/touchpad]
two-finger-scrolling-enabled=true
[org/gnome/desktop/privacy]
old-files-age=uint32 30
recent-files-max-age=-1
[org/gnome/desktop/screensaver]
color-shading-type='solid'
lock-enabled=false
picture-options='zoom'
picture-uri='file:///run/current-system/sw/share/backgrounds/gnome/amber-l.jxl'
primary-color='#ff7800'
secondary-color='#000000'
[org/gnome/desktop/session]
idle-delay=uint32 900
[org/gnome/desktop/sound]
event-sounds=true
theme-name='__custom'
[org/gnome/desktop/wm/preferences]
button-layout='appmenu:minimize,maximize,close'
[org/gnome/epiphany]
ask-for-default=false
[org/gnome/epiphany/state]
is-maximized=false
window-size=(1912, 1037)
[org/gnome/evolution-data-server]
migrated=true
network-monitor-gio-name=''
[org/gnome/file-roller/dialogs/extract]
recreate-folders=true
skip-newer=false
[org/gnome/file-roller/listing]
list-mode='as-folder'
name-column-width=250
show-path=false
sort-method='name'
sort-type='ascending'
[org/gnome/file-roller/ui]
sidebar-width=200
window-height=993
window-width=954
[org/gnome/gnome-system-monitor]
current-tab='processes'
maximized=false
network-total-in-bits=false
show-dependencies=false
show-whose-processes='all'
window-height=1040
window-state=(1912, 1040, 26, 23)
window-width=1912
[org/gnome/gnome-system-monitor/disktreenew]
col-6-visible=true
col-6-width=0
[org/gnome/gnome-system-monitor/proctree]
columns-order=[0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
sort-col=8
sort-order=0
[org/gnome/maps]
last-viewed-location=[34.015438242460405, -118.32766985901287]
map-type='MapsStreetSource'
transportation-type='pedestrian'
window-maximized=false
window-size=[1912, 1037]
zoom-level=9
[org/gnome/mutter]
attach-modal-dialogs=true
dynamic-workspaces=true
edge-tiling=false
focus-change-on-pointer-rest=true
workspaces-only-on-primary=true
[org/gnome/nautilus/icon-view]
default-zoom-level='large'
[org/gnome/nautilus/preferences]
default-folder-viewer='icon-view'
fts-enabled=false
migrated-gtk-settings=true
search-filter-time-type='last_modified'
search-view='list-view'
[org/gnome/nautilus/window-state]
initial-size=(1912, 1040)
maximized=false
[org/gnome/nm-applet/eap/202ce1d2-7306-40ac-b3bb-5b092c0f9734]
ignore-ca-cert=false
ignore-phase2-ca-cert=false
[org/gnome/nm-applet/eap/2afa07ed-64ca-44a0-948e-d8f265fa52b0]
ignore-ca-cert=false
ignore-phase2-ca-cert=false
[org/gnome/nm-applet/eap/8da70f78-fe38-3e50-a305-8fa32b2af624]
ignore-ca-cert=false
ignore-phase2-ca-cert=false
[org/gnome/nm-applet/eap/a9f5fb1c-2546-4fb9-82d0-7792e8982565]
ignore-ca-cert=false
ignore-phase2-ca-cert=false
[org/gnome/nm-applet/eap/e5e312d5-e2db-3928-8c98-8ec8a7cf61f2]
ignore-ca-cert=false
ignore-phase2-ca-cert=false
[org/gnome/portal/filechooser/brave-browser]
last-folder-path='/home/free/Downloads'
[org/gnome/portal/filechooser/chromium-browser]
last-folder-path='/home/free/Downloads'
[org/gnome/settings-daemon/plugins/color]
night-light-enabled=true
night-light-schedule-automatic=false
night-light-schedule-from=18.0
night-light-temperature=uint32 1744
[org/gnome/settings-daemon/plugins/power]
power-button-action='nothing'
sleep-inactive-ac-type='nothing'
[org/gnome/shell]
app-picker-layout=[{'org.gnome.Weather.desktop': <{'position': <0>}>, 'org.gnome.clocks.desktop': <{'position': <1>}>, 'org.gnome.Maps.desktop': <{'position': <2>}>, 'org.gnome.Calculator.desktop': <{'position': <3>}>, '68c075b1-a254-4b7c-ba63-c45f88bc2a58': <{'position': <4>}>, '3fea025e-f5e4-4905-9912-e70e38cd0419': <{'position': <5>}>, '83d8148a-1f0b-4f83-814a-11c33ab8debc': <{'position': <6>}>, 'Utilities': <{'position': <7>}>, 'd737daeb-6dbb-4a5d-9ec7-e674398539ce': <{'position': <8>}>, '7d66e46a-a135-4e42-91bb-d438e499d251': <{'position': <9>}>, '534e2716-83c7-4a2a-9678-8144999213ed': <{'position': <10>}>, '4acaa2d8-d284-4efd-bba3-40f150f1ace5': <{'position': <11>}>, '1e62b69b-d9bb-4e80-be8d-5e9b4d777fc8': <{'position': <12>}>, 'Bisq-hidpi.desktop': <{'position': <13>}>, 'com.obsproject.Studio.desktop': <{'position': <14>}>, 'Sovran_SystemsOS_External_Backup.desktop': <{'position': <15>}>, 'firefox.desktop': <{'position': <16>}>}]
disable-user-extensions=false
disabled-extensions=['transparent-top-bar@zhanghai.me']
enabled-extensions=['appindicatorsupport@rgcjonas.gmail.com', 'dash-to-dock-cosmic-@halfmexicanhalfamazing@gmail.com', 'Vitals@CoreCoding.com', 'dash-to-dock@micxgx.gmail.com', 'transparent-top-bar@ftpix.com', 'just-perfection-desktop@just-perfection', 'pop-shell@system76.com', 'date-menu-formatter@marcinjakubowski.github.com', 'systemd-manager@hardpixel.eu', 'light-style@gnome-shell-extensions.gcampax.github.com']
favorite-apps=['firefox.desktop', 'org.gnome.Nautilus.desktop', 'Sovran_SystemsOS_Updater.desktop', 'org.gnome.Settings.desktop', 'org.gnome.Software.desktop', 'io.freetubeapp.FreeTube.desktop', 'org.onlyoffice.desktopeditors.desktop', 'org.gnome.Geary.desktop', 'org.gnome.Contacts.desktop', 'org.gnome.Calendar.desktop', 'Bisq.desktop', 'sparrow-desktop.desktop']
last-selected-power-profile='performance'
welcome-dialog-last-shown-version='42.3.1'
[org/gnome/shell/extensions/dash-to-dock-pop]
apply-glossy-effect=false
background-color='rgb(0,0,0)'
background-opacity=0.25
border-radius=17
custom-background-color=true
custom-theme-shrink=false
dash-max-icon-size=64
dock-alignment='CENTRE'
dock-position='BOTTOM'
extend-height=false
floating-margin=0
force-straight-corner=false
height-fraction=0.90000000000000002
intellihide-mode='ALL_WINDOWS'
preferred-monitor=-2
preferred-monitor-by-connector='HDMI-1'
preview-size-scale=0.059999999999999998
running-indicator-style='DASHES'
show-apps-at-top=false
show-mounts=false
show-show-apps-button=true
show-trash=false
transparency-mode='FIXED'
unity-backlit-items=false
[org/gnome/shell/extensions/dash-to-dock]
apply-custom-theme=false
background-color='rgb(0,0,0)'
background-opacity=0.17000000000000001
custom-background-color=true
dash-max-icon-size=57
dock-position='BOTTOM'
extend-height=false
height-fraction=0.89000000000000001
icon-size-fixed=false
intellihide-mode='ALL_WINDOWS'
preferred-monitor=-2
preferred-monitor-by-connector='HDMI-2'
preview-size-scale=0.22
running-indicator-style='DASHES'
show-mounts=false
show-mounts-only-mounted=false
show-trash=false
transparency-mode='FIXED'
[org/gnome/shell/extensions/date-menu-formatter]
font-size=14
pattern='EEEE MMMM d h: mm a'
text-align='center'
[org/gnome/shell/extensions/just-perfection]
accessibility-menu=false
[org/gnome/shell/extensions/pop-shell]
active-hint-border-radius=uint32 3
gap-inner=uint32 1
gap-outer=uint32 1
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":"BTCPayserver","service":"btcpayserver.service","type":"system"}', '{"name":"Nbxplorer","service":"nbxplorer.service","type":"system"}', '{"name":"Caddy","service":"caddy.service","type":"system"}', '{"name":"Phpfpm-Mypool","service":"phpfpm-mypool.service","type":"system"}', '{"name":"Mysql","service":"mysql.service","type":"system"}', '{"name":"Postgresql","service":"postgresql.service","type":"system"}', '{"name":"Matrix-Synapse","service":"matrix-synapse.service","type":"system"}', '{"name":"Coturn","service":"coturn.service","type":"system"}', '{"name":"Tor","service":"tor.service","type":"system"}', '{"name":"VaultWarden","service":"vaultwarden.service","type":"system"}', '{"name":"LND","service":"lnd.service","type":"system"}', '{"name":"LND Loop","service":"lightning-loop.service","type":"system"}', '{"name":"Ride The Lightning","service":"rtl.service","type":"system"}']
[org/gnome/shell/extensions/vitals]
fixed-widths=false
hot-sensors=['_memory_usage_', '__network-tx_max__', '_processor_usage_', '_storage_free_', '_temperature_processor_0_']
show-fan=false
show-storage=true
show-voltage=false
[org/gnome/shell/weather]
automatic-location=true
locations=@av []
[org/gnome/shell/world-clocks]
locations=@av []
[org/gnome/software]
check-timestamp=int64 1715525466
first-run=false
flatpak-purge-timestamp=int64 1715478601
online-updates-timestamp=int64 1675355639
update-notification-timestamp=int64 1666382024
[org/gnome/terminal/legacy/profiles:/:b1dcc9dd-5262-4d8d-a863-c897e6d979b9]
font='Monospace 14'
use-system-font=false
[org/gnome/tweaks]
show-extensions-notice=false
[org/gtk/gtk4/settings/color-chooser]
selected-color=(true, 0.0, 0.0, 0.0, 1.0)
[org/gtk/gtk4/settings/file-chooser]
date-format='regular'
location-mode='path-bar'
show-hidden=false
show-size-column=true
show-type-column=true
sidebar-width=140
sort-column='name'
sort-directories-first=false
sort-order='ascending'
type-format='category'
view-type='list'
window-size=(1912, 1040)
[org/gtk/settings/file-chooser]
clock-format='12h'
date-format='regular'
location-mode='path-bar'
show-hidden=true
show-size-column=true
show-type-column=true
sidebar-width=165
sort-column='modified'
sort-directories-first=false
sort-order='descending'
type-format='category'
window-position=(26, 23)
window-size=(1401, 998)
[system/proxy]
ignore-hosts=@as []
mode='none'
[system/proxy/http]
port=0
[system/proxy/socks]
host='127.0.0.1'
port=9050

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

30
for_new_sovran_pros/flake.nix Executable file
View File

@@ -0,0 +1,30 @@
{
description = "Sovran_SystemsOS for the Sovran Pro from Sovran Systems";
inputs = {
Sovran_Systems.url = "git+https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS";
};
outputs = { self, Sovran_Systems, ... }@inputs: {
nixosConfigurations."nixos" = Sovran_Systems.inputs.nixpkgs.lib.nixosSystem {
modules = [
{ nixpkgs.hostPlatform = "x86_64-linux"; }
./hardware-configuration.nix
./custom.nix
Sovran_Systems.nixosModules.Sovran_SystemsOS
];
};
};
}

89
for_new_sovran_pros/psp.sh Executable file
View File

@@ -0,0 +1,89 @@
#!/usr/bin/env bash
# Begin: curl https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/psp.sh -o psp.sh
GREEN="\e[32m"
LIGHTBLUE="\e[94m"
ENDCOLOR="\e[0m"
lsblk
echo -e "${GREEN}What block for file-tree-root of drive (usually nvme0n1)?${ENDCOLOR}";read commitroot
parted /dev/"$commitroot" -- mklabel gpt
parted /dev/"$commitroot" -- mkpart primary 512MB -16GB
parted /dev/"$commitroot" -- mkpart swap linux-swap -16GB 100%
parted /dev/"$commitroot" -- mkpart ESP fat32 1MB 512MB
parted /dev/"$commitroot" -- set 3 esp on
lsblk
echo -e "${GREEN}What partition for Boot-Partition (usually nvme0n1p1)?${ENDCOLOR}";read commitbootpartition
echo -e "${GREEN}What partition for Main-Partition (usually nvme0n1p2)?${ENDCOLOR}";read commitmainpartition
echo -e "${GREEN}What partition for Swap-Partition (usually nvme0n1p3)?${ENDCOLOR}";read commitswappartition
mkfs.ext4 -L nixos /dev/"$commitmainpartition"
mkswap -L swap /dev/"$commitswappartition"
mkfs.fat -F 32 -n boot /dev/"$commitbootpartition"
mount /dev/disk/by-label/nixos /mnt
mkdir -p /mnt/boot/efi
mount /dev/disk/by-label/boot /mnt/boot/efi
nixos-generate-config --root /mnt
rm /mnt/etc/nixos/configuration.nix
cat <<EOT >> /mnt/etc/nixos/configuration.nix
{ config, pkgs, ... }: {
imports = [
./hardware-configuration.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.efi.efiSysMountPoint = "/boot/efi";
nix.settings.experimental-features = [ "nix-command" "flakes" ];
users.users = {
free = {
isNormalUser = true;
description = "free";
extraGroups = [ "networkmanager" ];
};
};
environment.systemPackages = with pkgs; [
wget
git
ranger
fish
pwgen
openssl
];
services.openssh = {
enable = true;
permitRootLogin = "yes";
};
}
EOT
nixos-install
reboot

View File

@@ -0,0 +1,85 @@
#!/usr/bin/env bash
# Begin: curl https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/psp_physical_ram.sh -o psp_physical_ram.sh
GREEN="\e[32m"
LIGHTBLUE="\e[94m"
ENDCOLOR="\e[0m"
lsblk
echo -e "${GREEN}What block for file-tree-root of drive (usually nvme0n1)?${ENDCOLOR}";read commitroot
parted /dev/"$commitroot" -- mklabel gpt
parted /dev/"$commitroot" -- mkpart ESP fat32 1MB 512MB
parted /dev/"$commitroot" -- set 1 esp on
parted /dev/"$commitroot" -- mkpart primary ext4 512MB 100%
lsblk
echo -e "${GREEN}What partition for Boot-Partition (usually nvme0n1p1)?${ENDCOLOR}";read commitbootpartition
echo -e "${GREEN}What partition for Primary-Partition (usually nvme0n1p2)?${ENDCOLOR}";read commitprimarypartition
mkfs.ext4 -L nixos /dev/"$commitprimarypartition"
mkfs.fat -F 32 -n boot /dev/"$commitbootpartition"
mount /dev/disk/by-label/nixos /mnt
mkdir -p /mnt/boot/efi
mount /dev/disk/by-label/boot /mnt/boot/efi
### Disk Step-up Finished
### Adding Configuration.nix
nixos-generate-config --root /mnt
rm /mnt/etc/nixos/configuration.nix
cat <<EOT >> /mnt/etc/nixos/configuration.nix
{ config, pkgs, ... }: {
imports = [
./hardware-configuration.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.efi.efiSysMountPoint = "/boot/efi";
nix.settings.experimental-features = [ "nix-command" "flakes" ];
users.users = {
free = {
isNormalUser = true;
description = "free";
extraGroups = [ "networkmanager" ];
};
};
environment.systemPackages = with pkgs; [
wget
git
ranger
fish
pwgen
openssl
];
services.openssh = {
enable = true;
permitRootLogin = "yes";
};
}
EOT
nixos-install
reboot

51
for_new_sovran_pros/sdpsp.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env bash
GREEN="\e[32m"
LIGHTBLUE="\e[94m"
ENDCOLOR="\e[0m"
lsblk
echo -e "${GREEN}What block for New Sovran Pro Second drive?${ENDCOLOR}";read commitroot
parted /dev/"$commitroot" -- mklabel gpt
parted /dev/"$commitroot" -- mkpart primary 0% 100%
lsblk
echo -e "${GREEN}What partition with New Sovran Pro Second Drive?${ENDCOLOR}";read commitsecond
mkfs.ext4 -L "BTCEcoandBackup" /dev/"$commitsecond"
sudo mkdir -p /mnt
mount /dev/"$commitsecond" /mnt
sudo mkdir -p /mnt/BTCEcoandBackup/Bitcoin_Node
sudo mkdir -p /mnt/BTCEcoandBackup/Electrs_Data
sudo mkdir -p /mnt/BTCEcoandBackup/NixOS_Snapshot_Backup
sudo mkdir -p /mnt/BTCEcoandBackup/clightning_db_backup
sudo systemctl stop bitcoind electrs nbxplorer btcpayserver lnd rtl lightning-loop clightning
rsync -ar --info=progress2 --info=name0 /run/media/Second_Drive/BTCEcoandBackup/Bitcoin_Node/ /mnt/BTCEcoandBackup/Bitcoin_Node/
rsync -ar --info=progress2 --info=name0 /run/media/Second_Drive/BTCEcoandBackup/Electrs_Data/ /mnt/BTCEcoandBackup/Electrs_Data/
sudo systemctl start bitcoind electrs nbxplorer btcpayserver lnd rtl lightning-loop clightning
sudo chown bitcoin:bitcoin /mnt/BTCEcoandBackup/Bitcoin_Node -R
sudo chown electrs:electrs /mnt/BTCEcoandBackup/Electrs_Data -R
sudo chmod 770 /mnt/BTCEcoandBackup/Bitcoin_Node -R
sudo chmod 770 /mnt/BTCEcoandBackup/Electrs_Data -R
sudo umount /dev/"$commitsecond"
echo -e "All Finished!"

406
for_new_sovran_pros/sp.sh Executable file
View File

@@ -0,0 +1,406 @@
#!/usr/bin/env bash
# wget https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/sp.sh
GREEN="\e[32m"
LIGHTBLUE="\e[94m"
#
pushd /etc/nixos/
wget https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/flake.nix
chown root:root /etc/nixos/ -R
chmod 770 /etc/nixos/ -R
popd
#
mkdir /var/lib/domains
touch /var/lib/domains/btcpayserver
touch /var/lib/domains/matrix
touch /var/lib/domains/nextcloud
touch /var/lib/domains/sslemail
touch /var/lib/domains/vaultwarden
touch /var/lib/domains/wordpress
#
echo -e "${GREEN}What is your New Matrix (Element Chat) domain name?${ENDCOLOR}"
read
echo -n $REPLY > /var/lib/domains/matrix
echo -e "${GREEN}What is your New Wordpress domain name?${ENDCOLOR}"
read
echo -n $REPLY > /var/lib/domains/wordpress
echo -e "${GREEN}What is your New Nextcloud domain name?${ENDCOLOR}"
read
echo -n $REPLY > /var/lib/domains/nextcloud
echo -e "${GREEN}What is your New BTCPayserver domain name?${ENDCOLOR}"
read
echo -n $REPLY > /var/lib/domains/btcpayserver
echo -e "${GREEN}What is your New Vaultwarden domain name?${ENDCOLOR}"
read
echo -n $REPLY > /var/lib/domains/vaultwarden
echo -e "${GREEN}What is the email you would like to use to manage the SSL certificates for your domains?${ENDCOLOR}"
read
echo -n $REPLY > /var/lib/domains/sslemail
#
mkdir /var/lib/nextcloudaddition
cat > /var/lib/nextcloudaddition/nextcloudaddition <<- "EOF"
'trusted_proxies' =>
array (
0 => '127.0.0.1',
),
'default_locale' => 'en_US',
'default_phone_region' => 'US',
'memcache.local' =>'\OC\Memcache\APCu' ,
EOF
#
mkdir /var/lib/njalla/
cat > /var/lib/njalla/njalla.sh <<- "EOF"
#!/usr/bin/env bash
IP=$(dig @resolver4.opendns.com myip.opendns.com +short -4)
## Manually Add DDNS Script From Njalla User Account AFTER Install
curl "https://...${IP}"
EOF
#
mkdir /var/lib/external_ip
cat > /var/lib/external_ip/external_ip.sh <<- "EOF"
#!/usr/bin/env bash
IP=$(dig @resolver4.opendns.com myip.opendns.com +short -4)
echo "${IP}" > /var/lib/secrets/external_ip
EOF
#
mkdir /var/lib/internal_ip
cat > /var/lib/internal_ip/internal_ip.sh <<- "EOF"
#!/usr/bin/env bash
sudo echo -n $(ip route get 1.2.3.4 | awk '{print $7}') > /var/lib/secrets/internal_ip
exit 0
EOF
#
touch /etc/nixos/custom.nix
cat > /etc/nixos/custom.nix <<- "EOF"
{config, pkgs, lib, ...}:
let
personalization = import ./personalization.nix;
in
{
}
EOF
#
mkdir /var/lib/agenix-secrets/
cat > /var/lib/agenix-secrets/secrets.nix <<- "EOF"
let
root = "placeholder" ;
in
{
"wordpressdb.age".publicKeys = [ root ];
"matrixdb.age".publicKeys = [ root ];
"nextclouddb.age".publicKeys = [ root ];
"turn.age".publicKeys = [ root ];
"matrix_reg_secret.age".publicKeys = [ root ];
}
EOF
#
mkdir /var/lib/secrets
mkdir /var/lib/secrets/vaultwarden
touch /var/lib/secrets/nextclouddb
touch /var/lib/secrets/wordpressdb
touch /var/lib/secrets/matrixdb
touch /var/lib/secrets/turn
touch /var/lib/secrets/matrix_reg_secret
touch /var/lib/secrets/main
touch /var/lib/secrets/vaultwarden/vaultwarden.env
touch /var/lib/secrets/external_ip
touch /var/lib/secrets/internal_ip
echo -n $(pwgen -s 17 -1) > /var/lib/secrets/nextclouddb
echo -n $(pwgen -s 17 -1) > /var/lib/secrets/wordpressdb
echo -n $(pwgen -s 17 -1) > /var/lib/secrets/matrixdb
echo -n $(pwgen -s 17 -1) > /var/lib/secrets/turn
echo -n $(pwgen -s 17 -1) > /var/lib/secrets/matrix_reg_secret
echo -n $(pwgen -s 17 -1) > /var/lib/secrets/main
echo -n ADMIN_TOKEN=$(openssl rand -base64 48
) > /var/lib/secrets/vaultwarden/vaultwarden.env
#
mkdir -p /root/.ssh/agenix
ssh-keygen -q -N "" -t ed25519 -f /root/.ssh/agenix/agenix-secret-keys
sed -i -e "0,/root.*/{s::root = $(cat /root/.ssh/agenix/agenix-secret-keys.pub):};s:root@nixos::" /var/lib/agenix-secrets/secrets.nix
sed -i 's:\(root =[[:blank:]]*\)\(.*\):\1"\2";:' /var/lib/agenix-secrets/secrets.nix
#
pushd /var/lib/agenix-secrets
echo -n $(cat /var/lib/secrets/wordpressdb) | EDITOR='cp /dev/stdin' nix run github:ryantm/agenix -- -e wordpressdb.age -i /root/.ssh/agenix/agenix-secret-keys
echo -n $(cat /var/lib/secrets/nextclouddb) | EDITOR='cp /dev/stdin' nix run github:ryantm/agenix -- -e nextclouddb.age -i /root/.ssh/agenix/agenix-secret-keys
echo -n $(cat /var/lib/secrets/matrixdb) | EDITOR='cp /dev/stdin' nix run github:ryantm/agenix -- -e matrixdb.age -i /root/.ssh/agenix/agenix-secret-keys
echo -n $(cat /var/lib/secrets/turn) | EDITOR='cp /dev/stdin' nix run github:ryantm/agenix -- -e turn.age -i /root/.ssh/agenix/agenix-secret-keys
echo -n $(cat /var/lib/secrets/matrix_reg_secret) | EDITOR='cp /dev/stdin' nix run github:ryantm/agenix -- -e matrix_reg_secret.age -i /root/.ssh/agenix/agenix-secret-keys
popd
#
pushd /etc/nixos
nix flake update
nixos-rebuild switch --impure
popd
#
chown root:root /var/lib/secrets/main -R
chown root:root /var/lib/secrets/external_ip -R
chown root:root /var/lib/secrets/internal_ip -R
chown matrix-synapse:matrix-synapse /var/lib/secrets/matrix_reg_secret -R
chown matrix-synapse:matrix-synapse /var/lib/secrets/matrixdb -R
chown postgres:postgres /var/lib/secrets/nextclouddb -R
chown turnserver:turnserver /var/lib/secrets/turn -R
chown mysql:mysql /var/lib/secrets/wordpressdb -R
chown vaultwarden:vaultwarden /var/lib/secrets/vaultwarden -R
chmod 770 /var/lib/secrets/ -R
#
chown caddy:php /var/lib/domains -R
chmod 770 /var/lib/domains -R
#
set -x
wget -P /var/lib/www/downloadwp https://wordpress.org/latest.zip
wget -P /var/lib/www/downloadnc https://download.nextcloud.com/server/releases/latest.zip
unzip /var/lib/www/downloadwp/latest.zip -d /var/lib/www/
unzip /var/lib/www/downloadnc/latest.zip -d /var/lib/www/
rm -rf /var/lib/www/downloadwp
rm -rf /var/lib/www/downloadnc
chown caddy:php /var/lib/www -R
chmod 770 /var/lib/www -R
#
mkdir /var/lib/nextcloud
chown caddy:php /var/lib/nextcloud -R
chmod 770 /var/lib/nextcloud -R
#
mkdir /var/lib/coturn
chown turnserver:turnserver /var/lib/coturn -R
chmod 770 /var/lib/coturn -R
#
rm -rf /root/sp.sh
#
chown bitcoin:bitcoin /run/media/Second_Drive/BTCEcoandBackup/Bitcoin_Node -R
chmod 770 /run/media/Second_Drive/BTCEcoandBackup/Bitcoin_Node -R
chown electrs:electrs /run/media/Second_Drive/BTCEcoandBackup/Electrs_Data -R
chmod 770 /run/media/Second_Drive/BTCEcoandBackup/Electrs_Data -R
#
mkdir -p /home/free/Downloads
pushd /home/free/Downloads
wget https://git.sovransystems.com/Sovran_Systems/Software/raw/branch/main/Sovran_SystemsOS_Resetter/sovran_systemsOS_resetter_local_installer/sovran_systemsOS_resetter_install.sh
bash sovran_systemsOS_resetter_install.sh
popd
#
pushd /home/free/Downloads
wget https://git.sovransystems.com/Sovran_Systems/Software/raw/branch/main/Sovran_SystemsOS_Updater/sovran_systemsOS_updater_local_installer/sovran_systemsOS_updater_install.sh
bash sovran_systemsOS_updater_install.sh
popd
#
mkdir -p /home/free/Pictures
pushd /home/free/Pictures
wget https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/Wallpaper_Dark_Wide.png
popd
chown free:users /home/free -R
chmod 700 /home/free -R
#
pushd /home/free/Downloads
sudo -u free wget https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/for_new_sovran_pros/Sovran_SystemsOS-Desktop
popd
#
wp=$(cat /var/lib/secrets/wordpressdb)
sudo mysql -u root -e "SET PASSWORD FOR wpusr@localhost = PASSWORD('${wp}')";
#
mkdir /root/.ssh
mkdir -p /home/free/.ssh
chown free:users /home/free/.ssh -R
touch /root/.ssh/authorized_keys
sudo -u free ssh-keygen -q -N "gosovransystems" -t ed25519 -f /home/free/.ssh/factory_login
chmod 700 /home/free/.ssh -R
echo "$(cat /home/free/.ssh/factory_login.pub)" >> /root/.ssh/authorized_keys
#
sudo matrix-synapse-register_new_matrix_user -u admin -p a -a
sudo echo "no" | matrix-synapse-register_new_matrix_user -u test -p a
#
# This key is removed before shipping as it allows Sovran Systems to access the machine via root remotely.
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCQa3DEhx9RUtV0WopfFuL3cjQt2fBzp5wOg/hkj0FXyZXpp+F47Td1B9mKMNvucINaMQB6T0mW6c70fyT92gZO2OqCff6aeWovtTd9ynRgtJbny/qvVSShDbJcR7nSMeVPoDRaYs18fuA50guYnfoYAkaXyXPmVQ0uK84HwIB5j8gq6GMji7vv+TTNhDP8qOceUzt1DYPo9Z2JSnkFey+Z/fmxWJGsu+MSrA0/PPENEmf6L0ZSgxnu3gHEtdyX2hrFzjE16y3G0wSQzbWJb8MJO0KRSMcyvz6AzOSW4RYdXR1c+4JiciKRdnIAYYHfg7tnZT9wC9AzHjdEbmmrlF05mtjXKnxbPgGY0tlRSYo7B5E0k2zfi30MkIJ6kIE9TMM2z/+1KstrQN4OKBTGomBTYQaRQCT6dGpRTR+b8lOvUcnCSuat1sUC2M2VGFcBbDbKD0FyXy/vOk1pgA4I7GoESWQClnl+ntRg8HrW4oVTX2KpqR2CXjlF956HJGqHW6k= free@nixos" >> /root/.ssh/authorized_keys
#
pushd /etc/nixos
nix flake update
nixos-rebuild switch --impure
popd
#
echo "root:$(cat /var/lib/secrets/main)" | chpasswd -c SHA512
echo "free:a" | chpasswd -c SHA512
#
chown free:users /home/free -R
chmod 700 /home/free -R
#
echo -e "${GREEN}All Finished! Please Reboot then Enjoy your New Sovran Pro!"

View File

@@ -0,0 +1,24 @@
{config, pkgs, lib, ...}:
{
systemd.services.Sovran_SystemsOS_File_Fixes_And_New_Services = {
unitConfig = {
After = "btcpayserver.service";
Requires = "network-online.target";
};
serviceConfig = {
ExecStartPre= "/run/current-system/sw/bin/sleep 30";
ExecStart = "/run/current-system/sw/bin/wget https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/raw/branch/main/file_fixes_and_new_services/Sovran_SystemsOS_File_Fixes_And_New_Services.sh -O /home/free/Downloads/Sovran_SystemsOS_File_Fixes_And_New_Services.sh ; /run/current-system/sw/bin/bash /home/free/Downloads/Sovran_SystemsOS_File_Fixes_And_New_Services.sh";
RemainAfterExit = "yes";
User = "root";
Type = "oneshot";
};
wantedBy = [ "multi-user.target" ];
};
}

23
modules/bip110.nix Executable file
View File

@@ -0,0 +1,23 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sovran_systemsOS;
in
{
options.sovran_systemsOS.packages.bip110 = lib.mkOption {
type = lib.types.nullOr lib.types.package;
default = null;
description = "BIP110 Bitcoin package";
};
config = lib.mkIf (
cfg.features.bip110 &&
cfg.packages.bip110 != null
) {
services.bitcoind.package = lib.mkForce cfg.packages.bip110;
environment.systemPackages = [
cfg.packages.bip110
];
};
}

7
modules/bitcoin-core.nix Executable file
View File

@@ -0,0 +1,7 @@
{ config, pkgs, lib, ... }:
lib.mkIf config.sovran_systemsOS.features.bitcoin-core {
services.bitcoind.package = lib.mkForce config.nix-bitcoin.pkgs.bitcoind;
}

95
modules/bitcoinecosystem.nix Executable file
View File

@@ -0,0 +1,95 @@
{ config, pkgs, lib, ... }:
lib.mkIf config.sovran_systemsOS.features.bitcoin {
## Bitcoind
services.bitcoind = {
enable = true;
package = config.nix-bitcoin.pkgs.bitcoind-knots;
dataDir = "/run/media/Second_Drive/BTCEcoandBackup/Bitcoin_Node";
txindex = true;
tor.proxy = true;
tor.enforce = true;
disablewallet = true;
extraConfig = ''
peerbloomfilters=1
server=1
'';
};
nix-bitcoin.onionServices.bitcoind.enable = true;
nix-bitcoin.onionServices.electrs.enable = true;
nix-bitcoin.onionServices.rtl.enable = true;
## Electrs
services.electrs = {
enable = true;
tor.enforce = true;
dataDir = "/run/media/Second_Drive/BTCEcoandBackup/Electrs_Data";
};
## LND
services.lnd = {
enable = true;
tor.enforce = true;
tor.proxy = true;
extraConfig = ''
protocol.option-scid-alias=true
'';
};
nix-bitcoin.onionServices.lnd.public = true;
## LNDconnect
services.lnd.lndconnect = {
enable = true;
onion = true;
};
## RTL
services.rtl = {
enable = true;
tor.enforce = true;
port = 3050;
nightTheme = true;
nodes = {
lnd = {
enable = true;
};
};
};
## BTCpayserver
services.btcpayserver = {
enable = true;
};
services.btcpayserver.lightningBackend = "lnd";
## System
nix-bitcoin.generateSecrets = true;
nix-bitcoin.nodeinfo.enable = true;
nix-bitcoin.operator = {
enable = true;
name = "free";
};
nix-bitcoin.useVersionLockedPkgs = false;
}

108
modules/core/caddy.nix Normal file
View 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
'';
};
}

View 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
View 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
View 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";
};
};
}

View 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
];
}

54
modules/coturn.nix Executable file
View File

@@ -0,0 +1,54 @@
{config, pkgs, lib, ...}:
let
personalization = import ./personalization.nix;
in
lib.mkIf config.sovran_systemsOS.features.coturn {
systemd.services.coturn-helper = {
script = ''
systemctl restart coturn
'';
unitConfig = {
Type = "simple";
After = "btcpayserver.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.coturn_static_auth_secret}";
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;
listening-port = 5349;
no-cli = true;
extraConfig = ''
verbose
external-ip=${personalization.external_ip_secret}
stale-nonce
fingerprint
'';
};
}

248
modules/element-calling.nix Executable file
View File

@@ -0,0 +1,248 @@
{ config, pkgs, lib, ... }:
let
livekitKeyFile = "/var/lib/livekit/livekit_keyFile";
in
lib.mkIf config.sovran_systemsOS.features.element-calling {
####### LIVEKIT KEY GENERATION #######
systemd.tmpfiles.rules = [
"d /var/lib/livekit 0750 root root -"
];
systemd.services.livekit-key-setup = {
description = "Generate LiveKit key file if missing";
wantedBy = [ "multi-user.target" ];
before = [ "livekit.service" "lk-jwt-service.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.openssl ];
script = ''
if [ ! -f ${livekitKeyFile} ]; then
API_KEY="devkey_$(openssl rand -hex 16)"
API_SECRET="$(openssl rand -base64 36 | tr -d '\n')"
echo "$API_KEY: $API_SECRET" > ${livekitKeyFile}
chmod 600 ${livekitKeyFile}
echo "LiveKit key file generated at ${livekitKeyFile}"
else
echo "LiveKit key file already exists, skipping generation"
fi
'';
};
####### ENSURE SERVICES START AFTER KEY EXISTS #######
systemd.services.livekit.after = [ "livekit-key-setup.service" ];
systemd.services.livekit.wants = [ "livekit-key-setup.service" ];
systemd.services.lk-jwt-service.after = [ "livekit-key-setup.service" ];
systemd.services.lk-jwt-service.wants = [ "livekit-key-setup.service" ];
####### CADDY SNIPPET — written to /run/caddy for caddy.nix to pick up #######
systemd.services.element-calling-caddy-config = {
description = "Generate Element Calling Caddy config snippet";
before = [ "caddy-generate-config.service" ];
requiredBy = [ "caddy-generate-config.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.coreutils ];
script = ''
MATRIX=$(cat /var/lib/domains/matrix)
ELEMENT_CALLING=$(cat /var/lib/domains/element-calling)
mkdir -p /run/caddy
cat > /run/caddy/element-calling.snippet <<EOF
$MATRIX {
reverse_proxy /_matrix/* http://localhost:8008
reverse_proxy /_synapse/client/* http://localhost:8008
header /.well-known/matrix/* Content-Type "application/json"
header /.well-known/matrix/* Access-Control-Allow-Origin "*"
header /.well-known/matrix/* Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
header /.well-known/matrix/* Access-Control-Allow-Headers "X-Requested-With, Content-Type, Authorization"
respond /.well-known/matrix/client \`{ "m.homeserver": {"base_url": "https://$MATRIX" }, "org.matrix.msc4143.rtc_foci": [{ "type":"livekit", "livekit_service_url":"https://$ELEMENT_CALLING/livekit/jwt" }] }\`
}
$MATRIX:8448 {
reverse_proxy http://localhost:8008
}
$ELEMENT_CALLING {
handle /livekit/jwt/sfu/get {
uri strip_prefix /livekit/jwt
reverse_proxy [::1]:8073 {
header_up Host {host}
header_up X-Forwarded-Server {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
}
}
handle {
reverse_proxy localhost:7880
}
}
EOF
'';
};
####### LIVEKIT RUNTIME CONFIG #######
systemd.services.livekit-runtime-config = {
description = "Generate LiveKit runtime config from domain files";
before = [ "livekit.service" ];
after = [ "livekit-key-setup.service" ];
requiredBy = [ "livekit.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.coreutils ];
script = ''
MATRIX=$(cat /var/lib/domains/matrix)
mkdir -p /run/livekit
cat > /run/livekit/runtime-config.yaml <<EOF
turn:
domain: $MATRIX
cert_file: /var/lib/livekit/$MATRIX.crt
key_file: /var/lib/livekit/$MATRIX.key
EOF
chmod 640 /run/livekit/runtime-config.yaml
'';
};
####### LIVEKIT SERVICE #######
services.livekit = {
enable = true;
openFirewall = true;
keyFile = livekitKeyFile;
settings = {
rtc.use_external_ip = true;
rtc.udp_port = "7882-7894";
room.auto_create = false;
turn = {
enabled = true;
tls_port = 5349;
udp_port = 3478;
};
};
};
networking.firewall.allowedTCPPorts = [ 7881 ];
networking.firewall.allowedUDPPortRanges = [
{ from = 7882; to = 7894; }
];
####### JWT SERVICE #######
systemd.services.lk-jwt-service-runtime-config = {
description = "Generate lk-jwt-service runtime config from domain files";
before = [ "lk-jwt-service.service" ];
after = [ "livekit-key-setup.service" ];
requiredBy = [ "lk-jwt-service.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.coreutils ];
script = ''
ELEMENT_CALLING=$(cat /var/lib/domains/element-calling)
mkdir -p /run/lk-jwt-service
cat > /run/lk-jwt-service/env <<EOF
LIVEKIT_URL=wss://$ELEMENT_CALLING
EOF
chmod 640 /run/lk-jwt-service/env
'';
};
services.lk-jwt-service = {
enable = true;
port = 8073;
keyFile = livekitKeyFile;
};
systemd.services.lk-jwt-service.serviceConfig.EnvironmentFile = [
"/run/lk-jwt-service/env"
];
####### SYNAPSE RUNTIME CONFIG (element-calling additions) #######
systemd.services.element-calling-synapse-config = {
description = "Generate Synapse runtime config for Element Calling";
before = [ "matrix-synapse.service" ];
requiredBy = [ "matrix-synapse.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.coreutils ];
script = ''
MATRIX=$(cat /var/lib/domains/matrix)
mkdir -p /run/matrix-synapse
cat > /run/matrix-synapse/element-calling-config.yaml <<EOF
server_name: "$MATRIX"
public_baseurl: "https://$MATRIX"
serve_server_wellknown: true
experimental_features:
msc3266_enabled: true
msc4222_enabled: true
max_event_delay_duration: "24h"
rc_message:
per_second: 0.5
burst_count: 30
rc_delayed_event_mgmt:
per_second: 1
burst_count: 20
EOF
chown matrix-synapse:matrix-synapse /run/matrix-synapse/element-calling-config.yaml
chmod 640 /run/matrix-synapse/element-calling-config.yaml
'';
};
services.matrix-synapse = {
extraConfigFiles = [ "/run/matrix-synapse/element-calling-config.yaml" ];
settings = lib.mkForce {
push.include_content = false;
url_preview_enabled = true;
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;
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" ];
presence.enabled = true;
enable_registration = false;
registration_shared_secret = config.age.secrets.matrix_reg_secret.path;
listeners = [
{
port = 8008;
bind_addresses = [ "::1" ];
type = "http";
tls = false;
x_forwarded = true;
resources = [
{ names = [ "client" ]; compress = true; }
{ names = [ "federation" ]; compress = false; }
];
}
];
};
};
}

158
modules/haven.nix Executable file
View File

@@ -0,0 +1,158 @@
{ config, pkgs, lib, ... }:
let
npub = config.sovran_systemsOS.nostr_npub;
in
lib.mkIf (config.sovran_systemsOS.features.haven && npub != "") {
# ── Caddy vhost is now handled centrally in caddy.nix ─────
# ── Generate Haven runtime config from domain files ───────
systemd.services.haven-runtime-config = {
description = "Generate Haven runtime config from domain files";
before = [ "haven.service" ];
requiredBy = [ "haven.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.coreutils ];
script = ''
HAVEN=$(cat /var/lib/domains/haven)
mkdir -p /run/haven
cat > /run/haven/runtime.env <<EOF
RELAY_URL=$HAVEN
PRIVATE_RELAY_NAME=$HAVEN private relay
PRIVATE_RELAY_DESCRIPTION=The Relay From
CHAT_RELAY_NAME=$HAVEN chat relay
CHAT_RELAY_DESCRIPTION=a relay for private chats
OUTBOX_RELAY_NAME=$HAVEN outbox relay
OUTBOX_RELAY_DESCRIPTION=a relay and Blossom server for public messages and media
INBOX_RELAY_NAME=$HAVEN inbox relay
INBOX_RELAY_DESCRIPTION=send your interactions with my notes here
EOF
chmod 640 /run/haven/runtime.env
chown haven:haven /run/haven/runtime.env
'';
};
services.haven = {
enable = true;
settings = {
OWNER_NPUB = npub;
# RELAY_URL injected at runtime via EnvironmentFile
RELAY_PORT = 3355;
RELAY_BIND_ADDRESS = "0.0.0.0";
DB_ENGINE = "badger";
LMDB_MAPSIZE = 3000000000;
BLOSSOM_PATH = "blossom/";
# Relay names/descriptions injected at runtime via EnvironmentFile
PRIVATE_RELAY_NPUB = npub;
CHAT_RELAY_NPUB = npub;
OUTBOX_RELAY_NPUB = npub;
INBOX_PULL_INTERVAL_SECONDS = 600;
PRIVATE_RELAY_EVENT_IP_LIMITER_TOKENS_PER_INTERVAL = 50;
PRIVATE_RELAY_EVENT_IP_LIMITER_INTERVAL = 1;
PRIVATE_RELAY_EVENT_IP_LIMITER_MAX_TOKENS = 100;
PRIVATE_RELAY_ALLOW_EMPTY_FILTERS = true;
PRIVATE_RELAY_ALLOW_COMPLEX_FILTERS = true;
PRIVATE_RELAY_CONNECTION_RATE_LIMITER_TOKENS_PER_INTERVAL = 3;
PRIVATE_RELAY_CONNECTION_RATE_LIMITER_INTERVAL = 5;
PRIVATE_RELAY_CONNECTION_RATE_LIMITER_MAX_TOKENS = 9;
CHAT_RELAY_WOT_DEPTH = 3;
CHAT_RELAY_WOT_REFRESH_INTERVAL_HOURS = 24;
CHAT_RELAY_MINIMUM_FOLLOWERS = 3;
CHAT_RELAY_EVENT_IP_LIMITER_TOKENS_PER_INTERVAL = 50;
CHAT_RELAY_EVENT_IP_LIMITER_INTERVAL = 1;
CHAT_RELAY_EVENT_IP_LIMITER_MAX_TOKENS = 100;
CHAT_RELAY_ALLOW_EMPTY_FILTERS = false;
CHAT_RELAY_ALLOW_COMPLEX_FILTERS = false;
CHAT_RELAY_CONNECTION_RATE_LIMITER_TOKENS_PER_INTERVAL = 3;
CHAT_RELAY_CONNECTION_RATE_LIMITER_INTERVAL = 3;
CHAT_RELAY_CONNECTION_RATE_LIMITER_MAX_TOKENS = 9;
OUTBOX_RELAY_EVENT_IP_LIMITER_TOKENS_PER_INTERVAL = 100;
OUTBOX_RELAY_EVENT_IP_LIMITER_INTERVAL = 600;
OUTBOX_RELAY_EVENT_IP_LIMITER_MAX_TOKENS = 1000;
OUTBOX_RELAY_ALLOW_EMPTY_FILTERS = true;
OUTBOX_RELAY_ALLOW_COMPLEX_FILTERS = true;
OUTBOX_RELAY_CONNECTION_RATE_LIMITER_TOKENS_PER_INTERVAL = 30;
OUTBOX_RELAY_CONNECTION_RATE_LIMITER_INTERVAL = 10;
OUTBOX_RELAY_CONNECTION_RATE_LIMITER_MAX_TOKENS = 90;
INBOX_RELAY_EVENT_IP_LIMITER_TOKENS_PER_INTERVAL = 10;
INBOX_RELAY_EVENT_IP_LIMITER_INTERVAL = 1;
INBOX_RELAY_EVENT_IP_LIMITER_MAX_TOKENS = 20;
INBOX_RELAY_ALLOW_EMPTY_FILTERS = false;
INBOX_RELAY_ALLOW_COMPLEX_FILTERS = false;
INBOX_RELAY_CONNECTION_RATE_LIMITER_TOKENS_PER_INTERVAL = 3;
INBOX_RELAY_CONNECTION_RATE_LIMITER_INTERVAL = 1;
INBOX_RELAY_CONNECTION_RATE_LIMITER_MAX_TOKENS = 9;
WOT_FETCH_TIMEOUT_SECONDS = 60;
WHITELISTED_NPUBS_FILE = "/var/lib/haven/whitelisted_npubs.json";
BLACKLISTED_NPUBS_FILE = "";
HAVEN_LOG_LEVEL = "INFO";
};
blastrRelays = [
"nos.lol"
"relay.nostr.band"
"relay.snort.social"
"nostr.mom"
"relay.primal.net"
"no.str.cr"
"nostr21.com"
"nostrue.com"
"wot.nostr.party"
"wot.sovbit.host"
"wot.girino.org"
"relay.lexingtonbitcoin.org"
"zap.watch"
"satsage.xyz"
"wons.calva.dev"
];
};
systemd.services.haven.serviceConfig.EnvironmentFile = [
"/run/haven/runtime.env"
];
systemd.tmpfiles.rules = [
"d /var/lib/haven 0750 haven haven -"
];
systemd.services.haven-whitelist-setup = {
description = "Ensure Haven whitelisted_npubs.json is valid";
wantedBy = [ "multi-user.target" ];
before = [ "haven.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
FILE="/var/lib/haven/whitelisted_npubs.json"
if [ ! -s "$FILE" ] || ! ${pkgs.jq}/bin/jq empty "$FILE" 2>/dev/null; then
echo '[]' > "$FILE"
chown haven:haven "$FILE"
chmod 770 "$FILE"
echo "Wrote valid empty JSON array to $FILE"
else
echo "$FILE already contains valid JSON, skipping"
fi
'';
};
systemd.services.haven.after = [ "haven-whitelist-setup.service" "haven-runtime-config.service" ];
systemd.services.haven.wants = [ "haven-whitelist-setup.service" "haven-runtime-config.service" ];
}

25
modules/mempool.nix Executable file
View File

@@ -0,0 +1,25 @@
{ config, pkgs, lib, ... }:
lib.mkIf config.sovran_systemsOS.features.mempool {
services.mempool = {
enable = true;
frontend.enable = true;
};
services.mysql.package = lib.mkForce pkgs.mariadb;
nix-bitcoin.onionServices.mempool-frontend.enable = true;
services.caddy = {
virtualHosts = {
":60847" = {
extraConfig = ''
reverse_proxy :60845
encode gzip zstd
'';
};
};
};
}

25
modules/modules.nix Normal file
View File

@@ -0,0 +1,25 @@
{ config, pkgs, lib, ... }:
{
imports = [
./core/roles.nix
./core/role-logic.nix
./core/caddy.nix
./core/sovran-manage.nix
./php.nix
./Sovran_SystemsOS_File_Fixes_And_New_Services.nix
./synapse.nix
./coturn.nix
./wordpress.nix
./nextcloud.nix
./btcpayserver.nix
./vaultwarden.nix
./haven.nix
./bip110.nix
./element-calling.nix
./mempool.nix
./bitcoin-core.nix
./rdp.nix
./bitcoinecosystem.nix
];
}

224
modules/nextcloud.nix Normal file
View File

@@ -0,0 +1,224 @@
{ config, pkgs, lib, ... }:
let
cfg = config.sovran_systemsOS.services.nextcloud;
in
{
options.sovran_systemsOS.services.nextcloud = {
enable = lib.mkEnableOption "Nextcloud (raw PHP served by Caddy)";
};
config = lib.mkIf cfg.enable {
# ── Caddy vhost is now handled centrally in caddy.nix ─────
# ── PostgreSQL database ───────────────────────────────────
services.postgresql = {
enable = true;
};
# ── Auto-generate DB password and initialize ──────────────
systemd.services.nextcloud-db-init = {
description = "Initialize Nextcloud PostgreSQL database with auto-generated password";
after = [ "postgresql.service" ];
requires = [ "postgresql.service" ];
before = [ "nextcloud-init.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ config.services.postgresql.package pkgs.pwgen pkgs.coreutils ];
script = ''
set -euo pipefail
SECRET_FILE="/var/lib/secrets/nextclouddb"
# Existing machines already have this file leave it alone
if [ ! -f "$SECRET_FILE" ]; then
mkdir -p /var/lib/secrets
pwgen -s 64 1 > "$SECRET_FILE"
chmod 600 "$SECRET_FILE"
fi
DB_PASS=$(cat "$SECRET_FILE")
# Create role if it doesn't exist, update password either way
psql -U postgres <<SQL
DO \$\$
BEGIN
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'ncusr') THEN
CREATE ROLE "ncusr" WITH LOGIN PASSWORD '$DB_PASS';
ELSE
ALTER ROLE "ncusr" WITH LOGIN PASSWORD '$DB_PASS';
END IF;
END
\$\$;
SQL
# Create database if it doesn't exist
if ! psql -U postgres -lqt | cut -d \| -f 1 | grep -qw "nextclouddb"; then
psql -U postgres -c "CREATE DATABASE nextclouddb WITH OWNER ncusr TEMPLATE template0 LC_COLLATE = 'C' LC_CTYPE = 'C';"
fi
'';
};
# ── Fully automated Nextcloud setup ───────────────────────
systemd.services.nextcloud-init = {
description = "Download, extract, and fully configure Nextcloud";
after = [ "network-online.target" "postgresql.service" "phpfpm-mypool.service" "nextcloud-db-init.service" ];
wants = [ "network-online.target" ];
requires = [ "postgresql.service" "nextcloud-db-init.service" ];
wantedBy = [ "multi-user.target" ];
unitConfig = {
ConditionPathExists = "!/var/lib/www/nextcloud/config/config.php";
};
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = with pkgs; [ curl unzip php pwgen coreutils ];
script = ''
set -euo pipefail
INSTALL_DIR="/var/lib/www/nextcloud"
DATA_DIR="/var/lib/www/nextcloud-data"
DOMAIN=$(cat /var/lib/domains/nextcloud)
DB_NAME="nextclouddb"
DB_USER="ncusr"
DB_PASS=$(cat /var/lib/secrets/nextclouddb)
DB_HOST="localhost"
ADMIN_USER=$(pwgen -s 16 1)
ADMIN_PASS=$(pwgen -s 24 1)
echo ""
echo " Nextcloud Automated Installation"
echo ""
# Download
if [ ! -f "$INSTALL_DIR/occ" ]; then
echo "Downloading Nextcloud..."
TEMP_DIR=$(mktemp -d)
curl -L -o "$TEMP_DIR/nextcloud.zip" "https://download.nextcloud.com/server/releases/latest.zip"
unzip -q "$TEMP_DIR/nextcloud.zip" -d "$TEMP_DIR"
mkdir -p "$INSTALL_DIR"
cp -a "$TEMP_DIR/nextcloud/"* "$INSTALL_DIR/"
rm -rf "$TEMP_DIR"
echo "Download complete."
fi
# Create data directory
mkdir -p "$DATA_DIR"
# Set permissions
chown -R caddy:root "$INSTALL_DIR"
chown -R caddy:root "$DATA_DIR"
find "$INSTALL_DIR" -type d -exec chmod 750 {} \;
find "$INSTALL_DIR" -type f -exec chmod 640 {} \;
chmod -R 770 "$INSTALL_DIR/apps"
chmod -R 770 "$INSTALL_DIR/config"
chmod -R 770 "$DATA_DIR"
# Wait for database
echo "Waiting for PostgreSQL..."
for i in $(seq 1 30); do
if su -s /bin/sh caddy -c "php -r \"new PDO('pgsql:host=$DB_HOST;dbname=$DB_NAME', '$DB_USER', '$DB_PASS');\"" 2>/dev/null; then
echo "Database ready."
break
fi
sleep 2
done
# Run Nextcloud install via occ
echo "Running Nextcloud installation..."
su -s /bin/sh caddy -c "
php $INSTALL_DIR/occ maintenance:install \
--database 'pgsql' \
--database-name '$DB_NAME' \
--database-user '$DB_USER' \
--database-pass '$DB_PASS' \
--database-host '$DB_HOST' \
--admin-user '$ADMIN_USER' \
--admin-pass '$ADMIN_PASS' \
--data-dir '$DATA_DIR'
"
# Configure trusted domains
echo "Configuring trusted domains..."
su -s /bin/sh caddy -c "
php $INSTALL_DIR/occ config:system:set trusted_domains 0 --value='$DOMAIN'
php $INSTALL_DIR/occ config:system:set overwrite.cli.url --value='https://$DOMAIN'
php $INSTALL_DIR/occ config:system:set overwriteprotocol --value='https'
"
# Set recommended settings <EFBFBD><EFBFBD>
echo "Applying recommended settings..."
su -s /bin/sh caddy -c "
php $INSTALL_DIR/occ config:system:set default_phone_region --value='US'
php $INSTALL_DIR/occ config:system:set memcache.local --value='\OC\Memcache\APCu'
php $INSTALL_DIR/occ background:cron
"
# Install default apps
echo "Installing default apps..."
su -s /bin/sh caddy -c "
php $INSTALL_DIR/occ app:install calendar || true
php $INSTALL_DIR/occ app:install contacts || true
php $INSTALL_DIR/occ app:install tasks || true
php $INSTALL_DIR/occ app:install notes || true
php $INSTALL_DIR/occ app:install deck || true
php $INSTALL_DIR/occ app:enable calendar || true
php $INSTALL_DIR/occ app:enable contacts || true
php $INSTALL_DIR/occ app:enable tasks || true
php $INSTALL_DIR/occ app:enable notes || true
php $INSTALL_DIR/occ app:enable deck || true
"
# Save admin credentials
CREDS_FILE="/var/lib/secrets/nextcloud-admin"
cat > "$CREDS_FILE" << CREDS
Nextcloud Admin Credentials
URL: https://$DOMAIN/
Username: $ADMIN_USER
Password: $ADMIN_PASS
CREDS
chmod 600 "$CREDS_FILE"
echo ""
echo ""
echo " Nextcloud installation complete!"
echo ""
echo " URL: https://$DOMAIN/"
echo " Username: $ADMIN_USER"
echo " Password: $ADMIN_PASS"
echo ""
echo " Installed apps: Calendar, Contacts, Tasks,"
echo " Notes, Deck"
echo ""
echo " Credentials saved to: $CREDS_FILE"
echo ""
'';
};
# ── Cron ──────────────────────────────────────────────────
services.cron.systemCronJobs = [
"*/5 * * * * caddy /run/current-system/sw/bin/php -f /var/lib/www/nextcloud/cron.php"
];
# ── Ensure directories ────────────────────────────────────
systemd.tmpfiles.rules = [
"d /var/lib/www 0755 caddy root -"
"d /var/lib/www/nextcloud 0750 caddy root -"
"d /var/lib/www/nextcloud-data 0770 caddy root -"
];
environment.systemPackages = with pkgs; [
unzip
];
};
}

24
modules/personalization.nix Executable file
View File

@@ -0,0 +1,24 @@
{
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_acme = builtins.readFile /var/lib/domains/sslemail;
vaultwarden_url = builtins.readFile /var/lib/domains/vaultwarden;
haven_url = builtins.readFile /var/lib/domains/haven;
element-calling_url = builtins.readFile /var/lib/domains/element-calling;
##
external_ip_secret = builtins.readFile /var/lib/secrets/external_ip;
coturn_static_auth_secret = builtins.readFile /var/lib/secrets/turn;
##
matrixdb = builtins.readFile /var/lib/secrets/matrixdb;
nextclouddb = builtins.readFile /var/lib/secrets/nextclouddb;
wordpressdb = builtins.readFile /var/lib/secrets/wordpressdb;
}

66
modules/php.nix Executable file
View File

@@ -0,0 +1,66 @@
{ config, pkgs, lib, ... }:
let
custom-php = pkgs.php83.buildEnv {
extensions = { enabled, all }: enabled ++ (with all; [ bz2 apcu redis imagick memcached ]);
extraConfig = ''
display_errors = On
display_startup_errors = On
max_execution_time = 10000
max_input_time = 3000
memory_limit = 1G;
opcache.enable=1;
opcache.memory_consumption=512;
opcache_revalidate_freq = 240;
opcache.max_accelerated_files=20000;
post_max_size = 3G
upload_max_filesize = 3G
apc.enable_cli=1
opcache.interned_strings_buffer = 192
redis.session.locking_enabled=1
redis.session.lock_retries=-1
redis.session.lock_wait_time=10000
'';
};
in
{
users.users = {
php = {
isSystemUser = true;
createHome = false;
uid = 7777;
};
};
users.users.php.group = "php";
users.groups.php = {};
environment.systemPackages = with pkgs; [
custom-php
];
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";
};
};
};
}

107
modules/rdp.nix Executable file
View File

@@ -0,0 +1,107 @@
{ config, pkgs, lib, ... }:
lib.mkIf config.sovran_systemsOS.features.rdp {
services.gnome.gnome-remote-desktop.enable = true;
networking.firewall.allowedTCPPorts = [ 3389 ];
environment.systemPackages = with pkgs; [
freerdp
];
# The NixOS module installs the unit but doesn't enable it — we just need to start it and order it
systemd.services.gnome-remote-desktop = {
wantedBy = [ "graphical.target" ];
after = [ "gnome-remote-desktop-setup.service" ];
wants = [ "gnome-remote-desktop-setup.service" ];
};
systemd.tmpfiles.rules = [
"d /var/lib/gnome-remote-desktop 0750 gnome-remote-desktop gnome-remote-desktop -"
"d /var/lib/gnome-remote-desktop/.local 0750 gnome-remote-desktop gnome-remote-desktop -"
"d /var/lib/gnome-remote-desktop/.local/share 0750 gnome-remote-desktop gnome-remote-desktop -"
"d /var/lib/gnome-remote-desktop/.local/share/gnome-remote-desktop 0750 gnome-remote-desktop gnome-remote-desktop -"
];
systemd.services.gnome-remote-desktop-setup = {
description = "Configure GNOME Remote Desktop RDP";
wantedBy = [ "multi-user.target" ];
before = [ "gnome-remote-desktop.service" ];
after = [ "systemd-tmpfiles-setup.service" "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [
pkgs.gnome-remote-desktop
pkgs.polkit
pkgs.openssl
pkgs.hostname
pkgs.gawk
];
script = ''
# Ensure directory structure exists
mkdir -p /var/lib/gnome-remote-desktop/.local/share/gnome-remote-desktop
chown -R gnome-remote-desktop:gnome-remote-desktop /var/lib/gnome-remote-desktop
TLS_DIR="/var/lib/gnome-remote-desktop/tls"
CRED_FILE="/var/lib/gnome-remote-desktop/rdp-credentials"
# Generate TLS certificate if it doesn't exist
if [ ! -f "$TLS_DIR/rdp-tls.crt" ]; then
mkdir -p "$TLS_DIR"
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
-sha256 -nodes -days 3650 \
-keyout "$TLS_DIR/rdp-tls.key" \
-out "$TLS_DIR/rdp-tls.crt" \
-subj "/CN=gnome-remote-desktop"
chown -R gnome-remote-desktop:gnome-remote-desktop "$TLS_DIR"
chmod 600 "$TLS_DIR/rdp-tls.key"
chmod 644 "$TLS_DIR/rdp-tls.crt"
echo "Generated RDP TLS certificate"
fi
# Configure TLS certificate
grdctl --system rdp set-tls-cert "$TLS_DIR/rdp-tls.crt"
grdctl --system rdp set-tls-key "$TLS_DIR/rdp-tls.key"
# Generate password on first boot only
PASSWORD=""
if [ ! -f /var/lib/gnome-remote-desktop/rdp-password ]; then
PASSWORD=$(openssl rand -base64 16)
echo "$PASSWORD" > /var/lib/gnome-remote-desktop/rdp-password
chmod 600 /var/lib/gnome-remote-desktop/rdp-password
else
PASSWORD=$(cat /var/lib/gnome-remote-desktop/rdp-password)
fi
# Get current IP address
LOCAL_IP=$(hostname -I | awk '{print $1}')
# Always rewrite the credentials file with the current IP
cat > "$CRED_FILE" <<EOF
========================================
GNOME Remote Desktop (RDP) Credentials
========================================
Username: sovran
Password: $PASSWORD
Connect from any RDP client to:
$LOCAL_IP:3389
========================================
EOF
chmod 600 "$CRED_FILE"
# Enable RDP backend and set credentials
grdctl --system rdp enable
grdctl --system rdp set-credentials sovran "$PASSWORD"
echo "GNOME Remote Desktop RDP configured successfully"
'';
};
}

136
modules/synapse.nix Normal file
View File

@@ -0,0 +1,136 @@
{ config, pkgs, lib, ... }:
{
# ── PostgreSQL database for Matrix ──────────────────────────
services.postgresql = {
enable = true;
ensureDatabases = [ "matrix-synapse" ];
ensureUsers = [
{
name = "matrix-synapse";
ensureDBOwnership = true;
}
];
};
# ── Auto-generate DB password and initialize ────────────────
systemd.services.matrix-synapse-db-init = {
description = "Initialize Matrix Synapse PostgreSQL database with auto-generated password";
after = [ "postgresql.service" ];
requires = [ "postgresql.service" ];
before = [ "matrix-synapse.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ config.services.postgresql.package pkgs.pwgen pkgs.coreutils ];
script = ''
SECRET_DIR="/var/lib/secrets"
SECRET_FILE="$SECRET_DIR/matrix_db_secret"
mkdir -p "$SECRET_DIR"
if [ ! -f "$SECRET_FILE" ]; then
pwgen -s 64 1 > "$SECRET_FILE"
chmod 600 "$SECRET_FILE"
chown matrix-synapse:matrix-synapse "$SECRET_FILE"
fi
DB_PASS=$(cat "$SECRET_FILE")
psql -U postgres -c "ALTER ROLE \"matrix-synapse\" WITH LOGIN PASSWORD '$DB_PASS';"
if ! psql -U postgres -lqt | cut -d \| -f 1 | grep -qw "matrix-synapse"; then
psql -U postgres -c "CREATE DATABASE \"matrix-synapse\" WITH OWNER \"matrix-synapse\" TEMPLATE template0 LC_COLLATE = 'C' LC_CTYPE = 'C';"
fi
'';
};
# ── Generate Synapse runtime config from /var/lib/domains ───
systemd.services.matrix-synapse-runtime-config = {
description = "Generate Matrix Synapse runtime config from domain files";
before = [ "matrix-synapse.service" ];
after = [ "matrix-synapse-db-init.service" ];
requiredBy = [ "matrix-synapse.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.coreutils ];
script = ''
MATRIX=$(cat /var/lib/domains/matrix)
RUNTIME_DIR="/run/matrix-synapse"
mkdir -p "$RUNTIME_DIR"
cat > "$RUNTIME_DIR/runtime-config.yaml" <<EOF
server_name: "$MATRIX"
EOF
chown matrix-synapse:matrix-synapse "$RUNTIME_DIR/runtime-config.yaml"
chmod 640 "$RUNTIME_DIR/runtime-config.yaml"
'';
};
# ── Synapse service ─────────────────────────────────────────
lib.mkIf config.sovran_systemsOS.features.synapse {
services.matrix-synapse = {
enable = true;
extraConfigFiles = [ "/run/matrix-synapse/runtime-config.yaml" ];
settings = {
push.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 is injected at runtime via extraConfigFiles
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" ];
presence.enabled = true;
enable_registration = false;
registration_shared_secret = config.age.secrets.matrix_reg_secret.path;
listeners = [
{
port = 8008;
bind_addresses = [ "::1" ];
type = "http";
tls = false;
x_forwarded = true;
resources = [
{
names = [ "client" ];
compress = true;
}
{
names = [ "federation" ];
compress = false;
}
];
}
];
};
};
}
}

47
modules/vaultwarden.nix Executable file
View File

@@ -0,0 +1,47 @@
{ config, pkgs, lib, ... }:
lib.mkIf config.sovran_systemsOS.features.vaultwarden {
# ── Caddy vhost is now handled centrally in caddy.nix ─────
# ── Generate Vaultwarden runtime config from domain files ──
systemd.services.vaultwarden-runtime-config = {
description = "Generate Vaultwarden runtime config from domain files";
before = [ "vaultwarden.service" ];
requiredBy = [ "vaultwarden.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ pkgs.coreutils ];
script = ''
VAULTWARDEN=$(cat /var/lib/domains/vaultwarden)
mkdir -p /run/vaultwarden
cat > /run/vaultwarden/runtime.env <<EOF
DOMAIN=https://$VAULTWARDEN
EOF
chmod 640 /run/vaultwarden/runtime.env
'';
};
services.vaultwarden = {
enable = true;
config = {
# DOMAIN injected at runtime via EnvironmentFile
SIGNUPS_ALLOWED = false;
ROCKET_ADDRESS = "127.0.0.1";
ROCKET_PORT = 8777;
ROCKET_LOG = "critical";
};
dbBackend = "sqlite";
environmentFile = "/var/lib/secrets/vaultwarden/vaultwarden.env";
};
systemd.services.vaultwarden.serviceConfig.EnvironmentFile = lib.mkAfter [
"/run/vaultwarden/runtime.env"
];
}

198
modules/wordpress.nix Normal file
View File

@@ -0,0 +1,198 @@
{ config, pkgs, lib, ... }:
let
cfg = config.sovran_systemsOS.services.wordpress;
in
{
options.sovran_systemsOS.services.wordpress = {
enable = lib.mkEnableOption "WordPress (raw PHP served by Caddy)";
};
config = lib.mkIf cfg.enable {
# ── Caddy vhost is now handled centrally in caddy.nix ─────
# ── MariaDB database ──────────────────────────────────────
services.mysql = {
enable = true;
package = pkgs.mariadb;
};
# ── Auto-generate DB password and initialize ──────────────
systemd.services.wordpress-db-init = {
description = "Initialize WordPress MariaDB database with auto-generated password";
after = [ "mysql.service" ];
requires = [ "mysql.service" ];
before = [ "wordpress-init.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [ config.services.mysql.package pkgs.pwgen pkgs.coreutils ];
script = ''
set -euo pipefail
SECRET_FILE="/var/lib/secrets/wordpressdb"
# Existing machines already have this file leave it alone
if [ ! -f "$SECRET_FILE" ]; then
mkdir -p /var/lib/secrets
pwgen -s 64 1 > "$SECRET_FILE"
chmod 600 "$SECRET_FILE"
fi
DB_PASS=$(cat "$SECRET_FILE")
mysql -u root <<SQL
CREATE DATABASE IF NOT EXISTS wordpressdb;
CREATE USER IF NOT EXISTS 'wpusr'@'localhost' IDENTIFIED BY '$DB_PASS';
ALTER USER 'wpusr'@'localhost' IDENTIFIED BY '$DB_PASS';
GRANT ALL ON wordpressdb.* TO 'wpusr'@'localhost';
FLUSH PRIVILEGES;
SQL
'';
};
# ── Fully automated WordPress setup ───────────────────────
systemd.services.wordpress-init = {
description = "Download, extract, and fully configure WordPress";
after = [ "network-online.target" "mysql.service" "phpfpm-mypool.service" "wordpress-db-init.service" ];
wants = [ "network-online.target" ];
requires = [ "mysql.service" "wordpress-db-init.service" ];
wantedBy = [ "multi-user.target" ];
unitConfig = {
ConditionPathExists = "!/var/lib/www/wordpress/wp-config.php";
};
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = with pkgs; [ curl unzip wp-cli pwgen php coreutils ];
script = ''
set -euo pipefail
INSTALL_DIR="/var/lib/www/wordpress"
DOMAIN=$(cat /var/lib/domains/wordpress)
DB_NAME="wordpressdb"
DB_USER="wpusr"
DB_PASS=$(cat /var/lib/secrets/wordpressdb)
DB_HOST="localhost"
ADMIN_USER=$(pwgen -s 16 1)
ADMIN_PASS=$(pwgen -s 24 1)
ADMIN_EMAIL="$ADMIN_USER@''${DOMAIN#*.}"
echo ""
echo " WordPress Automated Installation"
echo ""
# Download
if [ ! -f "$INSTALL_DIR/wp-includes/version.php" ]; then
echo "Downloading WordPress..."
TEMP_DIR=$(mktemp -d)
curl -L -o "$TEMP_DIR/wordpress.zip" "https://wordpress.org/latest.zip"
unzip -q "$TEMP_DIR/wordpress.zip" -d "$TEMP_DIR"
mkdir -p "$INSTALL_DIR"
cp -a "$TEMP_DIR/wordpress/"* "$INSTALL_DIR/"
rm -rf "$TEMP_DIR"
echo "Download complete."
fi
# Set permissions
chown -R caddy:root "$INSTALL_DIR"
find "$INSTALL_DIR" -type d -exec chmod 755 {} \;
find "$INSTALL_DIR" -type f -exec chmod 644 {} \;
chmod -R 775 "$INSTALL_DIR/wp-content"
# Generate wp-config.php
echo "Generating wp-config.php..."
cd "$INSTALL_DIR"
su -s /bin/sh caddy -c "
wp config create \
--dbname='$DB_NAME' \
--dbuser='$DB_USER' \
--dbpass='$DB_PASS' \
--dbhost='$DB_HOST' \
--skip-check
"
# Wait for database to be ready
echo "Waiting for database..."
for i in $(seq 1 30); do
if su -s /bin/sh caddy -c "wp db check" 2>/dev/null; then
break
fi
sleep 2
done
# Run WordPress install
echo "Running WordPress core install..."
su -s /bin/sh caddy -c "
wp core install \
--url='https://$DOMAIN' \
--title='Sovran_SystemsOS' \
--admin_user='$ADMIN_USER' \
--admin_password='$ADMIN_PASS' \
--admin_email='$ADMIN_EMAIL' \
--skip-email
"
# Configure WordPress settings
echo "Configuring WordPress..."
su -s /bin/sh caddy -c "
wp option update blogdescription 'Powered by Sovran_SystemsOS'
wp option update permalink_structure '/%postname%/'
wp option update default_ping_status 'closed'
wp option update default_comment_status 'closed'
wp rewrite flush
"
# Security hardening
echo "Applying security settings..."
su -s /bin/sh caddy -c "
wp config set DISALLOW_FILE_EDIT true --raw
wp config set WP_AUTO_UPDATE_CORE true --raw
wp config set FORCE_SSL_ADMIN true --raw
"
# Save admin credentials
CREDS_FILE="/var/lib/secrets/wordpress-admin"
cat > "$CREDS_FILE" << CREDS
WordPress Admin Credentials
URL: https://$DOMAIN/wp-admin/
Username: $ADMIN_USER
Password: $ADMIN_PASS
Email: $ADMIN_EMAIL
CREDS
chmod 600 "$CREDS_FILE"
echo ""
echo ""
echo " WordPress installation complete!"
echo ""
echo " URL: https://$DOMAIN/wp-admin/"
echo " Username: $ADMIN_USER"
echo " Password: $ADMIN_PASS"
echo ""
echo " Credentials saved to: $CREDS_FILE"
echo ""
'';
};
# ── Ensure directories ────────────────────────────────────
systemd.tmpfiles.rules = [
"d /var/lib/www 0755 caddy root -"
"d /var/lib/www/wordpress 0755 caddy root -"
];
environment.systemPackages = with pkgs; [
wp-cli
unzip
];
};
}

46
scripts/sovran-manage.sh Normal file
View File

@@ -0,0 +1,46 @@
case "$service" in
wordpress)
echo -e " ${BOLD}WordPress has been fully configured.${NC}"
echo ""
echo " View your admin credentials:"
echo -e " ${CYAN}sovran-manage show-creds wordpress${NC}"
echo ""
echo -e " Login at: ${CYAN}https://${domain}/wp-admin/${NC}"
echo ""
echo " Manage plugins:"
echo -e " ${CYAN}sovran-manage wp plugin install woocommerce --activate${NC}"
echo -e " ${CYAN}sovran-manage wp plugin list${NC}"
echo -e " ${CYAN}sovran-manage wp theme install flavor flavor --activate${NC}"
echo ""
;;
nextcloud)
echo -e " ${BOLD}Nextcloud has been fully configured.${NC}"
echo ""
echo " Pre-installed apps: Calendar, Contacts, Tasks, Notes, Deck"
echo ""
echo " View your admin credentials:"
echo -e " ${CYAN}sovran-manage show-creds nextcloud${NC}"
echo ""
echo -e " Login at: ${CYAN}https://${domain}/${NC}"
echo ""
echo " Manage apps:"
echo -e " ${CYAN}sovran-manage occ app:install cookbook${NC}"
echo -e " ${CYAN}sovran-manage occ app:list${NC}"
echo ""
;;
matrix)
echo -e " Matrix Synapse is running."
echo -e " URL: ${CYAN}https://${domain}${NC}"
echo ""
echo " Create your first user:"
echo -e " ${CYAN}sovran-manage matrix register-user${NC}"
echo ""
;;
*)
echo -e " URL: ${CYAN}https://${domain}${NC}"
echo ""
;;
esac

BIN
sovran_systems_grey.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB