Compare commits
No commits in common. "be45a769c7c59a46fcd1ee3fa24a3d4b1186ee17" and "master" have entirely different histories.
be45a769c7
...
master
14
.envrc
14
.envrc
@ -1,13 +1 @@
|
|||||||
if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then
|
use flake
|
||||||
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
|
|
9
.github/dependabot.yml
vendored
Normal file
9
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
groups:
|
||||||
|
github-actions:
|
||||||
|
patterns: ["*"]
|
51
.github/workflows/hosts.yml
vendored
Normal file
51
.github/workflows/hosts.yml
vendored
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
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*
|
48
.github/workflows/iso.yml
vendored
Normal file
48
.github/workflows/iso.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
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
5
.gitignore
vendored
@ -1,7 +1,6 @@
|
|||||||
/anywhere
|
|
||||||
.direnv
|
.direnv
|
||||||
.devenv
|
.VSCodeCounter
|
||||||
.pre-commit-config.yaml
|
anywhere
|
||||||
result*
|
result*
|
||||||
*.bak
|
*.bak
|
||||||
*.qcow2
|
*.qcow2
|
||||||
|
64
.sops.yaml
Normal file
64
.sops.yaml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
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
|
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"files.eol": "\n",
|
||||||
|
"[nix]": {
|
||||||
|
"editor.tabSize": 2
|
||||||
|
},
|
||||||
|
"cSpell.enabled": false
|
||||||
|
}
|
11
README.md
11
README.md
@ -1,3 +1,10 @@
|
|||||||
# NixOS configuration
|
NixOS Configurations
|
||||||
|
=======================
|
||||||
|
|
||||||
WIP
|
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)!
|
73
TODO.md
Normal file
73
TODO.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# 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
|
||||||
|
```
|
2352
flake.lock
generated
2352
flake.lock
generated
File diff suppressed because it is too large
Load Diff
286
flake.nix
286
flake.nix
@ -1,20 +1,11 @@
|
|||||||
{
|
{
|
||||||
description = "AtaraxiaSjel's NixOS configuration.";
|
description = "System configuration";
|
||||||
|
|
||||||
nixConfig = {
|
|
||||||
extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=";
|
|
||||||
extra-substituters = "https://devenv.cachix.org";
|
|
||||||
};
|
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
lite-config.url = "github:ataraxiasjel/lite-config/v0.6.0";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
devenv.url = "github:cachix/devenv";
|
nixpkgs-master.url = "github:nixos/nixpkgs/master";
|
||||||
devenv-root = {
|
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11";
|
||||||
url = "file+file:///dev/null";
|
|
||||||
flake = false;
|
|
||||||
};
|
|
||||||
flake-registry = {
|
flake-registry = {
|
||||||
url = "github:nixos/flake-registry";
|
url = "github:nixos/flake-registry";
|
||||||
flake = false;
|
flake = false;
|
||||||
@ -23,68 +14,237 @@
|
|||||||
url = "github:nix-community/home-manager";
|
url = "github:nix-community/home-manager";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
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 =
|
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (
|
||||||
inputs:
|
{ self, inputs, withSystem, ... }:
|
||||||
inputs.flake-parts.lib.mkFlake { inherit inputs; } (
|
let
|
||||||
{ ... }:
|
findModules = dir:
|
||||||
{
|
builtins.concatLists (
|
||||||
imports = [
|
builtins.attrValues (
|
||||||
inputs.devenv.flakeModule
|
builtins.mapAttrs (name: type:
|
||||||
inputs.lite-config.flakeModule
|
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)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
lite-config = {
|
# Patch nixpkgs
|
||||||
nixpkgs = {
|
nixpkgs-patched = n: p:
|
||||||
nixpkgs = inputs.nixpkgs;
|
(import n { system = "x86_64-linux"; }).pkgs.applyPatches {
|
||||||
config = { };
|
name = if n ? shortRev then "nixpkgs-patched-${n.shortRev}" else "nixpkgs-patched";
|
||||||
overlays = [ ];
|
src = n;
|
||||||
patches = [ ./patches/onlyoffice.patch ];
|
patches = p;
|
||||||
exportOverlayPackages = false;
|
};
|
||||||
setPerSystemPkgs = true;
|
# 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; };
|
||||||
};
|
};
|
||||||
|
|
||||||
systemModules = [ ./modules/nixos ];
|
patchesPath = map (x: ./patches + "/${x}");
|
||||||
homeModules = [ ./modules/home ];
|
in {
|
||||||
hostModuleDir = ./hosts;
|
imports = [ ];
|
||||||
|
systems = [ "x86_64-linux" ];
|
||||||
|
|
||||||
hosts = {
|
perSystem = { pkgs, self', ... }: {
|
||||||
NixOS-VM.system = "x86_64-linux";
|
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";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
perSystem =
|
flake = let
|
||||||
{ pkgs, lib, ... }:
|
unstable-nixpkgs = nixpkgs-patched inputs.nixpkgs unstable-patches;
|
||||||
{
|
stable-nixpkgs = nixpkgs-patched inputs.nixpkgs-stable stable-patches;
|
||||||
devenv.shells.default = {
|
unstable-system = nixosSystem unstable-nixpkgs;
|
||||||
devenv.root =
|
stable-system = nixosSystem stable-nixpkgs;
|
||||||
let
|
|
||||||
devenvRootFileContent = builtins.readFile inputs.devenv-root.outPath;
|
|
||||||
in
|
|
||||||
lib.mkIf (devenvRootFileContent != "") devenvRootFileContent;
|
|
||||||
|
|
||||||
name = "nixos-config";
|
shared-patches = patchesPath [ ];
|
||||||
packages = builtins.attrValues {
|
unstable-patches = shared-patches ++ patchesPath [
|
||||||
inherit (pkgs) nixfmt-rfc-style git sops;
|
# "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;
|
||||||
};
|
};
|
||||||
pre-commit.hooks = {
|
nixosSystem = unstable-system;
|
||||||
actionlint.enable = true;
|
format = "vm";
|
||||||
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;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
28
keys/hosts/amd-workstation.asc
Normal file
28
keys/hosts/amd-workstation.asc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----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-----
|
28
keys/hosts/dell-laptop.asc
Normal file
28
keys/hosts/dell-laptop.asc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----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-----
|
28
keys/hosts/home-hypervisor.asc
Normal file
28
keys/hosts/home-hypervisor.asc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----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-----
|
28
keys/hosts/nixos-vps.asc
Normal file
28
keys/hosts/nixos-vps.asc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----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-----
|
28
keys/hosts/suomi-vps.asc
Normal file
28
keys/hosts/suomi-vps.asc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----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-----
|
17
keys/users/ataraxia.asc
Normal file
17
keys/users/ataraxia.asc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
-----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-----
|
23
machines/AMD-Workstation/autoinstall.nix
Normal file
23
machines/AMD-Workstation/autoinstall.nix
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{ ... }: {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
86
machines/AMD-Workstation/boot.nix
Normal file
86
machines/AMD-Workstation/boot.nix
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{ 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 <<<"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
199
machines/AMD-Workstation/default.nix
Normal file
199
machines/AMD-Workstation/default.nix
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
{ 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";
|
||||||
|
}
|
108
machines/AMD-Workstation/hardware-configuration.nix
Normal file
108
machines/AMD-Workstation/hardware-configuration.nix
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# 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";
|
||||||
|
}
|
93
machines/AMD-Workstation/kernel/default.nix
Normal file
93
machines/AMD-Workstation/kernel/default.nix
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
{ 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";
|
||||||
|
}];
|
||||||
|
}
|
17
machines/AMD-Workstation/kernel/fix-znver-clang18.patch
Normal file
17
machines/AMD-Workstation/kernel/fix-znver-clang18.patch
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
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
|
40
machines/AMD-Workstation/kernel/no-dynamic-linker.patch
Normal file
40
machines/AMD-Workstation/kernel/no-dynamic-linker.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
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
machines/AMD-Workstation/system
Normal file
1
machines/AMD-Workstation/system
Normal file
@ -0,0 +1 @@
|
|||||||
|
x86_64-linux
|
188
machines/AMD-Workstation/vm/nixos-vm.xml
Normal file
188
machines/AMD-Workstation/vm/nixos-vm.xml
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<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>
|
221
machines/AMD-Workstation/vm/win10code.xml
Normal file
221
machines/AMD-Workstation/vm/win10code.xml
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
<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>
|
||||||
|
|
229
machines/AMD-Workstation/vm/win10ed.xml
Normal file
229
machines/AMD-Workstation/vm/win10ed.xml
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<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>
|
||||||
|
|
22
machines/Dell-Laptop/autoinstall.nix
Normal file
22
machines/Dell-Laptop/autoinstall.nix
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{ ... }: {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
69
machines/Dell-Laptop/boot.nix
Normal file
69
machines/Dell-Laptop/boot.nix
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{ 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 <<<"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
58
machines/Dell-Laptop/default.nix
Normal file
58
machines/Dell-Laptop/default.nix
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{ 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";
|
||||||
|
}
|
119
machines/Dell-Laptop/hardware-configuration.nix
Normal file
119
machines/Dell-Laptop/hardware-configuration.nix
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# 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
machines/Dell-Laptop/system
Normal file
1
machines/Dell-Laptop/system
Normal file
@ -0,0 +1 @@
|
|||||||
|
x86_64-linux
|
84
machines/Flakes-ISO/default.nix
Normal file
84
machines/Flakes-ISO/default.nix
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{ 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";
|
||||||
|
};
|
||||||
|
}
|
72
machines/Home-Hypervisor/backups.nix
Normal file
72
machines/Home-Hypervisor/backups.nix
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
103
machines/Home-Hypervisor/boot.nix
Normal file
103
machines/Home-Hypervisor/boot.nix
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
{ 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 <<<"
|
||||||
|
# '';
|
||||||
|
# };
|
||||||
|
}
|
162
machines/Home-Hypervisor/default.nix
Normal file
162
machines/Home-Hypervisor/default.nix
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
{ 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";
|
||||||
|
}
|
279
machines/Home-Hypervisor/disk-config.nix
Normal file
279
machines/Home-Hypervisor/disk-config.nix
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
{ ... }:
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
101
machines/Home-Hypervisor/dns-mapping.nix
Normal file
101
machines/Home-Hypervisor/dns-mapping.nix
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
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"
|
||||||
|
];
|
||||||
|
}
|
21
machines/Home-Hypervisor/hardware/networks.nix
Normal file
21
machines/Home-Hypervisor/hardware/networks.nix
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
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 = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
83
machines/Home-Hypervisor/networking.nix
Normal file
83
machines/Home-Hypervisor/networking.nix
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
168
machines/Home-Hypervisor/nginx.nix
Normal file
168
machines/Home-Hypervisor/nginx.nix
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
{ 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
machines/Home-Hypervisor/system
Normal file
1
machines/Home-Hypervisor/system
Normal file
@ -0,0 +1 @@
|
|||||||
|
x86_64-linux
|
36
machines/Home-Hypervisor/virtualisation.nix
Normal file
36
machines/Home-Hypervisor/virtualisation.nix
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
197
machines/Home-Hypervisor/vm/omv.xml
Normal file
197
machines/Home-Hypervisor/vm/omv.xml
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
<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>
|
||||||
|
|
276
machines/NixOS-FI-VPS/default.nix
Normal file
276
machines/NixOS-FI-VPS/default.nix
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
{ 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";
|
||||||
|
}
|
100
machines/NixOS-FI-VPS/disk-config.nix
Normal file
100
machines/NixOS-FI-VPS/disk-config.nix
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
{ 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" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
97
machines/NixOS-FI-VPS/hardware/networks.nix
Normal file
97
machines/NixOS-FI-VPS/hardware/networks.nix
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
73
machines/NixOS-FI-VPS/network.nix
Normal file
73
machines/NixOS-FI-VPS/network.nix
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
65
machines/NixOS-FI-VPS/services/backups.nix
Normal file
65
machines/NixOS-FI-VPS/services/backups.nix
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
239
machines/NixOS-FI-VPS/services/dns.nix
Normal file
239
machines/NixOS-FI-VPS/services/dns.nix
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
{ 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"
|
||||||
|
];
|
||||||
|
}
|
38
machines/NixOS-FI-VPS/services/tailscale.nix
Normal file
38
machines/NixOS-FI-VPS/services/tailscale.nix
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{ 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}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
112
machines/NixOS-FI-VPS/services/xtls.nix
Normal file
112
machines/NixOS-FI-VPS/services/xtls.nix
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
{ 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
machines/NixOS-FI-VPS/system
Normal file
1
machines/NixOS-FI-VPS/system
Normal file
@ -0,0 +1 @@
|
|||||||
|
x86_64-linux
|
281
machines/NixOS-RO-VPS/default.nix
Normal file
281
machines/NixOS-RO-VPS/default.nix
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
{ 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";
|
||||||
|
}
|
100
machines/NixOS-RO-VPS/disk-config.nix
Normal file
100
machines/NixOS-RO-VPS/disk-config.nix
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
{ 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" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
101
machines/NixOS-RO-VPS/dns-mapping.nix
Normal file
101
machines/NixOS-RO-VPS/dns-mapping.nix
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
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"
|
||||||
|
];
|
||||||
|
}
|
97
machines/NixOS-RO-VPS/hardware/networks.nix
Normal file
97
machines/NixOS-RO-VPS/hardware/networks.nix
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
73
machines/NixOS-RO-VPS/network.nix
Normal file
73
machines/NixOS-RO-VPS/network.nix
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
65
machines/NixOS-RO-VPS/services/backups.nix
Normal file
65
machines/NixOS-RO-VPS/services/backups.nix
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
239
machines/NixOS-RO-VPS/services/dns.nix
Normal file
239
machines/NixOS-RO-VPS/services/dns.nix
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
{ 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"
|
||||||
|
];
|
||||||
|
}
|
38
machines/NixOS-RO-VPS/services/tailscale.nix
Normal file
38
machines/NixOS-RO-VPS/services/tailscale.nix
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{ 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}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
46
machines/NixOS-RO-VPS/services/tor-bridge.nix
Normal file
46
machines/NixOS-RO-VPS/services/tor-bridge.nix
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{ 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" ];
|
||||||
|
}
|
132
machines/NixOS-RO-VPS/services/wireguard.nix
Normal file
132
machines/NixOS-RO-VPS/services/wireguard.nix
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
{ 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" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
112
machines/NixOS-RO-VPS/services/xtls.nix
Normal file
112
machines/NixOS-RO-VPS/services/xtls.nix
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
{ 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
machines/NixOS-RO-VPS/system
Normal file
1
machines/NixOS-RO-VPS/system
Normal file
@ -0,0 +1 @@
|
|||||||
|
x86_64-linux
|
@ -1,25 +1,28 @@
|
|||||||
{
|
{ modulesPath, self, inputs, config, pkgs, ... }: {
|
||||||
modulesPath,
|
disabledModules = [ "${self}/modules/pass-store.nix" ];
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
"${modulesPath}/profiles/qemu-guest.nix"
|
"${modulesPath}/profiles/qemu-guest.nix"
|
||||||
"${modulesPath}/virtualisation/qemu-vm.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.memorySize = 4096;
|
||||||
virtualisation.cores = 4;
|
virtualisation.cores = 4;
|
||||||
virtualisation.resolution.x = 1920;
|
virtualisation.resolution.x = 1920;
|
||||||
virtualisation.resolution.y = 1080;
|
virtualisation.resolution.y = 1080;
|
||||||
virtualisation.qemu.options = [
|
virtualisation.qemu.options = ["-vga none" "-device virtio-vga-gl" "-display gtk,gl=on"];
|
||||||
"-vga qxl"
|
|
||||||
"-display gtk"
|
services.desktopManager.cosmic.enable = true;
|
||||||
];
|
services.displayManager.cosmic-greeter.enable = true;
|
||||||
|
|
||||||
users.mutableUsers = false;
|
users.mutableUsers = false;
|
||||||
users.users.ataraxia = {
|
users.users.${config.mainuser} = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
hashedPassword = "$y$j9T$ZC44T3XYOPapB26cyPsA4.$8wlYEbwXFszC9nrg0vafqBZFLMPabXdhnzlT3DhUit6";
|
hashedPassword = "$y$j9T$ZC44T3XYOPapB26cyPsA4.$8wlYEbwXFszC9nrg0vafqBZFLMPabXdhnzlT3DhUit6";
|
1
machines/NixOS-VM/system
Normal file
1
machines/NixOS-VM/system
Normal file
@ -0,0 +1 @@
|
|||||||
|
x86_64-linux
|
BIN
misc/AAVMF_CODE.fd.zst
Normal file
BIN
misc/AAVMF_CODE.fd.zst
Normal file
Binary file not shown.
BIN
misc/AAVMF_VARS.fd.zst
Normal file
BIN
misc/AAVMF_VARS.fd.zst
Normal file
Binary file not shown.
1943
misc/grafana_blocky_rev3.json
Normal file
1943
misc/grafana_blocky_rev3.json
Normal file
File diff suppressed because it is too large
Load Diff
20
misc/mitmproxy-ca-cert.pem
Normal file
20
misc/mitmproxy-ca-cert.pem
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
-----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-----
|
28
misc/telemetry.hosts
Normal file
28
misc/telemetry.hosts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
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
|
BIN
misc/wallpaper.mkv
Normal file
BIN
misc/wallpaper.mkv
Normal file
Binary file not shown.
BIN
misc/wallpaper.png
Normal file
BIN
misc/wallpaper.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 487 KiB |
24
modules/applications.nix
Normal file
24
modules/applications.nix
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{ 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 = {};
|
||||||
|
};
|
||||||
|
}
|
188
modules/autoinstall/default.nix
Normal file
188
modules/autoinstall/default.nix
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
}
|
428
modules/autoinstall/install.nix
Executable file
428
modules/autoinstall/install.nix
Executable file
@ -0,0 +1,428 @@
|
|||||||
|
{ 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
|
||||||
|
''
|
81
modules/crypt-mount.nix
Normal file
81
modules/crypt-mount.nix
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
157
modules/devices.nix
Normal file
157
modules/devices.nix
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
76
modules/headscale-auth.nix
Normal file
76
modules/headscale-auth.nix
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
}
|
@ -1,4 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
103
modules/kiwix-serve.nix
Normal file
103
modules/kiwix-serve.nix
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
{ 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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
468
modules/libvirt-guests.nix
Normal file
468
modules/libvirt-guests.nix
Normal file
@ -0,0 +1,468 @@
|
|||||||
|
{ 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);
|
||||||
|
}
|
40
modules/modprobed-db.nix
Normal file
40
modules/modprobed-db.nix
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{ 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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -1,4 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
77
modules/pass-store.nix
Normal file
77
modules/pass-store.nix
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
111
modules/persist.nix
Normal file
111
modules/persist.nix
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
80
modules/rustic-postgresql.nix
Normal file
80
modules/rustic-postgresql.nix
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
}
|
101
modules/s3-sync.nix
Normal file
101
modules/s3-sync.nix
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
}
|
5
modules/users.nix
Normal file
5
modules/users.nix
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{ lib, ... }: {
|
||||||
|
options = {
|
||||||
|
mainuser = lib.mkOption { type = lib.types.str; };
|
||||||
|
};
|
||||||
|
}
|
22
patches/hyprland-tablet.patch
Normal file
22
patches/hyprland-tablet.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
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;
|
13
patches/neatvnc.patch
Normal file
13
patches/neatvnc.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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);
|
796
patches/netbird-24.11.patch
Normal file
796
patches/netbird-24.11.patch
Normal file
@ -0,0 +1,796 @@
|
|||||||
|
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";
|
||||||
|
};
|
||||||
|
}
|
16
patches/zen-kernels.patch
Normal file
16
patches/zen-kernels.patch
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
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 // {
|
13
profiles/applications/act.nix
Normal file
13
profiles/applications/act.nix
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
96
profiles/applications/aria2.nix
Normal file
96
profiles/applications/aria2.nix
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
{ 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" ];
|
||||||
|
}
|
40
profiles/applications/attic.nix
Normal file
40
profiles/applications/attic.nix
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{ 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" ];
|
||||||
|
};
|
||||||
|
}
|
8
profiles/applications/cassowary.nix
Normal file
8
profiles/applications/cassowary.nix
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{ config, pkgs, ... }: {
|
||||||
|
home-manager.users.${config.mainuser} = {
|
||||||
|
home.packages = [ pkgs.cassowary-py ];
|
||||||
|
};
|
||||||
|
persist.state.homeDirectories = [
|
||||||
|
".config/casualrdh"
|
||||||
|
];
|
||||||
|
}
|
16
profiles/applications/corectrl.nix
Normal file
16
profiles/applications/corectrl.nix
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{ 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
Loading…
x
Reference in New Issue
Block a user