Compare commits

...

No commits in common. "master" and "be45a769c7c59a46fcd1ee3fa24a3d4b1186ee17" have entirely different histories.

284 changed files with 183 additions and 28331 deletions
.envrc
.github
.gitignore.sops.yaml
.vscode
README.mdTODO.mdflake.lockflake.nix
hosts/NixOS-VM
keys
machines
misc
modules
patches
profiles/applications

14
.envrc

@ -1 +1,13 @@
use flake
if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM="
fi
watch_file flake.nix
watch_file flake.lock
DEVENV_ROOT_FILE="$(mktemp)"
printf %s "$PWD" > "$DEVENV_ROOT_FILE"
if ! use flake . --override-input devenv-root "file+file://$DEVENV_ROOT_FILE"
then
echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2
fi

@ -1,9 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
groups:
github-actions:
patterns: ["*"]

@ -1,51 +0,0 @@
name: "Build and cache hosts configurations"
on:
# push:
# branches:
# - master
# paths:
# - 'flake.lock'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@master
with:
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
remove-docker-images: 'true'
build-mount-path: '/nix'
temp-reserve-mb: '512'
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Install nix
uses: nixbuild/nix-quick-install-action@v30
with:
load_nixConfig: false
nix_conf: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
substituters = https://cache.nixos.org https://nix-community.cachix.org https://hyprland.cachix.org https://ataraxiadev-foss.cachix.org https://cache.ataraxiadev.com/ataraxiadev
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc= ataraxiadev-foss.cachix.org-1:ws/jmPRUF5R8TkirnV1b525lP9F/uTBsz2KraV61058= ataraxiadev:/V5bNjSzHVGx6r2XA2fjkgUYgqoz9VnrAHq45+2FJAs=
netrc-file = /home/runner/.config/nix/netrc
- name: Setup attic cache
run: |
mkdir -p /home/runner/.config/nix
echo "machine cache.ataraxiadev.com" > /home/runner/.config/nix/netrc
echo "password ${{ secrets.ATTIC_TOKEN }}" >> /home/runner/.config/nix/netrc
nix run github:AtaraxiaSjel/attic#attic -- login dev https://cache.ataraxiadev.com/ ${{ secrets.ATTIC_TOKEN }}
- name: Build NixOS configurations
run: nix run github:Mic92/nix-fast-build -- --max-jobs 2 --no-nom --retries 3 --skip-cached --eval-max-memory-size 2048 --eval-workers 4 --flake .#nixosHostsCI
- name: Push to attic
run: nix run github:AtaraxiaSjel/attic#attic -- push ataraxiadev result*

@ -1,48 +0,0 @@
name: "Build ISO"
on:
push:
branches:
- master
paths:
- 'flake.nix'
- 'flake.lock'
- 'machines/**/autoinstall.nix'
- 'machines/Flakes-ISO/**'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Install nix
uses: nixbuild/nix-quick-install-action@v30
with:
load_nixConfig: false
nix_conf: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
substituters = https://cache.nixos.org https://nix-community.cachix.org https://hyprland.cachix.org https://ataraxiadev-foss.cachix.org https://cache.ataraxiadev.com/ataraxiadev
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc= ataraxiadev-foss.cachix.org-1:ws/jmPRUF5R8TkirnV1b525lP9F/uTBsz2KraV61058= ataraxiadev:/V5bNjSzHVGx6r2XA2fjkgUYgqoz9VnrAHq45+2FJAs=
netrc-file = /home/runner/.config/nix/netrc
- name: Setup attic cache
run: |
mkdir -p /home/runner/.config/nix
echo "machine cache.ataraxiadev.com" > /home/runner/.config/nix/netrc
echo "password ${{ secrets.ATTIC_TOKEN }}" >> /home/runner/.config/nix/netrc
nix run github:AtaraxiaSjel/attic#attic -- login dev https://cache.ataraxiadev.com/ ${{ secrets.ATTIC_TOKEN }}
- name: Build ISO
run: nix build .#Flakes-ISO
- name: Push ISO to artifacts
uses: actions/upload-artifact@v4
with:
name: nix-flakes.iso.zip
path: result/iso/*.iso
if-no-files-found: error
retention-days: 30

5
.gitignore vendored

@ -1,6 +1,7 @@
/anywhere
.direnv
.VSCodeCounter
anywhere
.devenv
.pre-commit-config.yaml
result*
*.bak
*.qcow2

@ -1,64 +0,0 @@
keys:
- &ataraxiasjel age1n0prg9vynuwc56gn0xfe5qde8wqcd4uzg5ghhhetu2024ckvjyvqxf49el
- &ataraxia ad382d058c964607b7bbf01b071a8131bf166e80
- &nixos-vps 4ec141b4dd5a00e108b36211b0c4aaeff4e05aa6
- &nixos-vps-age age1n5qqe2tm93gc5gr2xq4f5k6luyhhak06ekw6qx6m2cxg9n9xdc5q8d4fkg
- &nixos-ro-vps-age age1xxakyntj60nds474xyhpqtl2cvyktefrqcd79x5ava6amewzugmq60rcdh
- &nixos-fi-vps-age age1d4mqql020mpne9r3vtt4l9ywfzfq7zpa3mad33syxln2kldkjsxqgju90f
- &home-hypervisor a32018133c7afbfd05d5b2795f3b89af369520c6
- &home-hypervisor-age age1m5msm7rgqye2q9zesgedg0emga4ntehlr629786lrxs3rhk0squq0ly9je
- &amd-workstation 78fa8fb95e85b2b89f1dd4f0834899283ee22a87
- &dell-laptop 05588f4245256f75a8da42e5d4fe28d9214b685a
- &dell-laptop-age age1ztrteyc2hae7c0tlrjx9pcjjtyeqazsq7ztf7dcmxlyxg5x2mcwq75p65f
creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *ataraxia
- *nixos-vps
- *home-hypervisor
- *amd-workstation
- *dell-laptop
age:
- *ataraxiasjel
- *dell-laptop-age
- *home-hypervisor-age
- *nixos-ro-vps-age
- *nixos-fi-vps-age
- path_regex: secrets/nixos-vps/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *ataraxia
- *nixos-vps
age:
- *ataraxiasjel
- *nixos-vps-age
- *nixos-ro-vps-age
- *nixos-fi-vps-age
- path_regex: secrets/home-hypervisor/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *ataraxia
- *home-hypervisor
- *nixos-vps
age:
- *ataraxiasjel
- *nixos-vps-age
- *nixos-ro-vps-age
- *nixos-fi-vps-age
- *home-hypervisor-age
- path_regex: secrets/amd-workstation/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *ataraxia
- *amd-workstation
age:
- *ataraxiasjel
- path_regex: secrets/dell-laptop/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *ataraxia
- *dell-laptop
age:
- *ataraxiasjel
- *dell-laptop-age

@ -1,7 +0,0 @@
{
"files.eol": "\n",
"[nix]": {
"editor.tabSize": 2
},
"cSpell.enabled": false
}

@ -1,10 +1,3 @@
NixOS Configurations
=======================
# NixOS configuration
NixOS is an advanced GNU/Linux distribution featuring declarative configuration and atomic upgrades. You can learn more on [nixos.org](https://nixos.org/nixos/about.html).
In this repository are the configurations of my NixOS machines.
You can find the configurations from other people in the [nixos.wiki](https://nixos.wiki/wiki/Configuration_Collection).
Big Thanks for original config: [balsoft](https://github.com/balsoft/nixos-config)!
WIP

73
TODO.md

@ -1,73 +0,0 @@
# TODO
* config.mainuser to extraArgs
* split modules to nixosModules and hmModules
* backup gitea with rustic
* fix waybar config (icons and catppuccin theme)
* move nginx config to respective profiles
* ocis confid and metadata backup (take zfs snapshot and backup it)
* grafana for all services
* move some profiles to modules (like vpn.nix)
* use sops for all occurrences of hashedPassword
* auto-import gpg keys
* config qbittorrent
* change writeShellScript and writeShellScriptBin to writeShellApplication
* remove aria2?
* move overlay and packages to root folder
* Change all 'latest' tags in docker container to digest: "statping/statping@sha256:aaaaa"
* or add cmd to all containers: "--pull=newer"
* fix global hotkeys for obs (use hyprland pass dispatcher)
https://github.com/catppuccin/rofi
https://github.com/catppuccin/waybar
https://github.com/catppuccin/base16
https://github.com/catppuccin/hyprlock
https://github.com/catppuccin/obs
https://github.com/catppuccin/spicetify
https://github.com/catppuccin/whoogle
https://github.com/catppuccin/dark-reader
## Tips:
* Copy sparse files
```bash
dd if=$1 of=$2 iflag=direct oflag=direct bs=64K conv=sparse
```
* swap on zfs zvol (on encrypted dataset only!)
```bash
zfs create -V 2G -b $(getconf PAGESIZE) -o logbias=throughput -o sync=always -o primarycache=metadata -o secondarycache=none -o com.sun:auto-snapshot=false -o compression=zle zroot/enc/swap
```
* disable offloading
```bash
ethtool --offload eth0 rx off tx off
```
```bash
eval "$(echo "gamemoderun mangohud %command%" | sed 's|BeamNG.drive.exe|BinLinux/BeamNG.drive.x64|g')" 2>&1 | tee $HOME/beamng.log
```
* reality url
vless://{uuid}@{server_ip}:{server_port}?encryption=none&flow=xtls-rprx-vision&security=reality&sni={domain}&fp=chrome&pbk={pubkey}&sid={short_id}&type=tcp&headerType=none#SING-BOX-TCP
* sops keys
```bash
ssh-to-pgp -i $HOME/.ssh/id_rsa -o ~/nixos-config/keys/users/ataraxia.asc
ssh root@ip "cat /etc/ssh/ssh_host_rsa_key" | ssh-to-pgp -o ~/nixos-config/keys/hosts/hostname.asc
```
* remove all github workflows
```bash
gh run list --limit 100 --json databaseId -q '.[].databaseId' | xargs -IID gh api --silent "repos/$(gh repo view --json nameWithOwner -q .nameWithOwner)/actions/runs/ID" -X DELETE
```

2338
flake.lock generated

File diff suppressed because it is too large Load Diff

286
flake.nix

@ -1,11 +1,20 @@
{
description = "System configuration";
description = "AtaraxiaSjel's NixOS configuration.";
nixConfig = {
extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=";
extra-substituters = "https://devenv.cachix.org";
};
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs-master.url = "github:nixos/nixpkgs/master";
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11";
flake-parts.url = "github:hercules-ci/flake-parts";
lite-config.url = "github:ataraxiasjel/lite-config/v0.6.0";
devenv.url = "github:cachix/devenv";
devenv-root = {
url = "file+file:///dev/null";
flake = false;
};
flake-registry = {
url = "github:nixos/flake-registry";
flake = false;
@ -14,237 +23,68 @@
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
impermanence.url = "github:nix-community/impermanence";
lix-module = {
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.91.1-2.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
};
aagl = {
url = "github:ezKEa/aagl-gtk-on-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
# ataraxiasjel-nur.url = "/home/ataraxia/projects/nur";
ataraxiasjel-nur.url = "github:AtaraxiaSjel/nur";
attic.url = "github:zhaofengli/attic";
base16.url = "github:AtaraxiaSjel/base16-nix";
base16-tokyonight-scheme = {
url = "github:AtaraxiaSjel/base16-tokyonight-scheme";
flake = false;
};
cassowary = {
url = "github:AtaraxiaSjel/cassowary";
inputs.nixpkgs.follows = "nixpkgs";
};
catppuccin.url = "github:catppuccin/nix";
deploy-rs.url = "github:serokell/deploy-rs";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
hyprland = {
url = "github:hyprwm/Hyprland";
# url = "git+https://github.com/hyprwm/Hyprland?submodules=1";
# inputs.nixpkgs.follows ="nixpkgs";
};
mms.url = "github:mkaito/nixos-modded-minecraft-servers";
nix-alien = {
url = "github:thiagokokada/nix-alien";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-direnv.url = "github:nix-community/nix-direnv";
nix-fast-build = {
url = "github:Mic92/nix-fast-build";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-vscode-marketplace = {
url = "github:nix-community/nix-vscode-extensions";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
prismlauncher.url = "github:AtaraxiaSjel/PrismLauncher/develop";
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
srvos = {
url = "github:nix-community/srvos";
inputs.nixpkgs.follows = "nixpkgs";
};
chaotic.url = "github:chaotic-cx/nyx/nyxpkgs-unstable";
};
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (
{ self, inputs, withSystem, ... }:
let
findModules = dir:
builtins.concatLists (
builtins.attrValues (
builtins.mapAttrs (name: type:
if type == "regular" then [
{
name = builtins.elemAt (builtins.match "(.*)\\.nix" name) 0;
value = dir + "/${name}";
}
] else if (builtins.readDir (dir + "/${name}")) ? "default.nix" then [
{
inherit name;
value = dir + "/${name}";
}
]
else findModules (dir + "/${name}")
) (builtins.readDir dir)
)
);
outputs =
inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } (
{ ... }:
{
imports = [
inputs.devenv.flakeModule
inputs.lite-config.flakeModule
];
# Patch nixpkgs
nixpkgs-patched = n: p:
(import n { system = "x86_64-linux"; }).pkgs.applyPatches {
name = if n ? shortRev then "nixpkgs-patched-${n.shortRev}" else "nixpkgs-patched";
src = n;
patches = p;
};
# Get nixosSystem func from patched nixpkgs
nixosSystem = n: import (n + "/nixos/lib/eval-config.nix");
# Make host config
mkHost = name: nixosSystem: self-nixpkgs:
nixosSystem {
system = builtins.readFile (./machines + "/${name}/system");
modules = builtins.attrValues self.customModules ++ [
(import (./machines + "/${name}"))
{ device = name; mainuser = "ataraxia"; }
{ nixpkgs.config.allowUnfree = true; }
{ sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; }
inputs.sops-nix.nixosModules.sops
inputs.lix-module.nixosModules.default
];
specialArgs = { inherit self inputs self-nixpkgs; secretsDir = ./secrets; };
lite-config = {
nixpkgs = {
nixpkgs = inputs.nixpkgs;
config = { };
overlays = [ ];
patches = [ ./patches/onlyoffice.patch ];
exportOverlayPackages = false;
setPerSystemPkgs = true;
};
patchesPath = map (x: ./patches + "/${x}");
in {
imports = [ ];
systems = [ "x86_64-linux" ];
systemModules = [ ./modules/nixos ];
homeModules = [ ./modules/home ];
hostModuleDir = ./hosts;
perSystem = { pkgs, self', ... }: {
devShells.default = let
rebuild = pkgs.writeShellScriptBin "rebuild" ''
[[ -n "$1" ]] && doas nixos-rebuild --flake . $@
'';
upgrade = pkgs.writeShellScriptBin "upgrade" ''
cp flake.lock flake.lock.bak && nix flake update
[[ "$1" == "zfs" ]] && ./scripts/gen-patch-zen.sh
'';
in pkgs.mkShell {
name = "aliases";
packages = [
rebuild upgrade
] ++ builtins.attrValues {
inherit (pkgs) nixfmt-rfc-style statix deadnix git deploy-rs sops;
};
};
packages = {
Flakes-ISO = inputs.nixos-generators.nixosGenerate {
system = "x86_64-linux";
modules = [
(import (./machines/Flakes-ISO))
{ device = "Flakes-ISO"; mainuser = "ataraxia"; }
./machines/AMD-Workstation/autoinstall.nix
./machines/Dell-Laptop/autoinstall.nix
self.customModules.autoinstall
];
specialArgs = { inherit inputs; };
format = "install-iso";
};
hosts = {
NixOS-VM.system = "x86_64-linux";
};
};
flake = let
unstable-nixpkgs = nixpkgs-patched inputs.nixpkgs unstable-patches;
stable-nixpkgs = nixpkgs-patched inputs.nixpkgs-stable stable-patches;
unstable-system = nixosSystem unstable-nixpkgs;
stable-system = nixosSystem stable-nixpkgs;
perSystem =
{ pkgs, lib, ... }:
{
devenv.shells.default = {
devenv.root =
let
devenvRootFileContent = builtins.readFile inputs.devenv-root.outPath;
in
lib.mkIf (devenvRootFileContent != "") devenvRootFileContent;
shared-patches = patchesPath [ ];
unstable-patches = shared-patches ++ patchesPath [
# "netbird-24.11.patch"
"onlyoffice.patch"
# "zen-kernels.patch"
];
stable-patches = shared-patches ++ patchesPath [];
in {
customModules = builtins.listToAttrs (findModules ./modules);
customProfiles = builtins.listToAttrs (findModules ./profiles);
customRoles = import ./roles;
secretsDir = ./secrets;
inherit unstable-nixpkgs;
nixosConfigurations = withSystem "x86_64-linux" ({ ... }:
{
AMD-Workstation = mkHost "AMD-Workstation" unstable-system unstable-nixpkgs;
Dell-Laptop = mkHost "Dell-Laptop" unstable-system unstable-nixpkgs;
Home-Hypervisor = mkHost "Home-Hypervisor" unstable-system unstable-nixpkgs;
NixOS-RO-VPS = mkHost "NixOS-RO-VPS" stable-system stable-nixpkgs;
NixOS-FI-VPS = mkHost "NixOS-FI-VPS" unstable-system unstable-nixpkgs;
}
);
packages.x86_64-linux = {
NixOS-VM = inputs.nixos-generators.nixosGenerate {
system = "x86_64-linux";
modules = builtins.attrValues self.customModules ++ [
(import (./machines/NixOS-VM))
{ device = "NixOS-VM"; mainuser = "ataraxia"; }
{ nixpkgs.config.allowUnfree = true; }
inputs.sops-nix.nixosModules.sops
];
specialArgs = {
inherit self inputs;
secrets = ./secrets;
self-nixpkgs = unstable-nixpkgs;
name = "nixos-config";
packages = builtins.attrValues {
inherit (pkgs) nixfmt-rfc-style git sops;
};
nixosSystem = unstable-system;
format = "vm";
pre-commit.hooks = {
actionlint.enable = true;
deadnix.enable = true;
flake-checker.enable = true;
lychee.enable = true;
markdownlint.enable = true;
nixfmt-rfc-style.enable = true;
ripsecrets.enable = true;
# statix.enable = true;
typos.enable = true;
yamlfmt.enable = true;
yamllint.enable = true;
};
# https://github.com/cachix/devenv/issues/528
containers = { };
};
};
deploy.nodes = withSystem "x86_64-linux" ({ ... }:
let
pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
deployPkgs = import inputs.nixpkgs {
system = "x86_64-linux";
overlays = [
inputs.deploy-rs.overlay
(self: super: { deploy-rs = { inherit (pkgs) deploy-rs; lib = super.deploy-rs.lib; }; })
];
};
mkDeploy = name: conf: {
profiles.system = {
sshUser = "deploy";
user = "root";
sudo = "doas -u";
fastConnection = true;
remoteBuild = false;
path = deployPkgs.deploy-rs.lib.activate.nixos self.nixosConfigurations.${name};
};
} // conf;
in builtins.mapAttrs mkDeploy {
Home-Hypervisor = { hostname = "10.10.10.10"; };
Dell-Laptop = { hostname = "10.10.10.101"; };
NixOS-VPS = { hostname = "45.135.180.193"; };
NixOS-RO-VPS = { hostname = "45.134.48.174"; };
NixOS-FI-VPS = { hostname = "104.164.54.197"; };
}
);
checks = builtins.mapAttrs (system: deployLib:
deployLib.deployChecks self.deploy
) inputs.deploy-rs.lib;
};
}
);
);
}

@ -1,28 +1,25 @@
{ modulesPath, self, inputs, config, pkgs, ... }: {
disabledModules = [ "${self}/modules/pass-store.nix" ];
{
modulesPath,
pkgs,
...
}:
{
imports = [
"${modulesPath}/profiles/qemu-guest.nix"
"${modulesPath}/virtualisation/qemu-vm.nix"
../AMD-Workstation/kernel
inputs.self.customModules.devices
inputs.self.customProfiles.ccache
inputs.self.customModules.users
inputs.nixos-cosmic.nixosModules.default
];
virtualisation.memorySize = 4096;
virtualisation.cores = 4;
virtualisation.resolution.x = 1920;
virtualisation.resolution.y = 1080;
virtualisation.qemu.options = ["-vga none" "-device virtio-vga-gl" "-display gtk,gl=on"];
services.desktopManager.cosmic.enable = true;
services.displayManager.cosmic-greeter.enable = true;
virtualisation.qemu.options = [
"-vga qxl"
"-display gtk"
];
users.mutableUsers = false;
users.users.${config.mainuser} = {
users.users.ataraxia = {
isNormalUser = true;
extraGroups = [ "wheel" ];
hashedPassword = "$y$j9T$ZC44T3XYOPapB26cyPsA4.$8wlYEbwXFszC9nrg0vafqBZFLMPabXdhnzlT3DhUit6";
@ -34,4 +31,4 @@
networking.hostId = "84977205";
system.stateVersion = "24.11";
}
}

@ -1,28 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEADmciW8EXCwOQtzDXZNgsaR1jLQshzVTfbYCuHBG9vQR+HwhJdr
K5+QRPcElq+LzK9aDjEnfWfGtaVIZbRS7Ixvl06H8q/rtK43pR/70f0ugKkc2WVy
3rx+bhKXUXoFwpIcMAX1q5drjj4OOaoXiVVKJEoPeFS+8fxYEm6QsLOL47vcXSHC
Qf8nK/6wdOLPV0GHCCi8qyYu3YL8vpGLyEImwjyFuxAzIkJL5m2h41qd10DkCt3f
mcOQolTeOdr5MRCsQGa7fWb3mmo+NU5YOCJgdearrJD4f5szEWOydcP2R+8z0h0w
UHGOAgsVbYgAtR/+X8c1B9jqRqVhjb9+kMQ/NtPuWMkhCBrsh/lg1Qot44xAWXwm
0+dI13qjBdsatl6dNYZrLLhWNHgxmgj9X1b0QINeHCR4FWB71yVOZQGoDSmI1DCo
rlcVx41zf+sDb/plnXeL0Mo0mD2VUjs9ji/YcqWJODxI5V/5ro+O3u4idn/0jc8b
cDOYL5Nd9hRAz13yNUCXElUE1qgf4jJia6FdAYiuEnaRObComFjuKe4Tzg4e9TVP
qPIPtwc9dKiDI1S4AiBDFNAC2Aqt84Iofc/+822usNJsv/F8c7TbLsENn1D42yR0
jlUrljuGs25fP8FpKgI23PKV7BoCQgrQATEHU8xgz9QAfeFcT09jJ0dDsQARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQg0iZKD7iKocCGw8CGQEAAOmcEADCGZj9da4rULBKH0tH57LE
miJUHnh5Ri1wFM4CJfwcKTEEd6pmY5b3iy8NN2Ci17AX2mHvVuuuU6NmUqVzHi9l
ccTStTbeTtEjwOIA8Ylh2Kl1Nmy2BQErwhVp+VXLXfbzjk0AyMt6wokFq4ZYlPr0
02m0MUZOi6+xooMtAEL5BBHSJDXbmiMHK5pusDu/xQz6oOQQgK8STVzWMSYCpL8k
iEKRqvqM2GkfwG4qqhQ9TKE5kenmmoQAAQVdAVpUGDV7zlJgpECCoKmVwnjHlsBS
zMocpV+c9DfSrC4l564vUvrMddkTxy9VN4oqF1NjM+uCQbo4V1k/MjNW8+VErgsc
l6GGUS/IoJ6W7d1PKmmmRppkdlYmo4vSIJ/8O+IFD+3Mv6amRhodRcvv/u5BRm+r
CECWzFfuE22E0rrR5Tl3YXOjrbMf6Rgtf924ZoTqexHy7wQmbj+mvTwdirMthntN
B4zs45mir8aS1TShlMLO58NUXVJUoP6EUuNuLYgr8t8hQYaqyD+yxUpy9AKqNe9E
n1FGv9040wwm9iZoXlH0L/kyIV6H7jjcyMxAI0510+ocKYFO4NAcSIIBg1rzAS1d
N62BvqhnGkQlqm8eK6HbpY3V6IqNdHtOJ9anorIT2HOeYdr5EJRKEm03rPc8Bot/
9I6UjUrOFOOFXK/AxTZ2/w==
=QWBM
-----END PGP PUBLIC KEY BLOCK-----

@ -1,28 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEACR9jZokEbSZ1uQ44Ov3oqvYUcPOsGWmBEzaZo6cG+s+04mr2+m
MtUoNOIiqtYA9nd5c0GId7Hew9mCO9bzEUuRfxWlP6eztRETZQNqFFHz15bkMfGt
EwZcMwT1UGkZieIrh1HCSVcEyLIkF+9XvgUeEmJb72doGr0RMo+k/tizc+ByvUse
gFFuf/jPC1DKlcVQHzduMMghzrqKv9om2IIPh8E3j32WumbS5XW/MnXGFLBW1d0f
Lsm6imiHsyvSJtCHDxKwP9ODVgOZNaUDI1HfMFI/SrKlce3Cku3sCoe47RXQ21c/
e0CGuEurkmOrhaksk/RxxOb4gBuyWLe/GckWbeoAzxgBB1kKYjRVBEM0rjQStdjB
ZCfR15WmbXtQsmeLqLhNGkUmCd0Yr0HMPgb5u6GkfVvhL+au3BrKeePD7nlcQ/Nd
BLqPKMk98zuHIULzGreYSGEbD3KzuF4NKUK0jLQBfrQzjh/0pzMz4R/E39QuSAUc
d2PaGcppJ1oN/pD39TR0P9JcJwa1D2aj3F78kkPWBMzAvEJ0QB9YaDp0y3oDYtWk
TKTarMZLiVrnXMhDphNTiMIdd2i7FKTYV7ES47F+cHC3vhhZwed0Wwc9Als+w5wa
hk8xv+IlWqP1yWnrgNthH1JhklVaxY+W1POk3Lvz38rhFwCwzpDD3GmAMwARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQ1P4o2SFLaFoCGw8CGQEAAJQGEACDg+Dz8qUeyG/T7PwIkvBH
vgAMSobQKTsDKNVIIKZt8ojfyLl5IN1Z4kqtIgq/uP4vLtKBrpzaEnpCP8lLbJ5I
C1jhPF8xmsQVMOJZ89DwaSr4YRm5Fybw3IVSdAjnWyfb1Bk9mgR5wnbZg9GGq3yO
28YVoKkSh14JXVJhcT+t5hagePz52zW91jo7lpJmrSQClWTjpXGthXO6BBc+PCEk
RjJNHrwi5VXRBVWLe5zdX2boqYTc5HHZ39iahTS7ZtKsXmEfU/XP4jzMrPZQIrX3
7eQJ+RcBhiSHSnSDMZIsRAWpcT3s5dzpCEICQ4ZkVCqnlGckd4vYHjk1IkNnCFRJ
9YsEYFNzvzpwLTb0LcvRnxk21gIA5cO5UN7ifS7C/cTYhoLKkuMysnaXOFOLf1Jw
rlOrgpiSwPnsD+4eBP01JastLvTqzSJm5AC/ZMaGAJ/PPg3tt1sqK5kx6/ZcEMZh
wZ6ghLdmVHvJ+WtKGVaj+DBYy/PG87ybh9XdISwgG8QFPeIQi0GEbXSsbDVom4LZ
xyERVySCEMmyRlb1jI6nbk7ePFpVEhvHgcNhoI55eaPnhUzOoVWWDnONu/dWKpz8
v2qjKUKds7BKMtL7K1ejyrNOAl+4bbK4XsUtiahaugw5nVK+BjCFAQTa6bOPNmVS
NjuFrogiksuuzLS1qQa4lg==
=MQ+a
-----END PGP PUBLIC KEY BLOCK-----

@ -1,28 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEADIckpTgLln/NwJ4wqu4yVZMGkwEUC9ut6wdf4DPY/NJKQ95hYW
R7TGRS9hccsmrp/129V2ex29McXMDxTCIJfLx5F+OyAzqYkkXFeBhCQNBfb6Q9F+
gb9YjndO8gkFsq6x+AYRwO9TOZJ2aVHNBSOq/59eaocZirfHsA9oTxRZOZR3kUz8
2Zj/4BTuYW2bBrdsvoiqHvof/E2fwFLVETISAKe0y8hIFI8Eq31NVV28uC+Zfy5d
lUTKCTLBU1Esn9vlVQ9BATlDGIl4lcOfWDhxZD3EtmHBTCIVv5LieYbj229p4gq2
ooUDqyoLScPUiNCEz8sSqwKt50SNGeABFxR+2xoYmZ1WWpcYOBlTZmj8cDMaZyXQ
s3l4Eo3LK1F97ow9wRpwEdJRvA0/tyGspCTuPeHbrKnsDqDbk282XrLJJ9jQNmH2
PFahmUYYVmETHnxBZ5qQw6ni5sh6l1RcwQ5PDcD5O9DhJCzAU9oP7Xug4YLIsTCM
+WSWkUWupoQq0I+78REv74+4/P4pCeParO9Qtl0WmHeABY4fGsnahyo7lNYaLqxB
0ymYxRmOUp/+eHU3G30wb+QU9upZBsE96xWjfZoci7J3TT23yr0g/z1rNiUqlaAW
X/PtYtAkIc3FoNhTM+4FQj5T+RgJEXrXTdzA74V0VPvIsj+RK0uPxFeu4wARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQXzuJrzaVIMYCGw8CGQEAAFx1EAAJVCv0ueK5iANOy+vrswHO
23fh+Ta6mNoqhEwQUv/ReMnx9LPPbYwxChPzwR+yFGe/133eG6R5F73KykhJE4Yv
qOysTEbEUbTYs02X2c/9/mCcTXN2V2XXRYryIfejf5jZTICUU5FH/juvXiZhU9/x
7+qIRhM3iXnwK+Q17LUwlxM370gs0ZrYMEoANADWY5ZmguYhQ9VVJ7qhFdXzO4ll
STFGO6XCyAD9FFCzK0IyAPfbb4oob1v7DBI0JxXbElPMeoDzgZL+iaptiTt05HJX
L4G4uqs9hq40QgnLY6N9wIUoTM+/6BbXpuz2vsPRYtS3yeZAYr5/4eVGV5BXssNt
BEmpCfBMlSHZAnCLHish98l4k/QVS13TIF9nXznqr3bePYz/02Y/u5JJdk5vBtkW
80Q4AeHOfeWhTSIMcYwnMfSFr8jXkB7UrXU4wqmnLDRJ8W6Tu8wOEKEi65pDpU3l
MSrtDcpQ1US43D3Pk2CmjYIupzVoTQXqpll6HcnzxXAR4V4NS6PJUOP/EuijFbWt
co59yDurWeG14JLdeO/Yqb6YmhNUTOpLQjIDhDDMeHNlmoph9Jsh0ngY+JwPnxBl
FZuN73gQfJSq7UD4IoWV/+zw7HFAE1hcZ3+4DXJEd2lWf5YdVQCU0p+PabnKFJdD
9apG7j0wFgNmGgdm41XP/A==
=RHFO
-----END PGP PUBLIC KEY BLOCK-----

@ -1,28 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEAC+hXc/r/l98Az2kBLE8hyf1JkdKPdUImlzLyB8DYbYcdhLJ/Fa
MatqYqiz1nSwJgmVVSP6FpExQcqhuqS24RsxAIRlcaf3qooOwSGOdbUk/lEEmKo4
7c1oy/EzS3bIMzcS5qEelQGVpP6BPx8fYPH8R8/jo1OKsgO/vDzmaOR8/dhXvfXS
WmRC0P7kyP4GwTWUIkQ447Plyj0q1dynixAx4z+zbH4k6h13ySD+MO7R1FPB+7Bu
fiQQ+EOM7UsP/gFSrFG+VYaxAHtBPM9m9xEIs/J2MpBhb6O6lFIQdyhlErHVm6R4
w7lIOiG/BVZJ0gG37r9GXdpHg1ZvhpWFBLDkBQPSa78F+m3aKWIuQs6wt25Ok9Sx
952x8FYz8nbNN43KiLG2fVorwDB3vYaie/vWVnb/KqnrvaARbLHdtObS51SPKcqe
G780MT9kSZ8CjZGkIiEGR6FlcXrSxtJqqLhStvmxsrs+2p+ryS0/PV1ueAJRYZtp
Zrqywr8soawS4DtV/Q6qRXT04COOpHsQdMnEGVe0zdmZpQa3lt69QdFm+uC2CB/A
WFbyKnxDijpgnGx8MhYQbEooyWPpZXIU3cqj69jELK8h8LC/Xc6cK28eSNswFWH6
p0KLaJjVnfR3IRsULmOUxdmEHArJRLKe3E6hyoPU5XL/DL9dr0FoGSpZCQARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQsMSq7/TgWqYCGw8CGQEAAJznEACwiFUMfos/ZH+ck3Y2J8z8
vk/256oUs+eiKQgApdj8Ve3VfP7csxTnvCgYzYLH/M7iLMbCSCmTRbeZhgULJTYw
oOwJbcbCs4JsX8WLJuFzh4FMBpUfNnoEddHRk+5eUlM2W940DoMqsKBCQvAbTFYM
UeCzFdoZxUAZfv0WJu/CzVjaQMNXeGEcWVpyw0W5MwUByZuYhuZxIX1/9xi2Bkkm
EnrPpmbl39b46MPUCO/cVXimrEixWttZqD016DsgVfRttdUvnoy+nJrYUm1hHYhZ
UOx/ap7zsWBUqG0LNGANzvclJybJ8wb5uVCto7OcbNU+quYuJ3V55Aqw/4/CEDD+
nhZsvQRYPPtSFsI8ThdfOQ34l0R3KXfA22Eot5E2wW0MIPKxga3J91106vYFIJPx
Rbp47BNvDFWRwfZfAq/BcQqPY+Z03x4Wi6yRW8XehuD92tsNE5Mo/sLLNObYQatm
iDXsgQ7By9USprv57TlzE9sRbiYVzxtEPlACE5SFyExtMrkKht3istsRGTJjqq5A
6sNELjs+AY06LKiBMS0MrTI1fgTa4QPQcJGl0NjZAFtDlKG72N/RWpd+1wLXPx5/
2XR65Y5ONGGjQlX1ek7cXj758Hx/nSZVya45xuNXq3xI2mLJx7tV/oMeFRIAxEo1
iWh/pz+cRoPKmR984pcAEw==
=uipR
-----END PGP PUBLIC KEY BLOCK-----

@ -1,28 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEAC1ZvLuhlCgsJpHCdaz5oUf5mhFQ88y9nh5sEcL35cEi7b9lR28
oijbMoIppB/q5v3Lf9MChCcKkyXMPvTQIi9uEPXUGDJBu0Layl6nPgwMqf0vZ728
h+0nUNe0qCrT6tFRH9Z3EnXS9370V7KZCbqaynVag5aaeB8wmALTNsRVWEfVYKyh
kliKcahMfh1kl9PGZG4p4IFuYtUcA9yY8xgKzvfvRiAauzRFh5RqYpaSiJIYqMdr
CTuiQqU0LoEM1It2X+NfVLNoU+oNMS0QeS55malqXEILlQKlvziYc1IWhMjqlBlm
/e4yw1by87zBiHLIt4ALBfkbFscSXN83GwKT/cCJwrP4G+IeJp9tm8/bSaEuuBrm
zPxEWcmdMq/qDh67YcdVybn6glPmY2pI0sNKdzsLbkNLoFFjD94wPHok43722NJ2
BtbPWiWrLrda4miknFfFvLvY0hZRDLwfuNVRC5+HYwvwlG4C85fWfueCsmqOHJAN
x+xV51hbDYoDoIyXvaL9K/xTontYDGR4oNUpaO+EI3l6npv81ChSqXkMxiuUtR1A
0ktWUIzpQRV4dZzxY3Q9sC7djCP1xjUDHlSjmWFxi++WMt8bTFLOHNd3y2uWJQVF
imTWysYyZ3gqs+GQ6VUzLKkYRnbVqtdKKrnvDa/pIzlVvJtpn/CZUz15swARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQI17HvHVwAsoCGw8CGQEAADCtEACX/NfWWjIJjPi1LFPEYQHb
BHeOj6BDhQ7bPVs0IR9twNMq3lj3CyWPZ5tIKesQ7ec8fTngdVRF5Jjkb1UgENhn
dVGWHtIVVRpvIdup6s8NRx3PRsHUp98Ly3+P+RkwoT+3ZY45xleZeCEgFU852Lfp
LViaj0xT2wtiNMGTdAVSkjt0+ZuB89y+91YLFLQvtASPCqg5Myc4184PEdUbfGh1
4kZJK/lFIQvXEKpreYCp6/mGj9arEuRno/KRG0pW5HS1fuGNYkKT96WSDE51Ofzb
1ihFcuEx7upJbCeUNnLvt1GaWez3hudCruwS8Cdnn6IafHIUBys0EnOXV99SFGQX
akvB22gWAAWcBdDlNyTzxPRaQEjgB9OxM9NIgSRLIUDPbdBlSAXFey5Nt/hL0bQE
J448uRgCwMmEXBc5butZ26bXKCbfJ4ZyTUPV6hRb0uiKFR1IecxhLVxn715pYrWm
MfiKrj3G+rDFKmCBXhqlEFC0TQdZoue+AxxBAzB9MTqRO2GhC35t1Tg1crwKflLd
rEBx2bYa1OOMIPfZePAA96X+LaXhkJYlhaPCP4R9oxErrPLBO3Ki7NPpJG0c+272
+xnjaBfd1fapmVLYdSQNhT4QfOPm1YDLyHQCJi3oK+7eRX6rLMiLtQbwhWoJ9c3N
JrpEiuMuhfru+fFCIiyoQw==
=/C2a
-----END PGP PUBLIC KEY BLOCK-----

@ -1,17 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsBNBAAAAAABCACYSL78uXx0m7SSLSfc5Dz27nDT+0uU/wjkTICrF0jqkcKVRoYw
ExteYzjINj8FqcxYGA5BHz72uUM653xCeVua31cU0WnjD+zUNfSaulQRROJMDeiR
Lf5LpTnuAhYA5O9TAL47l/2j2CKnWh6jE8qn5Lt6RCXDbv2rGHnm5+6uJYvTMohq
XbtfLbBGbBrczPL9WFda2aiv5B6AVSVA1YoPFpRX2gJqJKVgLpHjMTit/Lr3cvom
sEC8bFCAVomAjAotym05OVl6kIex4jwoSv2Yxhizhu7TO9NxeunNduI7xD3oCc2X
XUQoz6ASY5PFpbq7FkIQz2OLm41inxZlbv0lABEBAAHNKXJvb3QgKEltcG9ydGVk
IGZyb20gU1NIKSA8cm9vdEBsb2NhbGhvc3Q+wsBiBBMBCAAWBQIAAAAACRAHGoEx
vxZugAIbDwIZAQAAWJ8IADm/PZre00BcoVU2dQZy/H1SMrUVBZdYoBsYBRCm6Fh4
s8Wi+bvpI/4BN7FUAsu8WwY32XnNrVvJLBeKZYPTJlHcQyDY18eeOgUX2bsrT6vx
0QqDM4XauELtzxixCUADsvHM0EX1TrmA55f9AvCWASFuPARbKLWYtEx1O39DMi26
N8eaePKvRHnpNzAYIeVlXP25ZoYRtVffDdFJgWYiiLgHsn9NSBRmon2wZuZG/mdh
f1YzYibIFPAm8RVJhDjbsZMiWSFx+86jZEcG1DjJZQ4dJwfUsx4Q9cKHlX16ikPn
nlO4mnO8z1TPCczm8W4/lIjBsM/fLRK/er6uruOThkw=
=j5e1
-----END PGP PUBLIC KEY BLOCK-----

@ -1,23 +0,0 @@
{ ... }: {
autoinstall.AMD-Workstation = {
# debug = true;
mainuser = "ataraxia";
flakesPath = "/home/nixos/nixos-config";
encryption.encryptBoot = false;
encryption.encryptRoot = true;
encryption.passwordFile = "/home/nixos/pass";
encryption.argonIterTime = "4000";
partitioning.useEntireDisk = true;
partitioning.disk = "/dev/disk/by-id/nvme-XPG_GAMMIX_S11_Pro_2K342L2BBNUY";
partitioning.nullifyDisk = false;
partitioning.emptySpace = "100GiB";
partitioning.createBootPool = true;
swapPartition.enable = true;
swapPartition.size = "16GiB";
efiMountPoint = "/efi";
zfsOpts.ashift = 13;
zfsOpts.bootPoolReservation = "256M";
zfsOpts.rootPoolReservation = "45G";
persist.enable = true;
};
}

@ -1,86 +0,0 @@
{ config, pkgs, lib, ... }:
let
zfs_arc_max = toString (6 * 1024 * 1024 * 1024);
in {
boot = {
zfs.package = pkgs.zfs_unstable;
kernelPackages = pkgs.linuxPackages_xanmod_latest;
initrd = {
supportedFilesystems = [ "zfs" ];
luks.devices = {
"cryptroot" = {
keyFile = "/keyfile0.bin";
allowDiscards = true;
bypassWorkqueues = true;
};
};
secrets = {
"keyfile0.bin" = "/etc/secrets/keyfile0.bin";
};
};
loader = {
grub = {
enable = true;
device = "nodev";
copyKernels = true;
efiSupport = true;
enableCryptodisk = true;
useOSProber = false;
zfsSupport = true;
gfxmodeEfi = "2560x1440";
# efiInstallAsRemovable = true;
};
systemd-boot.enable = lib.mkForce false;
efi.canTouchEfiVariables = true;
efi.efiSysMountPoint = "/efi";
generationsDir.copyKernels = true;
};
binfmt.emulatedSystems = [ "aarch64-linux" ];
kernelParams = [
"zfs.metaslab_lba_weighting_enabled=0"
"zfs.zfs_arc_max=${zfs_arc_max}"
"amd_pstate=active"
"retbleed=off" # big performance impact
"amdgpu.ignore_min_pcap=1"
];
kernel.sysctl = {
"kernel.split_lock_mitigate" = 0;
};
tmp.useTmpfs = true;
tmp.tmpfsSize = "32G";
supportedFilesystems = [ "ntfs" ];
};
persist = {
enable = true;
cache.clean.enable = true;
};
fileSystems."/" = lib.mkForce {
device = "none";
options = [ "defaults" "size=4G" "mode=755" ];
fsType = "tmpfs";
};
fileSystems."/home".neededForBoot = true;
fileSystems."/persist".neededForBoot = true;
boot.initrd.systemd.enable = true;
boot.initrd.systemd.services.rollback = {
description = "Rollback zfs to a pristine state on boot";
wantedBy = [ "initrd.target" ];
after = [ "zfs-import-rpool.service" ];
before = [ "sysroot.mount" ];
path = [ config.boot.zfs.package ];
unitConfig.DefaultDependencies = "no";
serviceConfig.Type = "oneshot";
script = ''
zfs rollback -r rpool/nixos/root@empty && echo " >>> rollback root <<<"
zfs rollback -r rpool/user/home@empty && echo " >>> rollback home <<<"
'';
};
}

@ -1,199 +0,0 @@
{ inputs, config, lib, pkgs, secretsDir, ... }: {
imports = with inputs.self; [
./boot.nix
./hardware-configuration.nix
# ./kernel
customRoles.workstation
customProfiles.a2ln-server
customProfiles.act
customProfiles.aria2
# customProfiles.attic
customProfiles.bluetooth
customProfiles.cassowary
customProfiles.emulators
customProfiles.flatpak
customProfiles.hoyo
customProfiles.minecraft
customProfiles.nicotine
customProfiles.sunshine
customProfiles.wine-games
customProfiles.ollama
customProfiles.ccache
inputs.chaotic.nixosModules.default
];
# chaotic.nyx.overlay.enable = true;
startupApplications = [ "com.valvesoftware.Steam" ];
# nixpkgs.config.rocmSupport = true;
security.pki.certificateFiles = [ ../../misc/mitmproxy-ca-cert.pem ];
virtualisation.libvirt.guests = {
win10code = {
autoStart = false;
user = config.mainuser;
group = "libvirtd";
xmlFile = ./vm/win10code.xml;
};
win10ed = {
autoStart = false;
user = config.mainuser;
group = "libvirtd";
xmlFile = ./vm/win10ed.xml;
};
};
deviceSpecific.devInfo = {
cpu.vendor = "amd";
drive.type = "ssd";
gpu.vendor = "amd";
ram = 48;
fileSystem = "zfs";
};
deviceSpecific.isGaming = true;
deviceSpecific.enableVirtualisation = true;
# VPN
deviceSpecific.vpn.tailscale.enable = true;
deviceSpecific.vpn.sing-box.enable = true;
deviceSpecific.vpn.sing-box.config = "ataraxia-singbox";
# Mount
fileSystems = {
"/media/files" = {
fsType = "ntfs";
device = "/dev/disk/by-partuuid/15fa11a1-a6d8-4962-9c03-74b209d7c46a";
options = [
"nofail"
"uid=${toString config.users.users.${config.mainuser}.uid}"
"gid=${toString config.users.groups.users.gid}"
];
};
"/media/win-sys" = {
fsType = "ntfs";
device = "/dev/disk/by-partuuid/4fba33e7-6b47-4e3b-b18b-882a58032673";
options = [
"nofail"
"uid=${toString config.users.users.${config.mainuser}.uid}"
"gid=${toString config.users.groups.users.gid}"
];
};
"/media/local-nfs" = {
device = "10.10.10.11:/";
fsType = "nfs4";
options = [ "nfsvers=4.2" "x-systemd.automount" "noauto" ];
};
};
powerManagement.cpuFreqGovernor = "schedutil";
hardware.firmware = [ pkgs.rtl8761b-firmware ];
services.openssh.settings.PermitRootLogin = lib.mkForce "without-password";
services.ratbagd.enable = true;
# Networking
networking.firewall.allowedTCPPorts = [ 8000 5900 52736 3456 1080 ];
networking.nameservers = [ "10.10.10.1" ];
networking.defaultGateway = "10.10.10.1";
networking.bridges.br0.interfaces = [ "enp8s0" ];
networking.interfaces.br0 = {
useDHCP = false;
ipv4.addresses = [{
address = "10.10.10.100";
prefixLength = 24;
}];
};
services.postgresql.settings = {
full_page_writes = "off";
wal_init_zero = "off";
wal_recycle = "off";
};
services.modprobed-db.enable = true;
programs.nix-ld.enable = true;
environment.systemPackages = [
pkgs.kdiskmark
];
home-manager.users.${config.mainuser} = {
home.packages = [
inputs.nixos-generators.packages.${pkgs.hostPlatform.system}.nixos-generate
pkgs.devenv
pkgs.nh
pkgs.nix-alien
pkgs.nix-diff
pkgs.nix-eval-jobs
pkgs.nix-fast-build
# pkgs.nix-init
pkgs.nix-update
pkgs.nixfmt-rfc-style
pkgs.nixos-anywhere
pkgs.nixpkgs-review
pkgs.anydesk
pkgs.arduino-ide
pkgs.dbeaver-bin
pkgs.dig.dnsutils
pkgs.distrobox
pkgs.exercism
pkgs.freerdp
pkgs.kdePackages.merkuro
pkgs.libsForQt5.ark
pkgs.libsForQt5.dolphin
pkgs.maa-cli
pkgs.mitmproxy
pkgs.mkvtoolnix
pkgs.modprobed-db
pkgs.packwiz
pkgs.piper
pkgs.prismlauncher
pkgs.radeontop
pkgs.streamrip
pkgs.wayvnc
pkgs.winbox
pkgs.yt-archivist
];
xdg.configFile."distrobox/distrobox.conf".text = ''
container_always_pull="1"
container_manager="podman"
'';
home.stateVersion = "24.05";
};
# services.netbird.clients.priv = {
# interface = "wt0";
# port = 58467;
# hardened = false;
# ui.enable = true;
# autoStart = false;
# config = {
# AdminURL.Host = "net.ataraxiadev.com:443";
# AdminURL.Scheme = "https";
# ManagementURL.Host = "net.ataraxiadev.com:443";
# ManagementURL.Scheme = "https";
# RosenpassEnabled = true;
# RosenpassPermissive = true;
# };
# };
persist.state = {
directories = [ "/var/lib/netbird-priv" ];
homeDirectories = [
".arduino15"
".arduinoIDE"
".config/exercism"
".config/maa"
".config/modprobed-db"
".config/sops/age"
".config/streamrip"
".local/share/DBeaverData"
".local/share/distrobox"
".local/share/maa"
".local/share/PrismLauncher"
".local/share/winbox"
".mitmproxy"
];
};
system.stateVersion = "23.05";
}

@ -1,108 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# fileSystems."/" =
# { device = "rpool/nixos/root";
# fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
# };
fileSystems."/home" =
{ device = "rpool/user/home";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/persist" =
{ device = "rpool/persistent/impermanence";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/srv" =
{ device = "rpool/persistent/servers";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/etc/secrets" =
{ device = "rpool/persistent/secrets";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/nix" =
{ device = "rpool/persistent/nix";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/log" =
{ device = "rpool/persistent/log";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/lib/docker" =
{ device = "rpool/persistent/docker";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/lib/containers" =
{ device = "rpool/persistent/containers";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/lib/nixos-containers" =
{ device = "rpool/persistent/nixos-containers";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/media/bittorrent" =
{ device = "rpool/persistent/bittorrent";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/media/libvirt" =
{ device = "rpool/persistent/libvirt";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/boot" =
{ device = "bpool/nixos/boot";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/efi" =
{ device = "/dev/disk/by-uuid/A556-CD19";
fsType = "vfat";
};
swapDevices = [
{
device = "/dev/disk/by-partuuid/5305d817-d4ef-41a7-a51b-dc1fb8638227";
randomEncryption.enable = true;
randomEncryption.allowDiscards = true;
}
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp8s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# high-resolution display
networking.hostId = "0c00ab80";
boot.zfs.devNodes = "/dev/disk/by-id";
boot.supportedFilesystems = [ "zfs" ];
boot.initrd.luks.devices."cryptroot".device = "/dev/disk/by-partuuid/67e044d7-1a06-4a59-826a-bf24994934a7";
}

@ -1,93 +0,0 @@
{ config, pkgs, lib, ... }: {
# boot.kernelPackages = lib.mkForce (pkgs.linuxPackagesFor pkgs.linuxLqxZfs);
boot.kernelPackages = lib.mkForce pkgs.linuxPackages_lqx_clang;
nixpkgs.overlays = let
inherit (pkgs) overrideCC ccacheWrapper addAttrsToDerivation pkgsBuildHost pkgsBuildBuild;
llvmPackages = "llvmPackages_18";
noBintools = { bootBintools = null; bootBintoolsNoLibc = null; };
mkLLVMPlatform = platform: platform // { useLLVM = true; };
# Get llvmPackages for host and build platforms, disabling bootBintools
hostLLVM = pkgsBuildHost.${llvmPackages}.override noBintools;
# buildLLVM = pkgsBuildBuild.${llvmPackages}.override noBintools; # unused
# Get LLVM stdenv with clang
stdenvClangUseLLVM = overrideCC hostLLVM.stdenv hostLLVM.clangUseLLVM;
# set useLLVM to true for host and build platforms
stdenvPlatformLLVM = stdenvClangUseLLVM.override (old: {
hostPlatform = mkLLVMPlatform old.hostPlatform;
buildPlatform = mkLLVMPlatform old.buildPlatform;
});
# Wrap clang with ccache
stdenvCcacheLLVM = overrideCC stdenvPlatformLLVM (
ccacheWrapper.override { cc = stdenvPlatformLLVM.cc; }
);
# Disable fortify hardening as LLVM does not support it, and disable response file
stdenvLLVM = addAttrsToDerivation {
env.NIX_CC_USE_RESPONSE_FILE = "0";
hardeningDisable = [ "fortify" ];
} stdenvCcacheLLVM;
in [
(final: prev: {
# debug
inherit stdenvLLVM stdenvCcacheLLVM stdenvPlatformLLVM;
linuxPackages_lqx_clang = prev.linuxPackages_lqx.extend (lpfinal: lpprev: {
kernel = (lpprev.kernel.override {
buildPackages = final.buildPackages // { stdenv = stdenvLLVM; };
stdenv = stdenvLLVM;
argsOverride = let
version = "6.10.3";
suffix = "lqx1";
hash = "sha256-495xe6wZOMwy/N9yqwlGLTcAWuubUzmfoGOV7J1RWGk=";
no-dynamic-linker-patch = {
name = "no-dynamic-linker";
patch = ./no-dynamic-linker.patch;
};
fix-znver-clang18 = {
name = "fix-znver-clang18";
patch = ./fix-znver-clang18.patch;
};
in {
inherit version;
modDirVersion = lib.versions.pad 3 "${version}-${suffix}";
src = prev.fetchFromGitHub {
owner = "zen-kernel";
repo = "zen-kernel";
rev = "v${version}-${suffix}";
inherit hash;
};
extraMakeFlags = [ "LLVM=1" "LLVM_IAS=1" ];
kernelPatches = [ no-dynamic-linker-patch fix-znver-clang18 ] ++ lpprev.kernel.kernelPatches;
structuredExtraConfig = with lib.kernel;
lpprev.kernel.structuredExtraConfig //
builtins.mapAttrs (_: v: lib.mkForce v) {
CC_OPTIMIZE_FOR_PERFORMANCE_O3 = yes;
# GENERIC_CPU3 = yes;
MZEN = yes;
INIT_ON_ALLOC_DEFAULT_ON = yes;
INIT_STACK_ALL_ZERO = yes;
LTO_CLANG_FULL = yes;
MODULE_COMPRESS_XZ = no;
MODULE_COMPRESS_ZSTD = yes;
RCU_BOOST = no;
RCU_BOOST_DELAY = option (freeform "500");
RCU_LAZY = no;
};
};
});
});
})
];
assertions = [{
assertion = config.programs.ccache.enable;
message = "To compile custom kernel you must enable and setup ccache";
}];
}

@ -1,17 +0,0 @@
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index d283c59df4c1..3840ded8c34a 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -3,6 +3,14 @@
# Makefile for the Linux TCP/IP (INET6) layer.
#
+# temporary workaround for clang/lld-18 with -march/-mtune=znver*
+# clangbuiltlinux issue 1987
+ifeq ($(call test-ge, $(CONFIG_CLANG_VERSION), 180000),y)
+badparms = -march=znver1 -mtune=znver1
+KBUILD_CFLAGS := $(filter-out $(badparams), $(KBUILD_CFLAGS))
+KBUILD_CFLAGS += -march=x86-64-v3
+endif
+
obj-$(CONFIG_IPV6) += ipv6.o

@ -1,40 +0,0 @@
diff --git a/Makefile b/Makefile
index a171eafce2a3b..10ed19caecb1b 100644
--- a/Makefile
+++ b/Makefile
@@ -531,6 +531,9 @@ RUSTFLAGS_KERNEL =
AFLAGS_KERNEL =
LDFLAGS_vmlinux =
+LDFLAGS_MODULE += --no-dynamic-linker
+LDFLAGS_vmlinux += --no-dynamic-linker
+
# Use USERINCLUDE when you must reference the UAPI directories only.
USERINCLUDE := \
-I$(srctree)/arch/$(SRCARCH)/include/uapi \
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 3cece19b74732..390a4604166eb 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -102,7 +102,7 @@ $(obj)/zoffset.h: $(obj)/compressed/vmlinux FORCE
AFLAGS_header.o += -I$(objtree)/$(obj)
$(obj)/header.o: $(obj)/zoffset.h
-LDFLAGS_setup.elf := -m elf_i386 -z noexecstack -T
+LDFLAGS_setup.elf := --no-dynamic-linker -m elf_i386 -z noexecstack -T
$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
$(call if_changed,ld)
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile
index f614009d3e4e2..4b42006d9ce02 100644
--- a/arch/x86/realmode/rm/Makefile
+++ b/arch/x86/realmode/rm/Makefile
@@ -50,7 +50,7 @@ $(obj)/pasyms.h: $(REALMODE_OBJS) FORCE
targets += realmode.lds
$(obj)/realmode.lds: $(obj)/pasyms.h
-LDFLAGS_realmode.elf := -m elf_i386 --emit-relocs -T
+LDFLAGS_realmode.elf := --no-dynamic-linker -m elf_i386 --emit-relocs -T
CPPFLAGS_realmode.lds += -P -C -I$(objtree)/$(obj)
targets += realmode.elf

@ -1 +0,0 @@
x86_64-linux

@ -1,188 +0,0 @@
<domain type="kvm">
<name>nixos-unstable</name>
<uuid>8609e821-5ba2-47b4-997d-84ad84b45b53</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://nixos.org/nixos/unstable"/>
</libosinfo:libosinfo>
</metadata>
<memory unit="KiB">4194304</memory>
<currentMemory unit="KiB">4194304</currentMemory>
<vcpu placement="static">4</vcpu>
<os>
<type arch="x86_64" machine="pc-q35-8.0">hvm</type>
<loader readonly="yes" type="pflash">/run/libvirt/nix-ovmf/OVMF_CODE.fd</loader>
<nvram template="/run/libvirt/nix-ovmf/OVMF_VARS.fd">/var/lib/libvirt/qemu/nvram/nixos-unstable_VARS.fd</nvram>
</os>
<features>
<acpi/>
<apic/>
<vmport state="off"/>
</features>
<cpu mode="host-passthrough" check="none" migratable="on">
<topology sockets="1" dies="1" cores="2" threads="2"/>
</cpu>
<clock offset="utc">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
<timer name="hpet" present="no"/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/run/libvirt/nix-emulators/qemu-system-x86_64</emulator>
<disk type="file" device="cdrom">
<driver name="qemu" type="raw"/>
<source file="/media/libvirt/iso/nixos-minimal-23.05.1194.b6c73c5fe53-x86_64-linux.iso"/>
<target dev="sda" bus="sata"/>
<readonly/>
<boot order="2"/>
<address type="drive" controller="0" bus="0" target="0" unit="0"/>
</disk>
<disk type="file" device="disk">
<driver name="qemu" type="qcow2" discard="unmap"/>
<source file="/media/libvirt/images/nixos-unstable.qcow2"/>
<target dev="sdb" bus="sata"/>
<boot order="1"/>
<address type="drive" controller="0" bus="0" target="0" unit="1"/>
</disk>
<controller type="usb" index="0" model="qemu-xhci" ports="15">
<address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
</controller>
<controller type="pci" index="0" model="pcie-root"/>
<controller type="pci" index="1" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="1" port="0x10"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="2" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="2" port="0x11"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x1"/>
</controller>
<controller type="pci" index="3" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="3" port="0x12"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x2"/>
</controller>
<controller type="pci" index="4" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="4" port="0x13"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x3"/>
</controller>
<controller type="pci" index="5" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="5" port="0x14"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x4"/>
</controller>
<controller type="pci" index="6" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="6" port="0x15"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x5"/>
</controller>
<controller type="pci" index="7" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="7" port="0x16"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x6"/>
</controller>
<controller type="pci" index="8" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="8" port="0x17"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x7"/>
</controller>
<controller type="pci" index="9" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="9" port="0x18"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="10" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="10" port="0x19"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x1"/>
</controller>
<controller type="pci" index="11" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="11" port="0x1a"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x2"/>
</controller>
<controller type="pci" index="12" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="12" port="0x1b"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x3"/>
</controller>
<controller type="pci" index="13" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="13" port="0x1c"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x4"/>
</controller>
<controller type="pci" index="14" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="14" port="0x1d"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x5"/>
</controller>
<controller type="sata" index="0">
<address type="pci" domain="0x0000" bus="0x00" slot="0x1f" function="0x2"/>
</controller>
<controller type="virtio-serial" index="0">
<address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
</controller>
<interface type="network">
<mac address="52:54:00:75:4f:c7"/>
<source network="default"/>
<model type="virtio"/>
<address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</interface>
<serial type="pty">
<target type="isa-serial" port="0">
<model name="isa-serial"/>
</target>
</serial>
<console type="pty">
<target type="serial" port="0"/>
</console>
<channel type="unix">
<target type="virtio" name="org.qemu.guest_agent.0"/>
<address type="virtio-serial" controller="0" bus="0" port="1"/>
</channel>
<channel type="spicevmc">
<target type="virtio" name="com.redhat.spice.0"/>
<address type="virtio-serial" controller="0" bus="0" port="2"/>
</channel>
<input type="tablet" bus="usb">
<address type="usb" bus="0" port="1"/>
</input>
<input type="mouse" bus="ps2"/>
<input type="keyboard" bus="ps2"/>
<graphics type="spice" autoport="yes">
<listen type="address"/>
<image compression="off"/>
</graphics>
<sound model="ich9">
<address type="pci" domain="0x0000" bus="0x00" slot="0x1b" function="0x0"/>
</sound>
<audio id="1" type="spice"/>
<video>
<model type="qxl" ram="65536" vram="65536" vgamem="16384" heads="1" primary="yes"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0"/>
</video>
<redirdev bus="usb" type="spicevmc">
<address type="usb" bus="0" port="2"/>
</redirdev>
<redirdev bus="usb" type="spicevmc">
<address type="usb" bus="0" port="3"/>
</redirdev>
<watchdog model="itco" action="reset"/>
<memballoon model="virtio">
<address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
</memballoon>
<rng model="virtio">
<backend model="random">/dev/urandom</backend>
<address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
</rng>
</devices>
</domain>

@ -1,221 +0,0 @@
<domain type='kvm'>
<name>win10code</name>
<uuid>709a31f9-b654-4a64-947d-26b84dbebf33</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://microsoft.com/win/10"/>
</libosinfo:libosinfo>
</metadata>
<memory unit='KiB'>8388608</memory>
<currentMemory unit='KiB'>8388608</currentMemory>
<memoryBacking>
<source type='memfd'/>
<access mode='shared'/>
</memoryBacking>
<vcpu placement='static'>4</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-q35-9.2'>hvm</type>
<loader readonly='yes' type='pflash'>/run/libvirt/nix-ovmf/OVMF_CODE.fd</loader>
<nvram template='/run/libvirt/nix-ovmf/OVMF_VARS.fd' templateFormat="raw" format="raw">/var/lib/libvirt/qemu/nvram/win10code_VARS.fd</nvram>
</os>
<features>
<acpi/>
<apic/>
<hyperv mode='custom'>
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='8191'/>
</hyperv>
<vmport state='off'/>
</features>
<cpu mode='host-passthrough' check='none' migratable='on'>
<topology sockets='1' dies='1' clusters='1' cores='2' threads='2'/>
</cpu>
<clock offset='localtime'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/run/libvirt/nix-emulators/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' discard='unmap'/>
<source file='/media/libvirt/images/win10code.qcow2'/>
<backingStore type='file'>
<format type='qcow2'/>
<source file='/media/libvirt/images/win10min-base.qcow2'/>
<backingStore/>
</backingStore>
<target dev='vda' bus='virtio'/>
<boot order='1'/>
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' discard='unmap'/>
<source file='/media/libvirt/images/win10-persist.qcow2'/>
<backingStore/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<backingStore/>
<target dev='sdb' bus='sata'/>
<readonly/>
<boot order='2'/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pcie-root'/>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x10'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='2' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='2' port='0x11'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
</controller>
<controller type='pci' index='3' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='3' port='0x12'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
</controller>
<controller type='pci' index='4' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='4' port='0x13'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
</controller>
<controller type='pci' index='5' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='5' port='0x14'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
</controller>
<controller type='pci' index='6' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='6' port='0x15'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
</controller>
<controller type='pci' index='7' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='7' port='0x16'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
</controller>
<controller type='pci' index='8' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='8' port='0x17'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
</controller>
<controller type='pci' index='9' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='9' port='0x18'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='10' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='10' port='0x19'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
</controller>
<controller type='pci' index='11' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='11' port='0x1a'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
</controller>
<controller type='pci' index='12' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='12' port='0x1b'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
</controller>
<controller type='pci' index='13' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='13' port='0x1c'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
</controller>
<controller type='pci' index='14' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='14' port='0x1d'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
</controller>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
</controller>
<controller type='virtio-serial' index='0'>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</controller>
<filesystem type='mount' accessmode='passthrough'>
<driver type='virtiofs' queue='1024'/>
<binary path='/run/current-system/sw/bin/virtiofsd' xattr='on'>
<cache mode='always'/>
</binary>
<source dir='/media/libvirt/viofs'/>
<target dir='viofs'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</filesystem>
<interface type="network">
<mac address="52:54:00:a2:3d:a4"/>
<source network="default"/>
<model type="virtio"/>
<link state="up"/>
<address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
</interface>
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<input type='tablet' bus='usb'>
<address type='usb' bus='0' port='1'/>
</input>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<tpm model='tpm-crb'>
<backend type='emulator' version='2.0'/>
</tpm>
<graphics type='spice'>
<listen type='none'/>
<image compression='off'/>
<gl enable='no'/>
</graphics>
<sound model='ich9'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
</sound>
<audio id='1' type='spice'/>
<video>
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='2'/>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='3'/>
</redirdev>
<watchdog model='itco' action='reset'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='dac' relabel='yes'/>
</domain>

@ -1,229 +0,0 @@
<domain type='kvm'>
<name>win10ed</name>
<uuid>9485322e-63b4-4d6a-84e4-27544149dfd5</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://microsoft.com/win/10"/>
</libosinfo:libosinfo>
</metadata>
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>
<memoryBacking>
<source type='memfd'/>
<access mode='shared'/>
</memoryBacking>
<vcpu placement='static'>4</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-q35-9.2'>hvm</type>
<loader readonly='yes' type='pflash'>/run/libvirt/nix-ovmf/OVMF_CODE.fd</loader>
<nvram template='/run/libvirt/nix-ovmf/OVMF_VARS.fd' templateFormat="raw" format="raw">/var/lib/libvirt/qemu/nvram/win10ed_VARS.fd</nvram>
</os>
<features>
<acpi/>
<apic/>
<hyperv mode='custom'>
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='8191'/>
</hyperv>
<vmport state='off'/>
</features>
<cpu mode='host-passthrough' check='none' migratable='on'>
<topology sockets='1' dies='1' clusters='1' cores='2' threads='2'/>
</cpu>
<clock offset='localtime'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/run/libvirt/nix-emulators/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' discard='unmap'/>
<source file='/media/libvirt/images/win10ed.qcow2'/>
<backingStore type='file'>
<format type='qcow2'/>
<source file='/media/libvirt/images/win10min-base.qcow2'/>
<backingStore/>
</backingStore>
<target dev='vda' bus='virtio'/>
<boot order='1'/>
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' discard='unmap'/>
<source file='/media/libvirt/images/win10-persist.qcow2'/>
<backingStore/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<backingStore/>
<target dev='sdb' bus='sata'/>
<readonly/>
<boot order='2'/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pcie-root'/>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x10'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='2' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='2' port='0x11'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
</controller>
<controller type='pci' index='3' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='3' port='0x12'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
</controller>
<controller type='pci' index='4' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='4' port='0x13'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
</controller>
<controller type='pci' index='5' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='5' port='0x14'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
</controller>
<controller type='pci' index='6' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='6' port='0x15'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
</controller>
<controller type='pci' index='7' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='7' port='0x16'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
</controller>
<controller type='pci' index='8' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='8' port='0x17'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
</controller>
<controller type='pci' index='9' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='9' port='0x18'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='10' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='10' port='0x19'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
</controller>
<controller type='pci' index='11' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='11' port='0x1a'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
</controller>
<controller type='pci' index='12' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='12' port='0x1b'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
</controller>
<controller type='pci' index='13' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='13' port='0x1c'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
</controller>
<controller type='pci' index='14' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='14' port='0x1d'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
</controller>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
</controller>
<controller type='virtio-serial' index='0'>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</controller>
<filesystem type='mount' accessmode='passthrough'>
<driver type='virtiofs' queue='1024'/>
<binary path='/run/current-system/sw/bin/virtiofsd' xattr='on'>
<cache mode='always'/>
</binary>
<source dir='/media/libvirt/viofs'/>
<target dir='viofs'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</filesystem>
<filesystem type='mount' accessmode='passthrough'>
<driver type='virtiofs' queue='1024'/>
<binary path='/run/current-system/sw/bin/virtiofsd' xattr='on'>
<cache mode='always'/>
</binary>
<source dir='/media/games'/>
<target dir='games'/>
<address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/>
</filesystem>
<interface type="network">
<mac address="52:54:00:a2:3d:e8"/>
<source network="default"/>
<model type="virtio"/>
<link state="up"/>
<address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
</interface>
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<input type='tablet' bus='usb'>
<address type='usb' bus='0' port='1'/>
</input>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<tpm model='tpm-crb'>
<backend type='emulator' version='2.0'/>
</tpm>
<graphics type='spice' autoport='yes' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
<image compression='off'/>
</graphics>
<sound model='ich9'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
</sound>
<audio id='1' type='spice'/>
<video>
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='2'/>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='3'/>
</redirdev>
<watchdog model='itco' action='reset'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='dac' relabel='yes'/>
</domain>

@ -1,22 +0,0 @@
{ ... }: {
autoinstall.Dell-Laptop = {
mainuser = "ataraxia";
flakesPath = "/home/nixos/nixos-config";
encryption.encryptBoot = false;
encryption.encryptRoot = true;
encryption.passwordFile = "/home/nixos/pass";
encryption.argonIterTime = "4000";
partitioning.useEntireDisk = true;
partitioning.disk = "/dev/disk/by-id/nvme-Samsung_SSD_960_EVO_250GB_S3ESNX0K159868B";
partitioning.nullifyDisk = false;
partitioning.createBootPool = true;
swapPartition.enable = true;
swapPartition.size = "8GiB";
efiMountPoint = "/efi";
bootSize = "2G";
zfsOpts.ashift = 13;
zfsOpts.bootPoolReservation = "128M";
zfsOpts.rootPoolReservation = "12G";
persist.enable = true;
};
}

@ -1,69 +0,0 @@
{ inputs, config, pkgs, lib, ... }:
let
zfs_arc_max = toString (2 * 1024 * 1024 * 1024);
in {
boot = {
kernelPackages = pkgs.linuxPackages_xanmod_latest;
zfs.package = pkgs.zfs_unstable;
initrd = {
supportedFilesystems = [ "zfs" ];
luks.devices = {
"cryptroot" = {
keyFile = "/keyfile0.bin";
allowDiscards = true;
bypassWorkqueues = true;
};
};
secrets = {
"keyfile0.bin" = "/etc/secrets/keyfile0.bin";
};
};
loader = {
grub = {
enable = true;
device = "nodev";
copyKernels = true;
efiSupport = true;
enableCryptodisk = true;
useOSProber = false;
zfsSupport = true;
};
systemd-boot.enable = lib.mkForce false;
efi.canTouchEfiVariables = true;
efi.efiSysMountPoint = "/efi";
generationsDir.copyKernels = true;
};
kernelParams = [
"zfs.metaslab_lba_weighting_enabled=0"
"zfs.zfs_arc_max=${zfs_arc_max}"
];
tmp.useTmpfs = true;
tmp.tmpfsSize = "4G";
};
persist = {
enable = true;
cache.clean.enable = true;
};
fileSystems."/home".neededForBoot = true;
fileSystems."/persist".neededForBoot = true;
boot.initrd.systemd.enable = true;
boot.initrd.systemd.services.rollback = {
description = "Rollback zfs to a pristine state on boot";
wantedBy = [ "initrd.target" ];
after = [ "zfs-import-rpool.service" ];
before = [ "sysroot.mount" ];
path = [ config.boot.zfs.package ];
unitConfig.DefaultDependencies = "no";
serviceConfig.Type = "oneshot";
script = ''
zfs rollback -r rpool/nixos/root@empty && echo " >>> rollback root <<<"
zfs rollback -r rpool/user/home@empty && echo " >>> rollback home <<<"
'';
};
}

@ -1,58 +0,0 @@
{ inputs, config, pkgs, ... }: {
imports = with inputs.self; [
./boot.nix
./hardware-configuration.nix
customRoles.desktop
customProfiles.bluetooth
];
deviceSpecific.devInfo = {
cpu.vendor = "intel";
drive.type = "ssd";
gpu.vendor = "intel";
ram = 16;
fileSystem = "zfs";
};
deviceSpecific.isGaming = false;
deviceSpecific.enableVirtualisation = true;
deviceSpecific.vpn.tailscale.enable = true;
deviceSpecific.vpn.sing-box.enable = true;
deviceSpecific.vpn.sing-box.config = "dell-singbox";
boot.blacklistedKernelModules = [
"psmouse"
];
services.fwupd.enable = true;
services.tlp = {
enable = true;
settings = {
TLP_DEFAULT_MODE = "BAT";
TLP_PERSISTENT_DEFAULT = 1;
CPU_SCALING_GOVERNOR_ON_AC = "powersave";
CPU_SCALING_GOVERNOR_ON_BAT = "powersave";
CPU_BOOST_ON_AC = 1;
CPU_BOOST_ON_BAT = 0;
};
};
boot.kernelParams = [ "mem_sleep_default=deep" ];
fileSystems."/media/local-nfs" = {
device = "10.10.10.11:/";
fsType = "nfs4";
options = [ "nfsvers=4.2" "x-systemd.automount" "noauto" ];
};
persist.state.homeDirectories = [ ".config/Moonlight Game Streaming Project" ];
home-manager.users.${config.mainuser} = {
home.packages = [
pkgs.moonlight-qt
];
home.stateVersion = "24.05";
};
system.stateVersion = "23.05";
}

@ -1,119 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "rpool/nixos/root";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/home" =
{ device = "rpool/user/home";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/persist" =
{ device = "rpool/persistent/impermanence";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/srv" =
{ device = "rpool/persistent/servers";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/etc/secrets" =
{ device = "rpool/persistent/secrets";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/nix" =
{ device = "rpool/persistent/nix";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/log" =
{ device = "rpool/persistent/log";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/lib/docker" =
{ device = "rpool/persistent/docker";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/lib/containers" =
{ device = "rpool/persistent/containers";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/lib/nixos-containers" =
{ device = "rpool/persistent/nixos-containers";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/media/bittorrent" =
{ device = "rpool/persistent/bittorrent";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/lib/libvirt" =
{ device = "rpool/persistent/libvirt";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/media/libvirt" =
{ device = "rpool/persistent/libvirt-user";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/media/libvirt/images" =
{ device = "rpool/persistent/libvirt-user/images";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/boot" =
{ device = "bpool/nixos/boot";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/efi" =
{ device = "/dev/disk/by-uuid/01F6-72E7";
fsType = "vfat";
};
swapDevices = [
{
device = "/dev/disk/by-partuuid/e6605a31-26bb-437c-9de7-88fcfd4326b2";
randomEncryption.enable = true;
randomEncryption.allowDiscards = true;
}
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
networking.hostId = "08411033";
boot.zfs.devNodes = "/dev/disk/by-id";
boot.supportedFilesystems = [ "zfs" ];
boot.initrd.luks.devices."cryptroot".device = "/dev/disk/by-partuuid/c9110970-1e2d-47fd-828c-c5ecedf772c2";
}

@ -1 +0,0 @@
x86_64-linux

@ -1,84 +0,0 @@
{ modulesPath, lib, inputs, pkgs, config, ... }: {
imports = with inputs.self; [
"${toString modulesPath}/installer/cd-dvd/installation-cd-graphical-plasma5.nix"
# "${toString modulesPath}/installer/cd-dvd/installation-cd-base.nix"
];
options = {
device = lib.mkOption { type = lib.types.str; };
mainuser = lib.mkOption { type = lib.types.str; };
};
config = {
networking.hostName = config.device;
programs.ssh.extraConfig = ''
Host nix-builder
hostname 10.10.10.100
user ataraxia
identitiesOnly yes
identityFile /home/nixos/ssh-builder
'';
environment.systemPackages = [ pkgs.git pkgs.kitty ];
nix = {
nixPath = lib.mkForce [ "self=/etc/self/compat" "nixpkgs=/etc/nixpkgs" ];
registry.self.flake = inputs.self;
registry.nixpkgs.flake = inputs.nixpkgs;
extraOptions = ''
builders-use-substitutes = true
experimental-features = nix-command flakes
flake-registry = ${inputs.flake-registry}/flake-registry.json
'';
settings = {
require-sigs = true;
substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
"https://nixpkgs-wayland.cachix.org"
"https://hyprland.cachix.org"
"https://ataraxiadev-foss.cachix.org"
"https://numtide.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
"ataraxiadev-foss.cachix.org-1:ws/jmPRUF5R8TkirnV1b525lP9F/uTBsz2KraV61058="
"numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE="
];
trusted-users = [ "root" config.mainuser "@wheel" ];
};
buildMachines = [{
hostName = "nix-builder";
maxJobs = 8;
sshUser = "ataraxia";
sshKey = "/home/nixos/ssh-builder";
systems = [ "x86_64-linux" "aarch64-linux" ];
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
}];
distributedBuilds = true;
};
environment.etc.nixpkgs.source = inputs.nixpkgs;
environment.etc.self.source = inputs.self;
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
settings.PermitRootLogin = lib.mkForce "without-password";
settings.X11Forwarding = true;
extraConfig = "StreamLocalBindUnlink yes";
ports = [ 22 ];
};
users.users.nixos.openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+xd8ClJPvJuAdYC9HlNnjiubEtYfvnKjYr9ROV+UmPVvI3ZITF24OaMI+fxgR0EqGfcUzSGom8528IB53Q3aFMIAaA0vKjW+jrByyB2l/k/+ttpLbH75c9WyOpAcUDTen8BhHKPyXOHoJ1jLu7GFmtPZ+mZo8thFB/VIRrwECHd8DnF0drsSCorkRp1bZC7bAHgztaYHNBUoAVGgJ7nLwW7DotlgbUEDiPJHXOxd/c/ZlXIB/cfUUqF+L5ThbMPhMcwRMspLy+nQdmHhih9k6SkvYqJoNqHT5/XeShb0RkIzvUWT2CYTPop5kAY5mMnatVTOY1FZPhHzk3G8MhOQ3r/elM/ecZxmjL8uozMN9kRGf1IL4DgQZfVqQRILdNSQGb0tfeiyirNZe1RlDw9UvMnZJOw0EkiC9lSSRhBWXXxAmxRrbNFTPQSp+/kiIGDmp2AsGhD11CfTDEU3wcLEUPBUqp1FYSzHncJyEKGy2Dpa5xaUJ0cuyGL4W3WHDXa4sTfY+AIXbQTD88Ujdsbfzyd6lrikG4D/crCurXissrh7q9DuYKWRI24cp5bw9lG33U1EXisnZqFyZNwMAmSj2QEGsHCwSevn0FgyRa2WYXgpZ9hfgY4le+ZSMo2JTosQ6DjGyxMDyQAHJ/ismTTzL67Q2p6U+73toYm62Qqdspw== (none)"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDP0/DReYSAfkucroMTdELzTORsGhhbEa+W0FDFBnwViHuoqoKvetCOkW657icexc5v/j6Ghy3+Li9twbHnEDzUJVtNtauhGMjOcUYt6pTbeJ09CGSAh+orxzeY4vXp7ANb91xW8yRn/EE4ALxqbLsc/D7TUMl11fmf0UW+kLgU5TcUYVSLMjQqBpD1Lo7lXLrImloDxe5fwoBDT09E59r9tq6+/3aHz8mpKRLsIQIV0Av00BRJ+/OVmZuBd9WS35rfkpUYmpEVInSJy3G4O6kCvY/zc9Bnh67l4kALZZ0+6W23kBGrzaRfaOtCEcscwfIu+6GXiHOL33rrMNNinF0T2942jGc18feL6P/LZCzqz8bGdFNxT43jAGPeDDcrJEWAJZFO3vVTP65dTRTHQG2KlQMzS7tcif6YUlY2JLJIb61ZfLoShH/ini/tqsGT0Be1f3ndOFt48h4XMW1oIF+EXaHYeO2UJ6855m8Wpxs4bP/jX6vMV38IvvnHy4tWD50= alukard@AMD-Workstation"
];
users.users.root.openssh.authorizedKeys.keys = config.users.users.nixos.openssh.authorizedKeys.keys;
isoImage.squashfsCompression = "zstd -Xcompression-level 3";
};
}

@ -1,72 +0,0 @@
{ config, inputs, ... }: {
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
sops.secrets.rustic-nas-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
sops.secrets.rustic-backups-s3-env.sopsFile = inputs.self.secretsDir + /rustic.yaml;
services.rustic.backups = rec {
nas-backup = {
backup = true;
prune = false;
initialize = false;
environmentFile = config.sops.secrets.rustic-backups-s3-env.path;
extraEnvironment = { https_proxy = "http://10.10.10.6:8888"; };
pruneOpts = [ "--repack-cacheable-only=false" ];
timerConfig = {
OnCalendar = "05:00";
Persistent = true;
};
settings = let
label = "hypervisor-nas";
in {
repository = {
repository = "opendal:s3";
password-file = config.sops.secrets.rustic-nas-pass.path;
options = {
root = label;
bucket = "ataraxia-rustic-backups";
region = "eu-central-003";
endpoint = "https://s3.eu-central-003.backblazeb2.com";
};
};
backup = {
host = config.device;
label = label;
ignore-devid = true;
group-by = "label";
skip-identical-parent = true;
globs = [
"!/media/nas/**/cache"
"!/media/nas/**/.cache"
"!/media/nas/**/log"
"!/media/nas/**/logs"
"!/media/nas/media-stack/configs/lidarr/config/MediaCover"
"!/media/nas/media-stack/configs/qbittorrent/downloads"
"!/media/nas/media-stack/configs/recyclarr/repositories"
"!/srv/gitea"
"!/srv/wiki"
];
snapshots = [{
sources = [ "/srv /media/nas/containers" "/media/nas/media-stack/configs" ];
}];
};
forget = {
filter-labels = [ label ];
group-by = "label";
prune = true;
keep-daily = 4;
keep-weekly = 2;
keep-monthly = 0;
};
};
};
nas-prune = nas-backup // {
backup = false;
prune = true;
createWrapper = false;
timerConfig = {
OnCalendar = "Mon, 06:00";
Persistent = true;
};
};
};
}

@ -1,103 +0,0 @@
{ inputs, config, pkgs, lib, ... }:
let
zfs_arc_max = toString (3 * 1024 * 1024 * 1024);
in {
# CachyOS kernel
imports = [ inputs.chaotic.nixosModules.default ];
boot = {
# zfs.package = pkgs.zfs_cachyos;
# kernelPackages = pkgs.linuxPackages_cachyos-hardened;
# kernelPackages = pkgs.linuxPackages_cachyos-server;
# kernelPackages = pkgs.linuxPackages_hardened;
# kernelPackages = pkgs.linuxPackages;
# kernelPackages = pkgs.linuxPackages_xanmod;
initrd = {
luks.devices = {
# "cryptboot" = {
# allowDiscards = true;
# bypassWorkqueues = config.deviceSpecific.isSSD;
# keyFile = "/keyfile0.bin";
# };
"cryptroot" = {
allowDiscards = true;
bypassWorkqueues = config.deviceSpecific.isSSD;
keyFile = "/keyfile0.bin";
};
"crypt-nas" = {
device = "/dev/disk/by-id/ata-ST4000NM0035-1V4107_ZC1A7CWN";
keyFile = "/nas_keyfile0.bin";
};
};
secrets = {
"keyfile0.bin" = "/etc/secrets/keyfile0.bin";
"nas_keyfile0.bin" = "/etc/secrets/nas_keyfile0.bin";
};
supportedFilesystems = [ "zfs" ];
systemd.enable = true;
};
loader = {
efi.canTouchEfiVariables = false;
efi.efiSysMountPoint = "/efi";
generationsDir.copyKernels = true;
grub = {
enable = true;
enableCryptodisk = true;
device = "nodev";
copyKernels = true;
efiInstallAsRemovable = true;
efiSupport = true;
zfsSupport = true;
useOSProber = false;
};
};
kernelModules = [ "tcp_bbr" "veth" "nfsv4" ];
kernelParams = [
"zfs.zfs_arc_max=${zfs_arc_max}"
"zswap.enabled=0"
"scsi_mod.use_blk_mq=1"
"nofb"
"pti=off"
"spectre_v2=off"
"kvm.ignore_msrs=1"
"kvm.report_ignored_msrs=0"
"rd.systemd.show_status=auto"
"rd.udev.log_priority=3"
];
kernel.sysctl = {
"vm.swappiness" = 80;
"vm.vfs_cache_pressure" = 200;
"vm.dirty_background_ratio" = 1;
"vm.dirty_ratio" = 40;
"vm.page-cluster" = 0;
"vm.overcommit_memory" = lib.mkForce 1;
};
supportedFilesystems = [ "nfs4" ];
zfs.extraPools = [ "bpool" "rpool" "nas-pool" ];
};
networking.hostId = "a9408846";
# Impermanence
persist = {
enable = true;
cache.clean.enable = true;
};
fileSystems."/home".neededForBoot = true;
fileSystems."/persist".neededForBoot = true;
# boot.initrd.systemd.services.rollback = {
# description = "Rollback zfs to a pristine state on boot";
# wantedBy = [ "initrd.target" ];
# after = [ "zfs-import-rpool.service" ];
# before = [ "sysroot.mount" ];
# path = [ config.boot.zfs.package ];
# unitConfig.DefaultDependencies = "no";
# serviceConfig.Type = "oneshot";
# script = ''
# zfs rollback -r rpool/nixos/root@empty && echo " >>> rollback root <<<"
# zfs rollback -r rpool/user/home@empty && echo " >>> rollback home <<<"
# '';
# };
}

@ -1,162 +0,0 @@
{ inputs, lib, pkgs, config, ... }:
{
imports = with inputs.self; [
inputs.disko.nixosModules.disko
inputs.srvos.nixosModules.server
inputs.srvos.nixosModules.mixins-terminfo
./disk-config.nix
./backups.nix
./boot.nix
./networking.nix
./virtualisation.nix
customProfiles.hardened
customRoles.hypervisor
./nginx.nix
# customProfiles.tg-bot
customProfiles.acme
# customProfiles.attic
# customProfiles.atticd
customProfiles.authentik
# customProfiles.battery-historian
customProfiles.coturn
# customProfiles.fail2ban
customProfiles.gitea
# customProfiles.homepage
# customProfiles.hoyolab
customProfiles.inpx-web
customProfiles.it-tools
customProfiles.media-stack
# customProfiles.metrics
# customProfiles.minio
# customProfiles.netbird-server
# customProfiles.nginx
# customProfiles.ocis
# customProfiles.onlyoffice
# customProfiles.openbooks
# customProfiles.outline
customProfiles.radicale
# customProfiles.spdf
customProfiles.synapse
customProfiles.tinyproxy
# customProfiles.vault
customProfiles.vaultwarden
customProfiles.webhooks
customProfiles.wiki
# customProfiles.yandex-db
# (import customProfiles.blocky {
# inherit (import ./dns-mapping.nix) dnsmasq-list;
# })
(import customProfiles.headscale {
inherit (import ./dns-mapping.nix) headscale-list;
})
];
security.lockKernelModules = lib.mkForce false;
deviceSpecific.devInfo = {
cpu.vendor = "intel";
drive.type = "ssd";
gpu.vendor = "other";
ram = 8;
fileSystem = "zfs";
};
deviceSpecific.isServer = true;
deviceSpecific.vpn.tailscale.enable = true;
# Tailscale auto-login
# services.headscale-auth.home-hypervisor = {
# outPath = "/tmp/hypervisor-authkey";
# before = [ "tailscaled-autoconnect.service" ];
# };
# services.tailscale = {
# authKeyFile = "/tmp/hypervisor-authkey";
# extraUpFlags = [
# "--login-server=https://wg.ataraxiadev.com"
# "--accept-dns=false"
# "--advertise-exit-node=false"
# "--operator=${config.mainuser}"
# ];
# };
zramSwap = {
enable = true;
algorithm = "zstd";
memoryPercent = 150;
};
# Impermanence
persist = {
enable = true;
cache.clean.enable = true;
state = {
files = [ "/etc/machine-id" ];
};
};
fileSystems."/media/local-nfs" = {
device = "10.10.10.11:/";
fsType = "nfs4";
options = [ "nfsvers=4.2" "x-systemd.automount" "noauto" ];
};
environment.memoryAllocator.provider = "libc";
services.udisks2.enable = false;
fonts.enableDefaultPackages = false;
fonts.packages = with pkgs; [ nerd-fonts.fira-code nerd-fonts.victor-mono ];
security.polkit.enable = true;
services.zfs = {
autoScrub.enable = true;
autoScrub.interval = "monthly";
trim.enable = true;
trim.interval = "weekly";
};
services.postgresql.enable = true;
services.postgresql.settings = {
full_page_writes = "off";
wal_init_zero = "off";
wal_recycle = "off";
};
nix.settings.experimental-features = [
"cgroups"
"fetch-closure"
"recursive-nix"
];
environment.systemPackages = with pkgs; [ nfs-utils ];
home-manager.users.${config.mainuser} = {
home.file.".config/libvirt/libvirt.conf".text = ''
uri_default = "qemu:///system"
'';
home.packages = with pkgs; [
bat
bottom
comma
dig.dnsutils
fd
kitty
micro
mkvtoolnix-cli
nix-index-update
p7zip
podman-compose
pwgen
rclone
repgrep
restic
rsync
rustic-rs
smartmontools
];
xdg.mime.enable = false;
home.stateVersion = "24.11";
};
system.stateVersion = "24.11";
}

@ -1,279 +0,0 @@
{ ... }:
let
emptySnapshot = name: "zfs list -t snapshot -H -o name | grep -E '^${name}@blank$' || zfs snapshot ${name}@blank";
in {
disko.devices = {
disk = {
main = {
device = "/dev/disk/by-id/ata-Samsung_SSD_870_EVO_500GB_S5Y1NJ1R160554B";
type = "disk";
content = {
type = "gpt";
partitions = {
esp = {
type = "EF00";
name = "ESP";
size = "512M";
priority = 1;
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/efi";
mountOptions = [ "umask=0077" ];
};
};
swap = {
name = "swap";
size = "16G";
priority = 2;
content = {
type = "swap";
randomEncryption = true;
};
};
boot = {
name = "bpool";
size = "4G";
priority = 3;
content = {
type = "zfs";
pool = "bpool";
};
};
cryptroot = {
size = "100%";
priority = 4;
content = {
type = "luks";
name = "cryptroot";
settings.allowDiscards = true;
passwordFile = "/tmp/cryptroot.pass";
additionalKeyFiles = [ "/tmp/cryptroot.key" ];
content = {
type = "zfs";
pool = "rpool";
};
};
};
};
};
};
};
zpool = {
bpool = {
type = "zpool";
options = {
ashift = "13";
autotrim = "on";
compatibility = "grub2";
};
rootFsOptions = {
acltype = "posixacl";
atime = "on";
canmount = "off";
compression = "lz4";
devices = "off";
normalization = "formD";
relatime = "on";
xattr = "sa";
dedup = "off";
};
mountpoint = "/boot";
postCreateHook = emptySnapshot "bpool";
datasets = {
nixos = {
type = "zfs_fs";
options.mountpoint = "none";
options.canmount = "off";
postCreateHook = emptySnapshot "bpool/nixos";
};
"nixos/boot" = {
type = "zfs_fs";
mountpoint = "/boot";
options.canmount = "on";
postCreateHook = emptySnapshot "bpool/nixos/boot";
};
};
};
rpool = {
type = "zpool";
options = {
ashift = "13";
autotrim = "on";
cachefile = "none";
};
rootFsOptions = {
acltype = "posixacl";
atime = "on";
canmount = "off";
compression = "zstd-5";
dedup = "off";
dnodesize = "auto";
normalization = "formD";
relatime = "on";
xattr = "sa";
};
mountpoint = "/";
postCreateHook = emptySnapshot "rpool";
datasets = {
reserved = {
type = "zfs_fs";
options.mountpoint = "none";
options = {
canmount = "off";
refreservation = "20G";
};
};
nixos = {
type = "zfs_fs";
# mountpoint = "none";
options.mountpoint = "none";
options.canmount = "off";
postCreateHook = emptySnapshot "rpool/nixos";
};
user = {
type = "zfs_fs";
options.mountpoint = "none";
options.canmount = "off";
postCreateHook = emptySnapshot "rpool/user";
};
persistent = {
type = "zfs_fs";
options.mountpoint = "none";
options.canmount = "off";
postCreateHook = emptySnapshot "rpool/persistent";
};
"nixos/root" = {
type = "zfs_fs";
mountpoint = "/";
options.canmount = "noauto";
postCreateHook = emptySnapshot "rpool/nixos/root";
};
"user/home" = {
type = "zfs_fs";
mountpoint = "/home";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/user/home";
};
"persistent/impermanence" = {
type = "zfs_fs";
mountpoint = "/persist";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/impermanence";
};
"persistent/servers" = {
type = "zfs_fs";
mountpoint = "/srv";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/servers";
};
"persistent/nix" = {
type = "zfs_fs";
mountpoint = "/nix";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/nix";
};
"persistent/secrets" = {
type = "zfs_fs";
mountpoint = "/etc/secrets";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/secrets";
};
"persistent/log" = {
type = "zfs_fs";
mountpoint = "/var/log";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/log";
};
# "persistent/lxd" = {
# type = "zfs_fs";
# options.canmount = "noauto";
# postCreateHook = emptySnapshot "rpool/persistent/lxd";
# };
"persistent/docker" = {
type = "zfs_fs";
mountpoint = "/var/lib/docker";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/docker";
};
"persistent/nixos-containers" = {
type = "zfs_fs";
mountpoint = "/var/lib/nixos-containers";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/nixos-containers";
};
"persistent/bittorrent" = {
type = "zfs_fs";
mountpoint = "/media/bittorrent";
options.canmount = "on";
options.atime = "off";
options.recordsize = "16K";
options.compression = "lz4";
postCreateHook = emptySnapshot "rpool/persistent/bittorrent";
};
"persistent/libvirt" = {
type = "zfs_fs";
mountpoint = "/var/lib/libvirt";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/libvirt";
};
"persistent/libvirt-user" = {
type = "zfs_fs";
mountpoint = "/media/libvirt";
options.canmount = "on";
postCreateHook = emptySnapshot "rpool/persistent/libvirt-user";
};
"persistent/libvirt-user/images" = {
type = "zfs_fs";
mountpoint = "/media/libvirt/images";
options.canmount = "on";
options.atime = "off";
options.recordsize = "16K";
options.compression = "lz4";
postCreateHook = emptySnapshot "rpool/persistent/libvirt-user/images";
};
"persistent/ocis" = {
type = "zfs_fs";
mountpoint = "/var/lib/ocis";
options.canmount = "on";
options.recordsize = "1M";
postCreateHook = emptySnapshot "rpool/persistent/ocis";
};
# "persistent/podman" = {
# type = "zfs_fs";
# mountpoint = "/var/lib/podman";
# options.canmount = "on";
# options.atime = "off";
# postCreateHook = emptySnapshot "rpool/persistent/podman";
# };
"persistent/postgresql" = {
type = "zfs_fs";
mountpoint = "/var/lib/postgresql";
options.canmount = "on";
options.recordsize = "16K";
options.atime = "off";
options.logbias = "latency";
postCreateHook = emptySnapshot "rpool/persistent/postgresql";
};
vol = {
type = "zfs_fs";
options.canmount = "off";
postCreateHook = emptySnapshot "rpool/vol";
};
"vol/podman" = {
type = "zfs_volume";
size = "40G";
options.volblocksize = "16K";
content = {
type = "filesystem";
format = "xfs";
mountpoint = "/var/lib/containers";
};
};
};
};
};
};
}

@ -1,101 +0,0 @@
{
headscale-list = [
{ name = "ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "api.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
# { name = "auth.ataraxiadev.com"; type = "A"; value = "100.64.0.100"; }
{ name = "cache.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "cal.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "code.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "docs.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "element.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "file.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "home.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "jackett.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "jellyfin.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "joplin.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "kavita.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "ldap.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "lib.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "matrix.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "medusa.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "net.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "openbooks.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "pdf.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "qbit.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "radarr.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "restic.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "s3.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "sonarr.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "stats.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "tools.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "turn.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "vault.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "vw.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "wiki.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "api.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
# { name = "auth.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::100"; }
{ name = "cache.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "cal.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "code.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "docs.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "element.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "file.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "home.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "jackett.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "jellyfin.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "joplin.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "kavita.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "ldap.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "lib.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "matrix.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "medusa.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "net.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "openbooks.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "pdf.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "qbit.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "radarr.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "restic.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "s3.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "sonarr.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "stats.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "tools.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "turn.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "vault.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "vw.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "wiki.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
];
dnsmasq-list = [
"/api.ataraxiadev.com/10.10.10.10"
"/cache.ataraxiadev.com/10.10.10.10"
"/cal.ataraxiadev.com/10.10.10.10"
"/code.ataraxiadev.com/10.10.10.10"
"/docs.ataraxiadev.com/10.10.10.10"
"/element.ataraxiadev.com/10.10.10.10"
"/file.ataraxiadev.com/10.10.10.10"
"/home.ataraxiadev.com/10.10.10.10"
"/jackett.ataraxiadev.com/10.10.10.10"
"/jellyfin.ataraxiadev.com/10.10.10.10"
"/joplin.ataraxiadev.com/10.10.10.10"
"/kavita.ataraxiadev.com/10.10.10.10"
"/ldap.ataraxiadev.com/10.10.10.10"
"/lib.ataraxiadev.com/10.10.10.10"
"/matrix.ataraxiadev.com/10.10.10.10"
"/medusa.ataraxiadev.com/10.10.10.10"
"/net.ataraxiadev.com/10.10.10.10"
"/openbooks.ataraxiadev.com/10.10.10.10"
"/pdf.ataraxiadev.com/10.10.10.10"
"/qbit.ataraxiadev.com/10.10.10.10"
"/radarr.ataraxiadev.com/10.10.10.10"
"/restic.ataraxiadev.com/10.10.10.10"
"/s3.ataraxiadev.com/10.10.10.10"
"/sonarr.ataraxiadev.com/10.10.10.10"
"/stats.ataraxiadev.com/10.10.10.10"
"/tools.ataraxiadev.com/10.10.10.10"
"/turn.ataraxiadev.com/10.10.10.10"
"/vault.ataraxiadev.com/10.10.10.10"
"/vw.ataraxiadev.com/10.10.10.10"
"/wiki.ataraxiadev.com/10.10.10.10"
];
}

@ -1,21 +0,0 @@
{
domain = "home.ataraxiadev.com";
hasIPv6 = false;
interfaces = {
main' = {
mac = "d4:3d:7e:26:a8:af";
bridgeName = "br0";
ifname = "enp2s0";
IPv4 = {
address = "10.10.10.10/24";
gateway = "10.10.10.1";
dns = [ "10.10.10.1" "9.9.9.9" ];
};
IPv6 = {
address = "";
gateway = "";
dns = [ ];
};
};
};
}

@ -1,83 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (import ./hardware/networks.nix) interfaces domain hasIPv6;
in {
services.resolved.enable = true;
networking = {
dhcpcd.enable = false;
domain = domain;
enableIPv6 = hasIPv6;
hostName = config.device;
nftables.enable = true;
useDHCP = false;
useNetworkd = lib.mkForce false;
usePredictableInterfaceNames = true;
firewall = {
enable = true;
allowedTCPPorts = lib.mkDefault [ ];
allowedUDPPorts = lib.mkDefault [ ];
};
nameservers = [ "10.10.10.1" "9.9.9.9" ];
# extraHosts = ''
# 127.0.0.1 auth.ataraxiadev.com
# 127.0.0.1 code.ataraxiadev.com
# 127.0.0.1 cache.ataraxiadev.com
# 127.0.0.1 s3.ataraxiadev.com
# 127.0.0.1 wg.ataraxiadev.com
# 127.0.0.1 vault.ataraxiadev.com
# 127.0.0.1 matrix.ataraxiadev.com
# '';
};
systemd.network = with interfaces.main'; {
enable = lib.mkForce true;
wait-online.ignoredInterfaces = [ "lo" ];
networks = {
"40-${ifname}" = {
matchConfig.Name = ifname;
linkConfig.RequiredForOnline = "enslaved";
networkConfig.Bridge = bridgeName;
networkConfig.DHCP = "no";
};
"60-${bridgeName}" = {
matchConfig.Name = bridgeName;
address = [
IPv4.address
] ++ lib.optionals hasIPv6 [
IPv6.address
"fc00::1/64"
];
linkConfig.RequiredForOnline = "routable";
# networkConfig = {
# IPForward = true;
# DNS = IPv4.dns ++ lib.optionals hasIPv6 IPv6.dns;
# };
routes = [{
Gateway = IPv4.gateway;
GatewayOnLink = true;
}] ++ lib.optionals hasIPv6 [{
Gateway = IPv6.gateway;
GatewayOnLink = true;
}];
};
};
netdevs = {
"60-${bridgeName}" = {
netdevConfig = {
Kind = "bridge";
Name = bridgeName;
MACAddress = mac;
};
};
};
};
system.activationScripts.udp-gro-forwarding = {
text = with interfaces.main'; ''
${pkgs.ethtool}/bin/ethtool -K ${bridgeName} rx-udp-gro-forwarding on rx-gro-list off
'';
};
}

@ -1,168 +0,0 @@
{ pkgs, config, ... }:
{
services.nginx = {
enable = true;
package = pkgs.nginxQuic;
group = "acme";
recommendedBrotliSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
recommendedZstdSettings = true;
clientMaxBodySize = "250m";
commonHttpConfig = ''
proxy_hide_header X-Frame-Options;
'';
virtualHosts = let
default = {
useACMEHost = "ataraxiadev.com";
enableACME = false;
forceSSL = true;
};
proxySettings = ''
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
'';
in {
"media-stack" = {
serverAliases = [
"qbit.ataraxiadev.com"
"prowlarr.ataraxiadev.com"
"jackett.ataraxiadev.com"
"sonarr.ataraxiadev.com"
"radarr.ataraxiadev.com"
"lidarr.ataraxiadev.com"
"kavita.ataraxiadev.com"
];
locations."/" = {
proxyPass = "http://127.0.0.1:8180";
proxyWebsockets = true;
extraConfig = ''
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
send_timeout 15m;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 15m;
'' + proxySettings;
};
} // default;
"medusa.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:8180";
proxyWebsockets = true;
extraConfig = ''
add_header Content-Security-Policy "upgrade-insecure-requests";
'' + proxySettings;
};
} // default;
"jellyfin.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:8180";
extraConfig = ''
proxy_buffering off;
'' + proxySettings;
};
locations."/socket" = {
proxyPass = "http://127.0.0.1:8180";
proxyWebsockets = true;
extraConfig = proxySettings;
};
extraConfig = ''
client_max_body_size 50M;
'';
} // default;
"ataraxiadev.com" = {
locations."/" = {
root = "/srv/http/ataraxiadev.com/docroot";
extraConfig = ''
try_files $uri $uri/ =404;
'';
};
locations."/hooks" = {
proxyPass = "http://127.0.0.1:9510/hooks";
};
} // default;
"auth.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:9000";
proxyWebsockets = true;
extraConfig = proxySettings;
};
} // default;
"wg.ataraxiadev.com" = {
locations."/headscale." = {
extraConfig = ''
grpc_pass grpc://${config.services.headscale.settings.grpc_listen_addr};
'';
priority = 1;
};
locations."/metrics" = {
proxyPass = "http://127.0.0.1:${toString config.services.headscale.port}";
extraConfig = ''
allow 100.64.0.0/16;
allow 10.10.10.0/24;
deny all;
'';
priority = 2;
};
locations."/" = {
proxyPass = "http://127.0.0.1:${toString config.services.headscale.port}";
proxyWebsockets = true;
priority = 3;
};
} // default;
"cal.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:5232";
extraConfig = proxySettings;
};
} // default;
"code.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:6000";
extraConfig = proxySettings;
};
} // default;
"lib.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:8072";
proxyWebsockets = true;
};
} // default;
"tools.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:8070";
};
} // default;
"vw.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:8812";
extraConfig = proxySettings;
};
locations."/notifications/hub" = {
proxyPass = "http://127.0.0.1:3012";
proxyWebsockets = true;
extraConfig = proxySettings;
};
locations."/notifications/hub/negotiate" = {
proxyPass = "http://127.0.0.1:8812";
extraConfig = proxySettings;
};
} // default;
"wiki.ataraxiadev.com" = {
locations."/" = {
proxyPass = "http://127.0.0.1:8190";
};
} // default;
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
networking.firewall.allowedUDPPorts = [ 80 443 ];
}

@ -1 +0,0 @@
x86_64-linux

@ -1,36 +0,0 @@
{ config, pkgs, lib, inputs, ... }: {
imports = with inputs.self; [
customProfiles.virtualisation
];
deviceSpecific.enableVirtualisation = true;
boot.kernelModules = [ "x_tables" ];
virtualisation = {
docker.enable = lib.mkForce false;
podman.defaultNetwork.settings.dns_enabled = lib.mkForce true;
podman.extraPackages = [ pkgs.zfs ];
spiceUSBRedirection.enable = lib.mkForce false;
containers.storage.settings.storage.graphroot = lib.mkForce "/var/lib/podman/storage";
};
users.users.${config.mainuser} = {
subUidRanges = [{
count = 1000;
startUid = 10000;
}];
subGidRanges = [{
count = 1000;
startGid = 10000;
}];
};
virtualisation.libvirt.guests = {
omv = {
autoStart = true;
user = config.mainuser;
group = "libvirtd";
xmlFile = ./vm/omv.xml;
};
};
}

@ -1,197 +0,0 @@
<domain type='kvm'>
<name>omv</name>
<uuid>48cd00d8-9060-4221-a8bb-4d1db42c5939</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://debian.org/debian/12"/>
</libosinfo:libosinfo>
</metadata>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64' machine='pc-q35-9.1'>hvm</type>
<loader readonly='yes' type='pflash'>/run/libvirt/nix-ovmf/OVMF_CODE.fd</loader>
<nvram template='/run/libvirt/nix-ovmf/OVMF_VARS.fd'>/var/lib/libvirt/qemu/nvram/omv_VARS.fd</nvram>
</os>
<features>
<acpi/>
<apic/>
<vmport state='off'/>
</features>
<cpu mode='host-passthrough' check='none' migratable='on'>
<topology sockets='1' dies='1' clusters='1' cores='2' threads='1'/>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/run/libvirt/nix-emulators/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/media/libvirt/images/omv.qcow2'/>
<target dev='vda' bus='virtio'/>
<boot order='1'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</disk>
<disk type='block' device='disk'>
<driver name='qemu' type='raw'/>
<source dev='/dev/disk/by-id/ata-ST1000LM024_HN-M101MBB_S30YJ9DF829362'/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<target dev='sda' bus='sata'/>
<readonly/>
<boot order='2'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pcie-root'/>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x10'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='2' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='2' port='0x11'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
</controller>
<controller type='pci' index='3' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='3' port='0x12'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
</controller>
<controller type='pci' index='4' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='4' port='0x13'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
</controller>
<controller type='pci' index='5' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='5' port='0x14'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
</controller>
<controller type='pci' index='6' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='6' port='0x15'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
</controller>
<controller type='pci' index='7' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='7' port='0x16'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
</controller>
<controller type='pci' index='8' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='8' port='0x17'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
</controller>
<controller type='pci' index='9' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='9' port='0x18'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='10' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='10' port='0x19'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
</controller>
<controller type='pci' index='11' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='11' port='0x1a'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
</controller>
<controller type='pci' index='12' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='12' port='0x1b'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
</controller>
<controller type='pci' index='13' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='13' port='0x1c'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
</controller>
<controller type='pci' index='14' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='14' port='0x1d'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
</controller>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
</controller>
<controller type='virtio-serial' index='0'>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:d8:ef:84'/>
<source bridge='br0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
<address type='virtio-serial' controller='0' bus='0' port='2'/>
</channel>
<input type='tablet' bus='usb'>
<address type='usb' bus='0' port='1'/>
</input>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<tpm model='tpm-crb'>
<backend type='emulator' version='2.0'/>
</tpm>
<graphics type='spice' autoport='yes'>
<listen type='address'/>
<image compression='off'/>
</graphics>
<sound model='ich9'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
</sound>
<audio id='1' type='spice'/>
<video>
<model type='virtio' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='2'/>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='3'/>
</redirdev>
<watchdog model='itco' action='reset'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
</memballoon>
<rng model='virtio'>
<backend model='random'>/dev/urandom</backend>
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
</rng>
</devices>
</domain>

@ -1,276 +0,0 @@
{ modulesPath, self, inputs, lib, pkgs, config, ... }: {
disabledModules = [ "${self}/modules/pass-store.nix" ];
imports = with inputs.self; [
(modulesPath + "/profiles/qemu-guest.nix")
(modulesPath + "/profiles/minimal.nix")
inputs.disko.nixosModules.disko
./disk-config.nix
./network.nix
customModules.devices
customModules.libvirt-guests
customModules.persist
customModules.users
customProfiles.hardened
customProfiles.nix
customProfiles.vlock
customProfiles.hoyolab
# ./services/backups.nix
# ./services/dns.nix
./services/tailscale.nix
./services/xtls.nix
];
boot.kernelPackages = pkgs.linuxPackages_latest;
services.qemuGuest.enable = lib.mkForce true;
# Impermanence
boot.initrd = {
# hardware
availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
# reset rootfs on reboot
postDeviceCommands = pkgs.lib.mkBefore ''
mkdir -p /mnt
mount -o subvol=/ /dev/vda4 /mnt
btrfs subvolume list -o /mnt/rootfs |
cut -f9 -d' ' |
while read subvolume; do
echo "deleting /$subvolume subvolume..."
btrfs subvolume delete "/mnt/$subvolume"
done &&
echo "deleting /root subvolume..."
btrfs subvolume delete /mnt/rootfs
echo "restoring blank /root subvolume..."
btrfs subvolume snapshot /mnt/snapshots/rootfs-blank /mnt/rootfs
umount /mnt
'';
};
fileSystems."/home".neededForBoot = true;
fileSystems."/persist".neededForBoot = true;
persist = {
enable = true;
cache.clean.enable = true;
state = {
files = [
"/etc/machine-id"
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
"/etc/ssh/ssh_host_rsa_key"
"/etc/ssh/ssh_host_rsa_key.pub"
];
directories = [
"/var/lib/nixos"
"/var/lib/systemd"
"/var/lib/postgresql"
];
};
};
# TODO: write all needed modules in boot.kernelModules
security.lockKernelModules = lib.mkForce false;
# Misc
boot = {
supportedFilesystems = [ "vfat" "btrfs" ];
kernelModules = [
"kvm-intel" "tcp_bbr" "veth"
# podman
"nft_chain_nat" "xt_addrtype" "xt_comment" "xt_mark" "xt_MASQUERADE"
];
kernelParams = [
"scsi_mod.use_blk_mq=1"
"kvm.ignore_msrs=1"
"kvm.report_ignored_msrs=0"
];
kernel.sysctl = {
"vm.swappiness" = 50;
"vm.vfs_cache_pressure" = 200;
"vm.dirty_background_ratio" = 1;
"vm.dirty_ratio" = 40;
"vm.page-cluster" = 0;
# proxy tuning
"net.ipv4.tcp_congestion_control" = "bbr";
"net.ipv4.tcp_slow_start_after_idle" = 0;
"net.core.default_qdisc" = "cake";
"net.core.rmem_max" = 67108864;
"net.core.wmem_max" = 67108864;
"net.core.netdev_max_backlog" = 10000;
"net.core.somaxconn" = 4096;
"net.ipv4.tcp_syncookies" = 1;
"net.ipv4.tcp_tw_reuse" = 1;
"net.ipv4.tcp_fin_timeout" = 30;
"net.ipv4.tcp_keepalive_time" = 1200;
"net.ipv4.tcp_keepalive_probes" = 5;
"net.ipv4.tcp_keepalive_intvl" = 30;
"net.ipv4.tcp_max_syn_backlog" = 8192;
"net.ipv4.tcp_max_tw_buckets" = 5000;
"net.ipv4.tcp_fastopen" = 3;
"net.ipv4.tcp_mem" = "25600 51200 102400";
"net.ipv4.udp_mem" = "25600 51200 102400";
"net.ipv4.tcp_rmem" = "4096 87380 67108864";
"net.ipv4.tcp_wmem" = "4096 65536 67108864";
"net.ipv4.tcp_mtu_probing" = 1;
};
loader.grub = {
enable = true;
efiSupport = true;
efiInstallAsRemovable = true;
};
};
zramSwap = {
enable = true;
algorithm = "zstd";
memoryPercent = 100;
};
environment.memoryAllocator.provider = lib.mkForce "libc";
deviceSpecific.isServer = true;
services.journald.extraConfig = "Compress=false";
nix.optimise.automatic = false;
nix.distributedBuilds = lib.mkForce false;
fonts.enableDefaultPackages = lib.mkForce false;
security.polkit.enable = true;
# security.pam.enableSSHAgentAuth = true;
environment.systemPackages = with pkgs; [
bat
bottom
comma
git
kitty
micro
pwgen
inputs.nix-alien.packages.${pkgs.hostPlatform.system}.nix-index-update
rsync
];
# Locale
i18n.defaultLocale = "en_IE.UTF-8";
i18n.extraLocaleSettings = {
LANGUAGE = "en_IE:en_US:en:C:ru_RU";
LC_TIME = "en_DK.UTF-8";
LC_ADDRESS = "ru_RU.UTF-8";
LC_MONETARY = "ru_RU.UTF-8";
LC_NUMERIC = "ru_RU.UTF-8";
LC_PAPER = "ru_RU.UTF-8";
LC_TELEPHONE = "ru_RU.UTF-8";
};
i18n.supportedLocales = [
"C.UTF-8/UTF-8"
"en_DK.UTF-8/UTF-8"
"en_GB.UTF-8/UTF-8"
"en_IE.UTF-8/UTF-8"
"en_US.UTF-8/UTF-8"
"ru_RU.UTF-8/UTF-8"
];
time.timeZone = "Etc/UTC";
environment.sessionVariables = {
XKB_DEFAULT_LAYOUT = "us,ru";
XKB_DEFAULT_OPTIONS = "grp:win_space_toggle";
};
# Hardened
networking.firewall = {
enable = true;
allowPing = true;
allowedTCPPorts = lib.mkDefault [ ];
allowedUDPPorts = lib.mkDefault [ ];
};
systemd.coredump.enable = false;
services.openssh = {
enable = true;
settings.LogLevel = "VERBOSE";
settings.PasswordAuthentication = false;
settings.PermitRootLogin = lib.mkForce "prohibit-password";
settings.X11Forwarding = false;
extraConfig = "StreamLocalBindUnlink yes";
ports = [ 32323 ];
};
services.fail2ban = {
enable = true;
maxretry = 3;
bantime = "2h";
bantime-increment = {
enable = true;
maxtime = "72h";
overalljails = true;
};
ignoreIP = [
"10.0.0.0/8"
"172.16.0.0/12"
"192.168.0.0/16"
];
jails = {
sshd.settings = {
backend = "systemd";
mode = "aggressive";
};
};
};
# Users
users.mutableUsers = false;
users.users = {
${config.mainuser} = {
isNormalUser = true;
extraGroups = [ "disk" "systemd-journal" "wheel" "qemu-libvirtd" "libvirtd" ];
uid = 1000;
hashedPassword =
"$y$j9T$ZC44T3XYOPapB26cyPsA4.$8wlYEbwXFszC9nrg0vafqBZFLMPabXdhnzlT3DhUit6";
shell = pkgs.bash;
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+xd8ClJPvJuAdYC9HlNnjiubEtYfvnKjYr9ROV+UmPVvI3ZITF24OaMI+fxgR0EqGfcUzSGom8528IB53Q3aFMIAaA0vKjW+jrByyB2l/k/+ttpLbH75c9WyOpAcUDTen8BhHKPyXOHoJ1jLu7GFmtPZ+mZo8thFB/VIRrwECHd8DnF0drsSCorkRp1bZC7bAHgztaYHNBUoAVGgJ7nLwW7DotlgbUEDiPJHXOxd/c/ZlXIB/cfUUqF+L5ThbMPhMcwRMspLy+nQdmHhih9k6SkvYqJoNqHT5/XeShb0RkIzvUWT2CYTPop5kAY5mMnatVTOY1FZPhHzk3G8MhOQ3r/elM/ecZxmjL8uozMN9kRGf1IL4DgQZfVqQRILdNSQGb0tfeiyirNZe1RlDw9UvMnZJOw0EkiC9lSSRhBWXXxAmxRrbNFTPQSp+/kiIGDmp2AsGhD11CfTDEU3wcLEUPBUqp1FYSzHncJyEKGy2Dpa5xaUJ0cuyGL4W3WHDXa4sTfY+AIXbQTD88Ujdsbfzyd6lrikG4D/crCurXissrh7q9DuYKWRI24cp5bw9lG33U1EXisnZqFyZNwMAmSj2QEGsHCwSevn0FgyRa2WYXgpZ9hfgY4le+ZSMo2JTosQ6DjGyxMDyQAHJ/ismTTzL67Q2p6U+73toYm62Qqdspw== (none)"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDP0/DReYSAfkucroMTdELzTORsGhhbEa+W0FDFBnwViHuoqoKvetCOkW657icexc5v/j6Ghy3+Li9twbHnEDzUJVtNtauhGMjOcUYt6pTbeJ09CGSAh+orxzeY4vXp7ANb91xW8yRn/EE4ALxqbLsc/D7TUMl11fmf0UW+kLgU5TcUYVSLMjQqBpD1Lo7lXLrImloDxe5fwoBDT09E59r9tq6+/3aHz8mpKRLsIQIV0Av00BRJ+/OVmZuBd9WS35rfkpUYmpEVInSJy3G4O6kCvY/zc9Bnh67l4kALZZ0+6W23kBGrzaRfaOtCEcscwfIu+6GXiHOL33rrMNNinF0T2942jGc18feL6P/LZCzqz8bGdFNxT43jAGPeDDcrJEWAJZFO3vVTP65dTRTHQG2KlQMzS7tcif6YUlY2JLJIb61ZfLoShH/ini/tqsGT0Be1f3ndOFt48h4XMW1oIF+EXaHYeO2UJ6855m8Wpxs4bP/jX6vMV38IvvnHy4tWD50= alukard@AMD-Workstation"
];
};
deploy = {
description = "The administrator account for the servers.";
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys =
config.users.users.${config.mainuser}.openssh.authorizedKeys.keys;
};
root.openssh.authorizedKeys.keys =
config.users.users.${config.mainuser}.openssh.authorizedKeys.keys;
};
# Passwordless sudo for deploy user
security.sudo = {
extraRules = [{
users = [ "deploy" ];
commands = [{
command = "ALL";
options = [ "NOPASSWD" ];
}];
}];
extraConfig = ''
Defaults lecture = never
'';
};
# Podman
virtualisation = {
oci-containers.backend = lib.mkForce "podman";
podman.enable = true;
podman.dockerSocket.enable = true;
containers.registries.search = [
"docker.io" "ghcr.io" "quay.io"
];
containers.storage.settings = {
storage = {
driver = "overlay";
graphroot = "/var/lib/podman/storage";
runroot = "/run/containers/storage";
};
};
};
networking.firewall.trustedInterfaces = [ "podman*" "vnet*" "virbr*" ];
networking.firewall.interfaces."podman0".allowedUDPPorts = [ 53 5353 ];
security.unprivilegedUsernsClone = true;
nixpkgs.overlays = [ inputs.ataraxiasjel-nur.overlays.default ];
system.stateVersion = "24.11";
nixpkgs.hostPlatform = lib.mkForce "x86_64-linux";
}

@ -1,100 +0,0 @@
{ lib, ... }: {
disko.devices.disk.disk1 = {
device = lib.mkDefault "/dev/sda";
type = "disk";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "1M";
type = "EF02";
};
esp = {
name = "ESP";
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
swap = {
name = "swap";
size = "1G";
content = {
type = "swap";
randomEncryption = true;
};
};
root = {
name = "root";
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
postCreateHook = ''
mount -t btrfs /dev/sda4 /mnt
btrfs subvolume snapshot -r /mnt/rootfs /mnt/snapshots/rootfs-blank
btrfs subvolume snapshot -r /mnt/persistent/home /mnt/snapshots/home-blank
btrfs subvolume snapshot -r /mnt/persistent/docker /mnt/snapshots/docker-blank
btrfs subvolume snapshot -r /mnt/persistent/podman /mnt/snapshots/podman-blank
btrfs subvolume snapshot -r /mnt/persistent/containers /mnt/snapshots/containers-blank
btrfs subvolume snapshot -r /mnt/persistent/libvirt /mnt/snapshots/libvirt-blank
btrfs subvolume snapshot -r /mnt/persistent/log /mnt/snapshots/log-blank
btrfs subvolume snapshot -r /mnt/persistent/impermanence /mnt/snapshots/impermanence-blank
btrfs subvolume snapshot -r /mnt/persistent/srv /mnt/snapshots/srv-blank
umount /mnt
'';
subvolumes = {
"/snapshots" = { };
"/rootfs" = {
mountpoint = "/";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent" = { };
"/persistent/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/home" = {
mountpoint = "/home";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/srv" = {
mountpoint = "/srv";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/docker" = {
mountpoint = "/var/lib/docker";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/podman" = {
mountpoint = "/var/lib/podman";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/containers" = {
mountpoint = "/var/lib/containers";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/libvirt" = {
mountpoint = "/var/lib/libvirt";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/log" = {
mountpoint = "/var/log";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/impermanence" = {
mountpoint = "/persist";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
};
};
};
};
};
};
}

@ -1,97 +0,0 @@
rec {
privateIPv6Prefix = "fd3a:900e:8e74:ffff";
domain = "wg.ataraxiadev.com";
hasIPv6 = false;
interfaces = {
# This is the public-facing interface. Any interface name with a prime
# symbol means it's a public-facing interface.
main' = {
mac = "bc:24:11:6b:56:8a";
bridgeName = "br0";
ifname = "enp0s18";
IPv4 = {
address = "104.164.54.197/24";
gateway = "104.164.54.1";
dns = [ "9.9.9.9" "149.112.112.112" ];
};
IPv6 = {
address = "";
gateway = "";
dns = [ ];
};
};
wireguard0 = {
ifname = "wg0";
dns = [ "${privateIPv6Prefix}::0:53" ];
IPv4 = {
address = "10.100.0.1";
subnet = "10.100.0.0/16";
};
IPv6 = {
address = "${privateIPv6Prefix}::1";
subnet = "${privateIPv6Prefix}::0/64";
};
};
};
# Wireguard-related things.
wireguardPort = 40820;
wireguardIPv4Prefix = "10.100.0";
wireguardIPv6Prefix = "${privateIPv6Prefix}::0";
wireguardPeers = {
server = with interfaces.wireguard0; {
IPv4 = IPv4.address;
IPv6 = IPv6.address;
};
ataraxia = {
IPv4 = "${wireguardIPv4Prefix}.2";
IPv6 = "${wireguardIPv6Prefix}:2";
};
hypervisor = {
IPv4 = "${wireguardIPv4Prefix}.3";
IPv6 = "${wireguardIPv6Prefix}:3";
};
mikrotik = {
IPv4 = "${wireguardIPv4Prefix}.4";
IPv6 = "${wireguardIPv6Prefix}:4";
};
poco = {
IPv4 = "${wireguardIPv4Prefix}.5";
IPv6 = "${wireguardIPv6Prefix}:5";
};
kpoxa = {
IPv4 = "${wireguardIPv4Prefix}.6";
IPv6 = "${wireguardIPv6Prefix}:6";
};
kpoxa2 = {
IPv4 = "${wireguardIPv4Prefix}.7";
IPv6 = "${wireguardIPv6Prefix}:7";
};
faysss = {
IPv4 = "${wireguardIPv4Prefix}.8";
IPv6 = "${wireguardIPv6Prefix}:8";
};
faysss2 = {
IPv4 = "${wireguardIPv4Prefix}.9";
IPv6 = "${wireguardIPv6Prefix}:9";
};
faysss3 = {
IPv4 = "${wireguardIPv4Prefix}.10";
IPv6 = "${wireguardIPv6Prefix}:a";
};
doste = {
IPv4 = "${wireguardIPv4Prefix}.11";
IPv6 = "${wireguardIPv6Prefix}:b";
};
dell = {
IPv4 = "${wireguardIPv4Prefix}.12";
IPv6 = "${wireguardIPv6Prefix}:c";
};
hypervisor-dns = {
IPv4 = "${wireguardIPv4Prefix}.13";
IPv6 = "${wireguardIPv6Prefix}:d";
};
};
}

@ -1,73 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (import ./hardware/networks.nix) interfaces domain hasIPv6;
in {
services.resolved.enable = true;
networking = {
dhcpcd.enable = false;
domain = domain;
enableIPv6 = hasIPv6;
hostName = config.device;
nftables.enable = true;
useDHCP = false;
useNetworkd = lib.mkForce false;
usePredictableInterfaceNames = true;
firewall = {
enable = true;
allowedTCPPorts = lib.mkDefault [ ];
allowedUDPPorts = lib.mkDefault [ ];
};
nameservers = [ "1.1.1.1" "9.9.9.9" ];
};
systemd.network = with interfaces.main'; {
enable = lib.mkForce true;
wait-online.ignoredInterfaces = [ "lo" ];
networks = {
"40-${ifname}" = {
matchConfig.Name = ifname;
linkConfig.RequiredForOnline = "enslaved";
networkConfig.Bridge = bridgeName;
networkConfig.DHCP = "no";
};
"60-${bridgeName}" = {
matchConfig.Name = bridgeName;
address = [
IPv4.address
] ++ lib.optionals hasIPv6 [
IPv6.address
"fc00::1/64"
];
linkConfig.RequiredForOnline = "routable";
# networkConfig = {
# IPForward = true;
# DNS = IPv4.dns ++ lib.optionals hasIPv6 IPv6.dns;
# };
routes = [{
Gateway = IPv4.gateway;
GatewayOnLink = true;
}] ++ lib.optionals hasIPv6 [{
Gateway = IPv6.gateway;
GatewayOnLink = true;
}];
};
};
netdevs = {
"60-${bridgeName}" = {
netdevConfig = {
Kind = "bridge";
Name = bridgeName;
MACAddress = mac;
};
};
};
};
system.activationScripts.udp-gro-forwarding = {
text = with interfaces.main'; ''
${pkgs.ethtool}/bin/ethtool -K ${bridgeName} rx-udp-gro-forwarding on rx-gro-list off
'';
};
}

@ -1,65 +0,0 @@
{ config, lib, inputs, ... }: {
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
backups.postgresql.authentik.proxyAddress = lib.mkForce null;
sops.secrets.rustic-vps-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
sops.secrets.rustic-backups-s3-env.sopsFile = inputs.self.secretsDir + /rustic.yaml;
services.rustic.backups = rec {
vps-backup = {
backup = true;
prune = false;
initialize = false;
pruneOpts = [ "--repack-cacheable-only=false" ];
environmentFile = config.sops.secrets.rustic-backups-s3-env.path;
timerConfig = {
OnCalendar = "01:00";
Persistent = true;
};
settings = let
label = "vps-containers";
in {
repository = {
repository = "opendal:s3";
password-file = config.sops.secrets.rustic-vps-pass.path;
options = {
root = label;
bucket = "ataraxia-rustic-backups";
region = "eu-central-003";
endpoint = "https://s3.eu-central-003.backblazeb2.com";
};
};
repository.options = {
timeout = "5min";
retry = "10";
};
backup = {
host = config.device;
label = label;
ignore-devid = true;
group-by = "label";
skip-identical-parent = true;
snapshots = [{
sources = [ "/srv/marzban" ];
}];
};
forget = {
filter-labels = [ label ];
group-by = "label";
prune = true;
keep-daily = 4;
keep-weekly = 2;
keep-monthly = 1;
};
};
};
vps-prune = vps-backup // {
backup = false;
prune = true;
createWrapper = false;
timerConfig = {
OnCalendar = "Mon, 02:00";
Persistent = true;
};
};
};
}

@ -1,239 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (import ../hardware/networks.nix) interfaces;
wg = interfaces.wireguard0;
wgIfname = wg.ifname;
brIfname = interfaces.main'.bridgeName;
tailscaleIfname = config.services.tailscale.interfaceName;
in {
networking.extraHosts = ''
192.0.46.9 www.internic.net
'';
# For debugging purposes
environment.systemPackages = with pkgs; [ tcpdump dnsutils ];
services.resolved.extraConfig = ''
DNSStubListener=off
'';
systemd.network.networks."20-${brIfname}".networkConfig.DNS = lib.mkForce "127.0.0.1";
systemd.network.networks."90-${wgIfname}".networkConfig.DNS = lib.mkForce "127.0.0.1";
networking.firewall.interfaces = let
ports = {
allowedTCPPorts = [
config.services.blocky.settings.ports.dns
# config.services.grafana.settings.server.http_port
];
allowedUDPPorts = [
config.services.blocky.settings.ports.dns
];
};
in {
${wgIfname} = ports;
${tailscaleIfname} = ports;
};
# TODO: DoH (https://unbound.docs.nlnetlabs.nl/en/latest/topics/privacy/dns-over-https.html)
services.unbound = {
enable = true;
package = pkgs.unbound-full;
settings = {
server = {
root-hints = "${config.services.unbound.stateDir}/root.hints";
port = "553";
interface = [
"127.0.0.1"
"::1"
];
access-control = [
"0.0.0.0/0 refuse"
"127.0.0.0/8 allow"
"::0/0 refuse"
"::1 allow"
];
private-address = [
"127.0.0.0/8"
"::1"
];
hide-version = "yes";
aggressive-nsec = "yes";
cache-max-ttl = "86400";
cache-min-ttl = "600";
deny-any = "yes";
do-ip4 = "yes";
do-ip6 = "yes";
do-tcp = "yes";
do-udp = "yes";
harden-algo-downgrade = "yes";
harden-dnssec-stripped = "yes";
harden-glue = "yes";
harden-large-queries = "yes";
harden-referral-path = "yes";
harden-short-bufsize = "yes";
hide-identity = "yes";
minimal-responses = "yes";
msg-cache-size = "128m";
neg-cache-size = "4m";
prefer-ip6 = "no";
prefetch = "yes";
prefetch-key = "yes";
qname-minimisation = "yes";
rrset-cache-size = "256m";
rrset-roundrobin = "yes";
serve-expired = "yes";
so-rcvbuf = "4m";
so-reuseport = "yes";
so-sndbuf = "4m";
unwanted-reply-threshold = "100000";
use-caps-for-id = "yes";
};
cachedb = {
backend = "redis";
redis-server-host = "127.0.0.1";
redis-server-port = toString config.services.redis.servers.unbound.port;
redis-timeout = "300";
redis-expire-records = "no";
};
};
};
services.redis.vmOverCommit = true;
services.redis.servers.unbound = {
enable = true;
port = 7379;
databases = 1;
save = [ [ 3600 1 ] [ 1800 10 ] [ 600 100 ] ];
settings = {
maxmemory = "16mb";
protected-mode = true;
rdbchecksum = false;
stop-writes-on-bgsave-error = false;
tcp-keepalive = 300;
timeout = 0;
};
};
# TODO: maybe set internic ip address to hosts?
systemd.services.root-hints = {
script = ''
${pkgs.wget}/bin/wget -O ${config.services.unbound.stateDir}/root.hints https://www.internic.net/domain/named.root
'';
serviceConfig.Type = "oneshot";
startAt = "weekly";
};
# systemd.services.unbound = {
# after = [ "root-hints.service" ];
# };
# Blocky + prometheus + grafana
services.blocky = {
enable = true;
settings = {
upstream.default = [ "127.0.0.1:553" "[::1]:553" ];
upstreamTimeout = "10s";
bootstrapDns = [{
upstream = "https://dns.quad9.net/dns-query";
ips = [ "9.9.9.9" "149.112.112.112" ];
}];
blocking = {
blackLists = {
ads = [
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
"https://github.com/RPiList/specials/raw/master/Blocklisten/malware"
];
telemetry = [
"https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt"
"https://github.com/RPiList/specials/raw/master/Blocklisten/MS-Office-Telemetry"
"https://github.com/RPiList/specials/raw/master/Blocklisten/Win10Telemetry"
../../../misc/telemetry.hosts
];
};
clientGroupsBlock.default = [ "ads" "telemetry" ];
};
# disable caching (use unbound)
caching = {
minTime = -1;
maxTime = -1;
cacheTimeNegative = -1;
prefetching = false;
};
ports = {
dns = 53;
http = "127.0.0.1:4000";
};
prometheus.enable = true;
queryLog = {
type = "console";
};
};
};
# services.prometheus = {
# enable = true;
# listenAddress = "127.0.0.1";
# globalConfig.scrape_interval = "15s";
# globalConfig.evaluation_interval = "15s";
# scrapeConfigs = [{
# job_name = "blocky";
# static_configs = [{
# targets = [ config.services.blocky.settings.ports.http ];
# }];
# }];
# };
# services.grafana = {
# enable = true;
# settings = {
# analytics.reporting_enabled = false;
# server = {
# enable_gzip = true;
# domain = "localhost";
# http_addr = "0.0.0.0";
# http_port = 3000;
# };
# # Grafana can be accessed only through wireguard, so it's secure enough
# security = {
# admin_user = "admin";
# admin_password = "admin";
# };
# panels.disable_sanitize_html = true;
# };
# provision = {
# enable = true;
# datasources.settings = {
# datasources = [{
# name = "Prometheus";
# type = "prometheus";
# access = "proxy";
# orgId = 1;
# uid = "Y4SSG429DWCGDQ3R";
# url = "http://127.0.0.1:${toString config.services.prometheus.port}";
# isDefault = true;
# jsonData = {
# graphiteVersion = "1.1";
# tlsAuth = false;
# tlsAuthWithCACert = false;
# };
# version = 1;
# editable = true;
# }];
# };
# dashboards = {
# settings = {
# providers = [{
# name = "My Dashboards";
# options.path = "/etc/grafana-dashboards";
# }];
# };
# };
# };
# };
# environment.etc = {
# "grafana-dashboards/blocky_rev3.json" = {
# source = ../../../misc/grafana_blocky_rev3.json;
# group = "grafana";
# user = "grafana";
# };
# };
persist.state.directories = [
"/var/lib/grafana"
"/var/lib/prometheus2"
"/var/lib/redis-unbound"
"/var/lib/unbound"
];
}

@ -1,38 +0,0 @@
{ config, inputs, ... }:
let
bridgeName = (import ../hardware/networks.nix).interfaces.main'.bridgeName;
tailscalePort = config.services.tailscale.port;
tailscaleIfname = config.services.tailscale.interfaceName;
ssPort1 = 2234;
ssPort2 = 2235;
in {
imports = [ inputs.ataraxiasjel-nur.nixosModules.rinetd ];
networking.firewall.trustedInterfaces = [ tailscaleIfname ];
networking.firewall.interfaces.${bridgeName} = {
allowedUDPPorts = [ tailscalePort ];
allowedTCPPorts = [ ssPort1 ssPort2 ];
};
systemd.network.networks."50-tailscale" = {
matchConfig.Name = tailscaleIfname;
linkConfig.Unmanaged = true;
linkConfig.ActivationPolicy = "manual";
};
services.tailscale = {
enable = true;
port = 18491;
useRoutingFeatures = "both";
};
persist.state.directories = [ "/var/lib/tailscale" ];
services.rinetd = {
enable = true;
settings = ''
0.0.0.0 ${toString ssPort1} 100.64.0.1 ${toString ssPort1}
0.0.0.0 ${toString ssPort2} 100.64.0.2 ${toString ssPort2}
'';
};
}

@ -1,112 +0,0 @@
{ config, pkgs, inputs, modulesPath, ... }:
let
inherit (pkgs.hostPlatform) system;
cert-key = config.sops.secrets."cert.key".path;
cert-pem = config.sops.secrets."cert.pem".path;
nginx-conf = config.sops.secrets."nginx.conf".path;
marzban-env = config.sops.secrets.marzban.path;
fqdn = "wg.ataraxiadev.com";
in {
# disabledModules = [ "${modulesPath}/services/web-apps/ocis.nix" ];
# imports = [ inputs.ataraxiasjel-nur.nixosModules.ocis ];
networking.firewall.allowedTCPPorts = [ 80 443 ];
sops.secrets = let
nginx = {
sopsFile = inputs.self.secretsDir + /nixos-vps/nginx.yaml;
restartUnits = [ "podman-nginx.service" ];
};
marzban = {
format = "dotenv";
sopsFile = inputs.self.secretsDir + /nixos-vps/marzban.env;
restartUnits = [ "podman-marzban.service" ];
};
cf-dns-api = {
sopsFile = inputs.self.secretsDir + /misc.yaml;
owner = "acme";
};
in {
"cert.key" = nginx;
"cert.pem" = nginx;
"nginx.conf" = nginx;
inherit cf-dns-api marzban;
};
virtualisation.oci-containers.containers = {
marzban = {
autoStart = true;
# Tags: v0.8.4
image = "ghcr.io/gozargah/marzban@sha256:8e422c21997e5d2e3fa231eeff73c0a19193c20fc02fa4958e9368abb9623b8d";
environmentFiles = [ marzban-env ];
extraOptions = [ "--network=host" ];
volumes = [
"/srv/marzban:/var/lib/marzban"
];
};
nginx = {
autoStart = true;
# Tags: mainline-alpine3.21, mainline-alpine, alpine3.21
image = "docker.io/nginx@sha256:e4efffc3236305ae53fb54e5cd76c9ccac0cebf7a23d436a8f91bce6402c2665";
extraOptions = [ "--network=host" ];
volumes = [
"${cert-key}:/etc/ssl/certs/cf-cert.key:ro"
"${cert-pem}:/etc/ssl/certs/cf-cert.pem:ro"
"${config.security.acme.certs.${fqdn}.directory}/fullchain.pem:/etc/ssl/certs/cert.pem:ro"
"${config.security.acme.certs.${fqdn}.directory}/key.pem:/etc/ssl/certs/cert.key:ro"
"${nginx-conf}:/etc/nginx/nginx.conf:ro"
];
};
};
# services.ocis = {
# enable = true;
# package = inputs.ataraxiasjel-nur.packages.${system}.ocis-bin;
# configDir = "/srv/ocis/config";
# baseDataPath = "/srv/ocis/data";
# environment = {
# OCIS_INSECURE = "false";
# OCIS_URL = "https://cloud.ataraxiadev.com";
# PROXY_HTTP_ADDR = "127.0.0.1:9200";
# PROXY_TLS = "false";
# };
# };
systemd.tmpfiles.rules = [
"d /srv/marzban 0755 root root -"
];
# OpenConnect
security.acme = {
acceptTerms = true;
defaults.server = "https://acme-v02.api.letsencrypt.org/directory";
defaults.email = "admin@ataraxiadev.com";
defaults.renewInterval = "weekly";
certs = {
${fqdn} = {
extraDomainNames = [
"auth.ataraxiadev.com"
"doh.ataraxiadev.com"
"video.ataraxiadev.com"
];
dnsResolver = "1.1.1.1:53";
dnsProvider = "cloudflare";
credentialFiles."CF_DNS_API_TOKEN_FILE" = config.sops.secrets.cf-dns-api.path;
reloadServices = [ "podman-nginx.service" ];
};
};
};
persist.state.directories = [ "/var/lib/acme" ];
environment.systemPackages = [ pkgs.ocserv ];
# networking.nat = let
# inherit (import ../hardware/networks.nix) interfaces;
# in {
# enable = true;
# externalInterface = interfaces.main'.ifname;
# internalInterfaces = [ "vpns0" ];
# };
# networking.firewall.trustedInterfaces = [ "vpns0" ];
# networking.firewall.extraCommands = ''
# ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o enp0s18 -j SNAT --to-source 45.135.180.193
# '';
}

@ -1 +0,0 @@
x86_64-linux

@ -1,281 +0,0 @@
{ modulesPath, self, inputs, lib, pkgs, config, ... }: {
disabledModules = [ "${self}/modules/pass-store.nix" ];
imports = with inputs.self; [
(modulesPath + "/profiles/qemu-guest.nix")
(modulesPath + "/profiles/minimal.nix")
inputs.disko.nixosModules.disko
./disk-config.nix
./network.nix
customModules.devices
customModules.libvirt-guests
customModules.persist
customModules.users
# customProfiles.hardened
customProfiles.nix
./services/backups.nix
./services/dns.nix
./services/tailscale.nix
# ./services/tor-bridge.nix
# ./services/wireguard.nix
./services/xtls.nix
customProfiles.authentik
customProfiles.hoyolab
(import customProfiles.headscale {
inherit (import ./dns-mapping.nix) headscale-list;
})
];
boot.kernelPackages = pkgs.linuxPackages_latest;
services.qemuGuest.enable = lib.mkForce true;
# Impermanence
boot.initrd = {
# hardware
availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
# reset rootfs on reboot
postDeviceCommands = pkgs.lib.mkBefore ''
mkdir -p /mnt
mount -o subvol=/ /dev/vda4 /mnt
btrfs subvolume list -o /mnt/rootfs |
cut -f9 -d' ' |
while read subvolume; do
echo "deleting /$subvolume subvolume..."
btrfs subvolume delete "/mnt/$subvolume"
done &&
echo "deleting /root subvolume..."
btrfs subvolume delete /mnt/rootfs
echo "restoring blank /root subvolume..."
btrfs subvolume snapshot /mnt/snapshots/rootfs-blank /mnt/rootfs
umount /mnt
'';
};
fileSystems."/home".neededForBoot = true;
fileSystems."/persist".neededForBoot = true;
persist = {
enable = true;
cache.clean.enable = true;
state = {
files = [
"/etc/machine-id"
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
"/etc/ssh/ssh_host_rsa_key"
"/etc/ssh/ssh_host_rsa_key.pub"
];
directories = [
"/var/lib/nixos"
"/var/lib/systemd"
"/var/lib/postgresql"
];
};
};
# TODO: write all needed modules in boot.kernelModules
security.lockKernelModules = lib.mkForce false;
# Misc
boot = {
supportedFilesystems = [ "vfat" "btrfs" ];
kernelModules = [
"kvm-intel" "tcp_bbr" "veth"
# podman
"nft_chain_nat" "xt_addrtype" "xt_comment" "xt_mark" "xt_MASQUERADE"
];
kernelParams = [
"scsi_mod.use_blk_mq=1"
"kvm.ignore_msrs=1"
"kvm.report_ignored_msrs=0"
];
kernel.sysctl = {
"vm.swappiness" = 50;
"vm.vfs_cache_pressure" = 200;
"vm.dirty_background_ratio" = 1;
"vm.dirty_ratio" = 40;
"vm.page-cluster" = 0;
# proxy tuning
"net.ipv4.tcp_congestion_control" = "bbr";
"net.ipv4.tcp_slow_start_after_idle" = 0;
"net.core.default_qdisc" = "cake";
"net.core.rmem_max" = 67108864;
"net.core.wmem_max" = 67108864;
"net.core.netdev_max_backlog" = 10000;
"net.core.somaxconn" = 4096;
"net.ipv4.tcp_syncookies" = 1;
"net.ipv4.tcp_tw_reuse" = 1;
"net.ipv4.tcp_fin_timeout" = 30;
"net.ipv4.tcp_keepalive_time" = 1200;
"net.ipv4.tcp_keepalive_probes" = 5;
"net.ipv4.tcp_keepalive_intvl" = 30;
"net.ipv4.tcp_max_syn_backlog" = 8192;
"net.ipv4.tcp_max_tw_buckets" = 5000;
"net.ipv4.tcp_fastopen" = 3;
"net.ipv4.tcp_mem" = "25600 51200 102400";
"net.ipv4.udp_mem" = "25600 51200 102400";
"net.ipv4.tcp_rmem" = "4096 87380 67108864";
"net.ipv4.tcp_wmem" = "4096 65536 67108864";
"net.ipv4.tcp_mtu_probing" = 1;
};
loader.grub = {
enable = true;
efiSupport = true;
efiInstallAsRemovable = true;
};
};
zramSwap = {
enable = true;
algorithm = "zstd";
memoryPercent = 100;
};
environment.memoryAllocator.provider = lib.mkForce "libc";
deviceSpecific.isServer = true;
services.journald.extraConfig = "Compress=false";
nix.optimise.automatic = false;
nix.distributedBuilds = lib.mkForce false;
fonts.enableDefaultPackages = lib.mkForce false;
security.polkit.enable = true;
# security.pam.enableSSHAgentAuth = true;
environment.systemPackages = with pkgs; [
bat
bottom
comma
git
kitty
micro
pwgen
inputs.nix-alien.packages.${pkgs.hostPlatform.system}.nix-index-update
rsync
];
# Locale
i18n.defaultLocale = "en_IE.UTF-8";
i18n.extraLocaleSettings = {
LANGUAGE = "en_IE:en_US:en:C:ru_RU";
LC_TIME = "en_DK.UTF-8";
LC_ADDRESS = "ru_RU.UTF-8";
LC_MONETARY = "ru_RU.UTF-8";
LC_NUMERIC = "ru_RU.UTF-8";
LC_PAPER = "ru_RU.UTF-8";
LC_TELEPHONE = "ru_RU.UTF-8";
};
i18n.supportedLocales = [
"C.UTF-8/UTF-8"
"en_DK.UTF-8/UTF-8"
"en_GB.UTF-8/UTF-8"
"en_IE.UTF-8/UTF-8"
"en_US.UTF-8/UTF-8"
"ru_RU.UTF-8/UTF-8"
];
time.timeZone = "Etc/UTC";
environment.sessionVariables = {
XKB_DEFAULT_LAYOUT = "us,ru";
XKB_DEFAULT_OPTIONS = "grp:win_space_toggle";
};
# Hardened
networking.firewall = {
enable = true;
allowPing = false;
allowedTCPPorts = lib.mkDefault [ ];
allowedUDPPorts = lib.mkDefault [ ];
};
systemd.coredump.enable = false;
# Users
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
settings.PermitRootLogin = lib.mkForce "prohibit-password";
settings.X11Forwarding = false;
extraConfig = "StreamLocalBindUnlink yes";
ports = [ 22 ];
};
users.mutableUsers = false;
users.users = {
${config.mainuser} = {
isNormalUser = true;
extraGroups = [ "disk" "systemd-journal" "wheel" "qemu-libvirtd" "libvirtd" ];
uid = 1000;
hashedPassword =
"$y$j9T$ZC44T3XYOPapB26cyPsA4.$8wlYEbwXFszC9nrg0vafqBZFLMPabXdhnzlT3DhUit6";
shell = pkgs.bash;
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+xd8ClJPvJuAdYC9HlNnjiubEtYfvnKjYr9ROV+UmPVvI3ZITF24OaMI+fxgR0EqGfcUzSGom8528IB53Q3aFMIAaA0vKjW+jrByyB2l/k/+ttpLbH75c9WyOpAcUDTen8BhHKPyXOHoJ1jLu7GFmtPZ+mZo8thFB/VIRrwECHd8DnF0drsSCorkRp1bZC7bAHgztaYHNBUoAVGgJ7nLwW7DotlgbUEDiPJHXOxd/c/ZlXIB/cfUUqF+L5ThbMPhMcwRMspLy+nQdmHhih9k6SkvYqJoNqHT5/XeShb0RkIzvUWT2CYTPop5kAY5mMnatVTOY1FZPhHzk3G8MhOQ3r/elM/ecZxmjL8uozMN9kRGf1IL4DgQZfVqQRILdNSQGb0tfeiyirNZe1RlDw9UvMnZJOw0EkiC9lSSRhBWXXxAmxRrbNFTPQSp+/kiIGDmp2AsGhD11CfTDEU3wcLEUPBUqp1FYSzHncJyEKGy2Dpa5xaUJ0cuyGL4W3WHDXa4sTfY+AIXbQTD88Ujdsbfzyd6lrikG4D/crCurXissrh7q9DuYKWRI24cp5bw9lG33U1EXisnZqFyZNwMAmSj2QEGsHCwSevn0FgyRa2WYXgpZ9hfgY4le+ZSMo2JTosQ6DjGyxMDyQAHJ/ismTTzL67Q2p6U+73toYm62Qqdspw== (none)"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDP0/DReYSAfkucroMTdELzTORsGhhbEa+W0FDFBnwViHuoqoKvetCOkW657icexc5v/j6Ghy3+Li9twbHnEDzUJVtNtauhGMjOcUYt6pTbeJ09CGSAh+orxzeY4vXp7ANb91xW8yRn/EE4ALxqbLsc/D7TUMl11fmf0UW+kLgU5TcUYVSLMjQqBpD1Lo7lXLrImloDxe5fwoBDT09E59r9tq6+/3aHz8mpKRLsIQIV0Av00BRJ+/OVmZuBd9WS35rfkpUYmpEVInSJy3G4O6kCvY/zc9Bnh67l4kALZZ0+6W23kBGrzaRfaOtCEcscwfIu+6GXiHOL33rrMNNinF0T2942jGc18feL6P/LZCzqz8bGdFNxT43jAGPeDDcrJEWAJZFO3vVTP65dTRTHQG2KlQMzS7tcif6YUlY2JLJIb61ZfLoShH/ini/tqsGT0Be1f3ndOFt48h4XMW1oIF+EXaHYeO2UJ6855m8Wpxs4bP/jX6vMV38IvvnHy4tWD50= alukard@AMD-Workstation"
];
};
deploy = {
description = "The administrator account for the servers.";
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys =
config.users.users.${config.mainuser}.openssh.authorizedKeys.keys;
};
root.openssh.authorizedKeys.keys =
config.users.users.${config.mainuser}.openssh.authorizedKeys.keys;
};
# Passwordless sudo for deploy user
security.sudo = {
extraRules = [{
users = [ "deploy" ];
commands = [{
command = "ALL";
options = [ "NOPASSWD" ];
}];
}];
extraConfig = ''
Defaults lecture = never
'';
};
# Podman
virtualisation = {
oci-containers.backend = lib.mkForce "podman";
podman.enable = true;
podman.dockerSocket.enable = true;
containers.registries.search = [
"docker.io" "ghcr.io" "quay.io"
];
containers.storage.settings = {
storage = {
driver = "overlay";
graphroot = "/var/lib/podman/storage";
runroot = "/run/containers/storage";
};
};
libvirtd = {
enable = true;
qemu = {
ovmf.enable = true;
ovmf.packages = [ pkgs.OVMFFull.fd ];
runAsRoot = false;
};
onBoot = "ignore";
onShutdown = "shutdown";
};
};
programs.virt-manager.enable = true;
networking.firewall.trustedInterfaces = [ "podman*" "vnet*" "virbr*" ];
networking.firewall.interfaces."podman0".allowedUDPPorts = [ 53 5353 ];
security.unprivilegedUsernsClone = true;
nixpkgs.overlays = let
unstable = import self.unstable-nixpkgs {
config = config.nixpkgs.config;
localSystem = { system = pkgs.hostPlatform.system; };
};
in [
inputs.ataraxiasjel-nur.overlays.default
(final: prev: {
authentik = unstable.authentik;
authentik-outposts = unstable.authentik-outposts;
})
];
system.stateVersion = "24.11";
nixpkgs.hostPlatform = lib.mkForce "x86_64-linux";
}

@ -1,100 +0,0 @@
{ lib, ... }: {
disko.devices.disk.disk1 = {
device = lib.mkDefault "/dev/vda";
type = "disk";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "1M";
type = "EF02";
};
esp = {
name = "ESP";
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
swap = {
name = "swap";
size = "2G";
content = {
type = "swap";
randomEncryption = true;
};
};
root = {
name = "root";
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
postCreateHook = ''
mount -t btrfs /dev/vda4 /mnt
btrfs subvolume snapshot -r /mnt/rootfs /mnt/snapshots/rootfs-blank
btrfs subvolume snapshot -r /mnt/persistent/home /mnt/snapshots/home-blank
btrfs subvolume snapshot -r /mnt/persistent/docker /mnt/snapshots/docker-blank
btrfs subvolume snapshot -r /mnt/persistent/podman /mnt/snapshots/podman-blank
btrfs subvolume snapshot -r /mnt/persistent/containers /mnt/snapshots/containers-blank
btrfs subvolume snapshot -r /mnt/persistent/libvirt /mnt/snapshots/libvirt-blank
btrfs subvolume snapshot -r /mnt/persistent/log /mnt/snapshots/log-blank
btrfs subvolume snapshot -r /mnt/persistent/impermanence /mnt/snapshots/impermanence-blank
btrfs subvolume snapshot -r /mnt/persistent/srv /mnt/snapshots/srv-blank
umount /mnt
'';
subvolumes = {
"/snapshots" = { };
"/rootfs" = {
mountpoint = "/";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent" = { };
"/persistent/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/home" = {
mountpoint = "/home";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/srv" = {
mountpoint = "/srv";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/docker" = {
mountpoint = "/var/lib/docker";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/podman" = {
mountpoint = "/var/lib/podman";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/containers" = {
mountpoint = "/var/lib/containers";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/libvirt" = {
mountpoint = "/var/lib/libvirt";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/log" = {
mountpoint = "/var/log";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
"/persistent/impermanence" = {
mountpoint = "/persist";
mountOptions = [ "compress=zstd" "noatime" "autodefrag" "ssd" ];
};
};
};
};
};
};
};
}

@ -1,101 +0,0 @@
{
headscale-list = [
{ name = "ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "api.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
# { name = "auth.ataraxiadev.com"; type = "A"; value = "100.64.0.1"; }
{ name = "cache.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "cal.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "code.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "docs.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "element.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "file.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "home.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "jackett.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "jellyfin.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "joplin.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "kavita.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "ldap.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "lib.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "matrix.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "medusa.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "net.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "openbooks.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "pdf.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "qbit.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "radarr.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "restic.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "s3.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "sonarr.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "stats.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "tools.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "turn.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "vault.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "vw.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "wiki.ataraxiadev.com"; type = "A"; value = "100.64.0.3"; }
{ name = "ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "api.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
# { name = "auth.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::1"; }
{ name = "cache.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "cal.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "code.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "docs.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "element.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "file.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "home.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "jackett.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "jellyfin.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "joplin.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "kavita.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "ldap.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "lib.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "matrix.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "medusa.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "net.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "openbooks.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "pdf.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "qbit.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "radarr.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "restic.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "s3.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "sonarr.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "stats.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "tools.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "turn.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "vault.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "vw.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
{ name = "wiki.ataraxiadev.com"; type = "AAAA"; value = "fd7a:115c:a1e0::3"; }
];
dnsmasq-list = [
"/api.ataraxiadev.com/10.10.10.10"
"/cache.ataraxiadev.com/10.10.10.10"
"/cal.ataraxiadev.com/10.10.10.10"
"/code.ataraxiadev.com/10.10.10.10"
"/docs.ataraxiadev.com/10.10.10.10"
"/element.ataraxiadev.com/10.10.10.10"
"/file.ataraxiadev.com/10.10.10.10"
"/home.ataraxiadev.com/10.10.10.10"
"/jackett.ataraxiadev.com/10.10.10.10"
"/jellyfin.ataraxiadev.com/10.10.10.10"
"/joplin.ataraxiadev.com/10.10.10.10"
"/kavita.ataraxiadev.com/10.10.10.10"
"/ldap.ataraxiadev.com/10.10.10.10"
"/lib.ataraxiadev.com/10.10.10.10"
"/matrix.ataraxiadev.com/10.10.10.10"
"/medusa.ataraxiadev.com/10.10.10.10"
"/net.ataraxiadev.com/10.10.10.10"
"/openbooks.ataraxiadev.com/10.10.10.10"
"/pdf.ataraxiadev.com/10.10.10.10"
"/qbit.ataraxiadev.com/10.10.10.10"
"/radarr.ataraxiadev.com/10.10.10.10"
"/restic.ataraxiadev.com/10.10.10.10"
"/s3.ataraxiadev.com/10.10.10.10"
"/sonarr.ataraxiadev.com/10.10.10.10"
"/stats.ataraxiadev.com/10.10.10.10"
"/tools.ataraxiadev.com/10.10.10.10"
"/turn.ataraxiadev.com/10.10.10.10"
"/vault.ataraxiadev.com/10.10.10.10"
"/vw.ataraxiadev.com/10.10.10.10"
"/wiki.ataraxiadev.com/10.10.10.10"
];
}

@ -1,97 +0,0 @@
rec {
privateIPv6Prefix = "fd3a:900e:8e74:ffff";
domain = "wg.ataraxiadev.com";
hasIPv6 = false;
interfaces = {
# This is the public-facing interface. Any interface name with a prime
# symbol means it's a public-facing interface.
main' = {
mac = "00:16:3e:e3:cd:40";
bridgeName = "br0";
ifname = "enp0s3";
IPv4 = {
address = "45.134.48.174/32";
gateway = "45.134.48.1";
dns = [ "9.9.9.9" "149.112.112.112" ];
};
IPv6 = {
address = "";
gateway = "";
dns = [ ];
};
};
wireguard0 = {
ifname = "wg0";
dns = [ "${privateIPv6Prefix}::0:53" ];
IPv4 = {
address = "10.100.0.1";
subnet = "10.100.0.0/16";
};
IPv6 = {
address = "${privateIPv6Prefix}::1";
subnet = "${privateIPv6Prefix}::0/64";
};
};
};
# Wireguard-related things.
wireguardPort = 40820;
wireguardIPv4Prefix = "10.100.0";
wireguardIPv6Prefix = "${privateIPv6Prefix}::0";
wireguardPeers = {
server = with interfaces.wireguard0; {
IPv4 = IPv4.address;
IPv6 = IPv6.address;
};
ataraxia = {
IPv4 = "${wireguardIPv4Prefix}.2";
IPv6 = "${wireguardIPv6Prefix}:2";
};
hypervisor = {
IPv4 = "${wireguardIPv4Prefix}.3";
IPv6 = "${wireguardIPv6Prefix}:3";
};
mikrotik = {
IPv4 = "${wireguardIPv4Prefix}.4";
IPv6 = "${wireguardIPv6Prefix}:4";
};
poco = {
IPv4 = "${wireguardIPv4Prefix}.5";
IPv6 = "${wireguardIPv6Prefix}:5";
};
kpoxa = {
IPv4 = "${wireguardIPv4Prefix}.6";
IPv6 = "${wireguardIPv6Prefix}:6";
};
kpoxa2 = {
IPv4 = "${wireguardIPv4Prefix}.7";
IPv6 = "${wireguardIPv6Prefix}:7";
};
faysss = {
IPv4 = "${wireguardIPv4Prefix}.8";
IPv6 = "${wireguardIPv6Prefix}:8";
};
faysss2 = {
IPv4 = "${wireguardIPv4Prefix}.9";
IPv6 = "${wireguardIPv6Prefix}:9";
};
faysss3 = {
IPv4 = "${wireguardIPv4Prefix}.10";
IPv6 = "${wireguardIPv6Prefix}:a";
};
doste = {
IPv4 = "${wireguardIPv4Prefix}.11";
IPv6 = "${wireguardIPv6Prefix}:b";
};
dell = {
IPv4 = "${wireguardIPv4Prefix}.12";
IPv6 = "${wireguardIPv6Prefix}:c";
};
hypervisor-dns = {
IPv4 = "${wireguardIPv4Prefix}.13";
IPv6 = "${wireguardIPv6Prefix}:d";
};
};
}

@ -1,73 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (import ./hardware/networks.nix) interfaces domain hasIPv6;
in {
services.resolved.enable = true;
networking = {
dhcpcd.enable = false;
domain = domain;
enableIPv6 = hasIPv6;
hostName = config.device;
nftables.enable = true;
useDHCP = false;
useNetworkd = lib.mkForce false;
usePredictableInterfaceNames = true;
firewall = {
enable = true;
allowedTCPPorts = lib.mkDefault [ ];
allowedUDPPorts = lib.mkDefault [ ];
};
nameservers = [ "1.1.1.1" "9.9.9.9" ];
};
systemd.network = with interfaces.main'; {
enable = lib.mkForce true;
wait-online.ignoredInterfaces = [ "lo" ];
networks = {
"40-${ifname}" = {
matchConfig.Name = ifname;
linkConfig.RequiredForOnline = "enslaved";
networkConfig.Bridge = bridgeName;
networkConfig.DHCP = "no";
};
"60-${bridgeName}" = {
matchConfig.Name = bridgeName;
address = [
IPv4.address
] ++ lib.optionals hasIPv6 [
IPv6.address
"fc00::1/64"
];
linkConfig.RequiredForOnline = "routable";
# networkConfig = {
# IPForward = true;
# DNS = IPv4.dns ++ lib.optionals hasIPv6 IPv6.dns;
# };
routes = [{
Gateway = IPv4.gateway;
GatewayOnLink = true;
}] ++ lib.optionals hasIPv6 [{
Gateway = IPv6.gateway;
GatewayOnLink = true;
}];
};
};
netdevs = {
"60-${bridgeName}" = {
netdevConfig = {
Kind = "bridge";
Name = bridgeName;
MACAddress = mac;
};
};
};
};
system.activationScripts.udp-gro-forwarding = {
text = with interfaces.main'; ''
${pkgs.ethtool}/bin/ethtool -K ${bridgeName} rx-udp-gro-forwarding on rx-gro-list off
'';
};
}

@ -1,65 +0,0 @@
{ config, lib, inputs, ... }: {
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
backups.postgresql.authentik.proxyAddress = lib.mkForce null;
sops.secrets.rustic-vps-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
sops.secrets.rustic-backups-s3-env.sopsFile = inputs.self.secretsDir + /rustic.yaml;
services.rustic.backups = rec {
vps-backup = {
backup = true;
prune = false;
initialize = false;
pruneOpts = [ "--repack-cacheable-only=false" ];
environmentFile = config.sops.secrets.rustic-backups-s3-env.path;
timerConfig = {
OnCalendar = "01:00";
Persistent = true;
};
settings = let
label = "vps-containers";
in {
repository = {
repository = "opendal:s3";
password-file = config.sops.secrets.rustic-vps-pass.path;
options = {
root = label;
bucket = "ataraxia-rustic-backups";
region = "eu-central-003";
endpoint = "https://s3.eu-central-003.backblazeb2.com";
};
};
repository.options = {
timeout = "5min";
retry = "10";
};
backup = {
host = config.device;
label = label;
ignore-devid = true;
group-by = "label";
skip-identical-parent = true;
snapshots = [{
sources = [ "/srv/marzban" ];
}];
};
forget = {
filter-labels = [ label ];
group-by = "label";
prune = true;
keep-daily = 4;
keep-weekly = 2;
keep-monthly = 1;
};
};
};
vps-prune = vps-backup // {
backup = false;
prune = true;
createWrapper = false;
timerConfig = {
OnCalendar = "Mon, 02:00";
Persistent = true;
};
};
};
}

@ -1,239 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (import ../hardware/networks.nix) interfaces;
wg = interfaces.wireguard0;
wgIfname = wg.ifname;
brIfname = interfaces.main'.bridgeName;
tailscaleIfname = config.services.tailscale.interfaceName;
in {
networking.extraHosts = ''
192.0.46.9 www.internic.net
'';
# For debugging purposes
environment.systemPackages = with pkgs; [ tcpdump dnsutils ];
services.resolved.extraConfig = ''
DNSStubListener=off
'';
systemd.network.networks."20-${brIfname}".networkConfig.DNS = lib.mkForce "127.0.0.1";
systemd.network.networks."90-${wgIfname}".networkConfig.DNS = lib.mkForce "127.0.0.1";
networking.firewall.interfaces = let
ports = {
allowedTCPPorts = [
config.services.blocky.settings.ports.dns
# config.services.grafana.settings.server.http_port
];
allowedUDPPorts = [
config.services.blocky.settings.ports.dns
];
};
in {
${wgIfname} = ports;
${tailscaleIfname} = ports;
};
# TODO: DoH (https://unbound.docs.nlnetlabs.nl/en/latest/topics/privacy/dns-over-https.html)
services.unbound = {
enable = true;
package = pkgs.unbound-full;
settings = {
server = {
root-hints = "${config.services.unbound.stateDir}/root.hints";
port = "553";
interface = [
"127.0.0.1"
"::1"
];
access-control = [
"0.0.0.0/0 refuse"
"127.0.0.0/8 allow"
"::0/0 refuse"
"::1 allow"
];
private-address = [
"127.0.0.0/8"
"::1"
];
hide-version = "yes";
aggressive-nsec = "yes";
cache-max-ttl = "86400";
cache-min-ttl = "600";
deny-any = "yes";
do-ip4 = "yes";
do-ip6 = "yes";
do-tcp = "yes";
do-udp = "yes";
harden-algo-downgrade = "yes";
harden-dnssec-stripped = "yes";
harden-glue = "yes";
harden-large-queries = "yes";
harden-referral-path = "yes";
harden-short-bufsize = "yes";
hide-identity = "yes";
minimal-responses = "yes";
msg-cache-size = "128m";
neg-cache-size = "4m";
prefer-ip6 = "no";
prefetch = "yes";
prefetch-key = "yes";
qname-minimisation = "yes";
rrset-cache-size = "256m";
rrset-roundrobin = "yes";
serve-expired = "yes";
so-rcvbuf = "4m";
so-reuseport = "yes";
so-sndbuf = "4m";
unwanted-reply-threshold = "100000";
use-caps-for-id = "yes";
};
cachedb = {
backend = "redis";
redis-server-host = "127.0.0.1";
redis-server-port = toString config.services.redis.servers.unbound.port;
redis-timeout = "300";
redis-expire-records = "no";
};
};
};
services.redis.vmOverCommit = true;
services.redis.servers.unbound = {
enable = true;
port = 7379;
databases = 1;
save = [ [ 3600 1 ] [ 1800 10 ] [ 600 100 ] ];
settings = {
maxmemory = "16mb";
protected-mode = true;
rdbchecksum = false;
stop-writes-on-bgsave-error = false;
tcp-keepalive = 300;
timeout = 0;
};
};
# TODO: maybe set internic ip address to hosts?
systemd.services.root-hints = {
script = ''
${pkgs.wget}/bin/wget -O ${config.services.unbound.stateDir}/root.hints https://www.internic.net/domain/named.root
'';
serviceConfig.Type = "oneshot";
startAt = "weekly";
};
# systemd.services.unbound = {
# after = [ "root-hints.service" ];
# };
# Blocky + prometheus + grafana
services.blocky = {
enable = true;
settings = {
upstream.default = [ "127.0.0.1:553" "[::1]:553" ];
upstreamTimeout = "10s";
bootstrapDns = [{
upstream = "https://dns.quad9.net/dns-query";
ips = [ "9.9.9.9" "149.112.112.112" ];
}];
blocking = {
blackLists = {
ads = [
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
"https://github.com/RPiList/specials/raw/master/Blocklisten/malware"
];
telemetry = [
"https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt"
"https://github.com/RPiList/specials/raw/master/Blocklisten/MS-Office-Telemetry"
"https://github.com/RPiList/specials/raw/master/Blocklisten/Win10Telemetry"
../../../misc/telemetry.hosts
];
};
clientGroupsBlock.default = [ "ads" "telemetry" ];
};
# disable caching (use unbound)
caching = {
minTime = -1;
maxTime = -1;
cacheTimeNegative = -1;
prefetching = false;
};
ports = {
dns = 53;
http = "127.0.0.1:4000";
};
prometheus.enable = true;
queryLog = {
type = "console";
};
};
};
# services.prometheus = {
# enable = true;
# listenAddress = "127.0.0.1";
# globalConfig.scrape_interval = "15s";
# globalConfig.evaluation_interval = "15s";
# scrapeConfigs = [{
# job_name = "blocky";
# static_configs = [{
# targets = [ config.services.blocky.settings.ports.http ];
# }];
# }];
# };
# services.grafana = {
# enable = true;
# settings = {
# analytics.reporting_enabled = false;
# server = {
# enable_gzip = true;
# domain = "localhost";
# http_addr = "0.0.0.0";
# http_port = 3000;
# };
# # Grafana can be accessed only through wireguard, so it's secure enough
# security = {
# admin_user = "admin";
# admin_password = "admin";
# };
# panels.disable_sanitize_html = true;
# };
# provision = {
# enable = true;
# datasources.settings = {
# datasources = [{
# name = "Prometheus";
# type = "prometheus";
# access = "proxy";
# orgId = 1;
# uid = "Y4SSG429DWCGDQ3R";
# url = "http://127.0.0.1:${toString config.services.prometheus.port}";
# isDefault = true;
# jsonData = {
# graphiteVersion = "1.1";
# tlsAuth = false;
# tlsAuthWithCACert = false;
# };
# version = 1;
# editable = true;
# }];
# };
# dashboards = {
# settings = {
# providers = [{
# name = "My Dashboards";
# options.path = "/etc/grafana-dashboards";
# }];
# };
# };
# };
# };
# environment.etc = {
# "grafana-dashboards/blocky_rev3.json" = {
# source = ../../../misc/grafana_blocky_rev3.json;
# group = "grafana";
# user = "grafana";
# };
# };
persist.state.directories = [
"/var/lib/grafana"
"/var/lib/prometheus2"
"/var/lib/redis-unbound"
"/var/lib/unbound"
];
}

@ -1,38 +0,0 @@
{ config, inputs, ... }:
let
bridgeName = (import ../hardware/networks.nix).interfaces.main'.bridgeName;
tailscalePort = config.services.tailscale.port;
tailscaleIfname = config.services.tailscale.interfaceName;
ssPort1 = 2234;
ssPort2 = 2235;
in {
imports = [ inputs.ataraxiasjel-nur.nixosModules.rinetd ];
networking.firewall.trustedInterfaces = [ tailscaleIfname ];
networking.firewall.interfaces.${bridgeName} = {
allowedUDPPorts = [ tailscalePort ];
allowedTCPPorts = [ ssPort1 ssPort2 ];
};
systemd.network.networks."50-tailscale" = {
matchConfig.Name = tailscaleIfname;
linkConfig.Unmanaged = true;
linkConfig.ActivationPolicy = "manual";
};
services.tailscale = {
enable = true;
port = 18491;
useRoutingFeatures = "both";
};
persist.state.directories = [ "/var/lib/tailscale" ];
services.rinetd = {
enable = true;
settings = ''
0.0.0.0 ${toString ssPort1} 100.64.0.2 ${toString ssPort1}
0.0.0.0 ${toString ssPort2} 100.64.0.3 ${toString ssPort2}
'';
};
}

@ -1,46 +0,0 @@
{ pkgs, ... }:
let
inherit (import ../hardware/networks.nix) interfaces;
bridgeName = interfaces.main'.bridgeName;
obfs4Port = 18371;
orPort = 17429;
in {
networking.firewall.interfaces.${bridgeName} = {
allowedTCPPorts = [ obfs4Port orPort ];
};
# We can get bridge cert from file: /var/lib/tor/pt_state/obfs4_bridgeline.txt
# Fingerprint can be obtained from tor.service logs
services.tor = {
enable = true;
enableGeoIP = true;
client.enable = false;
relay.enable = true;
relay.role = "private-bridge";
settings = {
BridgeDistribution = "none";
BridgeRelay = true;
ContactInfo = "admin@ataraxiadev.com";
ORPort = [ orPort ];
ServerTransportListenAddr = "obfs4 0.0.0.0:${toString obfs4Port}";
Nickname = "Ataraxia";
};
};
services.networkd-dispatcher = {
enable = true;
rules."restart-tor" = {
onState = [ "routable" "off" ];
script = ''
#!${pkgs.runtimeShell}
if [[ $IFACE == "${bridgeName}" && $AdministrativeState == "configured" ]]; then
echo "Restarting Tor ..."
systemctl restart tor
fi
exit 0
'';
};
};
persist.state.directories = [ "/var/lib/tor" ];
}

@ -1,132 +0,0 @@
{ lib, pkgs, ... }:
let
inherit (import ../hardware/networks.nix) interfaces wireguardPort wireguardPeers hasIPv6;
wireguardIFName = interfaces.wireguard0.ifname;
in {
# Sometimes we need to disable checksum validation
# ethtool -K br0 tx off rx off
# ethtool -K enp0s1 tx off rx off
environment.systemPackages = [ pkgs.wireguard-tools ];
networking.firewall = {
allowedUDPPorts = [ wireguardPort ];
checkReversePath = lib.mkForce false;
};
boot.kernelModules = [ "wireguard" ];
systemd.network = {
wait-online.ignoredInterfaces = [ wireguardIFName ];
networks."90-${wireguardIFName}" = with interfaces.wireguard0; {
matchConfig.Name = wireguardIFName;
address = [
"${IPv4.address}/16"
] ++ lib.optionals hasIPv6 [
"${IPv6.address}/64"
];
DHCP = "no";
networkConfig = {
IPForward = true;
IPMasquerade = "both";
DNS = interfaces.main'.IPv4.dns ++ lib.optionals hasIPv6 interfaces.main'.IPv6.dns;
};
};
netdevs."90-${wireguardIFName}" = {
netdevConfig = {
Name = wireguardIFName;
Kind = "wireguard";
};
wireguardConfig = {
PrivateKeyFile = "/srv/wireguard/private";
ListenPort = wireguardPort;
};
wireguardPeers = [
{
wireguardPeerConfig = with wireguardPeers.ataraxia; {
PublicKey = "qjkV4V0on7H3hXG7udKOv4Qu/IUBrsDcXNZt3MupP3o=";
PresharedKeyFile = "/srv/wireguard/ataraxia/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.hypervisor; {
PublicKey = "oKQ3HXZ1wwWyVgmA4RoCXscImohqB8hdMzP1FRArw0o=";
PresharedKeyFile = "/srv/wireguard/hypervisor/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.mikrotik; {
PublicKey = "amReLTZgu6pwtKCnk1q8EG5uZSgUNxRoh5m3w1D3rQo=";
PresharedKeyFile = "/srv/wireguard/mikrotik/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.poco; {
PublicKey = "ZbBJziuMjyHJNcgrLYIQtio7l3fEOJ4GXW4ST+N9V34=";
PresharedKeyFile = "/srv/wireguard/poco/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.kpoxa; {
PublicKey = "U1wtbS8/yQGkBnBQUZs7KxxmvAajKb9jh83dDd2LdgE=";
PresharedKeyFile = "/srv/wireguard/kpoxa/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.kpoxa2; {
PublicKey = "ghU3Puwz5PeXmnDlxyh+IeuwFK44V3rXlMiFGs5YnwI=";
PresharedKeyFile = "/srv/wireguard/kpoxa2/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.faysss; {
PublicKey = "JLvKyFwI7b9MsiZsnNAt3qs5ob18b3mrOZKR5HZCORY=";
PresharedKeyFile = "/srv/wireguard/faysss/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.faysss2; {
PublicKey = "S6k9l0K5/YmO5BPETQludC1CBHsKLsk9+n6kwSjx4n8=";
PresharedKeyFile = "/srv/wireguard/faysss2/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.faysss3; {
PublicKey = "ka42gE67gShu88Ko7iQ/pK8zusod6bNIrIN8fkxVkC4=";
PresharedKeyFile = "/srv/wireguard/faysss3/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.doste; {
PublicKey = "KVbEaO4DSpTb941zxOPQLWq2Glm9CDgK/9MwW95WuC0=";
PresharedKeyFile = "/srv/wireguard/doste/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.dell; {
PublicKey = "//ss9UEHRFEZL4LbZaA1HiRUrMrn97kc7CmblUORXTc=";
PresharedKeyFile = "/srv/wireguard/dell/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
{
wireguardPeerConfig = with wireguardPeers.hypervisor-dns; {
PublicKey = "x4uavQEEfhdqNC4FCOPfKlEDRJiwOz4dy2W1KhJtnwc=";
PresharedKeyFile = "/srv/wireguard/hypervisor-dns/preshared";
AllowedIPs = [ "${IPv4}/32" "${IPv6}/128" ];
};
}
];
};
};
}

@ -1,112 +0,0 @@
{ config, pkgs, inputs, modulesPath, ... }:
let
inherit (pkgs.hostPlatform) system;
cert-key = config.sops.secrets."cert.key".path;
cert-pem = config.sops.secrets."cert.pem".path;
nginx-conf = config.sops.secrets."nginx.conf".path;
marzban-env = config.sops.secrets.marzban.path;
fqdn = "wg.ataraxiadev.com";
in {
disabledModules = [ "${modulesPath}/services/web-apps/ocis.nix" ];
imports = [ inputs.ataraxiasjel-nur.nixosModules.ocis ];
networking.firewall.allowedTCPPorts = [ 80 443 ];
sops.secrets = let
nginx = {
sopsFile = inputs.self.secretsDir + /nixos-vps/nginx.yaml;
restartUnits = [ "podman-nginx.service" ];
};
marzban = {
format = "dotenv";
sopsFile = inputs.self.secretsDir + /nixos-vps/marzban.env;
restartUnits = [ "podman-marzban.service" ];
};
cf-dns-api = {
sopsFile = inputs.self.secretsDir + /misc.yaml;
owner = "acme";
};
in {
"cert.key" = nginx;
"cert.pem" = nginx;
"nginx.conf" = nginx;
inherit cf-dns-api marzban;
};
virtualisation.oci-containers.containers = {
marzban = {
autoStart = true;
# Tags: v0.8.4
image = "ghcr.io/gozargah/marzban@sha256:8e422c21997e5d2e3fa231eeff73c0a19193c20fc02fa4958e9368abb9623b8d";
environmentFiles = [ marzban-env ];
extraOptions = [ "--network=host" ];
volumes = [
"/srv/marzban:/var/lib/marzban"
];
};
nginx = {
autoStart = true;
# Tags: mainline-alpine3.21, mainline-alpine, alpine3.21
image = "docker.io/nginx@sha256:e4efffc3236305ae53fb54e5cd76c9ccac0cebf7a23d436a8f91bce6402c2665";
extraOptions = [ "--network=host" ];
volumes = [
"${cert-key}:/etc/ssl/certs/cf-cert.key:ro"
"${cert-pem}:/etc/ssl/certs/cf-cert.pem:ro"
"${config.security.acme.certs.${fqdn}.directory}/fullchain.pem:/etc/ssl/certs/cert.pem:ro"
"${config.security.acme.certs.${fqdn}.directory}/key.pem:/etc/ssl/certs/cert.key:ro"
"${nginx-conf}:/etc/nginx/nginx.conf:ro"
];
};
};
services.ocis = {
enable = true;
package = inputs.ataraxiasjel-nur.packages.${system}.ocis-bin;
configDir = "/srv/ocis/config";
baseDataPath = "/srv/ocis/data";
environment = {
OCIS_INSECURE = "false";
OCIS_URL = "https://cloud.ataraxiadev.com";
PROXY_HTTP_ADDR = "127.0.0.1:9200";
PROXY_TLS = "false";
};
};
systemd.tmpfiles.rules = [
"d /srv/marzban 0755 root root -"
];
# OpenConnect
security.acme = {
acceptTerms = true;
defaults.server = "https://acme-v02.api.letsencrypt.org/directory"; # production
defaults.email = "admin@ataraxiadev.com";
defaults.renewInterval = "weekly";
certs = {
${fqdn} = {
extraDomainNames = [
"auth.ataraxiadev.com"
"doh.ataraxiadev.com"
"video.ataraxiadev.com"
];
dnsResolver = "1.1.1.1:53";
dnsProvider = "cloudflare";
credentialFiles."CF_DNS_API_TOKEN_FILE" = config.sops.secrets.cf-dns-api.path;
reloadServices = [ "podman-nginx.service" ];
};
};
};
persist.state.directories = [ "/var/lib/acme" ];
environment.systemPackages = [ pkgs.ocserv ];
networking.nat = let
inherit (import ../hardware/networks.nix) interfaces;
in {
enable = true;
externalInterface = interfaces.main'.ifname;
internalInterfaces = [ "vpns0" ];
};
networking.firewall.trustedInterfaces = [ "vpns0" ];
# networking.firewall.extraCommands = ''
# ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o enp0s18 -j SNAT --to-source 45.135.180.193
# '';
}

@ -1 +0,0 @@
x86_64-linux

@ -1 +0,0 @@
x86_64-linux

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -1,20 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDNTCCAh2gAwIBAgIUSXneu6OGvR3CHJ/HDstZXNFug/cwDQYJKoZIhvcNAQEL
BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN
MjUwMjI0MjAyMjMxWhcNMzUwMjI0MjAyMjMxWjAoMRIwEAYDVQQDDAltaXRtcHJv
eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBANPq+g3OR1qL2R/ldxlYXPsoSW5Dr1xQRJ7t4aR2xwyossT9K4E4SRrw
K6N7otDiKKvrE5o4ljFtNj090zV8oXYQJ2T6t7gY19eYpUCcekT7G8N6DCYdK7TR
ox9BzUaK4CyAeW70CilPsYRk/C8VXlyVJ5gdDdb6wLkL69qajGy82AyZ0XPadeaJ
lm6ngA6fcboDxHemBmj37LkB/TMSAhUuqhPZBT/z2TisrAjAbaEGQMxerVkRih+b
URSq37Qd6U+ieCR/3EvjLNfO+qczwmRiwRAbustdeo3NBMEDM9WCtBOxkvsxPqy5
Jb1SQ7rsTp87m2hlhDrPIt36TBnmp10CAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB
/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
FGuPqyg5DIw0Li0GAIeZfScpQUAuMA0GCSqGSIb3DQEBCwUAA4IBAQA+uexpT9N8
Nn4+E8dBUlOcfO1bry7xvPCwyCA7FXlWfFYkzBZy8vERs0GBUHWMeojNSZZpthz5
flIcCrNieNpwmurj7e+tLEDc2ajGygVU1mzNdBjw73CEPe1aHlv2+cYjDy2AvP8K
w5P0iMZUCfLXRHrYm1tEFdjQ6z0Bz3dBSqP8tQWZ/quUCg0xmHfAlTwaj/6ORe5c
GtFUncTt+nM9Mtwao9af6SwhfkE9ChlCkdKi9HWo1trsvMAY0YSSCRqO1+8QAjyD
1t4S2Nk1E8h5Kik1zhtEMMKcm4/KRKH+nepkHlxTG/e5Dbst8JiFM9WmiYxiUDhx
M2DbkVISfUQc
-----END CERTIFICATE-----

@ -1,28 +0,0 @@
overseauspider.yuanshen.com
overseauspider.yuanshen.com
log-upload-os.hoyoverse.com
log-upload-os.hoyoverse.com
log-upload-os.mihoyo.com
log-upload-os.mihoyo.com
dump.gamesafe.qq.com
dump.gamesafe.qq.com
log-upload.mihoyo.com
log-upload.mihoyo.com
devlog-upload.mihoyo.com
devlog-upload.mihoyo.com
uspider.yuanshen.com
uspider.yuanshen.com
sg-public-data-api.hoyoverse.com
sg-public-data-api.hoyoverse.com
public-data-api.mihoyo.com
public-data-api.mihoyo.com
prd-lender.cdp.internal.unity3d.com
prd-lender.cdp.internal.unity3d.com
thind-prd-knob.data.ie.unity3d.com
thind-prd-knob.data.ie.unity3d.com
thind-gke-usc.prd.data.corp.unity3d.com
thind-gke-usc.prd.data.corp.unity3d.com
cdp.cloud.unity3d.com
cdp.cloud.unity3d.com
remote-config-proxy-prd.uca.cloud.unity3d.com
remote-config-proxy-prd.uca.cloud.unity3d.com

Binary file not shown.

Binary file not shown.

Before

(image error) Size: 487 KiB

@ -1,24 +0,0 @@
{ config, lib, ... }:
with config.deviceSpecific;
{
options = with lib;
with types; {
defaultApplications = mkOption {
type = attrsOf (submodule ({ ... }: {
options = {
cmd = mkOption { type = path; };
desktop = mkOption { type = str; };
};
}));
description = "Preferred applications";
};
startupApplications = mkOption {
type = listOf str;
description = "Applications to run on startup";
};
};
config = {
defaultApplications = {};
};
}

@ -1,188 +0,0 @@
{ config, options, lib, pkgs, ... }:
with lib;
let
cfg = config.autoinstall;
autoinstallOptions = { name, ... }: {
options = {
autoReboot = mkOption {
type = types.bool;
default = false;
description = "Auto reboot after install complete successufuly";
};
partitioning = {
useEntireDisk = mkOption {
type = types.bool;
default = true;
description = "Wipe entire disk and write new partition table";
};
nullifyDisk = mkOption {
type = types.bool;
default = false;
description = "Nullify entire disk. Very slow!";
};
disk = mkOption {
type = types.str;
default = "";
description = "Path to the disk to wipe";
};
emptySpace = mkOption {
type = types.str;
default = "0";
description = "Empty space at the end of the disk";
};
createBootPool = mkOption {
type = types.bool;
default = true;
description = "";
};
};
debug = mkOption {
type = types.bool;
default = false;
description = "If we should exit before installing or not to let debugging occur";
};
mainuser = mkOption {
type = types.str;
default = "ataraxia";
description = "Name of the main user (used for creation of home folder)";
};
flakesPath = mkOption {
type = types.str;
default = "";
description = "Path to config folder with flakes";
};
efiSize = mkOption {
type = types.str;
default = "512MiB";
description = "Size of EFI partition";
};
efiMountPoint = mkOption {
type = types.str;
default = "/boot";
description = "EFI mount point";
};
bootSize = mkOption {
type = types.str;
default = "4GiB";
description = "Size of boot partition";
};
rootSize = mkOption {
type = types.str;
default = "0";
description = "Size of root partition. If using 0, expand root partition to entire free space on disk";
};
swapPartition = {
enable = mkOption {
type = types.bool;
default = true;
description = "Use swap partition";
};
size = mkOption {
type = types.str;
default = "2GiB";
description = "Size of swap partition";
};
};
encryption = {
encryptBoot = mkOption {
type = types.bool;
default = false;
description = "Encrypt boot partition";
};
encryptRoot = mkOption {
type = types.bool;
default = false;
description = "Encrypt boot partition";
};
argonIterTime = mkOption {
type = types.str;
default = "5000";
description = "iter-time for argon2 in ms";
};
cryptBoot = mkOption {
type = types.str;
default = "cryptboot";
description = "Name of luks boot device";
};
cryptRoot = mkOption {
type = types.str;
default = "cryptroot";
description = "Name of luks root device";
};
passwordFile = mkOption {
type = types.str;
default = "";
description = "Path to file that contains password that pass to luksFormat";
};
};
zfsOpts = {
ashift = mkOption {
type = types.int;
default = 13;
description = "ashift passed to zfs pool creation";
};
bootPoolReservation = mkOption {
type = types.str;
default = "0";
description = "Reserve some space on boot pool";
};
rootPoolReservation = mkOption {
type = types.str;
default = "0";
description = "Reserve some space on root pool";
};
};
persist = {
enable = mkOption {
type = types.bool;
default = true;
description = "Use persist module";
};
persistRoot = mkOption {
type = types.str;
default = "/persist";
description = "Path to persist mount point";
};
persistHome = mkOption {
type = types.str;
default = "/home/${cfg.${name}.mainuser}";
description = "Path to home user folder relative to persistRoot";
};
};
oldUefi = mkOption {
type = types.bool;
default = false;
description = "Copy bootx64.efi to windows efi location (EFI/Microsoft/Boot/bootmgr.efi)";
};
};
};
mkService = name: opt: {
description = "Autoinstall NixOS on ${name}";
path = with pkgs; [
"/run/current-system/sw/"
"/usr/bin/"
"${systemd}/bin/"
"${git}/bin"
];
script = import ./install.nix {
inherit lib; inherit opt; hostname = name;
};
environment = config.nix.envVars // rec {
inherit (config.environment.sessionVariables) NIX_PATH;
HOME = "/root";
};
serviceConfig = { Type = "oneshot"; };
};
in {
options.autoinstall = mkOption {
default = {};
type = types.attrsOf (types.submodule autoinstallOptions);
};
config = lib.mkIf (cfg != {}) {
systemd.services = mapAttrs' (n: v: nameValuePair "autoinstall-${n}" (mkService n v)) cfg;
};
}

@ -1,428 +0,0 @@
{ opt, hostname, lib }:
with lib; let
cfg = opt // {
hostname = hostname;
autoReboot = boolToString opt.autoReboot;
entireDisk = boolToString opt.partitioning.useEntireDisk;
nullifyDisk = boolToString opt.partitioning.nullifyDisk;
disk = opt.partitioning.disk or "0";
bootPartition = opt.partitioning.partitions.bootPartition or "0";
rootPartition = opt.partitioning.partitions.rootPartition or "0";
swapPartition = opt.partitioning.partitions.swapPartition or "0";
createBootPool = boolToString opt.partitioning.createBootPool;
emptySpace = opt.partitioning.emptySpace or "0";
debug = boolToString opt.debug;
useSwap = boolToString opt.swapPartition.enable;
encryptRoot = boolToString opt.encryption.encryptRoot;
encryptBoot = boolToString opt.encryption.encryptBoot;
swapSize = opt.swapPartition.size or "0";
zfsAshift = toString opt.zfsOpts.ashift;
usePersistModule = boolToString opt.persist.enable;
oldUefi = boolToString opt.oldUefi;
argonIterTime = opt.encryption.argonIterTime;
passwordFile = opt.encryption.passwordFile;
cryptBoot = opt.encryption.cryptBoot;
cryptRoot = opt.encryption.cryptRoot;
bootPoolReservation = opt.zfsOpts.bootPoolReservation;
rootPoolReservation = opt.zfsOpts.rootPoolReservation;
persistRoot = opt.persist.persistRoot;
persistHome = opt.persist.persistHome;
};
in ''
set -eux
if [ "${cfg.debug}" = "true" ]; then
cat >&2 << FIN
autoReboot="${cfg.autoReboot}"
flakesPath="${cfg.flakesPath}"
hostname="${cfg.hostname}"
mainuser="${cfg.mainuser}"
debug="${cfg.debug}"
entireDisk="${cfg.entireDisk}"
nullifyDisk="${cfg.nullifyDisk}"
disk="${cfg.disk}"
bootPartition="${cfg.bootPartition}"
rootPartition="${cfg.rootPartition}"
swapPartition="${cfg.swapPartition}"
efiMountPoint="${cfg.efiMountPoint}"
emptySpace="${cfg.emptySpace}"
createBootPool="${cfg.createBootPool}"
efiSize="${cfg.efiSize}"
bootSize="${cfg.bootSize}"
rootSize="${cfg.rootSize}"
swapSize="${cfg.swapSize}"
encryptRoot="${cfg.encryptRoot}"
encryptBoot="${cfg.encryptBoot}"
useSwap="${cfg.useSwap}"
argonIterTime="${cfg.argonIterTime}"
cryptRoot="${cfg.cryptRoot}"
cryptBoot="${cfg.cryptBoot}"
passwordFile="${cfg.passwordFile}"
zfsAshift="${cfg.zfsAshift}"
rootPoolReservation="${cfg.rootPoolReservation}"
bootPoolReservation="${cfg.bootPoolReservation}"
usePersistModule="${cfg.usePersistModule}"
persistRoot="${cfg.persistRoot}"
persistHome="${cfg.persistHome}"
oldUefi="${cfg.oldUefi}"
FIN
fi
pprint () {
local timestamp
timestamp=$(date +%FT%T.%3NZ)
echo -e "$timestamp $1" 1>&2
}
if [ ! -d "${cfg.flakesPath}" ]; then
pprint "flakesPath does not exists!"
exit 2
fi
if [ "${cfg.encryptBoot}" = "true" || "${cfg.encryptRoot}" = "true" ]; then
if [ ! -f "${cfg.passwordFile}" ]; then
pprint "passwordFile does not exists!"
exit 2
fi
fi
create_new_part_table() {
wack=0
diskByID=""
if echo ${cfg.disk} | grep '/dev/disk/by-id'; then
diskByID=${cfg.disk}
else
byid=$(find -L /dev/disk -samefile ${cfg.disk} | grep by-id)
if [ "$byid" = "" ]; then
pprint "fatal: Could not find a /dev/disk/by-id symlink for %s\n" "${cfg.disk}"
wack=1
else
diskByID=$byid
fi
fi
if [ "${cfg.debug}" = "true" ]; then
cat >&2 << FIN
diskByID=$diskByID
FIN
fi
# The for loop has the actual output
if [ "$wack" -gt 0 ]; then
exit 2
fi
if [ "${cfg.nullifyDisk}" = "true" ]; then
diskname=$(basename $(readlink -f $diskByID))
isHDD=$(cat /sys/block/$diskname/queue/rotational)
if [ "$isHDD" = 1 ]; then
cat /dev/zero > "$diskByID" || true
else
blkdiscard "$diskByID"
fi
fi
# partitioning
sgdisk --zap-all "$diskByID"
pprint "Creating boot (EFI) partition"
sgdisk -n1:1MiB:+${cfg.efiSize} -t1:EF00 "$diskByID"
efiPart="$diskByID-part1"
if [ "${cfg.createBootPool}" = "true" ]; then
pprint "Creating boot (ZFS) partition"
if [ "${cfg.encryptBoot}" = "true" ]; then
sgdisk -n2:0:+${cfg.bootSize} -t2:8309 "$diskByID"
else
sgdisk -n2:0:+${cfg.bootSize} -t2:BF00 "$diskByID"
fi
bootPart="$diskByID-part2"
fi
if [ "${cfg.emptySpace}" != "0" ]; then
pprint "Creating temp empty partition at the end of the disk"
sgdisk -n5:-${cfg.emptySpace}:0 -t5:8300 "$diskByID"
fi
if [ "${cfg.useSwap}" = "true" ]; then
pprint "Creating SWAP partition"
sgdisk -n4:-${cfg.swapSize}:0 -t4:8200 "$diskByID"
swapPart="$diskByID-part4"
fi
if [ "${cfg.encryptRoot}" = "true" ]; then
pprint "Creating LUKS partition"
sgdisk -n3:0:${cfg.rootSize} -t3:8309 "$diskByID"
else
pprint "Creating ROOT partition"
sgdisk -n3:0:${cfg.rootSize} -t3:BF00 "$diskByID"
fi
rootPart="$diskByID-part3"
if [ "${cfg.emptySpace}" != "0" ]; then
pprint "Remove temp partition"
sgdisk -d 5 -s "$diskByID"
fi
partprobe "$diskByID"
sleep 1
pprint "Format EFI partition $efiPart"
mkfs.vfat -n EFI "$efiPart"
}
# Installation begin
if [ "${cfg.entireDisk}" = "true" ]; then
create_new_part_table
else
use_existing_part_table
fi
if [ "${cfg.encryptBoot}" = "true" || "${cfg.encryptRoot}" = "true" ]; then
password=$(cat ${cfg.passwordFile})
dd if=/dev/urandom of=/tmp/keyfile0.bin bs=1024 count=4
if [ "${cfg.createBootPool}" = "true" ]; then
if [ "${cfg.encryptBoot}" = "true" ]; then
pprint "Creating LUKS container on $bootPart"
echo -n "$password" | cryptsetup --type luks2 --pbkdf argon2id --iter-time ${cfg.argonIterTime} -c aes-xts-plain64 -s 512 -h sha256 luksFormat "$bootPart" -
pprint "Add keyfile to LUKS container on $bootPart"
echo -n "$password" | cryptsetup luksAddKey $bootPart /tmp/keyfile0.bin -
pprint "Open LUKS container on $bootPart"
cryptsetup luksOpen --allow-discards "$bootPart" "${cfg.cryptBoot}" -d /tmp/keyfile0.bin
bootPool="$(ls /dev/disk/by-id/dm-uuid-*${cfg.cryptBoot})"
else
bootPool="$bootPart"
fi
fi
if [ "${cfg.encryptRoot}" = "true" ]; then
pprint "Creating LUKS container on $rootPart"
echo -n "$password" | cryptsetup --type luks2 --pbkdf argon2id --iter-time ${cfg.argonIterTime} -c aes-xts-plain64 -s 512 -h sha256 luksFormat "$rootPart" -
pprint "Add keyfile to LUKS container on $rootPart"
echo -n "$password" | cryptsetup luksAddKey $rootPart /tmp/keyfile0.bin -
pprint "Open LUKS container on $rootPart"
cryptsetup luksOpen --allow-discards "$rootPart" "${cfg.cryptRoot}" -d /tmp/keyfile0.bin
rootPool="$(ls /dev/disk/by-id/dm-uuid-*${cfg.cryptRoot})"
else
rootPool="$rootPart"
fi
else
[ "${cfg.createBootPool}" = "true" ] && bootPool="$bootPart"
rootPool="$rootPart"
fi
pprint "Create ZFS root pool on $rootPool"
zpool create \
-f \
-o ashift=${cfg.zfsAshift} \
-o autotrim=on \
-O acltype=posixacl \
-O atime=on \
-O canmount=off \
-O compression=zstd \
-O dnodesize=auto \
-O normalization=formD \
-O relatime=on \
-O xattr=sa \
-O dedup=off \
-O mountpoint=/ \
-R /mnt \
rpool "$rootPool"
pprint "Create ZFS root datasets"
if [ "${cfg.rootPoolReservation}" != "0" ]; then
zfs create -o refreservation=${cfg.rootPoolReservation} -o canmount=off -o mountpoint=none rpool/reserved
fi
# top level datasets
zfs create -o canmount=off -o mountpoint=none rpool/nixos
zfs create -o canmount=off -o mountpoint=none rpool/user
zfs create -o canmount=off -o mountpoint=none rpool/persistent
# empty root
zfs create -o canmount=noauto -o mountpoint=/ rpool/nixos/root
zfs mount rpool/nixos/root
zfs create -o canmount=on -o mountpoint=/home rpool/user/home
# persistent across boots
if [ "${cfg.usePersistModule}" = "true" ]; then
zfs create -o canmount=on -o mountpoint=${cfg.persistRoot} rpool/persistent/impermanence
mkdir -p /mnt${cfg.persistRoot}${cfg.persistHome}
chown 1000:100 /mnt${cfg.persistRoot}${cfg.persistHome}
chmod 755 /mnt${cfg.persistRoot}${cfg.persistHome}
fi
zfs create -o canmount=on -o mountpoint=/srv rpool/persistent/servers
zfs create -o canmount=on -o mountpoint=/etc/secrets rpool/persistent/secrets
zfs create -o canmount=on -o mountpoint=/nix rpool/persistent/nix
zfs create -o canmount=on -o mountpoint=/var/log rpool/persistent/log
zfs create -o canmount=noauto -o atime=off rpool/persistent/lxd
zfs create -o canmount=on -o mountpoint=/var/lib/docker -o atime=off rpool/persistent/docker
zfs create -o canmount=on -o mountpoint=/var/lib/containers -o atime=off rpool/persistent/containers
zfs create -o canmount=on -o mountpoint=/var/lib/nixos-containers -o atime=off rpool/persistent/nixos-containers
zfs create -o canmount=on -o mountpoint=/media/bittorrent -o atime=off -o recordsize=16K -o compression=lz4 rpool/persistent/bittorrent
chown 1000:100 /mnt/media/bittorrent
chmod 775 /mnt/media/bittorrent
zfs create -o canmount=on -o mountpoint=/var/lib/libvirt rpool/persistent/libvirt
zfs create -o canmount=on -o mountpoint=/media/libvirt rpool/persistent/libvirt-user
zfs create -o canmount=on -o mountpoint=/media/libvirt/images -o atime=off -o recordsize=16K -o compression=lz4 rpool/persistent/libvirt-user/images
chown 1000:67 /mnt/media/libvirt
chmod 775 /mnt/media/libvirt
# Create empty zfs snapshots
zfs snapshot rpool/nixos@empty
zfs snapshot rpool/nixos/root@empty
zfs snapshot rpool/user@empty
zfs snapshot rpool/user/home@empty
zfs snapshot rpool/persistent@empty
zfs snapshot rpool/persistent/impermanence@empty
zfs snapshot rpool/persistent/servers@empty
zfs snapshot rpool/persistent/secrets@empty
zfs snapshot rpool/persistent/nix@empty
zfs snapshot rpool/persistent/log@empty
zfs snapshot rpool/persistent/lxd@empty
zfs snapshot rpool/persistent/docker@empty
zfs snapshot rpool/persistent/containers@empty
zfs snapshot rpool/persistent/nixos-containers@empty
zfs snapshot rpool/persistent/bittorrent@empty
zfs snapshot rpool/persistent/libvirt@empty
zfs snapshot rpool/persistent/libvirt-user@empty
zfs snapshot rpool/persistent/libvirt-user/images@empty
if [ "${cfg.createBootPool}" = "true" ]; then
pprint "Create ZFS boot pool on $bootPool"
zpool create \
-f \
-o compatibility=grub2 \
-o ashift=${cfg.zfsAshift} \
-o autotrim=on \
-O acltype=posixacl \
-O atime=on \
-O canmount=off \
-O compression=lz4 \
-O devices=off \
-O normalization=formD \
-O relatime=on \
-O xattr=sa \
-O dedup=off \
-O mountpoint=/boot \
-R /mnt \
bpool "$bootPool"
pprint "Create ZFS boot datasets"
if [ "${cfg.bootPoolReservation}" != "0" ]; then
zfs create -o refreservation=${cfg.bootPoolReservation} -o canmount=off -o mountpoint=none bpool/reserved
fi
zfs create -o canmount=off -o mountpoint=none bpool/nixos
zfs create -o canmount=on -o mountpoint=/boot bpool/nixos/boot
zfs snapshot bpool/nixos@empty
zfs snapshot bpool/nixos/boot@empty
fi
# Disable cache, stale cache will prevent system from booting
if [ "${cfg.usePersistModule}" = "true" ]; then
mkdir -p /mnt"${cfg.persistRoot}"/etc/zfs/
rm -f /mnt"${cfg.persistRoot}"/etc/zfs/zpool.cache
touch /mnt"${cfg.persistRoot}"/etc/zfs/zpool.cache
chmod a-w /mnt"${cfg.persistRoot}"/etc/zfs/zpool.cache
chattr +i /mnt"${cfg.persistRoot}"/etc/zfs/zpool.cache
else
mkdir -p /mnt/etc/zfs/
rm -f /mnt/etc/zfs/zpool.cache
touch /mnt/etc/zfs/zpool.cache
chmod a-w /mnt/etc/zfs/zpool.cache
chattr +i /mnt/etc/zfs/zpool.cache
fi
mkdir -p /mnt${cfg.efiMountPoint}
mount -t vfat "$efiPart" /mnt${cfg.efiMountPoint}
if [ "${cfg.useSwap}" = "true" ]; then
mkswap -L swap -f "$swapPart"
fi
pprint "Generate NixOS configuration"
configExists=false
[ -f ${cfg.flakesPath}/machines/${cfg.hostname}/configuration.nix ] && configExists=true
nixos-generate-config --root /mnt --dir ${cfg.flakesPath}/machines/${cfg.hostname}
[ "$configExists" = "false" ] && rm -f ${cfg.flakesPath}/machines/${cfg.hostname}/configuration.nix
pprint "Append ZFS configuration to hardware-configuration.nix"
hostID=$(head -c8 /etc/machine-id)
hardwareConfig=$(mktemp)
cat <<CONFIG > "$hardwareConfig"
networking.hostId = "$hostID";
boot.zfs.devNodes = "/dev/disk/by-id";
boot.supportedFilesystems = [ "zfs" ];
CONFIG
if [ "${cfg.encryptBoot}" = "true" ]; then
bootPartUuid=$(blkid --match-tag PARTUUID --output value "$bootPart")
cat <<CONFIG >> "$hardwareConfig"
boot.initrd.luks.devices."${cfg.cryptBoot}".device = "/dev/disk/by-partuuid/$bootPartUuid";
CONFIG
fi
if [ "${cfg.encryptRoot}" = "true" ]; then
rootPartUuid=$(blkid --match-tag PARTUUID --output value "$rootPart")
cat <<CONFIG >> "$hardwareConfig"
boot.initrd.luks.devices."${cfg.cryptRoot}".device = "/dev/disk/by-partuuid/$rootPartUuid";
CONFIG
fi
sed -i "\$e cat $hardwareConfig" ${cfg.flakesPath}/machines/${cfg.hostname}/hardware-configuration.nix
sed -i 's|fsType = "zfs";|fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];|g' ${cfg.flakesPath}/machines/${cfg.hostname}/hardware-configuration.nix
if [ "${cfg.useSwap}" == "true" ]; then
swapPartUuid=$(blkid --match-tag PARTUUID --output value "$swapPart")
sed -i "s|swapDevices = \[ \];|swapDevices = \[\n {\n device = \"/dev/disk/by-partuuid/$swapPartUuid\";\n randomEncryption.enable = true;\n randomEncryption.allowDiscards = true;\n }\n \];|" ${cfg.flakesPath}/machines/${cfg.hostname}/hardware-configuration.nix
fi
chown 1000:100 ${cfg.flakesPath}/machines/${cfg.hostname}/hardware-configuration.nix
git config --global --add safe.directory "${cfg.flakesPath}"
git -C "${cfg.flakesPath}" add -A
pprint "Gen ssh host key for initrd"
ssh-keygen -t ed25519 -N "" -f /mnt/etc/secrets/ssh_host_key
chown root:root /mnt/etc/secrets/ssh_host_key
chmod 600 /mnt/etc/secrets/ssh_host_key
if [ "${cfg.encryptBoot}" = "true" || "${cfg.encryptRoot}" = "true" ]; then
cp /tmp/keyfile0.bin /mnt/etc/secrets/keyfile0.bin
chmod 000 /mnt/etc/secrets/keyfile*.bin
fi
if [ "${cfg.debug}" != "true" ]; then
nixos-install --flake "${cfg.flakesPath}/#${cfg.hostname}" --root /mnt --no-root-passwd
fi
configPath="/mnt/persist/home/"${cfg.mainuser}"/nixos-config"
if [ ! -d "$configPath" ]; then
mkdir -p $configPath
chown 1000:100 $configPath
fi
cp -aT ${cfg.flakesPath} $configPath
if [ "${cfg.oldUefi}" = "true" ]; then
mkdir -p /mnt/boot/efi/EFI/Microsoft/Boot
cp /mnt/boot/efi/EFI/BOOT/BOOTX64.EFI /mnt/boot/efi/EFI/Microsoft/Boot/bootmgr.efi
cp /mnt/boot/efi/EFI/BOOT/BOOTX64.EFI /mnt/boot/efi/EFI/Microsoft/Boot/bootmgfw.efi
fi
if [ "${cfg.debug}" != "true" ]; then
umount -Rl /mnt
zpool export -a
[ "${cfg.encryptBoot}" = "true" ] && cryptsetup luksClose ${cfg.cryptBoot}
[ "${cfg.encryptRoot}" = "true" ] && cryptsetup luksClose ${cfg.cryptRoot}
if [ "${cfg.autoReboot}" = "true" ]; then
if ! systemctl reboot --firmware-setup ; then
pprint "Reboot into efi firmware setup failed! Shutdown in 30 seconds"
sleep 30
systemctl poweroff
fi
fi
fi
''

@ -1,81 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
{
options.services.cryptmount = mkOption {
type = types.attrsOf (
types.submodule (
{ name, ... }:
{
options = {
cryptname = mkOption {
type = types.str;
default = name;
};
passwordFile = mkOption { type = types.str; };
what = mkOption { type = types.str; };
where = mkOption { type = types.str; };
fsType = mkOption {
type = with types; nullOr str;
default = null;
};
cryptType = mkOption {
type = types.enum [
"luks"
"luks1"
"luks2"
"plain"
"loopaes"
"tcrypt"
"bitlk"
];
default = "luks";
};
mountOptions = mkOption {
type = with types; listOf str;
default = [ ];
};
};
}
)
);
default = { };
};
config = mkIf (config.services.cryptmount != { }) {
systemd.services =
mapAttrs'
(
name: cfg:
nameValuePair "cryptmount-${name}" ({
wantedBy = [ "multi-user.target" ];
path = [ pkgs.cryptsetup ];
serviceConfig =
let
mount-type = if (cfg.fsType != null) then "-t ${cfg.fsType}" else "";
opts =
if (cfg.mountOptions != [ ]) then "-o ${strings.concatStringsSep "," cfg.mountOptions}" else "";
in
{
Type = "oneshot";
TimeoutStartSec = "infinity";
RemainAfterExit = true;
ExecStart = pkgs.writeShellScript "storage-decrypt-${name}" ''
set -euo pipefail
mkdir -p ${cfg.where}
cat ${cfg.passwordFile} | cryptsetup open ${cfg.what} ${cfg.cryptname} - --type ${cfg.cryptType}
/run/wrappers/bin/mount ${mount-type} ${opts} /dev/mapper/${cfg.cryptname} ${cfg.where}
'';
ExecStop = pkgs.writeShellScript "storage-decrypt-stop-${name}" ''
/run/wrappers/bin/umount -R ${cfg.where}
cryptsetup close ${cfg.cryptname}
'';
};
})
)
config.services.cryptmount;
};
}

@ -1,157 +0,0 @@
{ lib, config, ... }:
with lib;
with types; {
options = {
device = mkOption { type = str; };
deviceSpecific = {
devInfo = {
cpu = {
arch = mkOption { type = enum [ "x86_64" "aarch64" ]; };
vendor = mkOption { type = enum [ "amd" "intel" "broadcom" ]; };
clock = mkOption { type = int; };
cores = mkOption { type = int; };
};
drive = {
type = mkOption { type = enum [ "hdd" "ssd" ]; };
speed = mkOption { type = int; };
size = mkOption { type = int; };
};
gpu = {
vendor = mkOption { type = enum [ "amd" "nvidia" "intel" "vm" "other" ]; };
};
fileSystem = mkOption { type = enum [ "btrfs" "zfs" "other" ]; default = "other"; };
ram = mkOption { type = int; };
legacy = mkOption { type = bool; default = false; };
bigScreen = mkOption {
type = bool;
default = true;
};
};
isLaptop = mkOption {
type = bool;
default =
(builtins.match ".*Laptop" config.networking.hostName) != null;
};
isVM = mkOption {
type = bool;
default =
(builtins.match ".*VM" config.networking.hostName) != null;
};
isServer = mkOption {
type = bool;
default =
(builtins.match ".*(Cloud|Server)" config.networking.hostName) != null;
};
isContainer = mkOption {
type = bool;
default =
(builtins.match ".*(CT|Container)" config.networking.hostName) != null;
};
isISO = mkOption {
type = bool;
default =
(builtins.match ".*ISO" config.networking.hostName) != null;
};
isDesktop = mkOption {
type = bool;
default = with config.deviceSpecific; (!isLaptop && !isVM && !isISO);
};
isHost = mkOption {
type = bool;
default = false;
};
isShared = mkOption {
type = bool;
default = false;
};
isGaming = mkOption {
type = bool;
default = false;
};
enableVirtualisation = mkOption {
type = bool;
default = config.deviceSpecific.isHost;
};
isSSD = mkOption {
type = bool;
default = config.deviceSpecific.devInfo.drive.type == "ssd";
};
vpn = {
mullvad.enable = mkOption {
type = bool;
default = false;
};
ivpn.enable = mkOption {
type = bool;
default = false;
};
tailscale.enable = mkOption {
type = bool;
default = false;
};
sing-box.enable = mkOption {
type = bool;
default = false;
};
sing-box.config = mkOption {
type = str;
default = "";
};
wireguard = {
enable = mkOption {
type = bool;
default = false;
};
autostart = mkOption {
type = bool;
default = false;
};
port = mkOption {
type = int;
default = 51820;
};
endpoint = mkOption {
type = str;
default = "";
};
address = mkOption {
type = listOf str;
default = [];
};
allowedIPs = mkOption {
type = listOf str;
default = [];
};
dns = mkOption {
type = listOf str;
default = [];
};
gateway = {
ipv4 = mkOption {
type = nullOr str;
default = null;
};
ipv6 = mkOption {
type = nullOr str;
default = null;
};
};
keys = {
public = mkOption {
type = nullOr str;
default = null;
};
presharedFile = mkOption {
type = nullOr path;
default = null;
};
privateFile = mkOption {
type = nullOr path;
default = null;
};
};
};
};
};
};
}

@ -1,76 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
{
options.services.headscale-auth = mkOption {
description = ''
Request headscale auth key.
'';
type = types.attrsOf (types.submodule ({ ... }: {
options = {
autoStart = mkOption {
type = types.bool;
default = false;
description = "Request auth key on startup.";
};
ephemeral = mkOption {
type = types.bool;
default = false;
description = "Request ephemeral auth key.";
};
expire = mkOption {
type = types.str;
default = "1h";
description = "Auth key expiration time.";
};
user = mkOption {
type = types.str;
default = "ataraxiadev";
description = "Auth key user.";
};
outPath = mkOption {
type = types.str;
default = "/tmp/auth-key";
description = "Where to write down the auth key.";
};
before = mkOption {
type = with types; listOf str;
default = [ ];
description = "Start service before this services.";
};
};
}));
default = { };
};
config = mkIf (config.services.headscale-auth != { }) {
sops.secrets.headscale-api-env.sopsFile = inputs.self.secretsDir + /misc.yaml;
systemd.services =
mapAttrs'
(name: cfg: nameValuePair "headscale-auth-${name}" ({
path = [ pkgs.headscale pkgs.jq ];
restartIfChanged = false;
requiredBy = cfg.before;
before = cfg.before;
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = mkIf cfg.autoStart [ "multi-user.target" ];
environment = {
HEADSCALE_CLI_ADDRESS = "wg.ataraxiadev.com:443";
};
script = ''
while true; do
auth_key=$(headscale preauthkeys create -e ${cfg.expire} -u ${cfg.user} -o json ${optionalString cfg.ephemeral "--ephemeral"} | jq -r .key)
[[ "$auth_key" = "null" ]] || break
echo "Cannot retrieve auth key. Will try again after 5 seconds." >&2
sleep 5
done
echo $auth_key > "${cfg.outPath}"
'';
serviceConfig = {
EnvironmentFile = config.sops.secrets.headscale-api-env.path;
Type = "oneshot";
};
})
) config.services.headscale-auth;
};
}

4
modules/home/default.nix Normal file

@ -0,0 +1,4 @@
{ ... }:
{
}

@ -1,103 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.kiwix-serve;
in
{
options = {
services.kiwix-serve = {
enable = mkOption {
default = false;
type = types.bool;
};
package = mkOption {
type = types.package;
default = pkgs.kiwix-tools;
defaultText = literalExpression "pkgs.kiwix-tools";
description = "The package that provides `bin/kiwix-serve`";
};
port = mkOption {
type = types.port;
default = 80;
description = "Port number to listen on";
};
listenAddress = mkOption {
type = types.str;
default = "127.0.0.1";
description = "IP address to listen on";
};
zimPaths = mkOption {
default = null;
type = types.nullOr (types.nonEmptyListOf (types.either types.str types.path));
description = "ZIM file path(s)";
};
zimDir = mkOption {
default = null;
type = types.nullOr (types.either types.str types.path);
description = "ZIM directory";
};
};
};
config = mkIf cfg.enable {
systemd.services.kiwix-serve = {
description = "Deliver ZIM file(s) articles via HTTP";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = let
bindsPrivilegedPort = (0 < cfg.port && cfg.port < 1024);
maybeZimPaths = lib.optionals (cfg.zimPaths != null) cfg.zimPaths;
maybeZimDir = lib.optionals (cfg.zimDir != null) ["-l" "/tmp/library.xml"];
args = ["-i" cfg.listenAddress] ++ ["-p" cfg.port] ++ maybeZimDir ++ maybeZimPaths;
manage-lib = pkgs.writeShellScript "kiwix-manage-library" ''
for f in "${cfg.zimDir}"/*.zim; do
if [[ -f "$f" ]]; then
( set -x; ${cfg.package}/bin/kiwix-manage "/tmp/library.xml" add $f )
fi
done
'';
in {
ExecStartPre = lib.mkIf (cfg.zimDir != null) manage-lib;
ExecStart = "${cfg.package}/bin/kiwix-serve ${lib.escapeShellArgs args}";
Type = "simple";
Restart = "on-failure";
TimeoutStartSec = 600;
AmbientCapabilities = [""] ++ lib.optional bindsPrivilegedPort "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = [""] ++ lib.optional bindsPrivilegedPort "CAP_NET_BIND_SERVICE";
DevicePolicy = "closed";
DynamicUser = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateIPC = true;
PrivateUsers = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [ "@system-service" "~@privileged" ];
SystemCallErrorNumber = "EPERM";
UMask = "0002";
};
};
};
}

@ -1,468 +0,0 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.virtualisation.libvirt.guests;
diskOptions.options = {
diskFile = mkOption {
type = types.str;
default = "/var/lib/libvirt/images/guest-${name}.qcow2";
};
# TODO
bus = mkOption {
type = types.enum [ "virtio" "ide" "scsi" "sata" ];
default = "virtio";
};
type = mkOption {
type = types.enum [ "raw" "qcow2" ];
default = "qcow2";
};
targetName = mkOption {
type = types.str;
default = "vda";
};
discard = mkOption {
type = types.enum [ "ignore" "unmap" ];
default = "unmap";
};
cache = mkOption {
type = types.enum [ "none" "writethrough" "writeback" "directsync" "unsafe" ];
default = "writeback";
};
};
mountOptions.options = {
sourceDir = mkOption {
type = types.str;
default = "";
};
targetDir = mkOption {
type = types.str;
default = "";
};
# TODO
type = mkOption {
type = types.enum [ "virtiofs" "9p" ];
default = "virtiofs";
};
};
guestsOptions = { ... }: {
options = rec {
xmlFile = mkOption {
type = with types; nullOr path;
default = null;
};
connectUri = mkOption {
type = types.str;
default = "qemu:///system";
};
user = mkOption {
type = types.str;
default = "qemu-libvirtd";
};
group = mkOption {
type = types.str;
default = "qemu-libvirtd";
};
autoStart = mkOption {
type = types.bool;
default = false;
};
autoDefine = mkOption {
type = types.bool;
default = true;
};
guestOsType = mkOption {
type = types.enum [ "linux" "windows" ];
default = "linux";
};
uefi = mkOption {
type = types.bool;
default = false;
};
memory = mkOption {
type = types.int;
default = 1024;
};
sharedMemory = mkOption {
type = types.bool;
# TODO: not needed if using 9p mount
default = devices.mounts != [ ];
};
cpu = {
sockets = mkOption {
type = types.int;
default = 1;
};
cores = mkOption {
type = types.int;
default = 1;
};
threads = mkOption {
type = types.int;
default = 1;
};
};
devices = {
disks = mkOption {
type = with types; listOf (submodule diskOptions);
default = [ ];
};
mounts = mkOption {
type = with types; listOf (submodule mountOptions);
default = [ ];
};
tablet = mkOption {
type = types.bool;
default = true;
};
serial = mkOption {
type = types.bool;
default = true;
};
qemuGuestAgent = mkOption {
type = types.bool;
default = guestOsType != "windows";
};
audio = {
enable = mkOption {
type = types.bool;
default = true;
};
type = mkOption {
# TODO
type = types.enum [
"none"
"alsa"
"coreaudio"
"dbus"
"jack"
"oss"
"pulseaudio"
"sdl"
"spice"
"file"
];
default = "spice";
};
};
graphics = {
enable = mkOption {
type = types.bool;
# TODO: must be true if video == true?
default = true;
};
type = mkOption {
# TODO
type =
types.enum [ "sdl" "vnc" "spice" "rdp" "desktop" "egl-headless" ];
default = "spice";
};
};
video = {
enable = mkOption {
type = types.bool;
default = true;
};
type = mkOption {
# TODO
type = types.enum [
"vga"
"cirrus"
"vmvga"
"xen"
"vbox"
"qxl"
"virtio"
"gop"
"bochs"
"ramfb"
"none"
];
default = "virtio";
};
};
network = {
enable = mkOption {
type = types.bool;
default = true;
};
interfaceType = mkOption {
# TODO
type = types.enum [ "network" "macvlan" "bridge" ];
default = "network";
};
modelType = mkOption {
type = types.enum [ "virtio" "e1000" ];
default = "virtio";
};
macAddress = mkOption {
type = with types; nullOr str;
default = null;
};
active = mkOption {
type = types.bool;
default = true;
};
sourceDev = mkOption {
type = types.str;
default = "default";
};
};
};
timeout = mkOption {
type = types.int;
default = 10;
};
};
};
in {
options.virtualisation.libvirt.guests = mkOption {
default = { };
type = types.attrsOf (types.submodule guestsOptions);
};
config.systemd.services = lib.mkMerge (lib.mapAttrsToList (
name: guest: let
xml = pkgs.writeText "libvirt-guest-${name}.xml" ''
<domain type="kvm">
<name>${name}</name>
<uuid>UUID</uuid>
<memory unit="MiB">${toString guest.memory}</memory>
${
lib.optionalString guest.sharedMemory ''
<memoryBacking>
<source type="memfd"/>
<access mode="shared"/>
</memoryBacking>
''
}
<vcpu placement="static">${
with guest.cpu;
toString (sockets * cores * threads)
}</vcpu>
<os>
<type arch="x86_64" machine="pc-q35-9.2">hvm</type>
${
lib.optionalString guest.uefi ''
<loader readonly="yes" type="pflash" format="raw">/run/libvirt/nix-ovmf/OVMF_CODE.fd</loader>
<nvram template="/run/libvirt/nix-ovmf/OVMF_CODE.fd" templateFormat="raw" format="raw">/var/lib/libvirt/qemu/nvram/${name}_VARS.fd</nvram>
''
}
</os>
<features>
<acpi/>
<apic/>
${
lib.optionalString (guest.guestOsType == "windows") ''
<pae/>
<hyperv mode="custom">
<relaxed state="on"/>
<vapic state="on"/>
<spinlocks state="on" retries="8191"/>
<vpindex state="on"/>
<synic state="on"/>
</hyperv>
''
}
<vmport state="off"/>
</features>
<cpu mode="host-passthrough" check="none" migratable="on">
${
with guest.cpu; ''
<topology
sockets="${toString sockets}"
cores="${toString cores}"
threads="${toString threads}"
/>
''
}
</cpu>
<clock offset="${
if guest.guestOsType == "windows" then "localtime" else "utc"
}">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
<timer name="hpet" present="no"/>
${
lib.optionalString (guest.guestOsType == "windows") ''
<timer name="hypervclock" present="yes"/>
''
}
</clock>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/run/libvirt/nix-emulators/qemu-system-x86_64</emulator>
${
lib.concatStrings (map (disk: ''
<disk type="file" device="disk">
<driver name="qemu" type="${disk.type}" cache="${disk.cache}" discard="${disk.discard}"/>
<source file="${disk.diskFile}"/>
<target dev="${disk.targetName}" bus="${disk.bus}"/>
</disk>
'') guest.devices.disks)
}
${
lib.concatStrings (map (mount: ''
<filesystem type="mount" accessmode="passthrough">
<driver type="virtiofs" queue="1024"/>
<binary path="/run/current-system/sw/bin/virtiofsd" xattr="on">
<cache mode="always"/>
<lock posix="on" flock="on"/>
</binary>
<source dir="${mount.sourceDir}"/>
<target dir="${mount.targetDir}"/>
</filesystem>
'') guest.devices.mounts)
}
${
with guest.devices.network;
if enable then
if interfaceType == "network" then ''
<interface type="network">
${
lib.optionalString (macAddress != null) ''
<mac address="${macAddress}"/>
''
}
<source network="${sourceDev}"/>
<model type="${modelType}"/>
</interface>
'' else if interfaceType == "bridge" then ''
<interface type="bridge">
${lib.optionalString (macAddress != null) ''
<mac address="${macAddress}"/>
''}
<source bridge="${sourceDev}"/>
<model type="${modelType}"/>
</interface>
'' else if interfaceType == "macvlan" then ''
<interface type="direct">
${lib.optionalString (macAddress != null) ''
<mac address="${macAddress}"/>
''}
<source dev="${sourceDev}" mode="bridge"/>
<model type="${modelType}"/>
</interface>
'' else
""
else
""
}
${
lib.optionalString guest.devices.tablet ''
<input type="tablet" bus="usb"/>
''
}
${
lib.optionalString guest.devices.serial ''
<serial type="pty"/>
''
}
${
lib.optionalString guest.devices.qemuGuestAgent ''
<channel type="unix">
<target type="virtio" name="org.qemu.guest_agent.0"/>
</channel>
''
}
${
lib.optionalString guest.devices.audio.enable ''
<audio id="1" type="${guest.devices.audio.type}"/>
<sound model="ich9"/>
''
}
${
if guest.devices.graphics.enable then
if guest.devices.graphics.type == "spice" then ''
<graphics type="spice" autoport="yes">
<listen type="address"/>
<image compression="off"/>
</graphics>
'' else
""
else
""
}
${
with guest.devices.video;
with lib;
optionalString enable ''
<video>
${if type == "virtio" then ''
<model type="virtio" heads="1"/>
'' else if type == "qxl" then ''
<model type="qxl" ram="65536" vram="65536" vgamem="16384" heads="1"/>
'' else
""}
</video>
''
}
<channel type="spicevmc">
<target type="virtio" name="com.redhat.spice.0"/>
</channel>
<input type="mouse" bus="ps2"/>
<input type="keyboard" bus="ps2"/>
<redirdev bus='usb' type='spicevmc'/>
<memballoon model="virtio"/>
${
lib.optionalString (guest.guestOsType == "windows") ''
<rng model="virtio">
<backend model="random">/dev/urandom</backend>
</rng>
''
}
</devices>
</domain>
'';
in {
"libvirt-guest-define-${name}" = {
after = [ "libvirtd.service" ];
requires = [ "libvirtd.service" ];
wantedBy = lib.mkIf guest.autoDefine [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = "no";
User = guest.user;
Group = guest.group;
};
environment = { LIBVIRT_DEFAULT_URI = guest.connectUri; };
script = if guest.xmlFile != null then ''
${pkgs.libvirt}/bin/virsh define --file ${guest.xmlFile}
${pkgs.libvirt}/bin/virsh net-start ${guest.devices.network.sourceDev} || true
'' else ''
uuid="$(${pkgs.libvirt}/bin/virsh domuuid '${name}' || true)"
${pkgs.libvirt}/bin/virsh define <(sed "s/UUID/$uuid/" '${xml}')
${lib.optionalString
(guest.devices.network.interfaceType == "network")
"${pkgs.libvirt}/bin/virsh net-start ${guest.devices.network.sourceDev} || true"}
'';
};
"libvirt-guest-${name}" = {
after = [ "libvirt-guest-define-${name}.service" ];
requires = [ "libvirt-guest-define-${name}.service" ];
wantedBy = lib.mkIf guest.autoStart [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = "yes";
User = guest.user;
Group = guest.group;
};
environment = { LIBVIRT_DEFAULT_URI = guest.connectUri; };
script = "${pkgs.libvirt}/bin/virsh start '${name}'";
preStop = ''
${pkgs.libvirt}/bin/virsh shutdown '${name}'
let "timeout = $(date +%s) + ${toString guest.timeout}"
while [ "$(${pkgs.libvirt}/bin/virsh list --name | grep --count '^${name}$')" -gt 0 ]; do
if [ "$(date +%s)" -ge "$timeout" ]; then
${pkgs.libvirt}/bin/virsh destroy '${name}'
else
sleep 0.5
fi
done
'';
};
}
) cfg);
}

@ -1,40 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkEnableOption mkPackageOption mkIf;
cfg = config.services.modprobed-db;
in
{
options = {
services.modprobed-db = {
enable = mkEnableOption "modprobed-db service to scan and store new kernel modules";
package = mkPackageOption pkgs "modprobed-db" { };
};
};
config = mkIf cfg.enable {
systemd.user = {
services.modprobed-db = {
description = "modprobed-db service to scan and store new kernel modules";
wants = [ "modprobed-db.timer" ];
wantedBy = [ "default.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/modprobed-db storesilent";
ExecStop = "${cfg.package}/bin/modprobed-db storesilent";
Type = "simple";
};
path = builtins.attrValues {
inherit (pkgs) gawk getent coreutils gnugrep gnused kmod;
};
};
timers.modprobed-db = {
wantedBy = [ "timers.target" ];
partOf = [ "modprobed-db.service" ];
timerConfig = {
Persistent = true;
OnUnitActiveSec = "1h";
};
};
};
};
}

@ -0,0 +1,4 @@
{ ... }:
{
}

@ -1,77 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.services.password-store;
inherit (lib) mkEnableOption mkOption types escapeShellArg mkIf makeBinPath;
in {
options.services.password-store = {
enable = mkEnableOption "password-store";
store = mkOption {
type = types.path;
default = "${config.home-manager.users.${config.mainuser}.xdg.dataHome}/password-store";
};
gnupgHome = mkOption {
type = types.path;
default = "${config.home-manager.users.${config.mainuser}.xdg.dataHome}/gnupg";
};
repo = mkOption {
type = types.str;
};
sshKey = mkOption {
type = types.str;
};
};
config = mkIf (cfg.enable) {
home-manager.users.${config.mainuser} = {
systemd.user.services.activate-secrets = {
Service = {
Environment = [
"GIT_SSH_COMMAND='ssh -i ${cfg.sshKey} -o IdentitiesOnly=yes'"
"PATH=${makeBinPath [ pkgs.git pkgs.openssh ]}"
];
ExecStart = pkgs.writeShellScript "activate-secrets" ''
set -euo pipefail
if [ -d "${cfg.store}/.git" ]; then
git -C "${cfg.store}" pull
else
echo "Pulling ${escapeShellArg cfg.repo}"
git clone ${escapeShellArg cfg.repo} "${cfg.store}"
fi
'';
Type = "oneshot";
};
Unit.PartOf = [ "graphical-session-pre.target" ];
Install.WantedBy = [ "graphical-session-pre.target" ];
};
systemd.user.services.pass-store-sync = {
Service = {
Environment = [
"PASSWORD_STORE_DIR=${cfg.store}"
"GIT_SSH_COMMAND='ssh -i ${cfg.sshKey} -o IdentitiesOnly=yes'"
"PATH=${with pkgs; makeBinPath [ pass-wayland inotify-tools ]}"
];
ExecStart = pkgs.writeShellScript "pass-store-sync" ''
set -euo pipefail
while inotifywait "$PASSWORD_STORE_DIR" -r -e move -e close_write -e create -e delete --exclude .git; do
sleep 0.1
pass git add --all
pass git commit -m "$(date +%F)_$(date +%T)"
pass git pull --rebase
pass git push
done
'';
};
Unit = rec {
After = [ "activate-secrets.service" ];
Wants = After;
};
Install.WantedBy = [ "graphical-session-pre.target" ];
};
programs.password-store = {
enable = true;
package = pkgs.pass-wayland;
settings.PASSWORD_STORE_DIR = cfg.store;
};
};
};
}

@ -1,111 +0,0 @@
{ config, lib, inputs, ... }:
let
cfg = config.persist;
takeAll = what: concatMap (x: x.${what});
persists = with cfg; [ state cache ];
absoluteHomePath = map (x: "${cfg.homeDir}/${x}");
allFiles = takeAll "files" persists;
allHomeFiles = takeAll "homeFiles" persists;
allDirectories = takeAll "directories" persists;
allHomeDirectories = takeAll "homeDirectories" persists;
inherit (builtins) concatMap;
inherit (lib) mkIf;
homeDirectory = config.home-manager.users.${config.mainuser}.home.homeDirectory or "/home/${config.mainuser}";
in {
options = let
inherit (lib) mkOption mkEnableOption;
inherit (lib.types) listOf path str;
common = {
directories = mkOption {
type = listOf str;
default = [ ];
};
files = mkOption {
type = listOf str;
default = [ ];
};
homeFiles = mkOption {
type = listOf str;
default = [ ];
};
homeDirectories = mkOption {
type = listOf str;
default = [ ];
};
};
in {
persist = {
enable = mkEnableOption "a tmpfs root with explicit opt-in state";
persistRoot = mkOption {
type = path;
default = "/persist";
};
homeDir = mkOption {
type = path;
default = homeDirectory;
};
# Stuff that matters
# TODO backups of this stuff
state = {
# backup = {...};
} // common;
# Stuff that's just there to speed up the system
# It's cleaned up regularly, to solve the cache invalidation problem once and for all
cache = {
clean = {
enable = mkEnableOption "cleaning the cache files and directories";
dates = mkOption {
type = str;
default = "weekly";
description =
"A systemd.time calendar description of when to clean the cache files";
};
};
} // common;
};
};
imports = [ inputs.impermanence.nixosModules.impermanence ];
config = mkIf cfg.enable {
environment.persistence.${cfg.persistRoot} = {
hideMounts = true;
directories = allDirectories;
files = allFiles;
users.${config.mainuser} = {
home = "/home/${config.mainuser}";
directories = allHomeDirectories;
files = allHomeFiles;
};
};
systemd.services.persist-cache-cleanup = lib.mkIf cfg.cache.clean.enable {
description = "Cleaning up cache files and directories";
script = ''
${builtins.concatStringsSep "\n" (map (x: "rm ${lib.escapeShellArg x}")
(cfg.cache.files
++ absoluteHomePath cfg.cache.homeFiles))}
${builtins.concatStringsSep "\n" (map (x: "rm -rf ${lib.escapeShellArg x}")
(cfg.cache.directories ++ absoluteHomePath cfg.cache.homeDirectories))}
'';
startAt = cfg.cache.clean.dates;
};
};
}

@ -1,80 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
{
options.backups.postgresql = mkOption {
description = ''
Periodic backups of postgresql database to create with Rustic.
'';
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
dbName = mkOption {
type = types.str;
default = name;
};
proxyAddress = mkOption {
type = with types; nullOr str;
default = "http://10.10.10.6:8888";
};
};
}));
default = { };
};
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
config = mkIf (config.backups.postgresql != { }) {
sops.secrets.rustic-postgresql-s3-env.sopsFile = inputs.self.secretsDir + /rustic.yaml;
sops.secrets.rustic-postgresql-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
sops.secrets.rustic-postgresql-s3-env.owner = "postgres";
sops.secrets.rustic-postgresql-pass.owner = "postgres";
services.rustic.backups =
mapAttrs'
(name: backup: nameValuePair "postgresql-${name}" ({
backup = true;
prune = true;
initialize = true;
user = "postgres";
extraEnvironment.https_proxy = mkIf (backup.proxyAddress != null) backup.proxyAddress;
environmentFile = config.sops.secrets.rustic-postgresql-s3-env.path;
pruneOpts = [ "--repack-cacheable-only=false" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
# Backup postgresql db and pass it to rustic through stdin
# Runs the next command:
# pg_dump ${dbName} | zstd --rsyncable --stdout - | rustic -P postgresql-authentik backup -
backupCommandPrefix = "${config.services.postgresql.package}/bin/pg_dump ${backup.dbName} | ${pkgs.zstd}/bin/zstd --rsyncable --stdout - |";
extraBackupArgs = [ "-" ];
# Rustic profile yaml
settings = {
repository = {
repository = "opendal:s3";
password-file = config.sops.secrets.rustic-postgresql-pass.path;
options = {
root = backup.dbName;
bucket = "ataraxia-postgresql-backups";
region = "eu-central-003";
endpoint = "https://s3.eu-central-003.backblazeb2.com";
};
};
backup = {
host = config.device;
label = backup.dbName;
ignore-devid = true;
group-by = "label";
skip-identical-parent = true;
stdin-filename = "${backup.dbName}.dump.zst";
};
forget = {
filter-labels = [ backup.dbName ];
group-by = "label";
prune = true;
keep-daily = 4;
keep-weekly = 2;
keep-monthly = 1;
};
};
})
) config.backups.postgresql;
};
}

@ -1,101 +0,0 @@
{ config, lib, pkgs, utils, ... }:
with lib;
let
inherit (utils.systemdUtils.unitOptions) unitOption;
in {
options.backups.rclone-sync = mkOption {
description = ''
Sync buckets beetween two storages.
'';
type = types.attrsOf (types.submodule ({ ... }: {
options = {
rcloneConfigFile = mkOption {
type = with types; nullOr path;
default = null;
description = ''
Path to the file containing rclone configuration. This file
must contain configuration for the remotes specified in this backup
set and also must be readable by root.
'';
};
syncOpts = mkOption {
type = with types; listOf str;
default = [ "--checksum" "--fast-list" ];
description = ''
A list of options for 'rclone sync'.
'';
};
syncTargets = mkOption {
type = with types; listOf (submodule {
options = {
source = mkOption {
type = types.str;
default = "";
description = "Source to sync.";
};
target = mkOption {
type = types.str;
default = "";
description = "Target to sync.";
};
};
});
default = { };
description = ''
List of sync targets.
'';
};
timerConfig = mkOption {
type = types.attrsOf unitOption;
default = {
OnCalendar = "06:15";
RandomizedDelaySec = "15m";
Persistent = true;
};
description = ''
When to run the backup. See {manpage}`systemd.timer(5)` for details.
'';
};
proxyAddress = mkOption {
type = with types; nullOr str;
default = "http://10.10.10.6:8888";
};
};
}));
default = { };
};
config = mkIf (config.backups.rclone-sync != { }) {
systemd.services =
mapAttrs'
(name: backup: nameValuePair "rclone-sync-${name}" ({
path = [ pkgs.rclone ];
restartIfChanged = false;
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
environment = {
RCLONE_CONFIG = backup.rcloneConfigFile;
https_proxy = mkIf (backup.proxyAddress != null) backup.proxyAddress;
};
script = lib.pipe backup.syncTargets [
(map (v: "rclone sync ${concatStringsSep " " backup.syncOpts} ${v.source} ${v.target}"))
(lib.concatStringsSep "\n")
];
serviceConfig = {
Type = "oneshot";
RuntimeDirectory = "rclone-sync-${name}";
CacheDirectory = "rclone-sync-${name}";
CacheDirectoryMode = "0700";
PrivateTmp = true;
};
})
) config.backups.rclone-sync;
systemd.timers =
mapAttrs'
(name: backup: nameValuePair "rclone-sync-${name}" {
wantedBy = [ "timers.target" ];
timerConfig = backup.timerConfig;
})
config.backups.rclone-sync;
};
}

@ -1,5 +0,0 @@
{ lib, ... }: {
options = {
mainuser = lib.mkOption { type = lib.types.str; };
};
}

@ -1,22 +0,0 @@
diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp
index 0952a7d..f61d818 100644
--- a/src/managers/input/Tablets.cpp
+++ b/src/managers/input/Tablets.cpp
@@ -159,13 +159,12 @@ void CInputManager::onTabletAxis(CTablet::SAxisEvent e) {
void CInputManager::onTabletTip(CTablet::STipEvent e) {
const auto PTAB = e.tablet;
const auto PTOOL = ensureTabletToolPresent(e.tool);
- const auto POS = e.tip;
- g_pPointerManager->warpAbsolute(POS, PTAB);
- refocusTablet(PTAB, PTOOL, true);
- if (e.in)
+ if (e.in) {
+ simulateMouseMovement();
+ refocusTablet(PTAB, PTOOL);
PROTO::tablet->down(PTOOL);
- else
+ } else
PROTO::tablet->up(PTOOL);
PTOOL->isDown = e.in;

@ -1,13 +0,0 @@
diff --git a/src/display.c b/src/display.c
index ec59959..470f69b 100644
--- a/src/display.c
+++ b/src/display.c
@@ -117,6 +117,9 @@ void nvnc_display_feed_buffer(struct nvnc_display* self, struct nvnc_fb* fb,
struct nvnc* server = self->server;
assert(server);
+ pixman_region_intersect_rect(damage, damage, 0, 0, fb->width,
+ fb->height);
+
struct pixman_region16 refined_damage;
pixman_region_init(&refined_damage);

@ -1,796 +0,0 @@
diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md
index 3bb993ec33c6..91a91beb34d6 100644
--- a/nixos/doc/manual/release-notes/rl-2405.section.md
+++ b/nixos/doc/manual/release-notes/rl-2405.section.md
@@ -709,7 +709,7 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi
and `services.kavita.settings.IpAddresses`. The file at `services.kavita.tokenKeyFile` now needs to contain a secret with
512+ bits instead of 128+ bits.
-- `services.netbird` now allows running multiple tunnels in parallel through [`services.netbird.tunnels`](#opt-services.netbird.tunnels).
+- `services.netbird` now allows running multiple tunnels in parallel through [`services.netbird.tunnels`](#opt-services.netbird.clients).
- `services.nginx.virtualHosts` using `forceSSL` or
`globalRedirect` can now have redirect codes other than 301 through `redirectCode`.
diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md
index dd2db8de5a33..daef530c8993 100644
--- a/nixos/doc/manual/release-notes/rl-2411.section.md
+++ b/nixos/doc/manual/release-notes/rl-2411.section.md
@@ -248,6 +248,9 @@
- `tests.overriding` has its `passthru.tests` restructured as an attribute set instead of a list, making individual tests accessible by their names.
+- `services.netbird.tunnels` was renamed to [`services.netbird.clients`](#opt-services.netbird.clients),
+ hardened (using dedicated less-privileged users) and significantly extended.
+
- `vaultwarden` lost the capability to bind to privileged ports. If you rely on
this behavior, override the systemd unit to allow `CAP_NET_BIND_SERVICE` in
your local configuration.
diff --git a/nixos/modules/services/networking/netbird.md b/nixos/modules/services/networking/netbird.md
index e1f6753cbd30..876c27cb0d22 100644
--- a/nixos/modules/services/networking/netbird.md
+++ b/nixos/modules/services/networking/netbird.md
@@ -2,7 +2,7 @@
## Quickstart {#module-services-netbird-quickstart}
-The absolute minimal configuration for the netbird daemon looks like this:
+The absolute minimal configuration for the Netbird client daemon looks like this:
```nix
{
@@ -13,52 +13,76 @@ The absolute minimal configuration for the netbird daemon looks like this:
This will set up a netbird service listening on the port `51820` associated to the
`wt0` interface.
-It is strictly equivalent to setting:
+Which is equivalent to:
```nix
{
- services.netbird.tunnels.wt0.stateDir = "netbird";
+ services.netbird.clients.wt0 = {
+ port = 51820;
+ name = "netbird";
+ interface = "wt0";
+ hardened = false;
+ };
}
```
-The `enable` option is mainly kept for backward compatibility, as defining netbird
-tunnels through the `tunnels` option is more expressive.
+This will set up a `netbird.service` listening on the port `51820` associated to the
+`wt0` interface. There will also be `netbird-wt0` binary installed in addition to `netbird`.
+
+see [clients](#opt-services.netbird.clients) option documentation for more details.
## Multiple connections setup {#module-services-netbird-multiple-connections}
-Using the `services.netbird.tunnels` option, it is also possible to define more than
+Using the `services.netbird.clients` option, it is possible to define more than
one netbird service running at the same time.
-The following configuration will start a netbird daemon using the interface `wt1` and
-the port 51830. Its configuration file will then be located at `/var/lib/netbird-wt1/config.json`.
+You must at least define a `port` for the service to listen on, the rest is optional:
```nix
{
- services.netbird.tunnels = {
- wt1 = {
- port = 51830;
- };
- };
+ services.netbird.clients.wt1.port = 51830;
+ services.netbird.clients.wt2.port = 51831;
}
```
-To interact with it, you will need to specify the correct daemon address:
-
-```bash
-netbird --daemon-addr unix:///var/run/netbird-wt1/sock ...
-```
+see [clients](#opt-services.netbird.clients) option documentation for more details.
-The address will by default be `unix:///var/run/netbird-<name>`.
+## Exposing services internally on the Netbird network {#module-services-netbird-firewall}
-It is also possible to overwrite default options passed to the service, for
-example:
+You can easily expose services exclusively to Netbird network by combining
+[`networking.firewall.interfaces`](#opt-networking.firewall.interfaces) rules
+with [`interface`](#opt-services.netbird.clients._name_.interface) names:
```nix
{
- services.netbird.tunnels.wt1.environment = {
- NB_DAEMON_ADDR = "unix:///var/run/toto.sock";
+ services.netbird.clients.priv.port = 51819;
+ services.netbird.clients.work.port = 51818;
+ networking.firewall.interfaces = {
+ "${config.services.netbird.clients.priv.interface}" = {
+ allowedUDPPorts = [ 1234 ];
+ };
+ "${config.services.netbird.clients.work.interface}" = {
+ allowedTCPPorts = [ 8080 ];
+ };
};
}
```
-This will set the socket to interact with the netbird service to `/var/run/toto.sock`.
+### Additional customizations {#module-services-netbird-customization}
+
+Each Netbird client service by default:
+
+- runs in a [hardened](#opt-services.netbird.clients._name_.hardened) mode,
+- starts with the system,
+- [opens up a firewall](#opt-services.netbird.clients._name_.openFirewall) for direct (without TURN servers)
+ peer-to-peer communication,
+- can be additionally configured with environment variables,
+- automatically determines whether `netbird-ui-<name>` should be available,
+
+[autoStart](#opt-services.netbird.clients._name_.autoStart) allows you to start the client (an actual systemd service)
+on demand, for example to connect to work-related or otherwise conflicting network only when required.
+See the option description for more information.
+
+[environment](#opt-services.netbird.clients._name_.environment) allows you to pass additional configurations
+through environment variables, but special care needs to be taken for overriding config location and
+daemon address due [hardened](#opt-services.netbird.clients._name_.hardened) option.
diff --git a/nixos/modules/services/networking/netbird.nix b/nixos/modules/services/networking/netbird.nix
index e68c39946fe3..dae0936deb4f 100644
--- a/nixos/modules/services/networking/netbird.nix
+++ b/nixos/modules/services/networking/netbird.nix
@@ -1,72 +1,155 @@
-{
- config,
- lib,
- pkgs,
- ...
+{ config
+, lib
+, pkgs
+, ...
}:
let
inherit (lib)
- attrNames
+ attrValues
+ concatLists
+ concatStringsSep
+ escapeShellArgs
+ filterAttrs
getExe
literalExpression
maintainers
+ makeBinPath
mapAttrs'
+ mapAttrsToList
mkDefault
- mkEnableOption
mkIf
mkMerge
mkOption
+ mkOptionDefault
mkPackageOption
+ mkRemovedOptionModule
nameValuePair
optional
+ optionalString
+ toShellVars
+ versionAtLeast
versionOlder
;
inherit (lib.types)
attrsOf
+ bool
+ enum
+ package
port
str
submodule
;
- kernel = config.boot.kernelPackages;
+ inherit (config.boot) kernelPackages;
+ inherit (config.boot.kernelPackages) kernel;
cfg = config.services.netbird;
+
+ toClientList = fn: map fn (attrValues cfg.clients);
+ toClientAttrs = fn: mapAttrs' (_: fn) cfg.clients;
+
+ hardenedClients = filterAttrs (_: client: client.hardened) cfg.clients;
+ toHardenedClientList = fn: map fn (attrValues hardenedClients);
+ toHardenedClientAttrs = fn: mapAttrs' (_: fn) hardenedClients;
+
+ nixosConfig = config;
in
{
meta.maintainers = with maintainers; [
misuzu
+ nazarewk
];
meta.doc = ./netbird.md;
+ imports = [
+ (mkRemovedOptionModule [ "services" "netbird" "tunnels" ]
+ "The option `services.netbird.tunnels` has been renamed to `services.netbird.clients`")
+ ];
+
options.services.netbird = {
- enable = mkEnableOption "Netbird daemon";
+ enable = mkOption {
+ type = bool;
+ default = false;
+ description = ''
+ Enables backwards compatible Netbird client service.
+
+ This is strictly equivalent to:
+
+ ```nix
+ services.netbird.clients.wt0 = {
+ port = 51820;
+ name = "netbird";
+ interface = "wt0";
+ hardened = false;
+ };
+ ```
+ '';
+ };
package = mkPackageOption pkgs "netbird" { };
- tunnels = mkOption {
+ ui.enable = mkOption {
+ type = bool;
+ default = config.services.displayManager.sessionPackages != [ ] || config.services.xserver.enable;
+ defaultText = literalExpression ''
+ config.services.displayManager.sessionPackages != [ ] || config.services.xserver.enable
+ '';
+ description = ''
+ Controls presence `netbird-ui` wrappers, defaults to presence of graphical sessions.
+ '';
+ };
+ ui.package = mkPackageOption pkgs "netbird-ui" { };
+
+ clients = mkOption {
type = attrsOf (
submodule (
{ name, config, ... }:
+ let client = config; in
{
options = {
port = mkOption {
type = port;
- default = 51820;
+ example = literalExpression "51820";
description = ''
- Port for the ${name} netbird interface.
+ Port the Netbird client listens on.
'';
};
+ name = mkOption {
+ type = str;
+ default = name;
+ description = ''
+ Primary name for use (as a suffix) in:
+ - systemd service name,
+ - hardened user name and group,
+ - [systemd `*Directory=`](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory=) names,
+ - desktop application identification,
+ '';
+ };
+
+ interface = mkOption {
+ type = str;
+ default = "nb-${client.name}";
+ description = ''
+ Name of the network interface managed by this client.
+ '';
+ apply = iface:
+ lib.throwIfNot (builtins.stringLength iface <= 15) "Network interface name must be 15 characters or less"
+ iface;
+ };
+
environment = mkOption {
type = attrsOf str;
defaultText = literalExpression ''
{
- NB_CONFIG = "/var/lib/''${stateDir}/config.json";
- NB_LOG_FILE = "console";
- NB_WIREGUARD_PORT = builtins.toString port;
- NB_INTERFACE_NAME = name;
- NB_DAMEON_ADDR = "/var/run/''${stateDir}"
+ NB_CONFIG = "/var/lib/netbird-''${client.name}/config.json";
+ NB_DAEMON_ADDR = "unix:///var/run/netbird-''${client.name}/sock";
+ NB_INTERFACE_NAME = config.interface;
+ NB_LOG_FILE = mkOptionDefault "console";
+ NB_LOG_LEVEL = config.logLevel;
+ NB_SERVICE = "netbird-''${client.name}";
+ NB_WIREGUARD_PORT = toString config.port;
}
'';
description = ''
@@ -74,97 +157,364 @@ in
'';
};
- stateDir = mkOption {
- type = str;
- default = "netbird-${name}";
+ autoStart = mkOption {
+ type = bool;
+ default = true;
+ description = ''
+ Start the service with the system.
+
+ As of 2024-02-13 it is not possible to start a Netbird client daemon without immediately
+ connecting to the network, but it is [planned for a near future](https://github.com/netbirdio/netbird/projects/2#card-91718018).
+ '';
+ };
+
+ openFirewall = mkOption {
+ type = bool;
+ default = true;
+ description = ''
+ Opens up firewall `port` for communication between Netbird peers directly over LAN or public IP,
+ without using (internet-hosted) TURN servers as intermediaries.
+ '';
+ };
+
+ hardened = mkOption {
+ type = bool;
+ default = true;
description = ''
- Directory storing the netbird configuration.
+ Hardened service:
+ - runs as a dedicated user with minimal set of permissions (see caveats),
+ - restricts daemon configuration socket access to dedicated user group
+ (you can grant access to it with `users.users."<user>".extraGroups = [ "netbird-${client.name}" ]`),
+
+ Even though the local system resources access is restricted:
+ - `CAP_NET_RAW`, `CAP_NET_ADMIN` and `CAP_BPF` still give unlimited network manipulation possibilites,
+ - older kernels don't have `CAP_BPF` and use `CAP_SYS_ADMIN` instead,
+
+ Known security features that are not (yet) integrated into the module:
+ - 2024-02-14: `rosenpass` is an experimental feature configurable solely
+ through `--enable-rosenpass` flag on the `netbird up` command,
+ see [the docs](https://docs.netbird.io/how-to/enable-post-quantum-cryptography)
+ '';
+ };
+
+ logLevel = mkOption {
+ type = enum [
+ # logrus loglevels
+ "panic"
+ "fatal"
+ "error"
+ "warn"
+ "warning"
+ "info"
+ "debug"
+ "trace"
+ ];
+ default = "info";
+ description = "Log level of the Netbird daemon.";
+ };
+
+ ui.enable = mkOption {
+ type = bool;
+ default = nixosConfig.services.netbird.ui.enable;
+ defaultText = literalExpression ''config.ui.enable'';
+ description = ''
+ Controls presence of `netbird-ui` wrapper for this Netbird client.
+ '';
+ };
+
+ wrapper = mkOption {
+ type = package;
+ internal = true;
+ default =
+ let
+ makeWrapperArgs = concatLists (mapAttrsToList
+ (key: value: [ "--set-default" key value ])
+ config.environment
+ );
+ in
+ pkgs.stdenv.mkDerivation {
+ name = "${cfg.package.name}-wrapper-${client.name}";
+ meta.mainProgram = "netbird-${client.name}";
+ nativeBuildInputs = with pkgs; [ makeWrapper ];
+ phases = [ "installPhase" ];
+ installPhase = concatStringsSep "\n" [
+ ''
+ mkdir -p "$out/bin"
+ makeWrapper ${lib.getExe cfg.package} "$out/bin/netbird-${client.name}" \
+ ${escapeShellArgs makeWrapperArgs}
+ ''
+ (optionalString cfg.ui.enable ''
+ # netbird-ui doesn't support envvars
+ makeWrapper ${lib.getExe cfg.ui.package} "$out/bin/netbird-ui-${client.name}" \
+ --add-flags '--daemon-addr=${config.environment.NB_DAEMON_ADDR}'
+
+ mkdir -p "$out/share/applications"
+ substitute ${cfg.ui.package}/share/applications/netbird.desktop \
+ "$out/share/applications/netbird-${client.name}.desktop" \
+ --replace-fail 'Name=Netbird' "Name=Netbird @ netbird-${client.name}" \
+ --replace-fail '${lib.getExe cfg.ui.package}' "$out/bin/netbird-ui-${client.name}"
+ '')
+ ];
+ };
+ };
+
+ # see https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82
+ config = mkOption {
+ type = (pkgs.formats.json { }).type;
+ defaultText = literalExpression ''
+ {
+ DisableAutoConnect = !config.autoStart;
+ WgIface = config.interface;
+ WgPort = config.port;
+ }
+ '';
+ description = ''
+ Additional configuration that exists before the first start and
+ later overrides the existing values in `config.json`.
+
+ It is mostly helpful to manage configuration ignored/not yet implemented
+ outside of `netbird up` invocation.
+
+ WARNING: this is not an upstream feature, it could break in the future
+ (by having lower priority) after upstream implements an equivalent.
+
+ It is implemented as a `preStart` script which overrides `config.json`
+ with content of `/etc/netbird-${client.name}/config.d/*.json` files.
+ This option manages specifically `50-nixos.json` file.
+
+ Consult [the source code](https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82)
+ or inspect existing file for a complete list of available configurations.
'';
};
};
- config.environment = builtins.mapAttrs (_: mkDefault) {
- NB_CONFIG = "/var/lib/${config.stateDir}/config.json";
- NB_LOG_FILE = "console";
- NB_WIREGUARD_PORT = builtins.toString config.port;
- NB_INTERFACE_NAME = name;
- NB_DAEMON_ADDR = "unix:///var/run/${config.stateDir}/sock";
+ config.environment = {
+ NB_CONFIG = "/var/lib/netbird-${client.name}/config.json";
+ NB_DAEMON_ADDR = "unix:///var/run/netbird-${client.name}/sock";
+ NB_INTERFACE_NAME = config.interface;
+ NB_LOG_FILE = mkOptionDefault "console";
+ NB_LOG_LEVEL = config.logLevel;
+ NB_SERVICE = "netbird-${client.name}";
+ NB_WIREGUARD_PORT = toString config.port;
+ };
+
+ config.config = {
+ DisableAutoConnect = !config.autoStart;
+ WgIface = config.interface;
+ WgPort = config.port;
};
}
)
);
default = { };
description = ''
- Attribute set of Netbird tunnels, each one will spawn a daemon listening on ...
+ Attribute set of Netbird client daemons, by default each one will:
+
+ 1. be manageable using dedicated tooling:
+ - `netbird-<name>` script,
+ - `Netbird - netbird-<name>` graphical interface when appropriate (see `ui.enable`),
+ 2. run as a `netbird-<name>.service`,
+ 3. listen for incoming remote connections on the port `51820` (`openFirewall` by default),
+ 4. manage the `netbird-<name>` wireguard interface,
+ 5. use the `/var/lib/netbird-<name>/config.json` configuration file,
+ 6. override `/var/lib/netbird-<name>/config.json` with values from `/etc/netbird-<name>/config.d/*.json`,
+ 7. (`hardened`) be locally manageable by `netbird-<name>` system group,
+
+ With following caveats:
+
+ - multiple daemons will interfere with each other's DNS resolution of `netbird.cloud`, but
+ should remain fully operational otherwise.
+ Setting up custom (non-conflicting) DNS zone is currently possible only when self-hosting.
+ '';
+ example = lib.literalExpression ''
+ {
+ services.netbird.clients.wt0.port = 51820;
+ services.netbird.clients.personal.port = 51821;
+ services.netbird.clients.work1.port = 51822;
+ }
'';
};
};
config = mkMerge [
- (mkIf cfg.enable {
- # For backwards compatibility
- services.netbird.tunnels.wt0.stateDir = "netbird";
- })
+ (mkIf cfg.enable (
+ let name = "wt0"; client = cfg.clients."${name}"; in {
+ services.netbird.clients."${name}" = {
+ port = mkDefault 51820;
+ name = mkDefault "netbird";
+ interface = mkDefault "wt0";
+ hardened = mkDefault false;
+ };
- (mkIf (cfg.tunnels != { }) {
- boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
+ environment.systemPackages = [
+ (lib.hiPrio (pkgs.runCommand "${client.name}-as-default" { } ''
+ mkdir -p "$out/bin"
+ for binary in netbird ${optionalString cfg.ui.enable "netbird-ui"} ; do
+ ln -s "${client.wrapper}/bin/$binary-${client.name}" "$out/bin/$binary"
+ done
+ ''))
+ ];
+ }
+ ))
+ {
+ boot.extraModulePackages = optional
+ (cfg.clients != { } && (versionOlder kernel.version "5.6"))
+ kernelPackages.wireguard;
- environment.systemPackages = [ cfg.package ];
+ environment.systemPackages =
+ toClientList (client: client.wrapper)
+ # omitted due to https://github.com/netbirdio/netbird/issues/1562
+ #++ optional (cfg.clients != { }) cfg.package
+ # omitted due to https://github.com/netbirdio/netbird/issues/1581
+ #++ optional (cfg.clients != { } && cfg.ui.enable) cfg.ui.package
+ ;
- networking.dhcpcd.denyInterfaces = attrNames cfg.tunnels;
+ networking.dhcpcd.denyInterfaces = toClientList (client: client.interface);
+ networking.networkmanager.unmanaged = toClientList (client: "interface-name:${client.interface}");
- systemd.network.networks = mkIf config.networking.useNetworkd (
- mapAttrs'
- (
- name: _:
- nameValuePair "50-netbird-${name}" {
- matchConfig = {
- Name = name;
- };
- linkConfig = {
- Unmanaged = true;
- ActivationPolicy = "manual";
- };
- }
- )
- cfg.tunnels
- );
+ networking.firewall.allowedUDPPorts = concatLists (toClientList (client: optional client.openFirewall client.port));
- systemd.services =
- mapAttrs'
- (
- name:
- { environment, stateDir, ... }:
- nameValuePair "netbird-${name}" {
- description = "A WireGuard-based mesh network that connects your devices into a single private network";
+ systemd.network.networks = mkIf config.networking.useNetworkd (toClientAttrs (client:
+ nameValuePair "50-netbird-${client.interface}" {
+ matchConfig = {
+ Name = client.interface;
+ };
+ linkConfig = {
+ Unmanaged = true;
+ ActivationPolicy = "manual";
+ };
+ }
+ ));
- documentation = [ "https://netbird.io/docs/" ];
+ environment.etc = toClientAttrs (client: nameValuePair "netbird-${client.name}/config.d/50-nixos.json" {
+ text = builtins.toJSON client.config;
+ mode = "0444";
+ });
- after = [ "network.target" ];
- wantedBy = [ "multi-user.target" ];
+ systemd.services = toClientAttrs (client: nameValuePair "netbird-${client.name}" {
+ description = "A WireGuard-based mesh network that connects your devices into a single private network";
- path = with pkgs; [ openresolv ];
+ documentation = [ "https://netbird.io/docs/" ];
- inherit environment;
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
- serviceConfig = {
- ExecStart = "${getExe cfg.package} service run";
- Restart = "always";
- RuntimeDirectory = stateDir;
- StateDirectory = stateDir;
- StateDirectoryMode = "0700";
- WorkingDirectory = "/var/lib/${stateDir}";
- };
+ path = optional (!config.services.resolved.enable) pkgs.openresolv;
- unitConfig = {
- StartLimitInterval = 5;
- StartLimitBurst = 10;
- };
+ serviceConfig = {
+ ExecStart = "${getExe client.wrapper} service run";
+ Restart = "always";
+
+ RuntimeDirectory = "netbird-${client.name}";
+ RuntimeDirectoryMode = mkDefault "0755";
+ ConfigurationDirectory = "netbird-${client.name}";
+ StateDirectory = "netbird-${client.name}";
+ StateDirectoryMode = "0700";
+
+ WorkingDirectory = "/var/lib/netbird-${client.name}";
+ };
+
+ unitConfig = {
+ StartLimitInterval = 5;
+ StartLimitBurst = 10;
+ };
+
+ stopIfChanged = false;
+ });
+ }
+ # Hardening section
+ (mkIf (hardenedClients != { }) {
+ users.groups = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" { });
+ users.users = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" {
+ isSystemUser = true;
+ home = "/var/lib/netbird-${client.name}";
+ group = "netbird-${client.name}";
+ });
+
+ systemd.services = toHardenedClientAttrs (client: nameValuePair "netbird-${client.name}" (mkIf client.hardened {
+ serviceConfig = {
+ RuntimeDirectoryMode = "0750";
+
+ User = "netbird-${client.name}";
+ Group = "netbird-${client.name}";
+
+ # settings implied by DynamicUser=true, without actully using it,
+ # see https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser=
+ RemoveIPC = true;
+ PrivateTmp = true;
+ ProtectSystem = "strict";
+ ProtectHome = "yes";
- stopIfChanged = false;
- }
- )
- cfg.tunnels;
+ AmbientCapabilities = [
+ # see https://man7.org/linux/man-pages/man7/capabilities.7.html
+ # see https://docs.netbird.io/how-to/installation#running-net-bird-in-docker
+ #
+ # seems to work fine without CAP_SYS_ADMIN and CAP_SYS_RESOURCE
+ # CAP_NET_BIND_SERVICE could be added to allow binding on low ports, but is not required,
+ # see https://github.com/netbirdio/netbird/pull/1513
+
+ # failed creating tunnel interface wt-priv: [operation not permitted
+ "CAP_NET_ADMIN"
+ # failed to pull up wgInterface [wt-priv]: failed to create ipv4 raw socket: socket: operation not permitted
+ "CAP_NET_RAW"
+ ]
+ # required for eBPF filter, used to be subset of CAP_SYS_ADMIN
+ ++ optional (versionAtLeast kernel.version "5.8") "CAP_BPF"
+ ++ optional (versionOlder kernel.version "5.8") "CAP_SYS_ADMIN"
+ ;
+ };
+ }));
+
+ # see https://github.com/systemd/systemd/blob/17f3e91e8107b2b29fe25755651b230bbc81a514/src/resolve/org.freedesktop.resolve1.policy#L43-L43
+ # see all actions used at https://github.com/netbirdio/netbird/blob/13e7198046a0d73a9cd91bf8e063fafb3d41885c/client/internal/dns/systemd_linux.go#L29-L32
+ security.polkit.extraConfig = mkIf config.services.resolved.enable ''
+ // systemd-resolved access for Netbird clients
+ polkit.addRule(function(action, subject) {
+ var actions = [
+ "org.freedesktop.resolve1.revert",
+ "org.freedesktop.resolve1.set-default-route",
+ "org.freedesktop.resolve1.set-dns-servers",
+ "org.freedesktop.resolve1.set-domains",
+ ];
+ var users = ${builtins.toJSON (toHardenedClientList (client: "netbird-${client.name}"))};
+
+ if (actions.indexOf(action.id) >= 0 && users.indexOf(subject.user) >= 0 ) {
+ return polkit.Result.YES;
+ }
+ });
+ '';
})
+ # migration & temporary fixups section
+ {
+ systemd.services = toClientAttrs (client: nameValuePair "netbird-${client.name}" {
+ preStart = ''
+ set -eEuo pipefail
+ ${optionalString (client.logLevel == "trace" || client.logLevel == "debug") "set -x"}
+
+ PATH="${makeBinPath (with pkgs; [coreutils jq diffutils])}:$PATH"
+ export ${toShellVars client.environment}
+
+ # merge /etc/netbird-${client.name}/config.d' into "$NB_CONFIG"
+ {
+ test -e "$NB_CONFIG" || echo -n '{}' > "$NB_CONFIG"
+
+ # merge config.d with "$NB_CONFIG" into "$NB_CONFIG.new"
+ jq -sS 'reduce .[] as $i ({}; . * $i)' \
+ "$NB_CONFIG" \
+ /etc/netbird-${client.name}/config.d/*.json \
+ > "$NB_CONFIG.new"
+
+ echo "Comparing $NB_CONFIG with $NB_CONFIG.new ..."
+ if ! diff <(jq -S <"$NB_CONFIG") "$NB_CONFIG.new" ; then
+ echo "Updating $NB_CONFIG ..."
+ mv "$NB_CONFIG.new" "$NB_CONFIG"
+ else
+ echo "Files are the same, not doing anything."
+ rm "$NB_CONFIG.new"
+ fi
+ }
+ '';
+ });
+ }
];
}
diff --git a/nixos/tests/netbird.nix b/nixos/tests/netbird.nix
index 7342e8d04a39..063fff6d42f0 100644
--- a/nixos/tests/netbird.nix
+++ b/nixos/tests/netbird.nix
@@ -12,10 +12,32 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
};
};
+ # TODO: confirm the whole solution is working end-to-end when netbird server is implemented
testScript = ''
start_all()
- node.wait_for_unit("netbird-wt0.service")
+ node.wait_for_unit("netbird.service")
node.wait_for_file("/var/run/netbird/sock")
- node.succeed("netbird status | grep -q 'Daemon status: NeedsLogin'")
+ output = node.succeed("netbird status")
+ # used to print `Daemon status: NeedsLogin`, but not anymore `Management: Disconnected`
+ assert "Disconnected" in output or "NeedsLogin" in output
'';
+
+ /*
+ `netbird status` used to print `Daemon status: NeedsLogin`
+ https://github.com/netbirdio/netbird/blob/23a14737974e3849fa86408d136cc46db8a885d0/client/cmd/status.go#L154-L164
+ as the first line, but now it is just:
+
+ Daemon version: 0.26.3
+ CLI version: 0.26.3
+ Management: Disconnected
+ Signal: Disconnected
+ Relays: 0/0 Available
+ Nameservers: 0/0 Available
+ FQDN:
+ NetBird IP: N/A
+ Interface type: N/A
+ Quantum resistance: false
+ Routes: -
+ Peers count: 0/0 Connected
+ */
})
diff --git a/pkgs/tools/networking/netbird/default.nix b/pkgs/tools/networking/netbird/default.nix
index c4bce67ff89d..7a27c2bbef10 100644
--- a/pkgs/tools/networking/netbird/default.nix
+++ b/pkgs/tools/networking/netbird/default.nix
@@ -111,6 +111,6 @@ buildGoModule rec {
description = "Connect your devices into a single secure private WireGuard®-based mesh network with SSO/MFA and simple access controls";
license = licenses.bsd3;
maintainers = with maintainers; [ misuzu vrifox ];
- mainProgram = "netbird";
+ mainProgram = if ui then "netbird-ui" else "netbird";
};
}

@ -1,16 +0,0 @@
diff --git a/pkgs/os-specific/linux/kernel/zen-kernels.nix b/pkgs/os-specific/linux/kernel/zen-kernels.nix
index 9d1566216..c3113eb5c 100644
--- a/pkgs/os-specific/linux/kernel/zen-kernels.nix
+++ b/pkgs/os-specific/linux/kernel/zen-kernels.nix
@@ -11,9 +11,9 @@ let
};
# ./update-zen.py lqx
lqxVariant = {
- version = "6.9.8"; #lqx
+ version = "6.8.11"; #lqx
suffix = "lqx1"; #lqx
- sha256 = "1r5ld2xibr0qkwi1yy7h746sclsmd8cq68z0zdpbbn2qrgyx302k"; #lqx
+ sha256 = "1dj4znir4wp6jqs680dcxn8z6p02d518993rmrx54ch04jyy5brj"; #lqx
isLqx = true;
};
zenKernelsFor = { version, suffix, sha256, isLqx }: buildLinux (args // {

@ -1,13 +0,0 @@
{ config, pkgs, inputs, ... }: {
sops.secrets.github-token.sopsFile = inputs.self.secretsDir + /amd-workstation/misc.yaml;
sops.secrets.github-token.owner = config.mainuser;
home-manager.users.${config.mainuser} = {
home.packages = [ pkgs.act ];
home.file.".actrc".text = ''
--secret-file ${config.sops.secrets.github-token.path}
-P ubuntu-latest=catthehacker/ubuntu:act-latest
-P ubuntu-22.04=catthehacker/ubuntu:act-22.04
'';
};
}

@ -1,96 +0,0 @@
{ config, pkgs, ... }: {
# TODO: enable websocket (--rpc-certificate)
home-manager.users.${config.mainuser} = { config, ...}:
let
homeDir = config.home.homeDirectory;
in {
# home.packages = [ pkgs.ariang ];
programs.aria2 = {
enable = true;
settings = {
### Basic ###
dir = "${homeDir}/Downloads";
input-file = "${homeDir}/.config/aria2/aria2.session";
save-session = "${homeDir}/.config/aria2/aria2.session";
save-session-interval = 60;
max-concurrent-downloads = 5;
continue = true;
max-overall-download-limit = 0;
max-download-limit = 0;
quiet = true;
### Advanced ###
allow-overwrite = true;
allow-piece-length-change = true;
always-resume = true;
async-dns = false;
auto-file-renaming = true;
content-disposition-default-utf8 = true;
disk-cache = "64M";
file-allocation = "falloc";
no-file-allocation-limit = "8M";
# Set log level to output to console. LEVEL is either debug, info, notice, warn or error. Default: notice
console-log-level = "notice";
# Set log level to output. LEVEL is either debug, info, notice, warn or error. Default: debug
log-level = "warn";
log = "${homeDir}/.config/aria2/aria2.log";
### RPC ###
enable-rpc = true;
pause = false;
rpc-save-upload-metadata = true;
rpc-allow-origin-all = true;
rpc-listen-all = false;
rpc-listen-port = 49100;
# rpc-secret=
# The certificate must be either in PKCS12 (.p12, .pfx) or in PEM format. When using PEM, you have to specify the private key via --rpc-private-key as well.
# rpc-certificate=
# rpc-private-key=
rpc-secure = false;
### HTTP/FTP/SFTP ###
max-connection-per-server = 16;
min-split-size = "8M";
split = 32;
# user-agent = "Transmission/4.0.2";
### BitTorrent ###
# bt-save-metadata=false
listen-port = "49101-49109";
# max-overall-upload-limit=256K
# max-upload-limit=0
seed-ratio = 0.1;
seed-time = 0;
# bt-enable-lpd = false;
enable-dht = true;
enable-dht6 = true;
dht-listen-port = "49101-49109";
dht-entry-point = "dht.transmissionbt.com:6881";
dht-entry-point6 = "dht.transmissionbt.com:6881";
dht-file-path = "${homeDir}/.config/aria2/dht.dat";
dht-file-path6 = "${homeDir}/.config/aria2/dht6.dat";
enable-peer-exchange = true;
# peer-id-prefix = "-TR2770-";
peer-agent = "Transmission/4.0.2";
# bt-tracker = "";
};
};
systemd.user.services.aria2 = {
Unit.Description = "aria2 is a download utility operated in command-line";
Service = {
Restart = "on-failure";
ExecStart = "${pkgs.aria2}/bin/aria2c";
};
Install.WantedBy = [ "default.target" ];
};
};
systemd.tmpfiles.rules = [
"f /home/${config.mainuser}/.config/aria2/aria2.session 0644 ${config.mainuser} users -"
"f /home/${config.mainuser}/.config/aria2/dht.dat 0644 ${config.mainuser} users -"
"f /home/${config.mainuser}/.config/aria2/dht6.dat 0644 ${config.mainuser} users -"
];
persist.state.homeDirectories = [ ".config/aria2" ];
}

@ -1,40 +0,0 @@
{ config, pkgs, inputs, ... }:
let
homeDir = config.home-manager.users.${config.mainuser}.home.homeDirectory;
token-file = config.sops.secrets.attic-token.path;
attic-config = pkgs.writeText "config.toml" ''
default-server = "dev"
[servers.dev]
endpoint = "https://cache.ataraxiadev.com/"
token = "@token@"
'';
nix-config = pkgs.writeText "netrc" ''
machine cache.ataraxiadev.com
password @token@
'';
in {
home-manager.users.${config.mainuser} = {
home.packages = [ pkgs.attic-client ];
nix.settings = {
substituters = config.nix.settings.substituters;
trusted-public-keys = config.nix.settings.trusted-public-keys;
netrc-file = "${homeDir}/.config/nix/netrc";
};
};
sops.secrets.attic-token.sopsFile = inputs.self.secretsDir + /misc.yaml;
sops.secrets.attic-token.restartUnits = [ "attic-config.service" ];
systemd.services.attic-config = {
serviceConfig.Type = "oneshot";
script = ''
token=$(cat ${token-file})
mkdir -p ${homeDir}/.config/{nix,attic} > /dev/null 2>&1
cp ${attic-config} ${homeDir}/.config/attic/config.toml
cp ${nix-config} ${homeDir}/.config/nix/netrc
sed -i "s/@token@/$token/" ${homeDir}/.config/attic/config.toml
sed -i "s/@token@/$token/" ${homeDir}/.config/nix/netrc
chown -R ${config.mainuser}:users ${homeDir}/.config/{attic,nix}
'';
wantedBy = [ "multi-user.target" ];
};
}

@ -1,8 +0,0 @@
{ config, pkgs, ... }: {
home-manager.users.${config.mainuser} = {
home.packages = [ pkgs.cassowary-py ];
};
persist.state.homeDirectories = [
".config/casualrdh"
];
}

@ -1,16 +0,0 @@
{ pkgs, lib, config, ... }:
with config.deviceSpecific; {
config = lib.mkIf (devInfo.gpu.vendor == "amd") {
programs.corectrl = {
enable = true;
gpuOverclock.enable = true;
gpuOverclock.ppfeaturemask = "0xffffffff";
};
startupApplications = [ "${pkgs.corectrl}/bin/corectrl" ];
persist.state.homeDirectories = [
".config/corectrl"
];
};
}

Some files were not shown because too many files have changed in this diff Show More