My Nix Configuration

Compare changes

Choose any two refs to compare.

Changed files
+4002 -5194
devShells
homeModules
hosts
lib
nixosModules
default-config
default-users
dn42Wireguard
homes
pyrox
pyrox-zaphod
thehedgehog
thehedgehog-zaphod
programs
firefox
hyprland
misc
neovim
services
forgejo-runner
overlays
cinny
hy3-fixes
nix-index
openssh-fixperms
packages
+6 -6
.envrc
···
-
if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then
-
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM="
+
if ! has nix_direnv_version || ! nix_direnv_version 3.1.0; then
+
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.1.0/direnvrc" "sha256-yMJ2OVMzrFaDPn7q8nCBZFRYpL/f0RcHzhmw/i6btJM="
fi
+
export NH_NOM=1
export NH_LOG=nh=info
-
export NH_FLAKE=$(pwd)
+
NH_FLAKE=$(pwd)
+
export NH_FLAKE
-
if [[ $(hostname) == "zaphod" ]]; then
-
use flake . --accept-flake-config
-
fi
+
use flake . --accept-flake-config
+31
.nvim.lua
···
+
local nvim_lsp = require("lspconfig")
+
nvim_lsp.nixd.setup({
+
cmd = { "nixd" },
+
settings = {
+
nixd = {
+
nixpkgs = {
+
expr = "import <nixpkgs> { }",
+
},
+
formatting = {
+
command = { "treefmt" },
+
},
+
options = {
+
nixos = {
+
expr = "(builtins.getFlake (builtins.toString ./.)).nixosConfigurations.zaphod.options",
+
},
+
home_manager = {
+
expr = "(builtins.getFlake (builtins.toString ./.)).nixosConfigurations.zaphod.options.home-manager.users.type.getSubOptions []",
+
},
+
flake_parts = {
+
expr = "(builtins.getFlake (builtins.toString ./.)).debug.options",
+
},
+
flake_parts_perSystem = {
+
expr = "(builtins.getFlake (builtins.toString ./.)).currentSystem.options",
+
},
+
my_modules = {
+
exper = "(pkgs.lib.evalModules { modules = (builtins.getFlake (builtins.toString ./.)).nixosModules; }).options",
+
},
+
},
+
},
+
},
+
})
+1
.shellcheckrc
···
+
disable=SC2148
+4 -2
Justfile
···
alias s := switch
build:
-
nh os build . --verbose -- --show-trace --accept-flake-config
+
nixos-rebuild-ng build --flake . --accept-flake-config --verbose --show-trace \
+
--max-jobs 3 --cores 6 \
+
&& nvd diff /run/current-system result
switch:
-
nh os switch . --verbose -- --show-trace --accept-flake-config
+
nixos-rebuild-ng switch --flake . --accept-flake-config --verbose --show-trace --sudo
-6
MIGRATE.md
···
-
- [ ] easy-hosts
-
- [ ] HM Configs
-
- [x] modules
-
- [x] packages
-
- [x] devShells
-
- [x] overlays
+30 -18
README.md
···
# PyroConf, a custom Nix config
## No Place Like ~
-
This is PyroNet's (relatively) production-grade NixOS config repo. It contains configurations for 3 different machines, as well as `home-manager` configurations.
-
I try to keep the configuration organized. All home-manager related items go in `/home`, host configurations go in `/hosts`, and custom packages are in `/pkgs`, among other folders.
+
This is PyroNet's (relatively) production-grade NixOS config repo. It contains configurations for 3 different machines,
+
as well as `home-manager` configurations.
-
My machines serve production infra for *.pyrox.dev domains. There are a few exceptions:
-
* [My blog](https://blog.pyrox.dev), and the [root domain](https://pyrox.dev) which are served by [OMG.LOL](https://omg.lol).
-
I highly recommend their services, as you get a great domain name at a company that cares about you. If you do sign up, consider using [my referral link](https://omg.lol?refer=py), as I get 3 months of service credit if you sign up through it.
+
I try to keep the configuration organized. All home-manager related items go in `/home`, host configurations go in
+
`/hosts`, and custom packages are in `/pkgs`, among other folders.
+
+
My machines serve production infra for \*.pyrox.dev domains. There are a few exceptions:
+
+
- [My blog](https://blog.pyrox.dev), and the [root domain](https://pyrox.dev) which are served by
+
[OMG.LOL](https://omg.lol). I highly recommend their services, as you get a great domain name at a company that cares
+
about you. If you do sign up, consider using [my referral link](https://omg.lol?refer=py), as I get 3 months of
+
service credit if you sign up through it.
There are some services I run that many homelabs do not. They are:
-
* Authoritative DNS for my domains, run on `prefect`.
-
* A Tailscale tunnel from `marvin` to `prefect` which allows me to run services on `marvin` while having them be externally accessible.
-
* Email services for my domains, also run on `prefect`, with all email data backed up hourly to `marvin`, ensuring data reliability.
-
* Connections to the [DN42](https://dn42.us) network, run on `prefect`.
+
+
- Authoritative DNS for my domains, run on `prefect`.
+
- A Tailscale tunnel from `marvin` to `prefect` which allows me to run services on `marvin` while having them be
+
externally accessible.
+
- Email services for my domains, also run on `prefect`, with all email data backed up hourly to `marvin`, ensuring data
+
reliability.
+
- Connections to the [DN42](https://dn42.us) network, run on `prefect`.
I also run many typical homelab services, such as:
-
* [Vaultwarden](https://github.com/danigarcia/vaultwarden) for passwords
-
* [Jellyfin](https://jellyfin.org) for media
-
* [Authentik](https://goauthentik.io) for central auth
-
* And many more
+
+
- [Vaultwarden](https://github.com/danigarcia/vaultwarden) for passwords
+
- [Jellyfin](https://jellyfin.org) for media
+
- [Authentik](https://goauthentik.io) for central auth
+
- And many more
# Contact
-
If you have any questions about any of the services I run, or would like to reach out, my contact info is on my profile [here](https://pyrox.dev)
+
+
If you have any questions about any of the services I run, or would like to reach out, my contact info is on my profile
+
[here](https://pyrox.dev)
# License
-
Copyright (c) 2023 Pyrox and PyroNet. All rights reserved.
-
This Source Code Form is subject to the terms of the Mozilla Public
-
License, v. 2.0. If a copy of the MPL was not distributed with this
-
file, You can obtain one at <http://mozilla.org/MPL/2.0/>.
+
+
Copyright (c) 2023 Pyrox and PyroNet. All rights reserved. This Source Code Form is subject to the terms of the Mozilla
+
Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at
+
<http://mozilla.org/MPL/2.0/>.
-2
TODO.md
···
- [ ] Move all Docker containers to using native versions of databases, redis, etc.
- Ensures higher performance and reduces the number of running containers.
- https://github.com/felschr/nixos-config/blob/main/services/immich.nix for an example of how to do it
-
- [ ] Add Archivebox service(needs custom module)
-
- [ ] Add Immich service
## Zaphod
+7
devShells/default/default.nix
···
}:
pkgs.mkShellNoCC {
packages = [
+
# keep-sorted start
pkgs.deadnix
pkgs.just
pkgs.nil
+
pkgs.nix-output-monitor
pkgs.nix-tree
+
pkgs.nix-update
pkgs.nixd
pkgs.nixfmt-rfc-style
+
pkgs.nixos-rebuild-ng
+
pkgs.nvd
pkgs.statix
+
pkgs.tokei
+
# keep-sorted endd
];
}
+1 -4
devShells/default.nix
···
-
{
-
...
-
}:
-
{
+
_: {
perSystem =
{ pkgs, ... }:
{
+267 -349
flake.lock
···
{
"nodes": {
+
"actor-typeahead-src": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1762835797,
+
"narHash": "sha256-heizoWUKDdar6ymfZTnj3ytcEv/L4d4fzSmtr0HlXsQ=",
+
"ref": "refs/heads/main",
+
"rev": "677fe7f743050a4e7f09d4a6f87bbf1325a06f6b",
+
"revCount": 6,
+
"type": "git",
+
"url": "https://tangled.org/@jakelazaroff.com/actor-typeahead"
+
},
+
"original": {
+
"type": "git",
+
"url": "https://tangled.org/@jakelazaroff.com/actor-typeahead"
+
}
+
},
"agenix": {
"inputs": {
"darwin": "darwin",
···
"nixpkgs": [
"nixpkgs"
],
-
"systems": [
-
"systems"
-
]
+
"systems": "systems"
},
"locked": {
-
"lastModified": 1754433428,
-
"narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=",
+
"lastModified": 1762618334,
+
"narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=",
"owner": "ryantm",
"repo": "agenix",
-
"rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d",
+
"rev": "fcdea223397448d35d9b31f798479227e80183f6",
"type": "github"
},
"original": {
···
"type": "github"
}
},
-
"blobs": {
-
"flake": false,
+
"bird": {
+
"inputs": {
+
"flake-utils": "flake-utils",
+
"nixpkgs": [
+
"dn42",
+
"nixpkgs"
+
]
+
},
"locked": {
-
"lastModified": 1604995301,
-
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
-
"owner": "simple-nixos-mailserver",
-
"repo": "blobs",
-
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
-
"type": "gitlab"
+
"lastModified": 1757884119,
+
"narHash": "sha256-RF0Em7PjDRaQ5cBFgc3fL22qgDVbv2HoVW1TDRaaSNo=",
+
"owner": "NuschtOS",
+
"repo": "bird.nix",
+
"rev": "f8d18c2c8eebd477987001a9c0af50a9ca7909e5",
+
"type": "github"
},
"original": {
-
"owner": "simple-nixos-mailserver",
-
"repo": "blobs",
-
"type": "gitlab"
+
"owner": "NuschtOS",
+
"repo": "bird.nix",
+
"type": "github"
}
},
"buildbot-nix": {
···
"treefmt-nix": []
},
"locked": {
-
"lastModified": 1758897213,
-
"narHash": "sha256-pLZgNsmCMhTWd8aRuGkK23ik5nclpIn1flnURKH6QjI=",
+
"lastModified": 1763946641,
+
"narHash": "sha256-kPP7k2b+Dkd91yJO01y3l1F0t+Mqvv8+FrPfjcCwszg=",
"owner": "nix-community",
"repo": "buildbot-nix",
-
"rev": "985d069a2a45cf4a571a4346107671adc2bd2a16",
+
"rev": "cd32d1c420320383bfcc80c1b0b402b6a7eccc23",
"type": "github"
},
"original": {
···
"type": "github"
}
},
+
"caelestia": {
+
"inputs": {
+
"caelestia-cli": "caelestia-cli",
+
"nixpkgs": [
+
"nixpkgs"
+
],
+
"quickshell": [
+
"quickshell"
+
]
+
},
+
"locked": {
+
"lastModified": 1764466211,
+
"narHash": "sha256-rBK+usqfAP9ZuEthw9wMCwTKQgKUMmziuzrrkpDZdzY=",
+
"owner": "caelestia-dots",
+
"repo": "shell",
+
"rev": "40813e520582c5df11f6d4c870a31900fe171cce",
+
"type": "github"
+
},
+
"original": {
+
"owner": "caelestia-dots",
+
"repo": "shell",
+
"type": "github"
+
}
+
},
+
"caelestia-cli": {
+
"inputs": {
+
"caelestia-shell": [
+
"caelestia"
+
],
+
"nixpkgs": [
+
"caelestia",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1764381410,
+
"narHash": "sha256-WR/oQQjveFqQxo8oHngZuOVgBQINDgPe+lCXLeNhAAg=",
+
"owner": "caelestia-dots",
+
"repo": "cli",
+
"rev": "ed12d4cb82600872a82feb577711be1148c7af35",
+
"type": "github"
+
},
+
"original": {
+
"owner": "caelestia-dots",
+
"repo": "cli",
+
"type": "github"
+
}
+
},
"ctp": {
"inputs": {
"nixpkgs": "nixpkgs"
},
"locked": {
-
"lastModified": 1759572023,
-
"narHash": "sha256-2fzYq/m2PXie5WZO5LhyiZrTIUdUFp1SCLZAwvPL5xo=",
+
"lastModified": 1764325801,
+
"narHash": "sha256-LQ7tsrXs1wuB6KBwUctL3JlUsG/FWI2pCI6NkoO52dk=",
"owner": "catppuccin",
"repo": "nix",
-
"rev": "eeada12912d80d04733383d231a9d66172858718",
+
"rev": "a696fed6b9b6aa89ef495842cdca3fc2a7cef0de",
"type": "github"
},
"original": {
···
"type": "github"
}
},
-
"determinate": {
+
"dgop": {
"inputs": {
-
"determinate-nixd-aarch64-darwin": "determinate-nixd-aarch64-darwin",
-
"determinate-nixd-aarch64-linux": "determinate-nixd-aarch64-linux",
-
"determinate-nixd-x86_64-darwin": [
-
"determinate",
-
"determinate-nixd-aarch64-darwin"
-
],
-
"determinate-nixd-x86_64-linux": "determinate-nixd-x86_64-linux",
-
"nix": [
-
"dix"
-
],
"nixpkgs": [
+
"dms",
"nixpkgs"
]
},
"locked": {
-
"lastModified": 1757699119,
-
"narHash": "sha256-iOOoVdrkcyk95Xg68TuPeAwpz+v80mgZCqil0jpPZuY=",
-
"owner": "DeterminateSystems",
-
"repo": "determinate",
-
"rev": "1e16c8f8a44573bb0648c76b6c98352436f5171e",
+
"lastModified": 1762435535,
+
"narHash": "sha256-QhzRn7pYN35IFpKjjxJAj3GPJECuC+VLhoGem3ezycc=",
+
"owner": "AvengeMedia",
+
"repo": "dgop",
+
"rev": "6cf638dde818f9f8a2e26d0243179c43cb3458d7",
"type": "github"
},
"original": {
-
"owner": "DeterminateSystems",
-
"repo": "determinate",
+
"owner": "AvengeMedia",
+
"repo": "dgop",
"type": "github"
}
},
-
"determinate-nixd-aarch64-darwin": {
-
"flake": false,
+
"dms": {
+
"inputs": {
+
"dgop": "dgop",
+
"nixpkgs": [
+
"nixpkgs"
+
]
+
},
"locked": {
-
"narHash": "sha256-q1tqDvmfjDgLk/wbYf4pRhyHDS94iY85Q79FPBtcv7g=",
-
"type": "file",
-
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.11.2/macOS"
+
"lastModified": 1764553800,
+
"narHash": "sha256-kHlx3E3K2UNWI1Hpbyl5zieoOVevZfwz8P/OcyViDHY=",
+
"owner": "AvengeMedia",
+
"repo": "DankMaterialShell",
+
"rev": "7959a795753d9f646cfb9e21cfb778adf7e5c933",
+
"type": "github"
},
"original": {
-
"type": "file",
-
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.11.2/macOS"
+
"owner": "AvengeMedia",
+
"repo": "DankMaterialShell",
+
"type": "github"
}
},
-
"determinate-nixd-aarch64-linux": {
+
"dms-plugins": {
"flake": false,
"locked": {
-
"narHash": "sha256-E1vGfcQ5dqtRG9EDP6eOQWCnCIRB2XFkFBp2C4FgQ8c=",
-
"type": "file",
-
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.11.2/aarch64-linux"
+
"lastModified": 1764085668,
+
"narHash": "sha256-KtOu12NVLdyho9T4EXJaReNhFO98nAXpemkb6yeOvwE=",
+
"owner": "AvengeMedia",
+
"repo": "dms-plugins",
+
"rev": "3bc66f186a8184cb8eca5fdfc0699cb4a828cd90",
+
"type": "github"
},
"original": {
-
"type": "file",
-
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.11.2/aarch64-linux"
+
"owner": "AvengeMedia",
+
"repo": "dms-plugins",
+
"type": "github"
}
},
-
"determinate-nixd-x86_64-linux": {
+
"dms-power-usage": {
"flake": false,
"locked": {
-
"narHash": "sha256-GtxtkI0cOC2A30Xw6gCDTN7JxN1zJGh7/eIXr6AlTSA=",
-
"type": "file",
-
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.11.2/x86_64-linux"
+
"lastModified": 1760429135,
+
"narHash": "sha256-M/H4nlAzUFrxZ01ldaR/YH1hqVN4vlBrkaCUqjtMaTM=",
+
"owner": "Daniel-42-z",
+
"repo": "dms-power-usage",
+
"rev": "3f75b651d90210c6f9442a099cf14262ac47750d",
+
"type": "github"
},
"original": {
-
"type": "file",
-
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.11.2/x86_64-linux"
+
"owner": "Daniel-42-z",
+
"repo": "dms-power-usage",
+
"type": "github"
}
},
-
"dix": {
-
"inputs": {
-
"flake-parts": [],
-
"git-hooks-nix": [],
-
"nixpkgs": [
-
"nixpkgs"
-
],
-
"nixpkgs-23-11": [],
-
"nixpkgs-regression": []
-
},
+
"dms-wp-shuffler": {
+
"flake": false,
"locked": {
-
"lastModified": 1757694985,
-
"narHash": "sha256-3Ia+y7Hbwnzcuf1hyuVnFtbnSR6ErQeFjemHdVxjCNE=",
-
"rev": "766f43aa6acb1b3578db488c19fbbedf04ed9f24",
-
"revCount": 22340,
-
"type": "tarball",
-
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nix-src/3.11.2/01993ee9-f8e7-7b80-80df-ec0a20a32514/source.tar.gz"
+
"lastModified": 1760657995,
+
"narHash": "sha256-71kZLdVZmWMG+sgpbPHH8RFGmvLWve9NNTpZNJXrRd4=",
+
"owner": "Daniel-42-z",
+
"repo": "dms-wallpaper-shuffler",
+
"rev": "cc459906990e562d3a332bd5c6869e8f5af1ee52",
+
"type": "github"
},
"original": {
-
"type": "tarball",
-
"url": "https://flakehub.com/f/DeterminateSystems/nix-src/%2A"
+
"owner": "Daniel-42-z",
+
"repo": "dms-wallpaper-shuffler",
+
"type": "github"
}
},
-
"dns": {
+
"dn42": {
"inputs": {
-
"flake-utils": [
-
"flake-utils"
-
],
+
"bird": "bird",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
-
"lastModified": 1759510210,
-
"narHash": "sha256-rR3BuhcSyQ3bQ0rS14I53O7gWzlPEs15skl1TWx+TeI=",
-
"owner": "nix-community",
-
"repo": "dns.nix",
-
"rev": "f3cb11f642d4fa6224e2b1ddfd2c3ba42e9ffea2",
+
"lastModified": 1764646680,
+
"narHash": "sha256-HEVzGL23bev8CuZXbLgDZRWy+mD/qPZhRBpjag7G/dU=",
+
"owner": "pyrox0",
+
"repo": "dn43.nix",
+
"rev": "c8b68602cf1ef696e6a9f9c25e8c177d4101331b",
"type": "github"
},
"original": {
-
"owner": "nix-community",
-
"repo": "dns.nix",
+
"owner": "pyrox0",
+
"repo": "dn43.nix",
"type": "github"
}
},
···
},
"flake-compat": {
"locked": {
-
"lastModified": 1747046372,
-
"narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=",
+
"lastModified": 1761588595,
+
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
"owner": "edolstra",
"repo": "flake-compat",
-
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
+
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
"type": "github"
},
"original": {
···
},
"flake-parts": {
"inputs": {
-
"nixpkgs-lib": [
-
"nixpkgs-lib"
-
]
+
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
-
"lastModified": 1759362264,
-
"narHash": "sha256-wfG0S7pltlYyZTM+qqlhJ7GMw2fTF4mLKCIVhLii/4M=",
+
"lastModified": 1763759067,
+
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
"owner": "hercules-ci",
"repo": "flake-parts",
-
"rev": "758cf7296bee11f1706a574c77d072b8a7baa881",
+
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
"type": "github"
},
"original": {
···
},
"flake-utils": {
"inputs": {
-
"systems": [
-
"systems"
-
]
+
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
···
},
"flake-utils_2": {
"inputs": {
-
"systems": "systems_2"
+
"systems": "systems_3"
},
"locked": {
-
"lastModified": 1694529238,
-
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
+
"lastModified": 1731533236,
+
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
-
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
···
},
"flake-utils_3": {
"inputs": {
-
"systems": "systems_3"
+
"systems": "systems_5"
},
"locked": {
-
"lastModified": 1731533236,
-
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+
"lastModified": 1694529238,
+
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
-
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
···
"type": "github"
}
},
-
"git-hooks": {
-
"inputs": {
-
"flake-compat": [
-
"mailserver",
-
"flake-compat"
-
],
-
"gitignore": "gitignore",
-
"nixpkgs": [
-
"mailserver",
-
"nixpkgs"
-
]
-
},
-
"locked": {
-
"lastModified": 1758108966,
-
"narHash": "sha256-ytw7ROXaWZ7OfwHrQ9xvjpUWeGVm86pwnEd1QhzawIo=",
-
"owner": "cachix",
-
"repo": "git-hooks.nix",
-
"rev": "54df955a695a84cd47d4a43e08e1feaf90b1fd9b",
-
"type": "github"
-
},
-
"original": {
-
"owner": "cachix",
-
"repo": "git-hooks.nix",
-
"type": "github"
-
}
-
},
-
"gitignore": {
-
"inputs": {
-
"nixpkgs": [
-
"mailserver",
-
"git-hooks",
-
"nixpkgs"
-
]
-
},
-
"locked": {
-
"lastModified": 1709087332,
-
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
-
"owner": "hercules-ci",
-
"repo": "gitignore.nix",
-
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
-
"type": "github"
-
},
-
"original": {
-
"owner": "hercules-ci",
-
"repo": "gitignore.nix",
-
"type": "github"
-
}
-
},
"golink": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
-
"systems": [
-
"systems"
-
]
+
"systems": "systems_4"
},
"locked": {
-
"lastModified": 1757610027,
-
"narHash": "sha256-EYc0BuEchmltffjrQaT3O8HDBWf4gaK9ejAkriFToTM=",
+
"lastModified": 1764170522,
+
"narHash": "sha256-4c9jCOfkKNRHJLXgOIcVcNSaw/XaiVaqesaLJn86wGA=",
"owner": "tailscale",
"repo": "golink",
-
"rev": "e33c1c26e134a3f1ee61233d4108c4e7bb5530b5",
+
"rev": "6821994de926c565d3ef9fbf3cb0e0fcb780f4be",
"type": "github"
},
"original": {
···
},
"gomod2nix": {
"inputs": {
-
"flake-utils": "flake-utils_2",
+
"flake-utils": "flake-utils_3",
"nixpkgs": [
"tangled",
"nixpkgs"
···
},
"hardware": {
"locked": {
-
"lastModified": 1759582739,
-
"narHash": "sha256-spZegilADH0q5OngM86u6NmXxduCNv5eX9vCiUPhOYc=",
+
"lastModified": 1764440730,
+
"narHash": "sha256-ZlJTNLUKQRANlLDomuRWLBCH5792x+6XUJ4YdFRjtO4=",
"owner": "nixos",
"repo": "nixos-hardware",
-
"rev": "3441b5242af7577230a78ffb03542add264179ab",
+
"rev": "9154f4569b6cdfd3c595851a6ba51bfaa472d9f3",
"type": "github"
},
"original": {
···
]
},
"locked": {
-
"lastModified": 1759853171,
-
"narHash": "sha256-uqbhyXtqMbYIiMqVqUhNdSuh9AEEkiasoK3mIPIVRhk=",
+
"lastModified": 1764544324,
+
"narHash": "sha256-GVBGjO7UsmzLrlOJV8NlKSxukHaHencrJqWkCA6FkqI=",
"owner": "nix-community",
"repo": "home-manager",
-
"rev": "1a09eb84fa9e33748432a5253102d01251f72d6d",
+
"rev": "e4e25a8c310fa45f2a8339c7972dc43d2845a612",
"type": "github"
},
"original": {
···
"url": "https://github.com/IBM/plex/releases/download/@ibm/plex-mono@1.1.0/ibm-plex-mono.zip"
}
},
-
"iceshrimp": {
-
"inputs": {
-
"nixpkgs": [
-
"nixpkgs"
-
]
-
},
-
"locked": {
-
"lastModified": 1721338360,
-
"narHash": "sha256-1CEhakLtPq+Lqo+p40wo00hkewmyzPAvjBr8ah6Faqk=",
-
"ref": "refs/heads/dev",
-
"rev": "98c3678cfbcea5e750a5947394d35a73ae72634a",
-
"revCount": 48,
-
"type": "git",
-
"url": "https://iceshrimp.dev/pyrox/packaging"
-
},
-
"original": {
-
"type": "git",
-
"url": "https://iceshrimp.dev/pyrox/packaging"
-
}
-
},
"indigo": {
"flake": false,
"locked": {
···
"url": "https://github.com/lucide-icons/lucide/releases/download/0.536.0/lucide-icons-0.536.0.zip"
}
},
-
"mailserver": {
-
"inputs": {
-
"blobs": "blobs",
-
"flake-compat": [
-
"flake-compat"
-
],
-
"git-hooks": "git-hooks",
-
"nixpkgs": [
-
"nixpkgs"
-
],
-
"nixpkgs-25_05": "nixpkgs-25_05"
-
},
-
"locked": {
-
"lastModified": 1759489698,
-
"narHash": "sha256-2lT2i5ha23I2vrolEaBaAS/63ChgZPh181Awt6q1bDY=",
-
"owner": "simple-nixos-mailserver",
-
"repo": "nixos-mailserver",
-
"rev": "6005d88bed7a5418f9772b4058a73cd0fd1e69a1",
-
"type": "gitlab"
-
},
-
"original": {
-
"owner": "simple-nixos-mailserver",
-
"ref": "master",
-
"repo": "nixos-mailserver",
-
"type": "gitlab"
-
}
-
},
"my-pkgs": {
"inputs": {
"nixpkgs": [
···
"url": "https://git.pyrox.dev/pyrox/pkgs"
}
},
-
"nix-index": {
-
"inputs": {
-
"flake-compat": [
-
"flake-compat"
-
],
-
"nixpkgs": [
-
"nixpkgs"
-
]
-
},
-
"locked": {
-
"lastModified": 1756113554,
-
"narHash": "sha256-fFDr5BYisjkEFSgf+dGJTuhMUaH0aVE6Qy3Ql2EOJ2I=",
-
"owner": "nix-community",
-
"repo": "nix-index",
-
"rev": "0fc38040a22a08052103d0fbbafd67ac54165f2b",
-
"type": "github"
-
},
-
"original": {
-
"owner": "nix-community",
-
"repo": "nix-index",
-
"type": "github"
-
}
-
},
"nix-index-database": {
"inputs": {
"nixpkgs": [
···
]
},
"locked": {
-
"lastModified": 1759637156,
-
"narHash": "sha256-8NI1SqntLfKl6Q0Luemc3aIboezSJElofUrqipF5g78=",
+
"lastModified": 1764475780,
+
"narHash": "sha256-77jL5H5x51ksLiOUDjY0ZK8e2T4ZXLhj3ap8ETvknWI=",
"owner": "Mic92",
"repo": "nix-index-database",
-
"rev": "0ca69684091aa3a6b1fe994c4afeff305b15e915",
+
"rev": "5a3ff8c1a09003f399f43d5742d893c0b1ab8af0",
"type": "github"
},
"original": {
···
"type": "github"
}
},
-
"nix-search": {
-
"inputs": {
-
"flake-compat": [
-
"flake-compat"
-
],
-
"flake-utils": [
-
"flake-utils"
-
],
-
"nixpkgs": [
-
"nixpkgs"
-
]
-
},
-
"locked": {
-
"lastModified": 1741306118,
-
"narHash": "sha256-699XDyrMhx0nSI2z/WRhTsJhiiMt4WqaPx8//cPiBGY=",
-
"owner": "diamondburned",
-
"repo": "nix-search",
-
"rev": "7dcd7b9ae3ec59b7a8ee61371157f83e6bd87b89",
-
"type": "github"
-
},
-
"original": {
-
"owner": "diamondburned",
-
"repo": "nix-search",
-
"type": "github"
-
}
-
},
"nixpkgs": {
"locked": {
-
"lastModified": 1759381078,
-
"narHash": "sha256-gTrEEp5gEspIcCOx9PD8kMaF1iEmfBcTbO0Jag2QhQs=",
+
"lastModified": 1763966396,
+
"narHash": "sha256-6eeL1YPcY1MV3DDStIDIdy/zZCDKgHdkCmsrLJFiZf0=",
"owner": "NixOS",
"repo": "nixpkgs",
-
"rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee",
+
"rev": "5ae3b07d8d6527c42f17c876e404993199144b6a",
"type": "github"
},
"original": {
···
"type": "github"
}
},
-
"nixpkgs-25_05": {
-
"locked": {
-
"lastModified": 1759143472,
-
"narHash": "sha256-TvODmeR2W7yX/JmOCmP+lAFNkTT7hAxYcF3Kz8SZV3w=",
-
"owner": "NixOS",
-
"repo": "nixpkgs",
-
"rev": "5ed4e25ab58fd4c028b59d5611e14ea64de51d23",
-
"type": "github"
-
},
-
"original": {
-
"owner": "NixOS",
-
"ref": "nixos-25.05",
-
"repo": "nixpkgs",
-
"type": "github"
-
}
-
},
"nixpkgs-lib": {
"locked": {
-
"lastModified": 1754788789,
-
"narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=",
+
"lastModified": 1761765539,
+
"narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
-
"rev": "a73b9c743612e4244d865a2fdee11865283c04e6",
+
"rev": "719359f4562934ae99f5443f20aa06c2ffff91fc",
"type": "github"
},
"original": {
···
},
"nixpkgs-stalwart-fix": {
"locked": {
-
"lastModified": 1755293787,
-
"narHash": "sha256-L+msFwg9jXAj4JmDFQF9BIg2kQhgUzexVmDYePfKMW8=",
+
"lastModified": 1762728499,
+
"narHash": "sha256-XtT/8ID3gz9RGk8ITBnktmodq5/ZG6tF60XSfuKSmro=",
"owner": "pyrox0",
"repo": "nixpkgs",
-
"rev": "52f6d43ca3db097cde5d0bfb30db0af5bdf41103",
+
"rev": "b5178ff139339638e98a1e5833add22b047f96d0",
"type": "github"
},
"original": {
···
},
"nixpkgs_2": {
"locked": {
-
"lastModified": 315532800,
-
"narHash": "sha256-K9s0wLYHHR9syJV2Ii28kDT65NeT5EI8vH56/CKm924=",
-
"rev": "8b5c9dd8856f0c0cf46cc91f2c21c106a9d42e25",
+
"lastModified": 1764527385,
+
"narHash": "sha256-gpwyCnyi2or0InBXe+4I9YeED3Uly3EGH58qvVnchBY=",
+
"rev": "23258e03aaa49b3a68597e3e50eb0cbce7e42e9d",
"type": "tarball",
-
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.11pre874129.8b5c9dd8856f/nixexprs.tar.xz"
+
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre904683.23258e03aaa4/nixexprs.tar.xz"
},
"original": {
"type": "tarball",
···
"type": "github"
}
},
-
"nixpkgs_4": {
+
"quickshell": {
+
"inputs": {
+
"nixpkgs": [
+
"nixpkgs"
+
]
+
},
"locked": {
-
"lastModified": 1759036355,
-
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
-
"owner": "nixos",
-
"repo": "nixpkgs",
-
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
+
"lastModified": 1764482797,
+
"narHash": "sha256-ynV90KoBrPe38YFlKAHtPFk4Ee3IANUsIFGxRaq7H/s=",
+
"owner": "quickshell-mirror",
+
"repo": "quickshell",
+
"rev": "d24e8e9736287d01ee73ef9d573d2bc316a62d5c",
"type": "github"
},
"original": {
-
"owner": "nixos",
-
"ref": "nixos-unstable",
-
"repo": "nixpkgs",
+
"owner": "quickshell-mirror",
+
"repo": "quickshell",
"type": "github"
}
},
···
"inputs": {
"agenix": "agenix",
"buildbot-nix": "buildbot-nix",
+
"caelestia": "caelestia",
"ctp": "ctp",
-
"determinate": "determinate",
-
"dix": "dix",
-
"dns": "dns",
+
"dms": "dms",
+
"dms-plugins": "dms-plugins",
+
"dms-power-usage": "dms-power-usage",
+
"dms-wp-shuffler": "dms-wp-shuffler",
+
"dn42": "dn42",
"easy-hosts": "easy-hosts",
"flake-compat": "flake-compat",
"flake-parts": "flake-parts",
-
"flake-utils": "flake-utils",
+
"flake-utils": "flake-utils_2",
"golink": "golink",
"hardware": "hardware",
"home-manager": "home-manager",
-
"iceshrimp": "iceshrimp",
-
"mailserver": "mailserver",
"my-pkgs": "my-pkgs",
-
"nix-index": "nix-index",
"nix-index-database": "nix-index-database",
-
"nix-search": "nix-search",
"nixpkgs": "nixpkgs_2",
-
"nixpkgs-lib": "nixpkgs-lib",
"nixpkgs-stalwart-fix": "nixpkgs-stalwart-fix",
-
"stable": "stable",
-
"systems": "systems",
+
"quickshell": "quickshell",
"tangled": "tangled",
-
"vicinae": "vicinae"
+
"treefmt-nix": "treefmt-nix"
}
},
"sqlite-lib-src": {
···
"original": {
"type": "tarball",
"url": "https://sqlite.org/2024/sqlite-amalgamation-3450100.zip"
-
}
-
},
-
"stable": {
-
"locked": {
-
"lastModified": 1735563628,
-
"narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=",
-
"owner": "nixos",
-
"repo": "nixpkgs",
-
"rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798",
-
"type": "github"
-
},
-
"original": {
-
"owner": "nixos",
-
"ref": "nixos-24.05",
-
"repo": "nixpkgs",
-
"type": "github"
}
},
"systems": {
···
"type": "github"
}
},
+
"systems_4": {
+
"locked": {
+
"lastModified": 1681028828,
+
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+
"owner": "nix-systems",
+
"repo": "default",
+
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-systems",
+
"repo": "default",
+
"type": "github"
+
}
+
},
+
"systems_5": {
+
"locked": {
+
"lastModified": 1681028828,
+
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+
"owner": "nix-systems",
+
"repo": "default",
+
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-systems",
+
"repo": "default",
+
"type": "github"
+
}
+
},
"tangled": {
"inputs": {
+
"actor-typeahead-src": "actor-typeahead-src",
"flake-compat": "flake-compat_2",
"gomod2nix": "gomod2nix",
"htmx-src": "htmx-src",
···
"sqlite-lib-src": "sqlite-lib-src"
},
"locked": {
-
"lastModified": 1759933847,
-
"narHash": "sha256-lLyX1f4fSG1IYsjcsUKKCAOHpa3ZTFexJMRc/0K2g3c=",
+
"lastModified": 1764494836,
+
"narHash": "sha256-u1i7aMo0fTQ6WVdOZhG2fo/gEx2Fq8+3URmuqEBZGWI=",
"ref": "refs/heads/master",
-
"rev": "eaa11ecb2112c90113a8ee49a8aa05be327b13ad",
-
"revCount": 1508,
+
"rev": "d37f774fb8c60aa2bd0cb965c9884457d0afb660",
+
"revCount": 1689,
"type": "git",
"url": "https://tangled.org/@tangled.org/core"
},
···
"url": "https://tangled.org/@tangled.org/core"
}
},
-
"vicinae": {
+
"treefmt-nix": {
"inputs": {
-
"flake-utils": "flake-utils_3",
-
"nixpkgs": "nixpkgs_4"
+
"nixpkgs": [
+
"nixpkgs"
+
]
},
"locked": {
-
"lastModified": 1759965448,
-
"narHash": "sha256-A6P8tBlWhUo6lJA/9ku9hjhzs1NlPDs4f8V/qlqf1dQ=",
-
"owner": "vicinaehq",
-
"repo": "vicinae",
-
"rev": "b1f24c7c077b7f55fea25547267ea0489ca1dbb5",
+
"lastModified": 1762938485,
+
"narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=",
+
"owner": "numtide",
+
"repo": "treefmt-nix",
+
"rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4",
"type": "github"
},
"original": {
-
"owner": "vicinaehq",
-
"repo": "vicinae",
+
"owner": "numtide",
+
"repo": "treefmt-nix",
"type": "github"
}
}
+55 -59
flake.nix
···
extra-substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
-
"https://install.determinate.systems"
-
"https://vicinae.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
-
"cache.flakehub.com-3:hJuILl5sVK4iKm86JzgdXW12Y2Hwd5G07qKtHTOcDCM="
-
"vicinae.cachix.org-1:1kDrfienkGHPYbkpNj1mWTr7Fm1+zcenzgTizIcI3oc="
];
cores = 0;
max-jobs = 2;
···
inputs = {
flake-parts = {
url = "github:hercules-ci/flake-parts";
-
inputs.nixpkgs-lib.follows = "nixpkgs-lib";
};
nixpkgs.url = "https://nixpkgs.dev/channel/nixpkgs-unstable";
nixpkgs-stalwart-fix.url = "github:pyrox0/nixpkgs/fix/stalwart-module";
-
stable.url = "github:nixos/nixpkgs/nixos-24.05";
# Overrides
flake-compat.url = "github:edolstra/flake-compat";
-
systems.url = "github:nix-systems/default";
flake-utils = {
url = "github:numtide/flake-utils";
-
inputs.systems.follows = "systems";
};
-
nixpkgs-lib.url = "github:nix-community/nixpkgs.lib";
# Inputs
agenix = {
url = "github:ryantm/agenix";
inputs = {
nixpkgs.follows = "nixpkgs";
-
systems.follows = "systems";
home-manager.follows = "home-manager";
};
};
···
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-parts.follows = "flake-parts";
inputs.treefmt-nix.follows = "";
+
};
+
caelestia = {
+
url = "github:caelestia-dots/shell";
+
inputs.nixpkgs.follows = "nixpkgs";
+
inputs.quickshell.follows = "quickshell";
};
ctp = {
url = "github:catppuccin/nix";
};
-
dix = {
-
url = "https://flakehub.com/f/DeterminateSystems/nix-src/*";
-
inputs = {
-
nixpkgs.follows = "nixpkgs";
-
nixpkgs-regression.follows = "";
-
nixpkgs-23-11.follows = "";
-
-
flake-parts.follows = "";
-
git-hooks-nix.follows = "";
-
};
+
dn42 = {
+
url = "github:pyrox0/dn43.nix";
+
inputs.nixpkgs.follows = "nixpkgs";
+
};
+
dms = {
+
url = "github:AvengeMedia/DankMaterialShell";
+
inputs.nixpkgs.follows = "nixpkgs";
+
};
+
# DMS Plugins
+
dms-wp-shuffler = {
+
url = "github:Daniel-42-z/dms-wallpaper-shuffler";
+
flake = false;
};
-
determinate = {
-
url = "github:DeterminateSystems/determinate";
-
inputs = {
-
nixpkgs.follows = "nixpkgs";
-
nix.follows = "dix";
-
};
+
dms-power-usage = {
+
url = "github:Daniel-42-z/dms-power-usage";
+
flake = false;
};
-
dns = {
-
url = "github:nix-community/dns.nix";
-
inputs.flake-utils.follows = "flake-utils";
-
inputs.nixpkgs.follows = "nixpkgs";
+
dms-plugins = {
+
url = "github:AvengeMedia/dms-plugins";
+
flake = false;
};
easy-hosts.url = "github:tgirlcloud/easy-hosts";
golink = {
url = "github:tailscale/golink";
-
inputs.systems.follows = "systems";
inputs.nixpkgs.follows = "nixpkgs";
};
hardware = {
···
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
-
iceshrimp = {
-
url = "git+https://iceshrimp.dev/pyrox/packaging";
-
inputs.nixpkgs.follows = "nixpkgs";
-
};
-
mailserver = {
-
url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
-
inputs = {
-
flake-compat.follows = "flake-compat";
-
nixpkgs.follows = "nixpkgs";
-
};
-
};
-
nix-search = {
-
url = "github:diamondburned/nix-search";
-
inputs.nixpkgs.follows = "nixpkgs";
-
inputs.flake-utils.follows = "flake-utils";
-
inputs.flake-compat.follows = "flake-compat";
-
};
-
nix-index = {
-
url = "github:nix-community/nix-index";
-
inputs.flake-compat.follows = "flake-compat";
-
inputs.nixpkgs.follows = "nixpkgs";
-
};
nix-index-database = {
url = "github:Mic92/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
···
url = "git+https://git.pyrox.dev/pyrox/pkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
-
vicinae = {
-
url = "github:vicinaehq/vicinae";
+
quickshell = {
+
url = "github:quickshell-mirror/quickshell";
+
inputs.nixpkgs.follows = "nixpkgs";
};
tangled = {
url = "git+https://tangled.org/@tangled.org/core";
+
};
+
treefmt-nix = {
+
url = "github:numtide/treefmt-nix";
+
inputs.nixpkgs.follows = "nixpkgs";
};
};
···
imports = [
inputs.easy-hosts.flakeModule
inputs.home-manager.flakeModules.home-manager
-
./packages
+
inputs.treefmt-nix.flakeModule
+
./packages.nix
./lib
./overlays
./devShells
···
# Per-system stuff
perSystem =
{
-
pkgs,
system,
...
}:
···
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
overlays = [
-
# inputs.self.overlays.pyronet-packages
inputs.self.overlays.openssh-fixperms
inputs.golink.overlays.default
];
···
allowUnfree = true;
};
};
-
formatter = pkgs.nixfmt;
+
treefmt = {
+
programs = {
+
deadnix = {
+
enable = true;
+
no-underscore = true;
+
};
+
jsonfmt.enable = true;
+
jsonfmt.excludes = [ ".zed/settings.json" ];
+
just.enable = true;
+
keep-sorted.enable = true;
+
mdformat.enable = true;
+
mdformat.settings.wrap = 120;
+
nixf-diagnose.enable = true;
+
nixfmt.enable = true;
+
nixfmt.indent = 2;
+
nixfmt.width = 120;
+
shellcheck.enable = true;
+
statix.enable = true;
+
stylua.enable = true;
+
taplo.enable = true;
+
yamlfmt.enable = true;
+
};
+
};
};
# Enable debugging for nixd
debug = true;
+2 -1
homeModules/all-modules.nix
···
inputs.nix-index-database.homeModules.nix-index
inputs.ctp.homeModules.catppuccin
-
inputs.vicinae.homeManagerModules.default
+
inputs.caelestia.homeManagerModules.default
+
inputs.dms.homeModules.dankMaterialShell.default
];
}
+5 -1
homeModules/default.nix
···
-
{ inputs, flake-parts-lib, ... }:
+
{
+
inputs,
+
flake-parts-lib,
+
...
+
}:
{
flake.homeModules = {
wayland = import ./wayland;
+1 -1
homeModules/profiles/base/default.nix
···
{
options.py.profiles.base.enable = lib.mkEnableOption "Base Home Profile";
config = lib.mkIf cfg.enable {
-
home.stateVersion = "25.11";
+
home.stateVersion = "26.05";
home.language = {
base = "en_US.utf8";
};
+1 -1
homeModules/profiles/cli/default.nix
···
glow
gnupg
nix-search
-
pinentry
+
pinentry-qt
rbw
rsync
xdg-utils
+7 -1
homeModules/profiles/cli/rbw-config.json
···
-
{"email":"pyrox@pyrox.dev","base_url":"https://bw.pyrox.dev","identity_url":null,"lock_timeout":3600,"pinentry":"pinentry"}
+
{
+
"email": "pyrox@pyrox.dev",
+
"base_url": "https://bw.pyrox.dev",
+
"identity_url": null,
+
"lock_timeout": 3600,
+
"pinentry": "pinentry"
+
}
+25 -2
homeModules/profiles/desktop/default.nix
···
}:
let
cfg = config.py.profiles.desktop;
+
inherit (cfg) shell;
inherit (lib) mkIf mkDefault mkEnableOption;
+
+
mkShellOption =
+
name: var:
+
lib.mkOption {
+
type = lib.types.bool;
+
default = if (shell == var) then true else false;
+
description = "Enable ${name}";
+
readOnly = true;
+
visible = false;
+
internal = true;
+
};
in
{
-
options.py.profiles.desktop.enable = mkEnableOption "Desktop Config";
+
options.py.profiles.desktop = {
+
enable = mkEnableOption "Desktop Config";
+
shell = lib.mkOption {
+
type = lib.types.enum [
+
"caelestia"
+
"dms"
+
];
+
default = "caelestia";
+
description = "The desktop shell to use in the graphical environment";
+
};
+
caelestia = mkShellOption "Caelestia shell" "caelestia";
+
dms = mkShellOption "DMS" "dms";
+
};
config = mkIf cfg.enable {
py.profiles.base.enable = true;
py.profiles.cli.enable = true;
···
playerctl
poptracker
thunderbird
-
wlogout
wl-clipboard
zotero
];
-7
homeModules/profiles/gui/default.nix
···
ghostty.enable = mkDefault true;
kitty.enable = mkDefault false;
obs.enable = mkDefault true;
-
onagre.enable = mkDefault true;
vscodium.enable = mkDefault false;
-
wlogout.enable = mkDefault true;
zed-editor.enable = mkDefault true;
};
services = {
gpg-agent.enable = mkDefault true;
-
kanshi.enable = mkDefault false;
kdeconnect.enable = mkDefault true;
-
mako.enable = mkDefault false;
-
vicinae.enable = mkDefault true;
-
swayidle.enable = mkDefault true;
syncthing.enable = mkDefault false;
};
};
···
krita
libappindicator
libappindicator-gtk3
-
lutris
prismlauncher
pwvucontrol
hyprshot
+50
homeModules/programs/caelestia/caelestia-cli.json
···
+
{
+
"record": {
+
"extraArgs": []
+
},
+
"theme": {
+
"enableTerm": false,
+
"enableHypr": false,
+
"enableDiscord": false,
+
"enableSpicetify": false,
+
"enableFuzzel": false,
+
"enableBtop": true,
+
"enableGtk": false,
+
"enableQt": false
+
},
+
"toggles": {
+
"discord": {
+
"discord": {
+
"enable": true,
+
"match": [
+
{
+
"class": "equibop"
+
}
+
],
+
"command": [
+
"equibop"
+
],
+
"move": true
+
}
+
},
+
"sysmon": {
+
"btop": {
+
"enable": true,
+
"match": [
+
{
+
"class": "btop",
+
"title": "btop",
+
"workspace": {
+
"name": "special:sysmon"
+
}
+
}
+
],
+
"command": [
+
"ghostty",
+
"-e",
+
"btop"
+
]
+
}
+
}
+
}
+
}
+364
homeModules/programs/caelestia/caelestia-shell.json
···
+
{
+
"appearance": {
+
"anim": {
+
"durations": {
+
"scale": 0.5
+
}
+
},
+
"font": {
+
"family": {
+
"clock": "Inter",
+
"material": "Material Symbols Rounded",
+
"mono": "BlexMono Nerd Font",
+
"sans": "Inter"
+
},
+
"size": {
+
"scale": 1.1
+
}
+
},
+
"padding": {
+
"scale": 1
+
},
+
"rounding": {
+
"scale": 0
+
},
+
"spacing": {
+
"scale": 0.5
+
},
+
"transparency": {
+
"base": 0.85,
+
"enabled": false,
+
"layers": 0.4
+
}
+
},
+
"background": {
+
"desktopClock": {
+
"enabled": false
+
},
+
"enabled": true,
+
"visualiser": {
+
"autoHide": true,
+
"enabled": false,
+
"rounding": 1,
+
"spacing": 1
+
}
+
},
+
"bar": {
+
"clock": {
+
"showIcon": false
+
},
+
"dragThreshold": 20,
+
"entries": [
+
{
+
"enabled": true,
+
"id": "workspaces"
+
},
+
{
+
"enabled": true,
+
"id": "spacer"
+
},
+
{
+
"enabled": false,
+
"id": "activeWindow"
+
},
+
{
+
"enabled": true,
+
"id": "spacer"
+
},
+
{
+
"enabled": true,
+
"id": "clock"
+
},
+
{
+
"enabled": true,
+
"id": "statusIcons"
+
},
+
{
+
"enabled": true,
+
"id": "tray"
+
},
+
{
+
"enabled": true,
+
"id": "power"
+
}
+
],
+
"persistent": true,
+
"scrollActions": {
+
"brightness": false,
+
"volume": false,
+
"workspaces": false
+
},
+
"showOnHover": true,
+
"status": {
+
"showAudio": true,
+
"showBattery": true,
+
"showBluetooth": true,
+
"showKbLayout": false,
+
"showLockStatus": true,
+
"showMicrophone": false,
+
"showNetwork": true
+
},
+
"tray": {
+
"background": true,
+
"compact": false,
+
"iconSubs": [],
+
"recolour": true
+
},
+
"workspaces": {
+
"activeIndicator": true,
+
"activeLabel": "",
+
"activeTrail": false,
+
"label": " ",
+
"occupiedBg": false,
+
"occupiedLabel": "",
+
"perMonitorWorkspaces": true,
+
"showWindows": true,
+
"shown": 5
+
}
+
},
+
"border": {
+
"rounding": 0,
+
"thickness": 10
+
},
+
"dashboard": {
+
"dragThreshold": 50,
+
"enabled": true,
+
"mediaUpdateInterval": 500,
+
"showOnHover": true
+
},
+
"general": {
+
"apps": {
+
"audio": [
+
"pwvucontrol"
+
],
+
"explorer": [
+
"thunar"
+
],
+
"playback": [
+
"mpv"
+
],
+
"terminal": [
+
"ghostty"
+
]
+
},
+
"battery": {
+
"criticalLevel": 3,
+
"warnLevels": [
+
{
+
"icon": "battery_android_frame_2",
+
"level": 20,
+
"message": "You might want to plug in a charger",
+
"title": "Low battery"
+
},
+
{
+
"icon": "battery_android_frame_1",
+
"level": 10,
+
"message": "You should probably plug in a charger <b>now</b>",
+
"title": "Did you see the previous message?"
+
},
+
{
+
"critical": true,
+
"icon": "battery_android_alert",
+
"level": 5,
+
"message": "PLUG THE CHARGER RIGHT NOW!!",
+
"title": "Critical battery level"
+
}
+
]
+
},
+
"idle": {
+
"inhibitWhenAudio": false,
+
"lockBeforeSleep": false,
+
"timeouts": []
+
}
+
},
+
"launcher": {
+
"actionPrefix": ">",
+
"actions": [
+
{
+
"command": [
+
"autocomplete",
+
"calc"
+
],
+
"dangerous": false,
+
"description": "Do simple math equations (powered by Qalc)",
+
"enabled": true,
+
"icon": "calculate",
+
"name": "Calculator"
+
},
+
{
+
"name": "Wallpaper",
+
"icon": "image",
+
"description": "Change the current wallpaper",
+
"command": [
+
"autocomplete",
+
"wallpaper"
+
],
+
"enabled": true,
+
"dangerous": false
+
},
+
{
+
"name": "Random",
+
"icon": "casino",
+
"description": "Switch to a random wallpaper",
+
"command": [
+
"caelestia",
+
"wallpaper",
+
"-r"
+
],
+
"enabled": true,
+
"dangerous": false
+
},
+
{
+
"command": [
+
"systemctl",
+
"poweroff"
+
],
+
"dangerous": true,
+
"description": "Shutdown the system",
+
"enabled": true,
+
"icon": "power_settings_new",
+
"name": "Shutdown"
+
},
+
{
+
"command": [
+
"systemctl",
+
"reboot"
+
],
+
"dangerous": true,
+
"description": "Reboot the system",
+
"enabled": true,
+
"icon": "cached",
+
"name": "Reboot"
+
},
+
{
+
"command": [
+
"loginctl",
+
"terminate-user",
+
""
+
],
+
"dangerous": true,
+
"description": "Log out of the current session",
+
"enabled": true,
+
"icon": "exit_to_app",
+
"name": "Logout"
+
},
+
{
+
"command": [
+
"loginctl",
+
"lock-session"
+
],
+
"dangerous": false,
+
"description": "Lock the current session",
+
"enabled": true,
+
"icon": "lock",
+
"name": "Lock"
+
},
+
{
+
"command": [
+
"systemctl",
+
"suspend"
+
],
+
"dangerous": false,
+
"description": "Suspend",
+
"enabled": true,
+
"icon": "bedtime",
+
"name": "Sleep"
+
}
+
],
+
"dragThreshold": 50,
+
"enableDangerousActions": false,
+
"hiddenApps": [],
+
"maxShown": 7,
+
"maxWallpapers": 9,
+
"showOnHover": false,
+
"specialPrefix": "@",
+
"useFuzzy": {
+
"actions": false,
+
"apps": true,
+
"schemes": false,
+
"variants": false,
+
"wallpapers": false
+
},
+
"vimKeybinds": true
+
},
+
"lock": {
+
"recolourLogo": false,
+
"enableFprint": false
+
},
+
"notifs": {
+
"actionOnClick": true,
+
"clearThreshold": 0.3,
+
"defaultExpireTimeout": 5000,
+
"expandThreshold": 20,
+
"expire": true
+
},
+
"osd": {
+
"enableBrightness": true,
+
"enableMicrophone": false,
+
"enabled": true,
+
"hideDelay": 2000
+
},
+
"paths": {
+
"mediaGif": "",
+
"sessionGif": "",
+
"wallpaperDir": "~/bgs/wallpapers"
+
},
+
"services": {
+
"audioIncrement": 0.1,
+
"defaultPlayer": "Spotify",
+
"gpuType": "",
+
"playerAliases": [
+
{
+
"from": "Mozilla firefox",
+
"to": "Firefox"
+
}
+
],
+
"smartScheme": false,
+
"useFahrenheit": true,
+
"useTwelveHourClock": false,
+
"visualiserBars": 0,
+
"weatherLocation": "Norfolk+Virginia"
+
},
+
"session": {
+
"commands": {
+
"hibernate": [
+
"systemctl",
+
"suspend"
+
],
+
"logout": [
+
"loginctl",
+
"terminate-user"
+
],
+
"reboot": [
+
"systemctl",
+
"reboot"
+
],
+
"shutdown": [
+
"systemctl",
+
"poweroff"
+
]
+
},
+
"dragThreshold": 30,
+
"enabled": true,
+
"vimKeybinds": true
+
},
+
"sidebar": {
+
"dragThreshold": 80,
+
"enabled": true
+
},
+
"utilities": {
+
"enabled": true,
+
"maxToasts": 4,
+
"toasts": {
+
"audioInputChanged": true,
+
"audioOutputChanged": true,
+
"capsLockChanged": true,
+
"chargingChanged": true,
+
"configLoaded": true,
+
"dndChanged": true,
+
"gameModeChanged": true,
+
"numLockChanged": true,
+
"nowPlaying": true
+
}
+
}
+
}
+23
homeModules/programs/caelestia/default.nix
···
+
{
+
config,
+
lib,
+
...
+
}:
+
let
+
cfg = config.py.profiles.desktop.caelestia;
+
en = config.py.profiles.desktop.enable;
+
in
+
{
+
config = lib.mkIf (cfg && en) {
+
programs.caelestia = {
+
enable = true;
+
settings = builtins.fromJSON (builtins.readFile ./caelestia-shell.json);
+
systemd = {
+
enable = true;
+
target = "graphical-session.target";
+
};
+
cli.enable = true;
+
cli.settings = builtins.fromJSON (builtins.readFile ./caelestia-cli.json);
+
};
+
};
+
}
+4 -2
homeModules/programs/default.nix
···
{
imports = [
+
# keep-sorted start
+
./caelestia
./chromium
+
./dms
./firefox
./fish
./ghostty
···
./misc-programs
./neovim
./nushell
-
./onagre
./ssh
./starship
./vscodium
-
./wlogout
./zed-editor
+
# keep-sorted end
];
}
+20
homeModules/programs/dms/default.nix
···
+
{
+
config,
+
lib,
+
...
+
}:
+
let
+
cfg = config.py.profiles.desktop.dms;
+
en = config.py.profiles.desktop.enable;
+
in
+
{
+
config = lib.mkIf (cfg && en) {
+
programs.dankMaterialShell = {
+
enable = true;
+
enableDynamicTheming = false;
+
enableAudioWavelength = false;
+
enableCalendarEvents = false;
+
enableSystemSound = false;
+
};
+
};
+
}
+28 -50
homeModules/programs/git/default.nix
···
git = lib.mkIf cfg.enable {
enable = true;
package = pkgs.git;
-
aliases = {
-
a = "add -p";
-
co = "checkout";
-
cob = "checkout -b";
-
f = "fetch -p";
-
c = "commit";
-
p = "push";
-
ba = "branch -a";
-
bd = "branch -d";
-
bD = "branch -D";
-
d = "diff";
-
dc = "diff --cached";
-
ds = "diff --staged";
-
r = "restore";
-
rs = "restore --staged";
-
st = "status -sb";
-
# reset
-
soft = "reset --soft";
-
hard = "reset --hard";
-
s1ft = "soft HEAD~1";
-
h1rd = "hard HEAD~1";
-
# logging
-
lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
-
plog = "log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
-
tlog = "log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
-
rank = "shortlog -sn --no-merges";
-
# delete merged branches
-
bdm = "!git branch --merged | grep -v '*' | xargs -n 1 git branch -d";
-
wt = "worktree";
-
};
-
delta = {
-
enable = true;
-
options.line-numbers = true;
-
};
-
extraConfig = {
+
settings = {
branch.sort = "-committerdate";
column.ui = "auto";
core.editor = lib.getExe pkgs.neovim;
···
};
rebase.updateRefs = true;
tag.sort = "version:refname";
-
};
-
lfs = {
-
enable = true;
-
skipSmudge = false;
+
lfs = {
+
enable = true;
+
skipSmudge = false;
+
};
+
user = {
+
email = "pyrox@pyrox.dev";
+
name = "dish";
+
};
+
signing = {
+
key = "~/.ssh/main.pub";
+
format = "ssh";
+
signByDefault = true;
+
};
};
-
signing = {
-
key = "~/.ssh/main.pub";
-
format = "ssh";
-
signByDefault = true;
-
};
-
userEmail = "pyrox@pyrox.dev";
-
userName = "dish";
+
};
+
delta = {
+
enable = true;
+
options.line-numbers = true;
+
enableGitIntegration = true;
+
};
+
mergiraf = lib.mkIf cfg.enable {
+
enable = true;
};
lazygit = lib.mkIf cfg.lazygit.enable {
enable = true;
···
showRandomTip = false;
theme.selectedLineBgColor = [ "default" ];
};
-
git.paging = {
-
pager = "${lib.getExe pkgs.delta} --dark --paging=never";
-
colorArg = "always";
-
};
+
git.pagers = [
+
{
+
pager = "${lib.getExe pkgs.delta} --dark --paging=never";
+
colorArg = "always";
+
}
+
];
services = {
"git.pyrox.dev" = "gitea:git.pyrox.dev";
"git.dn42.dev" = "gitea:git.dn42.dev";
+1 -1
homeModules/programs/helix/default.nix
···
{
options.py.programs.helix.enable = lib.mkEnableOption "helix editor";
config.catppuccin.helix = {
-
enable = cfg.enable;
+
inherit (cfg) enable;
useItalics = cfg.enable;
};
config.programs.helix = lib.mkIf cfg.enable {
+1 -1
homeModules/programs/misc-programs/default.nix
···
};
};
home = {
-
packages = mkIf cfg.wakatime.enable [ pkgs.wakatime ];
+
packages = mkIf cfg.wakatime.enable [ pkgs.wakatime-cli ];
sessionVariables = {
WAKATIME_HOME = "${config.xdg.configHome}/wakatime";
};
+6 -6
homeModules/programs/neovim/default.nix
···
pkgs.gcc
pkgs.go
pkgs.nodejs
-
]
-
++ lib.optionals config.py.profiles.gui.enable [
-
pkgs.ffmpegthumbnailer
-
pkgs.fontpreview
-
pkgs.poppler
-
pkgs.ueberzug
+
# ]
+
# ++ lib.optionals config.py.profiles.gui.enable [
+
# pkgs.ffmpegthumbnailer
+
# pkgs.fontpreview
+
# pkgs.poppler
+
# pkgs.ueberzug
];
};
}
-13
homeModules/programs/onagre/default.nix
···
-
{
-
lib,
-
config,
-
pkgs,
-
...
-
}:
-
let
-
cfg = config.py.programs.onagre;
-
in
-
{
-
options.py.programs.onagre.enable = lib.mkEnableOption "onagre";
-
config.home.packages = lib.mkIf cfg.enable [ pkgs.onagre ];
-
}
+13 -1
homeModules/programs/ssh/default.nix
···
config = lib.mkIf cfg.enable {
programs.ssh = {
enable = true;
-
compression = true;
+
enableDefaultConfig = false;
matchBlocks = {
+
"*" = {
+
forwardAgent = false;
+
addKeysToAgent = "no";
+
serverAliveInterval = 0;
+
serverAliveCountMax = 3;
+
hashKnownHosts = false;
+
userKnownHostsFile = "~/.ssh/known_hosts";
+
controlMaster = "no";
+
controlPath = "~/.ssh/master-%r@%n:%p";
+
controlPersist = "no";
+
compression = true;
+
};
"marvin" = {
hostname = "100.123.15.72";
user = "thehedgehog";
-55
homeModules/programs/wlogout/default.nix
···
-
{
-
pkgs,
-
config,
-
lib,
-
...
-
}:
-
let
-
cfg = config.py.programs.wlogout;
-
pkg = config.programs.wlogout.package;
-
in
-
{
-
options.py.programs.wlogout.enable = lib.mkEnableOption "wlogout";
-
config.programs.wlogout = lib.mkIf cfg.enable {
-
enable = true;
-
style = import ./style.nix { inherit pkg; };
-
layout = [
-
{
-
label = "hibernate";
-
action = "systemctl hibernate";
-
text = "Hibernate";
-
keybind = "h";
-
}
-
{
-
label = "reboot";
-
action = "systemctl reboot";
-
text = "Reboot";
-
keybind = "r";
-
}
-
{
-
label = "suspend";
-
action = "systemctl suspend";
-
text = "Suspend";
-
keybind = "u";
-
}
-
{
-
label = "suspend-then-hibernate";
-
action = "systemctl suspend-then-hibernate";
-
text = "Supend then Hibernate";
-
keybind = "p";
-
}
-
{
-
label = "lock";
-
action = "hyprlock";
-
text = "Lock";
-
keybind = "l";
-
}
-
{
-
label = "shutdown";
-
action = "systemctl poweroff";
-
text = "Shutdown";
-
keybind = "s";
-
}
-
];
-
};
-
}
-52
homeModules/programs/wlogout/style.nix
···
-
{ pkg, ... }:
-
let
-
icon-path = "${pkg}/share/wlogout/icons";
-
in
-
''
-
* {
-
background-image: none;
-
}
-
window {
-
background-image: image(url("/home/thehedgehog/bgs/wallpapers/xenia/chimmie_valentine_xenia.png"), url("/home/thehedgehog/bgs/wallpapers/xenia/chimmie_valentine_xenia.png"));
-
background-size: cover;
-
}
-
button {
-
color: #cdd6f4;
-
background-color: #11111b;
-
border: none;
-
border-color: #6c7086;
-
background-repeat: no-repeat;
-
background-position: center;
-
background-size: 25%;
-
}
-
-
button:focus, button:active, button:hover {
-
background-color: #1e1e2e;
-
outline-style: none;
-
border:none;
-
}
-
-
#lock {
-
background-image: image(url("${icon-path}/lock.png"), url("${icon-path}/lock.png"));
-
}
-
-
#suspend-then-hibernate {
-
background-image: image(url("${icon-path}/suspend.png"), url("${icon-path}/suspend.png"));
-
}
-
-
#suspend {
-
background-image: image(url("${icon-path}/suspend.png"), url("${icon-path}/suspend.png"));
-
}
-
-
#hibernate {
-
background-image: image(url("${icon-path}/hibernate.png"), url("${icon-path}/hibernate.png"));
-
}
-
-
#shutdown {
-
background-image: image(url("${icon-path}/shutdown.png"), url("${icon-path}/shutdown.png"));
-
}
-
-
#reboot {
-
background-image: image(url("${icon-path}/reboot.png"), url("${icon-path}/reboot.png"));
-
}
-
''
+1 -11
homeModules/programs/zed-editor/settings.nix
···
auto_update = false;
buffer_font_family = "BlexMono Nerd Font";
buffer_font_size = 15;
+
disable_ai = true;
git_panel.button = true;
load_direnv = "direct";
lsp.deno.settings.deno.enable = true;
···
ui_font_size = 15;
vim_mode = true;
wrap_guides = [ 100 ];
-
-
assistant = {
-
enabled = false;
-
button = false;
-
version = "2";
-
};
-
-
features = {
-
copilot = false;
-
edit_prediction_provider = "none";
-
};
icon_theme = {
mode = "dark";
-4
homeModules/services/default.nix
···
{
imports = [
./gpg-agent
-
./kanshi
./kdeconnect
-
./mako
-
./swayidle
./syncthing
-
./vicinae
];
}
-18
homeModules/services/kanshi/default.nix
···
-
{ config, lib, ... }:
-
let
-
cfg = config.py.services.kanshi;
-
in
-
{
-
options.py.services.kanshi = {
-
enable = lib.mkEnableOption "kanshi";
-
settings = lib.mkOption {
-
type = lib.types.listOf lib.types.attrs;
-
default = [ ];
-
description = "The value of `config.services.kanshi.settings`.";
-
};
-
};
-
config.services.kanshi = lib.mkIf cfg.enable {
-
enable = true;
-
inherit (cfg) settings;
-
};
-
}
-31
homeModules/services/mako/default.nix
···
-
{ lib, config, ... }:
-
let
-
cfg = config.py.services.mako;
-
hl = config.wayland.windowManager.hyprland;
-
in
-
{
-
options.py.services.mako.enable = lib.mkEnableOption "mako";
-
# avoid IFD
-
config.catppuccin.mako.enable = false;
-
# Hyprpanel with hyprland uses its own notification daemon
-
config.services.mako = lib.mkIf (cfg.enable && !hl.enable) {
-
enable = true;
-
-
settings = {
-
font = "IBM Plex Sans 14pt";
-
# Vendored Catppuccin Theme(avoids IFD)
-
background-color = "#1e1e2e";
-
text-color = "#cdd6f4";
-
border-color = "#89b4fa";
-
progress-color = "over #313244";
-
-
actions = 1;
-
default-timeout = 10000;
-
icons = 1;
-
layer = "overlay";
-
"urgency=high" = {
-
border-color = "#fab387";
-
};
-
};
-
};
-
}
-35
homeModules/services/swayidle/default.nix
···
-
{
-
pkgs,
-
config,
-
lib,
-
...
-
}:
-
let
-
cfg = config.py.services.swayidle;
-
in
-
{
-
options.py.services.swayidle.enable = lib.mkEnableOption "swayidle";
-
config.services.swayidle = lib.mkIf cfg.enable {
-
enable = false;
-
events = [
-
{
-
event = "lock";
-
command = "lock";
-
}
-
{
-
event = "before-sleep";
-
command = lib.getExe pkgs.swaylock-effects;
-
}
-
{
-
event = "after-resume";
-
command = ''swaymsg "output * dpms on"'';
-
}
-
];
-
timeouts = [
-
{
-
timeout = 300;
-
command = lib.getExe pkgs.swaylock-effects;
-
}
-
];
-
};
-
}
-15
homeModules/services/vicinae/default.nix
···
-
{
-
config,
-
lib,
-
...
-
}:
-
let
-
cfg = config.py.services.vicinae;
-
in
-
{
-
options.py.services.vicinae.enable = lib.mkEnableOption "Vicinae";
-
config.services.vicinae = lib.mkIf cfg.enable {
-
enable = true;
-
autoStart = true;
-
};
-
}
+28 -5
homeModules/wayland/default.nix
···
+
{
+
pkgs,
+
config,
+
osConfig,
+
lib,
+
...
+
}:
+
let
+
c = osConfig.py.programs.hyprland;
+
in
{
imports = [
-
./sway.nix
-
./keybindings.nix
-
./waybar.nix
-
./swaylock.nix
-
./hyprland
+
./services.nix
+
./hypridle.nix
];
+
config = {
+
catppuccin.hyprland.enable = c.enable;
+
wayland.windowManager.hyprland = {
+
inherit (c) enable;
+
# Per https://nix-community.github.io/home-manager/options.xhtml#opt-wayland.windowManager.hyprland.package
+
package = null;
+
systemd = {
+
enable = true;
+
enableXdgAutostart = true;
+
};
+
settings = import ./settings.nix { inherit lib config; };
+
plugins = [
+
pkgs.hyprlandPlugins.hy3
+
];
+
};
+
};
}
+11
homeModules/wayland/env.nix
···
+
{
+
env = [
+
"WLR_NO_HARDWARE_CURSORS, 1"
+
"WLR_RENDERER_ALLOW_SOFTWARE, 1"
+
"NIXOS_OZONE_WL, 1"
+
"XDG_SESSION_TYPE, wayland"
+
"QT_QPA_PLATFORM, wayland"
+
"XDG_CURRENT_DESKTOP, Hyprland"
+
"XDG_SESSION_DESKTOP, Hyprland"
+
];
+
}
+36
homeModules/wayland/hypridle.nix
···
+
{
+
config,
+
lib,
+
...
+
}:
+
let
+
cfg = config.wayland.windowManager.hyprland;
+
in
+
{
+
config.services.hypridle = lib.mkIf cfg.enable {
+
enable = true;
+
settings = {
+
general = {
+
lock_cmd = "loginctl lock-session";
+
# before_sleep_cmd = "loginctl lock-session";
+
after_sleep_cmd = "hyprctl dispatch dpms on";
+
inhibit_sleep = 3;
+
};
+
listener = [
+
{
+
timeout = 420;
+
on-timeout = "loginctl lock-session";
+
}
+
{
+
timeout = 600;
+
on-timeout = "hyprctl dispatch dpms off";
+
on-resume = "hyprctl dispatch dpms on";
+
}
+
{
+
timeout = 900;
+
on-timeout = "systemctl resume";
+
}
+
];
+
};
+
};
+
}
-35
homeModules/wayland/hyprland/default.nix
···
-
{
-
pkgs,
-
config,
-
osConfig,
-
lib,
-
...
-
}:
-
let
-
c = osConfig.py.programs.hyprland;
-
cfg = config.wayland.windowManager.hyprland;
-
in
-
{
-
imports = [
-
./hyprpanel.nix
-
./services.nix
-
./hypridle.nix
-
./hyprlock.nix
-
];
-
config = {
-
catppuccin.hyprland.enable = c.enable;
-
wayland.windowManager.hyprland = {
-
enable = c.enable;
-
# Per https://nix-community.github.io/home-manager/options.xhtml#opt-wayland.windowManager.hyprland.package
-
package = null;
-
systemd = {
-
enable = true;
-
enableXdgAutostart = true;
-
};
-
settings = import ./settings.nix;
-
plugins = [
-
pkgs.hyprlandPlugins.hy3
-
];
-
};
-
};
-
}
-9
homeModules/wayland/hyprland/env.nix
···
-
{
-
env = [
-
"WLR_NO_HARDWARE_CURSORS, 1"
-
"WLR_RENDERER_ALLOW_SOFTWARE, 1"
-
"NIXOS_OZONE_WL, 1"
-
"XDG_SESSION_TYPE, wayland"
-
"QT_QPA_PLATFORM, wayland"
-
];
-
}
-18
homeModules/wayland/hyprland/hypridle.nix
···
-
{
-
config,
-
lib,
-
...
-
}:
-
let
-
cfg = config.wayland.windowManager.hyprland;
-
in
-
{
-
config.services.hypridle = lib.mkIf cfg.enable {
-
enable = false;
-
settings = {
-
general = {
-
lock_cmd = "hyprlock";
-
};
-
};
-
};
-
}
-93
homeModules/wayland/hyprland/hyprlock.nix
···
-
{
-
config,
-
lib,
-
...
-
}:
-
let
-
cfg = config.wayland.windowManager.hyprland;
-
in
-
{
-
config.catppuccin.hyprlock.enable = cfg.enable;
-
config.catppuccin.hyprlock.useDefaultConfig = false;
-
config.programs.hyprlock = lib.mkIf cfg.enable {
-
enable = true;
-
settings = {
-
general = {
-
hide_cursor = true;
-
immediate_render = true;
-
text_trim = true;
-
};
-
};
-
extraConfig = ''
-
$accent = $mauve
-
$accentAlpha = $mauveAlpha
-
$font = Blex Mono Nerd Font
-
-
# BACKGROUND
-
background {
-
monitor =
-
path = $HOME/bgs/wallpapers/xenia/chimmie_valentine_xenia.png
-
blur_passes = 1
-
color = $base
-
}
-
-
# TIME
-
label {
-
monitor =
-
text = $TIME
-
color = $text
-
font_size = 90
-
font_family = $font
-
position = -30, 0
-
halign = right
-
valign = top
-
}
-
-
# DATE
-
label {
-
monitor =
-
text = cmd[update:43200000] date +"%A, %d %B %Y"
-
color = $text
-
font_size = 25
-
font_family = $font
-
position = -30, -150
-
halign = right
-
valign = top
-
}
-
-
# USER AVATAR
-
image {
-
monitor =
-
path = $HOME/.face
-
size = 100
-
border_color = $accent
-
position = 0, 75
-
halign = center
-
valign = center
-
}
-
-
# INPUT FIELD
-
input-field {
-
monitor =
-
size = 300, 60
-
outline_thickness = 4
-
dots_size = 0.2
-
dots_spacing = 0.2
-
dots_center = true
-
outer_color = $accent
-
inner_color = $surface0
-
font_color = $text
-
fade_on_empty = false
-
placeholder_text = <span foreground="##$textAlpha"><i>󰌾 Logged in as </i><span foreground="##$accentAlpha">$USER</span></span>
-
hide_input = false
-
check_color = $accent
-
fail_color = $red
-
fail_text = <i>$FAIL <b>($ATTEMPTS)</b></i>
-
capslock_color = $yellow
-
position = 0, -47
-
halign = center
-
valign = center
-
}
-
'';
-
};
-
}
-14
homeModules/wayland/hyprland/hyprpanel.nix
···
-
{
-
config,
-
lib,
-
...
-
}:
-
let
-
cfg = config.wayland.windowManager.hyprland;
-
in
-
{
-
programs.hyprpanel = lib.mkIf cfg.enable {
-
enable = true;
-
systemd.enable = true;
-
};
-
}
-98
homeModules/wayland/hyprland/keybindings.nix
···
-
{
-
"$mod" = "SUPER";
-
"$satty" = "satty -f -";
-
-
binde = [
-
# Media binds that can be held and repeated
-
", XF86MonBrightnessDown, exec, brightnessctl set 5%-"
-
", XF86MonBrightnessUp, exec, brightnessctl set +5%"
-
", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"
-
", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
-
];
-
-
bind = [
-
"SUPER_SHIFT, F, exec, MOZ_DISABLE_RDD_SANDBOX=1 firefox"
-
"$mod, Return, exec, ghostty"
-
"$mod, X, exec, wlogout"
-
"$mod, D, exec, vicinae toggle"
-
"SUPER_SHIFT, E, exit"
-
-
# Media Binds
-
", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
-
", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
-
", XF86AudioPlay, exec, playerctl play-pause"
-
", XF86AudioNext, exec, playerctl next"
-
", XF86AudioPrev, exec, playerctl previous"
-
-
# Workspace binds
-
"$mod, 1, workspace, 01"
-
"SUPER_SHIFT, 1, hy3:movetoworkspace, 01, follow, warp"
-
"$mod, 2, workspace, 02"
-
"SUPER_SHIFT, 2, hy3:movetoworkspace, 02, follow, warp"
-
"$mod, 3, workspace, 03"
-
"SUPER_SHIFT, 3, hy3:movetoworkspace, 03, follow, warp"
-
"$mod, 4, workspace, 04"
-
"SUPER_SHIFT, 4, hy3:movetoworkspace, 04, follow, warp"
-
"$mod, 5, workspace, 05"
-
"SUPER_SHIFT, 5, hy3:movetoworkspace, 05, follow, warp"
-
"$mod, 6, workspace, 06"
-
"SUPER_SHIFT, 6, hy3:movetoworkspace, 06, follow, warp"
-
"$mod, 7, workspace, 07"
-
"SUPER_SHIFT, 7, hy3:movetoworkspace, 07, follow, warp"
-
"$mod, 8, workspace, 08"
-
"SUPER_SHIFT, 8, hy3:movetoworkspace, 08, follow, warp"
-
"$mod, 9, workspace, 09"
-
"SUPER_SHIFT, 9, hy3:movetoworkspace, 09, follow, warp"
-
"$mod, 0, workspace, 10"
-
"SUPER_SHIFT, 0, hy3:movetoworkspace, 10, follow, warp"
-
# Scratchpad
-
"SUPER_SHIFT, -, movetoworkspace, special"
-
"$mod, -, togglespecialworkspace"
-
-
# Window Management
-
"SUPER_SHIFT, Up, hy3:movewindow, up, once, visible"
-
"SUPER_SHIFT, K, hy3:movewindow, up, once, visible"
-
"$mod, Up, hy3:movefocus, up, visible, warp"
-
"$mod, K, hy3:movefocus, up, visible, warp"
-
-
"SUPER_SHIFT, Right, hy3:movewindow, right, once, visible"
-
"SUPER_SHIFT, L, hy3:movewindow, right, once, visible"
-
"$mod, Right, hy3:movefocus, right, visible, warp"
-
"$mod, L, hy3:movefocus, right, visible, warp"
-
-
"SUPER_SHIFT, Left, hy3:movewindow, left, once, visible"
-
"SUPER_SHIFT, H, hy3:movewindow, left, once, visible"
-
"$mod, Left, hy3:movefocus, left, visible, warp"
-
"$mod, H, hy3:movefocus, left, visible, warp"
-
-
"SUPER_SHIFT, Down, hy3:movewindow, down, once, visible"
-
"SUPER_SHIFT, J, hy3:movewindow, down, once, visible"
-
"$mod, Down, hy3:movefocus, down, visible, warp"
-
"$mod, J, hy3:movefocus, down, visible, warp"
-
-
"SUPER_SHIFT, Q, killactive"
-
"$mod, F, fullscreen, 0"
-
"$mod, Space, hy3:togglefocuslayer"
-
"SUPER_SHIFT, Space, togglefloating, active"
-
-
# Screenshots
-
"SHIFT, F3, exec, hyprshot -m output --raw -z -s | $satty"
-
"SHIFT, F4, exec, hyprshot -m region --raw -z -s | $satty"
-
];
-
-
bindm = [
-
"$mod, mouse:272, movewindow"
-
];
-
-
# Unbind a bunch of default keybinds
-
unbind = [
-
"$mod, C"
-
"$mod, E"
-
"$mod, J"
-
"$mod, M"
-
"$mod, P"
-
"$mod, Q"
-
"$mod, R"
-
"$mod, V"
-
];
-
}
-8
homeModules/wayland/hyprland/monitors.nix
···
-
{
-
monitor = [
-
"eDP-1, 2560x1600@165, 0x0, 1, vrr, 1"
-
"desc:Acer Technologies SA241Y 0x1497CF17, preferred, 2560x0, 1"
-
# Fallback for random monitors
-
", preferred, auto, 1"
-
];
-
}
-7
homeModules/wayland/hyprland/plugins.nix
···
-
{
-
plugin = {
-
hy3 = {
-
no_gaps_when_only = 1;
-
};
-
};
-
}
-10
homeModules/wayland/hyprland/services.nix
···
-
{
-
config,
-
...
-
}:
-
let
-
cfg = config.wayland.windowManager.hyprland;
-
in
-
{
-
services.hyprpolkitagent.enable = cfg.enable;
-
}
-22
homeModules/wayland/hyprland/settings.nix
···
-
let
-
keybinds = import ./keybindings.nix;
-
monitors = import ./monitors.nix;
-
variables = import ./variables.nix;
-
plugins = import ./plugins.nix;
-
env = import ./env.nix;
-
windowrules = import ./windowrules.nix;
-
in
-
{
-
exec-once = [
-
"hyprpanel"
-
];
-
animation = [
-
"global, 1, 4, default"
-
];
-
}
-
// keybinds
-
// monitors
-
// variables
-
// plugins
-
// env
-
// windowrules
-33
homeModules/wayland/hyprland/variables.nix
···
-
# https://wiki.hypr.land/Configuring/Variables
-
{
-
general = {
-
gaps_in = 1;
-
gaps_out = 1;
-
gaps_workspaces = 80;
-
layout = "hy3";
-
resize_on_border = true;
-
};
-
decoration = {
-
blur.enabled = false;
-
shadow.enabled = false;
-
};
-
misc = {
-
disable_hyprland_logo = true;
-
disable_splash_rendering = true;
-
font_family = "Inter";
-
mouse_move_focuses_monitor = true;
-
};
-
input = {
-
kb_options = "caps:escape";
-
repeat_delay = 300;
-
touchpad = {
-
scroll_factor = 1.5;
-
tap_button_map = "lmr";
-
tap-and-drag = false;
-
};
-
};
-
ecosystem = {
-
no_update_news = true;
-
no_donation_nag = true;
-
};
-
}
-6
homeModules/wayland/hyprland/windowrules.nix
···
-
{
-
windowrule = [
-
"immediate, content game, title:Celeste"
-
"tile, title:Melvor Idle"
-
];
-
}
+108 -43
homeModules/wayland/keybindings.nix
···
-
{ config, lib, ... }:
-
let
-
inherit (config.wayland.windowManager.sway.config) menu;
-
mod = config.wayland.windowManager.sway.config.modifier;
-
term = config.wayland.windowManager.sway.config.terminal;
-
grim = "grim -g";
-
slurp-screen = "\"$(slurp -c -b '#1e1e2e80' -o -r)\" -";
-
slurp-box = "\"$(slurp -c '#f38ba8ff' -b '#1e1e2e80' -w 1 -d -F 'IBM Plex Mono')\" -";
-
satty = "satty -f -";
-
cfg = config.py.profiles.gui;
-
in
+
{ lib, shell }:
{
-
config.wayland.windowManager.sway.config.keybindings = lib.mkIf cfg.enable (
-
lib.mkOptionDefault {
-
"${mod}+d" = "${menu}";
-
"${mod}+Shift+F" = "exec MOZ_DISABLE_RDD_SANDBOX=1 firefox";
-
"${mod}+Return" = "exec ${term}";
-
"${mod}+x" = "exec wlogout";
-
"${mod}+s" = null;
-
"${mod}+w" = null;
-
"XF86MonBrightnessDown" = "exec brightnessctl set 5%-";
-
"XF86MonBrightnessUp" = "exec brightnessctl set +5%";
-
"XF86AudioRaiseVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+";
-
"XF86AudioLowerVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
-
"XF86AudioMute" = "exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
-
"XF86AudioMicMute" = "exec wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
-
"XF86AudioPlay" = "exec playerctl play-pause";
-
"XF86AudioNext" = "exec playerctl next";
-
"XF86AudioPrev" = "exec playerctl previous";
-
"Shift+F3" = "exec ${grim} ${slurp-screen} | ${satty}";
-
"Shift+F4" = "exec ${grim} ${slurp-box} | ${satty}";
-
"${mod}+Shift+1" = "move container to workspace number 1";
-
"${mod}+Shift+2" = "move container to workspace number 2";
-
"${mod}+Shift+3" = "move container to workspace number 3";
-
"${mod}+Shift+4" = "move container to workspace number 4";
-
"${mod}+Shift+5" = "move container to workspace number 5";
-
"${mod}+Shift+6" = "move container to workspace number 6";
-
"${mod}+Shift+7" = "move container to workspace number 7";
-
"${mod}+Shift+8" = "move container to workspace number 8";
-
"${mod}+Shift+9" = "move container to workspace number 9";
-
"${mod}+Shift+0" = "move container to workspace number 10";
-
"${mod}+0" = "workspace number 10";
-
}
-
);
+
"$mod" = "SUPER";
+
"$satty" = "satty -f -";
+
+
binde = [
+
# Media binds that can be held and repeated
+
", XF86MonBrightnessDown, exec, brightnessctl set 5%-"
+
", XF86MonBrightnessUp, exec, brightnessctl set +5%"
+
", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"
+
", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
+
];
+
+
bind = [
+
"SUPER_SHIFT, F, exec, MOZ_DISABLE_RDD_SANDBOX=1 firefox"
+
"$mod, Return, exec, ghostty"
+
"SUPER_SHIFT, E, exit"
+
+
# Media Binds
+
", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
+
", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
+
", XF86AudioPlay, exec, playerctl play-pause"
+
", XF86AudioNext, exec, playerctl next"
+
", XF86AudioPrev, exec, playerctl previous"
+
+
# Workspace binds
+
"$mod, 1, workspace, 01"
+
"SUPER_SHIFT, 1, hy3:movetoworkspace, 01"
+
"$mod, 2, workspace, 02"
+
"SUPER_SHIFT, 2, hy3:movetoworkspace, 02"
+
"$mod, 3, workspace, 03"
+
"SUPER_SHIFT, 3, hy3:movetoworkspace, 03"
+
"$mod, 4, workspace, 04"
+
"SUPER_SHIFT, 4, hy3:movetoworkspace, 04"
+
"$mod, 5, workspace, 05"
+
"SUPER_SHIFT, 5, hy3:movetoworkspace, 05"
+
"$mod, 6, workspace, 06"
+
"SUPER_SHIFT, 6, hy3:movetoworkspace, 06"
+
"$mod, 7, workspace, 07"
+
"SUPER_SHIFT, 7, hy3:movetoworkspace, 07"
+
"$mod, 8, workspace, 08"
+
"SUPER_SHIFT, 8, hy3:movetoworkspace, 08"
+
"$mod, 9, workspace, 09"
+
"SUPER_SHIFT, 9, hy3:movetoworkspace, 09"
+
"$mod, 0, workspace, 10"
+
"SUPER_SHIFT, 0, hy3:movetoworkspace, 10"
+
# Scratchpad
+
"SUPER_SHIFT, -, hy3:movetoworkspace, special:default"
+
"$mod, -, togglespecialworkspace, default"
+
+
# Window Management
+
"SUPER_SHIFT, Up, hy3:movewindow, up, once, visible"
+
"SUPER_SHIFT, K, hy3:movewindow, up, once, visible"
+
"$mod, Up, hy3:movefocus, up, visible, warp"
+
"$mod, K, hy3:movefocus, up, visible, warp"
+
+
"SUPER_SHIFT, Right, hy3:movewindow, right, once, visible"
+
"SUPER_SHIFT, L, hy3:movewindow, right, once, visible"
+
"$mod, Right, hy3:movefocus, right, visible, warp"
+
"$mod, L, hy3:movefocus, right, visible, warp"
+
+
"SUPER_SHIFT, Left, hy3:movewindow, left, once, visible"
+
"SUPER_SHIFT, H, hy3:movewindow, left, once, visible"
+
"$mod, Left, hy3:movefocus, left, visible, warp"
+
"$mod, H, hy3:movefocus, left, visible, warp"
+
+
"SUPER_SHIFT, Down, hy3:movewindow, down, once, visible"
+
"SUPER_SHIFT, J, hy3:movewindow, down, once, visible"
+
"$mod, Down, hy3:movefocus, down, visible, warp"
+
"$mod, J, hy3:movefocus, down, visible, warp"
+
+
"SUPER_SHIFT, Q, killactive"
+
"$mod, F, fullscreen, 0"
+
# Super-(literal equals)
+
"$mod, code:21, hy3:togglefocuslayer"
+
# Super-(literal plus)
+
"SUPER_SHIFT, code:21, togglefloating, active"
+
+
# Screenshots
+
"SHIFT, F3, exec, hyprshot -m output --raw -z -s | $satty"
+
"SHIFT, F4, exec, hyprshot -m region --raw -z -s | $satty"
+
]
+
++ lib.optionals (shell == "caelestia") [
+
"$mod, X, global, caelestia:session"
+
", XF86PowerOff , global, caelestia:session"
+
"$mod, Space, global, caelestia:launcher"
+
]
+
++ lib.optionals (shell == "dms") [
+
"$mod, X, exec, dms ipc call powermenu toggle"
+
", XF86PowerOff ,exec, dms ipc call powermenu toggle"
+
"SUPER_SHIFT, X, exec, dms ipc call lock lock"
+
"$mod, Space, exec, dms ipc call spotlight toggle"
+
];
+
+
bindm = [
+
"$mod, mouse:272, movewindow"
+
];
+
+
# Unbind a bunch of default keybinds
+
unbind = [
+
"$mod, C"
+
"$mod, E"
+
"$mod, J"
+
"$mod, M"
+
"$mod, P"
+
"$mod, Q"
+
"$mod, R"
+
"$mod, V"
+
];
}
+8
homeModules/wayland/monitors.nix
···
+
{
+
monitor = [
+
"eDP-1, 2560x1600@165, 0x0, 1, vrr, 1"
+
"desc:Acer Technologies SA241Y 0x1497CF17, preferred, 2560x0, 1"
+
# Fallback for random monitors
+
", preferred, auto, 1"
+
];
+
}
+7
homeModules/wayland/plugins.nix
···
+
{
+
plugin = {
+
hy3 = {
+
no_gaps_when_only = 1;
+
};
+
};
+
}
+10
homeModules/wayland/services.nix
···
+
{
+
config,
+
...
+
}:
+
let
+
cfg = config.wayland.windowManager.hyprland;
+
in
+
{
+
services.hyprpolkitagent.enable = cfg.enable;
+
}
+25
homeModules/wayland/settings.nix
···
+
{ config, lib, ... }:
+
let
+
inherit (config.py.profiles.desktop) shell;
+
keybinds = import ./keybindings.nix { inherit lib shell; };
+
monitors = import ./monitors.nix;
+
variables = import ./variables.nix;
+
plugins = import ./plugins.nix;
+
env = import ./env.nix;
+
windowrules = import ./windowrules.nix;
+
in
+
{
+
animation = [
+
"global, 1, 4, default"
+
];
+
exec-once = lib.optionals (shell == "dms") [
+
"dms run"
+
"bash -c \"wl-paste --watch cliphist store &\""
+
];
+
}
+
// keybinds
+
// monitors
+
// variables
+
// plugins
+
// env
+
// windowrules
-156
homeModules/wayland/sway.nix
···
-
{
-
pkgs,
-
config,
-
lib,
-
...
-
}:
-
let
-
term = config.wayland.windowManager.sway.config.terminal;
-
homeDir = config.home.homeDirectory;
-
cfg = config.py.profiles.gui;
-
in
-
{
-
config = lib.mkIf cfg.enable {
-
catppuccin = {
-
sway.enable = true;
-
};
-
home.sessionVariables = {
-
XDG_CURRENT_DESKTOP = "sway";
-
};
-
wayland.windowManager.sway = {
-
enable = lib.mkDefault true;
-
package = null;
-
# nix-community/home-manager/issues/5311
-
checkConfig = false;
-
wrapperFeatures.base = true;
-
wrapperFeatures.gtk = true;
-
extraConfig = ''
-
default_border pixel
-
focus_on_window_activation smart
-
'';
-
systemd = {
-
enable = true;
-
xdgAutostart = true;
-
};
-
config = {
-
terminal = lib.getExe pkgs.ghostty;
-
menu = "exec ${lib.getExe pkgs.onagre}";
-
modifier = "Mod4";
-
bars = [ { command = "true"; } ];
-
focus = {
-
followMouse = true;
-
mouseWarping = true;
-
newWindow = "smart";
-
};
-
fonts = {
-
names = [ "Inter" ];
-
style = "Regular";
-
size = 12.0;
-
};
-
gaps = {
-
inner = 1;
-
outer = 1;
-
smartBorders = "on";
-
smartGaps = false;
-
};
-
input = {
-
"type:keyboard" = {
-
xkb_options = "caps:escape";
-
};
-
"type:mouse" = {
-
accel_profile = "flat";
-
};
-
"type:touchpad" = {
-
accel_profile = "adaptive";
-
scroll_factor = "1.5";
-
tap = "enabled";
-
};
-
};
-
modes = {
-
resize = {
-
Escape = "mode default";
-
Return = "mode default";
-
Up = "resize shrink height 10 px";
-
Down = "resize grow height 10 px";
-
Left = "resize shrink width 10 px";
-
Right = "resize grow width 10 px";
-
h = "resize shrink width 10 px";
-
j = "resize grow height 10 px";
-
k = "resize shrink height 10 px";
-
l = "resize grow width 10 px";
-
};
-
};
-
output = {
-
eDP-1 = {
-
scale = "1.2";
-
};
-
};
-
startup = [
-
{ command = "${pkgs.dex}/bin/dex -a"; }
-
{ command = "${homeDir}/scripts/unfuck-xdg-portals.fish"; }
-
{ command = "wl-paste -t text --watch clipman store --no-persist"; }
-
];
-
window = {
-
commands = [
-
{
-
command = "inhibit_idle fullscreen";
-
criteria = {
-
class = "Chromium|zoom|Firefox";
-
};
-
}
-
{
-
command = "floating enable, sticky enable, resize set 20 ppt 40 ppt, border pixel 4";
-
criteria = {
-
app_id = "^py.floating$";
-
};
-
}
-
{
-
command = "resize set 20 ppt";
-
criteria = {
-
title = "Mumble PTT";
-
};
-
}
-
];
-
};
-
colors = {
-
background = "$base";
-
focused = {
-
border = "$pink";
-
background = "$base";
-
text = "$text";
-
indicator = "$rosewater";
-
childBorder = "$pink";
-
};
-
focusedInactive = {
-
border = "$mauve";
-
background = "$base";
-
text = "$text";
-
indicator = "$rosewater";
-
childBorder = "$mauve";
-
};
-
unfocused = {
-
border = "$mauve";
-
background = "$base";
-
text = "$text";
-
indicator = "$rosewater";
-
childBorder = "$mauve";
-
};
-
urgent = {
-
border = "$peach";
-
background = "$base";
-
text = "$peach";
-
indicator = "$overlay0";
-
childBorder = "$peach";
-
};
-
placeholder = {
-
border = "$overlay0";
-
background = "$base";
-
text = "$text";
-
indicator = "$overlay0";
-
childBorder = "$overlay0";
-
};
-
};
-
};
-
};
-
};
-
}
-67
homeModules/wayland/swaylock.nix
···
-
{
-
lib,
-
config,
-
pkgs,
-
...
-
}:
-
let
-
cfg = config.py.profiles.gui;
-
in
-
{
-
catppuccin = {
-
swaylock.enable = false;
-
};
-
programs.swaylock = lib.mkIf cfg.enable {
-
enable = lib.mkDefault true;
-
package = pkgs.swaylock-effects;
-
settings = {
-
daemonize = true;
-
image = "/home/thehedgehog/bgs/ctp-waves.png";
-
scaling = "fill";
-
line-uses-ring = true;
-
ignore-empty-password = true;
-
clock = true;
-
timestr = "%T";
-
effect-blur = "5x5";
-
-
font = "IBM Plex Sans";
-
font-size = 20;
-
-
indicator = true;
-
indicator-idle-visible = true;
-
indicator-radius = 100;
-
indicator-thickness = 5;
-
-
# Catppuccin Theme(avoid IFD by vendoring it in here)
-
color = "1e1e2e";
-
bs-hl-color = "f5e0dc";
-
caps-lock-bs-hl-color = "f5e0dc";
-
caps-lock-key-hl-color = "a6e3a1";
-
inside-color = "00000000";
-
inside-clear-color = "00000000";
-
inside-caps-lock-color = "00000000";
-
inside-ver-color = "00000000";
-
inside-wrong-color = "00000000";
-
key-hl-color = "a6e3a1";
-
layout-bg-color = "00000000";
-
layout-border-color = "00000000";
-
layout-text-color = "cdd6f4";
-
line-color = "00000000";
-
line-clear-color = "00000000";
-
line-caps-lock-color = "00000000";
-
line-ver-color = "00000000";
-
line-wrong-color = "00000000";
-
ring-color = "b4befe";
-
ring-clear-color = "f5e0dc";
-
ring-caps-lock-color = "fab387";
-
ring-ver-color = "89b4fa";
-
ring-wrong-color = "eba0ac";
-
separator-color = "00000000";
-
text-color = "cdd6f4";
-
text-clear-color = "f5e0dc";
-
text-caps-lock-color = "fab387";
-
text-ver-color = "89b4fa";
-
text-wrong-color = "eba0ac";
-
};
-
};
-
}
+35
homeModules/wayland/variables.nix
···
+
# https://wiki.hypr.land/Configuring/Variables
+
{
+
general = {
+
gaps_in = 1;
+
gaps_out = 10;
+
layout = "hy3";
+
resize_on_border = true;
+
};
+
decoration = {
+
blur.enabled = false;
+
shadow.enabled = false;
+
};
+
misc = {
+
disable_hyprland_logo = true;
+
disable_splash_rendering = true;
+
font_family = "Inter";
+
mouse_move_focuses_monitor = true;
+
};
+
input = {
+
kb_options = "caps:escape";
+
repeat_delay = 300;
+
touchpad = {
+
scroll_factor = 1.5;
+
tap_button_map = "lmr";
+
tap-and-drag = false;
+
};
+
};
+
cursor = {
+
hotspot_padding = 2;
+
};
+
ecosystem = {
+
no_update_news = true;
+
no_donation_nag = true;
+
};
+
}
-37
homeModules/wayland/waybar-mocha.css
···
-
/*
-
*
-
* Catppuccin Mocha palette
-
* Maintainer: rubyowo
-
*
-
*/
-
-
@define-color base #1e1e2e;
-
@define-color mantle #181825;
-
@define-color crust #11111b;
-
-
@define-color text #cdd6f4;
-
@define-color subtext0 #a6adc8;
-
@define-color subtext1 #bac2de;
-
-
@define-color surface0 #313244;
-
@define-color surface1 #45475a;
-
@define-color surface2 #585b70;
-
-
@define-color overlay0 #6c7086;
-
@define-color overlay1 #7f849c;
-
@define-color overlay2 #9399b2;
-
-
@define-color blue #89b4fa;
-
@define-color lavender #b4befe;
-
@define-color sapphire #74c7ec;
-
@define-color sky #89dceb;
-
@define-color teal #94e2d5;
-
@define-color green #a6e3a1;
-
@define-color yellow #f9e2af;
-
@define-color peach #fab387;
-
@define-color maroon #eba0ac;
-
@define-color red #f38ba8;
-
@define-color mauve #cba6f7;
-
@define-color pink #f5c2e7;
-
@define-color flamingo #f2cdcd;
-
@define-color rosewater #f5e0dc;
-128
homeModules/wayland/waybar-style.css
···
-
@import "mocha.css";
-
#waybar {
-
font-family:
-
BlexMono Nerd Font,
-
sans-serif;
-
font-size: 16px;
-
}
-
-
#window {
-
padding: 0 4px;
-
}
-
-
.modules-center {
-
padding-right: 20px;
-
}
-
-
window#waybar {
-
border: none;
-
border-radius: 0;
-
box-shadow: none;
-
text-shadow: none;
-
transition-duration: 0s;
-
color: @text;
-
background: @base;
-
}
-
-
#workspaces {
-
margin: 0 5px;
-
}
-
-
#workspaces button {
-
padding: 0 8px;
-
color: @text;
-
border-bottom: 2px solid @subtext0;
-
border-radius: 0px;
-
min-width: 25px;
-
margin-right: 8px;
-
}
-
-
#workspaces button.visible {
-
color: @subtext0;
-
}
-
-
#workspaces button.focused {
-
border-bottom: 3px solid @mauve;
-
font-weight: bold;
-
}
-
-
#workspaces button.urgent {
-
border: 2px solid @red;
-
}
-
-
#workspaces button:hover {
-
border-color: @blue;
-
color: @blue;
-
}
-
-
/* Repeat style here to ensure properties are overwritten as there's no !important and button:hover above resets the colour */
-
-
#workspaces button.focused {
-
color: @subtext0;
-
}
-
#workspaces button.focused:hover {
-
color: @text;
-
}
-
-
#tray,
-
#mode,
-
#battery,
-
#temperature,
-
#cpu,
-
#memory,
-
#network,
-
#wireplumber,
-
#clock,
-
#idle_inhibitor,
-
#sway-language,
-
#backlight {
-
padding: 2px 8px;
-
margin: 2px 5px;
-
color: @text;
-
}
-
-
#mode:hover,
-
#battery:hover,
-
#temperature:hover,
-
#cpu:hover,
-
#memory:hover,
-
#network:hover,
-
#wireplumber:hover,
-
#clock:hover,
-
#idle_inhibitor:hover,
-
#sway-language:hover,
-
#backlight:hover {
-
background-color: @subtext1;
-
color: @base;
-
}
-
-
#clock {
-
font-weight: bold;
-
}
-
-
#battery.warning {
-
color: @yellow;
-
}
-
-
#battery.critical {
-
color: @red;
-
}
-
-
#battery.charging,
-
#battery.full {
-
color: @green;
-
}
-
-
#battery.warning:hover,
-
#battery.critical:hover,
-
#battery.charging:hover,
-
#battery.full:hover {
-
color: @base;
-
}
-
-
@keyframes blink {
-
to {
-
background-color: #ffffff;
-
color: black;
-
}
-
}
-172
homeModules/wayland/waybar.nix
···
-
{
-
pkgs,
-
lib,
-
config,
-
...
-
}:
-
let
-
cfg = config.py.profiles.gui;
-
sway = config.wayland.windowManager.sway;
-
in
-
{
-
config = {
-
xdg.configFile."waybar/mocha.css" = lib.mkIf (cfg.enable && sway.enable) {
-
source = ./waybar-mocha.css;
-
recursive = false;
-
};
-
catppuccin.waybar.enable = false;
-
programs.waybar = lib.mkIf (cfg.enable && sway.enable) {
-
enable = lib.mkDefault false;
-
systemd.enable = true;
-
systemd.target = "sway-session.target";
-
style = ./waybar-style.css;
-
settings = {
-
mainBar = {
-
layer = "top";
-
position = "top";
-
height = 32;
-
modules-left = [
-
"sway/workspaces"
-
"sway/mode"
-
];
-
modules-center = [ "mpris" ];
-
modules-right = [
-
"idle_inhibitor"
-
"wireplumber"
-
"network"
-
"temperature"
-
"backlight"
-
"battery"
-
"clock"
-
"tray"
-
];
-
"sway/workspaces" = {
-
disable-scroll = true;
-
enable-bar-scroll = false;
-
active-only = false;
-
all-outputs = false;
-
format = "{icon}";
-
};
-
"idle_inhibitor" = {
-
format = "{icon} ";
-
format-icons = {
-
"activated" = "";
-
"deactivated" = "";
-
};
-
};
-
"tray" = {
-
icon-size = 25;
-
spacing = 12;
-
};
-
"clock" = {
-
tooltip-format = "<tt><small>{calendar}</small></tt>";
-
format = " {:%H:%M:%S}";
-
format-alt = "{%d %b %Y}";
-
interval = 1;
-
calendar = {
-
format = {
-
today = "<span color='#89b4fa'><b><u>{}</u></b></span>";
-
};
-
};
-
};
-
"cpu" = {
-
format = " {usage}%";
-
interval = 5;
-
tooltip = false;
-
};
-
"memory" = {
-
format = " {}%";
-
};
-
"temperature" = {
-
critical-threshold = 80;
-
format = "{icon} {temperatureC}°C";
-
format-icons = [
-
""
-
""
-
""
-
""
-
""
-
];
-
};
-
"backlight" = {
-
format = "{icon} {percent}%";
-
format-icons = [
-
"󰃚"
-
"󰃛"
-
"󰃜"
-
"󰃝"
-
"󰃞"
-
"󰃟"
-
"󰃠"
-
];
-
};
-
"battery" = {
-
states = {
-
good = 65;
-
warning = 30;
-
critical = 15;
-
};
-
full-at = 80;
-
format = "{icon} {capacity}%";
-
format-charging = "󰂄 {capacity}%";
-
format-plugged = " {capacity}%";
-
format-alt = "{icon} {time}";
-
format-icons = [
-
"󰂎"
-
"󰁺"
-
"󰁻"
-
"󰁼"
-
"󰁽"
-
"󰁾"
-
"󰁿"
-
"󰂀"
-
"󰂁"
-
"󰂂"
-
"󰁹"
-
];
-
};
-
"network" = {
-
format-wifi = "<big></big> {essid}";
-
format-ethernet = "󰈀 {ifname}: {ipaddr}/{cidr}";
-
format-linked = "󰄡 {ifname} (No IP)";
-
format-disconnected = "⚠ Disconnected!";
-
format-alt = "{ifname}: {ipaddr}/{cidr}";
-
on-click = lib.getExe pkgs.networkmanagerapplet;
-
};
-
"wireplumber" = {
-
format = "{icon} {volume}%";
-
format-muted = "󰝟";
-
format-icons = [
-
""
-
""
-
""
-
];
-
states = {
-
low = 15;
-
med = 40;
-
high = 60;
-
};
-
scroll-step = 5;
-
on-click = lib.getExe pkgs.pwvucontrol;
-
};
-
mpris = {
-
format = "{status_icon} {dynamic}";
-
max-length = 100;
-
format-paused = "{status_icon} <i>{dynamic}</i>";
-
dynamic-order = [
-
"artist"
-
"title"
-
];
-
status-icons = {
-
playing = "";
-
paused = "";
-
};
-
player-icons = {
-
firefox = "󰈹";
-
};
-
};
-
};
-
};
-
};
-
};
-
}
+7
homeModules/wayland/windowrules.nix
···
+
{
+
windowrule = [
+
"immediate, content game, title:Celeste"
+
"tile, title:Melvor Idle"
+
"immediate, content game, fullscreen, monitor DP-2, class:steam_app_49520, initialClass:steam_app_49520"
+
];
+
}
+5 -4
homeModules/xdg/default.nix
···
xdgOpenUsePortal = true;
extraPortals = [
pkgs.xdg-desktop-portal-gtk
-
pkgs.xdg-desktop-portal-wlr
];
config = {
common = {
-
default = [ "gtk" ];
-
"org.freedesktop.impl.portal.Screenshot" = [ "wlr" ];
-
"org.freedesktop.impl.portal.ScreenCast" = [ "wlr" ];
+
default = [
+
"hyprland"
+
"gtk"
+
];
+
"org.freedesktop.impl.portal.FileChooser" = [ "gtk" ];
};
};
};
+1 -2
hosts/default.nix
···
modules = [
inputs.agenix.nixosModules.default
inputs.ctp.nixosModules.catppuccin
-
inputs.determinate.nixosModules.default
inputs.home-manager.nixosModules.home-manager
inputs.self.nixosModules.chromium
inputs.self.nixosModules.defaultConfig
···
"vps"
];
modules = [
-
inputs.mailserver.nixosModule
+
inputs.dn42.nixosModules.default
];
};
thought = {
+4 -5
hosts/marvin/default.nix
···
./hardware.nix
# Running Services
+
# keep-sorted start
./services/anubis.nix
-
# ./services/authentik.nix
./services/avahi.nix
./services/bots.nix
./services/deemix.nix
···
./services/git.nix
./services/golink.nix
./services/grafana.nix
-
# ./services/iceshrimp.nix
+
./services/immich.nix
./services/jellyfin.nix
./services/matrix.nix
./services/miniflux.nix
+
./services/nextcloud
./services/nginx.nix
-
./services/nextcloud
./services/pinchflat.nix
-
./services/pingvin-share.nix
./services/planka.nix
./services/pocket-id.nix
./services/podman.nix
./services/postgres.nix
./services/prometheus.nix
-
# ./services/redlib.nix
./services/scrutiny.nix
./services/syncthing.nix
./services/tailscale.nix
./services/tangled.nix
./services/vaultwarden.nix
./services/zfs.nix
+
# keep-sorted end
];
nix.settings.max-jobs = 12;
networking = {
+3
hosts/marvin/services/anubis.nix
···
{
config,
+
self',
...
}:
{
···
extraFlags = [ "-metrics-bind \"\"" ];
settings = {
BIND_NETWORK = "tcp";
+
METRICS_BIND_NETWORK = "tcp";
SERVE_ROBOTS_TXT = true;
COOKIE_DOMAIN = ".pyrox.dev";
ED25519_PRIVATE_KEY_HEX_FILE = config.age.secrets.anubis-key.path;
OG_PASSTHROUGH = true;
OG_CACHE_CONSIDER_HOST = true;
+
POLICY_FNAME = "${self'.packages.anubis-files}/policies/default.yaml";
};
};
age.secrets.anubis-key = {
-92
hosts/marvin/services/authentik.nix
···
-
{
-
config,
-
self,
-
...
-
}:
-
let
-
d = self.lib.data.services.authentik;
-
in
-
{
-
virtualisation.oci-containers.containers =
-
let
-
authentikVersion = "2025.4";
-
base = {
-
environmentFiles = [ config.age.secrets.authentik-env.path ];
-
extraOptions = [ "--network=authentik" ];
-
};
-
authentikBase = base // {
-
image = "ghcr.io/goauthentik/server:${authentikVersion}";
-
environment = {
-
AUTHENTIK_REDIS__HOST = "authentik-redict";
-
-
# Postgres Settings
-
AUTHENTIK_POSTGRESQL__HOST = "authentik-db";
-
AUTHENTIK_POSTGRESQL__PORT = "5432";
-
AUTHENTIK_POSTGRESQL__USER = "authentik";
-
AUTHENTIK_POSTGRESQL__NAME = "authentik";
-
AUTHENTIK_POSTGRESQL__PASSWORD = "\${PG_PASS}";
-
-
# Disable error reporting
-
AUTHENTIK_ERROR_REPORTING__ENABLED = "false";
-
-
# Avatars are an attribute based on an uploaded file
-
AUTHENTIK_AVATARS = "attributes.user.avatar";
-
-
# Email Settings
-
AUTHENTIK_EMAIL__HOST = "mail.pyrox.dev";
-
AUTHENTIK_EMAIL__USERNAME = "auth@pyrox.dev";
-
AUTHENTIK_EMAIL__PORT = "465";
-
AUTHENTIK_EMAIL__USE_TLS = "true";
-
AUTHENTIK_EMAIL__FROM = "PyroServ Auth <auth@pyrox.dev>";
-
};
-
};
-
authentikVols = [
-
"/var/lib/authentik/media:/media"
-
"/var/lib/authentik/templates:/templates"
-
];
-
in
-
{
-
authentik-db = base // {
-
image = "postgres:17-alpine";
-
volumes = [ "/var/lib/authentik/db:/var/lib/postgresql/data" ];
-
environment = {
-
POSTGRES_PASSWORD = "\${PG_PASS}";
-
POSTGRES_USER = "authentik";
-
POSTGRES_DB = "authentik";
-
};
-
};
-
authentik-redict = {
-
image = "registry.redict.io/redict:alpine";
-
extraOptions = [ "--network=authentik" ];
-
};
-
authentik-server = authentikBase // {
-
cmd = [ "server" ];
-
ports = [
-
"${toString d.port}:9000"
-
"6943:9443"
-
"9301:9300"
-
];
-
volumes = authentikVols ++ [ "/var/lib/authentik/custom.css:/web/dist/custom.css" ];
-
};
-
authentik-worker = authentikBase // {
-
cmd = [ "worker" ];
-
volumes = authentikVols ++ [ "/var/lib/authentik/certs:/certs" ];
-
};
-
authentik-ldap = base // {
-
image = "ghcr.io/goauthentik/ldap:${authentikVersion}";
-
ports = [
-
"389:3389"
-
"636:6636"
-
];
-
environment = {
-
AUTHENTIK_HOST = "https://${d.extUrl}";
-
AUTHENTIK_INSECURE = "false";
-
};
-
};
-
};
-
age.secrets.authentik-env = {
-
file = ./secrets/authentik-env.age;
-
owner = "thehedgehog";
-
group = "misc";
-
};
-
}
-5
hosts/marvin/services/bookstack.nix
···
-
{
-
services.bookstack = {
-
enable = true;
-
};
-
}
+1 -1
hosts/marvin/services/gdq-cals.nix
···
description = "GDQ Calendar Updater";
path = [ pyWithLibs ];
serviceConfig = {
-
ExecStart = "${lib.getExe pyWithLibs} gdq_cal_ics_exporter.py --id 56 --fatales --gcal";
+
ExecStart = "${lib.getExe pyWithLibs} gdq_cal_ics_exporter.py --fatales --gcal --disable_general";
Type = "oneshot";
WorkingDirectory = "/home/thehedgehog/gdq-cals/";
User = "thehedgehog";
+5 -5
hosts/marvin/services/git.nix
···
};
settings = {
DEFAULT = {
-
APP_NAME = "PyroNet Git";
+
APP_NAME = "dishNet Git";
RUN_MODE = "prod";
};
attachment = {
MAX_SIZE = 200;
};
-
log."logger.router.MODE" = "";
+
log.LOGGER_ROUTER_MODE = "";
mailer = {
ENABLED = true;
-
FROM = "PyroNet Git <git@pyrox.dev>";
+
FROM = "dishNet Git <git@pyrox.dev>";
PROTOCOL = "smtps";
SMTP_ADDR = "mail.pyrox.dev";
SMTP_PORT = 465;
···
};
"ui.meta" = {
AUTHOR = "dish";
-
DESCRIPTION = "PyroNet Git Services";
+
DESCRIPTION = "dishNet Git Services";
};
metrics = {
ENABLED = true;
···
ISSUE_INDEXER_PATH = "indexers/issues.bleve";
# Enable repo indexing
REPO_INDEXER_ENABLED = true;
-
REPO_INDEXER_REPO_TYPES = "sources,forks,templates,mirrors";
+
REPO_INDEXER_REPO_TYPES = "sources,forks";
REPO_INDEXER_TYPE = "bleve";
REPO_INDEXER_PATH = "indexers/repos.bleve";
};
-7
hosts/marvin/services/golink.nix
···
{
services.golink = {
enable = true;
-
tailscaleAuthKeyFile = /run/agenix/golink-authkey;
-
};
-
age.secrets.golink-authkey = {
-
file = ./secrets/golink-authkey.age;
-
path = "/run/agenix/golink-authkey";
-
owner = "golink";
-
group = "golink";
};
}
+4 -4
hosts/marvin/services/grafana.nix
···
};
smtp = {
enabled = true;
-
user = "grafana@thehedgehog.me";
-
from_address = "grafana@thehedgehog.me";
-
host = "smtp.migadu.com:465";
+
user = "grafana@pyrox.dev";
+
from_address = "grafana@pyrox.dev";
+
host = "mail.pyrox.dev:465";
password = "$__file{${config.age.secrets.grafana-smtp-password.path}}";
};
};
···
services.anubis.instances.grafana = {
settings = {
BIND = ":${toString d.anubis}";
-
POLICY_FNAME = "${self'.packages.anubis-files}/policies/grafana.yaml";
+
POLICY_FNAME = "${self'.packages.anubis-files}/policies/default.yaml";
TARGET = "http://localhost:${toString d.port}";
};
};
-97
hosts/marvin/services/iceshrimp.nix
···
-
{
-
config,
-
inputs,
-
pkgs,
-
lib,
-
self,
-
...
-
}:
-
let
-
-
d = self.lib.data.services.iceshrimp;
-
-
package = inputs.iceshrimp.packages.x86_64-linux.iceshrimp-pre.overrideAttrs rec {
-
version = "2023.12.8-pyrox1";
-
src = pkgs.fetchgit {
-
url = "https://iceshrimp.dev/pyrox/iceshrimp";
-
hash = "sha256-hxZ3rVVAiAMFAYhZ2o+WhlMuhjbt5EyHKOl1VyyL5RA=";
-
rev = "v${version}";
-
fetchLFS = true;
-
deepClone = false;
-
};
-
patches = [ ];
-
};
-
in
-
{
-
services.iceshrimp = {
-
inherit package;
-
enable = false;
-
secretConfig = config.age.secrets.iceshrimp-secret-config.path;
-
dbPasswordFile = config.age.secrets.iceshrimp-db-password.path;
-
createDb = true;
-
configureNginx.enable = false;
-
settings = {
-
inherit (d) port;
-
url = "https://${d.extUrl}";
-
accountDomain = "pyrox.dev";
-
redis.port = 6997;
-
maxNoteLength = 16384;
-
maxCaptionLength = 8192;
-
clusterLimit = 4;
-
deliverJobConcurrency = 192;
-
inboxJobConcurrency = 32;
-
deliverJobPerSec = 256;
-
inboxJobPerSec = 32;
-
outgoingAddressFamily = "dual";
-
# See the withdrawal patches for obliterate info
-
enableObliterate = true;
-
obliterateJobPerSec = 16;
-
obliterateJobMaxAttempts = 3;
-
mediaCleanup = {
-
cron = true;
-
maxAgeDays = 30;
-
cleanAvatars = true;
-
cleanHeaders = true;
-
};
-
htmlCache = {
-
ttl = "6h";
-
prewarm = true;
-
dbFallback = true;
-
};
-
wordMuteCache.ttl = "24h";
-
isManagedHosting = true;
-
email = {
-
managed = true;
-
address = "social@pyrox.dev";
-
host = "mail.pyrox.dev";
-
port = 465;
-
user = "social@pyrox.dev";
-
useImplicitSslTls = true;
-
};
-
objectStorage = {
-
managed = true;
-
baseUrl = "https://pool.jortage.com/socialpyroxdev";
-
bucket = "socialpyroxdev";
-
prefix = "mkmedia";
-
endpoint = "pool-api.jortage.com";
-
region = "jort";
-
useSsl = true;
-
connnectOverProxy = false;
-
setPublicReadOnUpload = false;
-
s3ForcePathStyle = true;
-
};
-
};
-
};
-
age.secrets = lib.mkIf config.services.iceshrimp.enable {
-
iceshrimp-secret-config = {
-
inherit (config.services.iceshrimp) group;
-
file = ./secrets/iceshrimp-secret-config.age;
-
owner = config.services.iceshrimp.user;
-
};
-
iceshrimp-db-password = {
-
file = ./secrets/iceshrimp-db-password.age;
-
owner = "postgres";
-
group = "postgres";
-
};
-
};
-
}
+223
hosts/marvin/services/immich-config.json
···
+
{
+
"backup": {
+
"database": {
+
"cronExpression": "0 02 * * *",
+
"enabled": true,
+
"keepLastAmount": 14
+
}
+
},
+
"ffmpeg": {
+
"accel": "vaapi",
+
"accelDecode": true,
+
"acceptedAudioCodecs": ["aac", "mp3", "libopus"],
+
"acceptedContainers": ["mov", "ogg", "webm"],
+
"acceptedVideoCodecs": ["h264"],
+
"bframes": -1,
+
"cqMode": "auto",
+
"crf": 23,
+
"gopSize": 0,
+
"maxBitrate": "0",
+
"preferredHwDevice": "auto",
+
"preset": "veryfast",
+
"refs": 0,
+
"targetAudioCodec": "aac",
+
"targetResolution": "720",
+
"targetVideoCodec": "h264",
+
"temporalAQ": false,
+
"threads": 0,
+
"tonemap": "hable",
+
"transcode": "required",
+
"twoPass": false
+
},
+
"image": {
+
"colorspace": "p3",
+
"extractEmbedded": false,
+
"fullsize": {
+
"enabled": false,
+
"format": "jpeg",
+
"quality": 80
+
},
+
"preview": {
+
"format": "jpeg",
+
"quality": 80,
+
"size": 1440
+
},
+
"thumbnail": {
+
"format": "webp",
+
"quality": 80,
+
"size": 250
+
}
+
},
+
"job": {
+
"backgroundTask": {
+
"concurrency": 5
+
},
+
"faceDetection": {
+
"concurrency": 2
+
},
+
"library": {
+
"concurrency": 5
+
},
+
"metadataExtraction": {
+
"concurrency": 5
+
},
+
"migration": {
+
"concurrency": 5
+
},
+
"notifications": {
+
"concurrency": 5
+
},
+
"ocr": {
+
"concurrency": 1
+
},
+
"search": {
+
"concurrency": 5
+
},
+
"sidecar": {
+
"concurrency": 5
+
},
+
"smartSearch": {
+
"concurrency": 2
+
},
+
"thumbnailGeneration": {
+
"concurrency": 3
+
},
+
"videoConversion": {
+
"concurrency": 1
+
},
+
"workflow": {
+
"concurrency": 5
+
}
+
},
+
"library": {
+
"scan": {
+
"cronExpression": "0 0 * * *",
+
"enabled": true
+
},
+
"watch": {
+
"enabled": false
+
}
+
},
+
"logging": {
+
"enabled": true,
+
"level": "log"
+
},
+
"machineLearning": {
+
"availabilityChecks": {
+
"enabled": true,
+
"interval": 30000,
+
"timeout": 2000
+
},
+
"clip": {
+
"enabled": true,
+
"modelName": "ViT-B-16-SigLIP2__webli"
+
},
+
"duplicateDetection": {
+
"enabled": true,
+
"maxDistance": 0.01
+
},
+
"enabled": true,
+
"facialRecognition": {
+
"enabled": true,
+
"maxDistance": 0.5,
+
"minFaces": 7,
+
"minScore": 0.7,
+
"modelName": "buffalo_l"
+
},
+
"ocr": {
+
"enabled": true,
+
"maxResolution": 736,
+
"minDetectionScore": 0.5,
+
"minRecognitionScore": 0.8,
+
"modelName": "EN__PP-OCRv5_mobile"
+
},
+
"urls": ["http://localhost:3003"]
+
},
+
"map": {
+
"darkStyle": "https://tiles.immich.cloud/v1/style/dark.json",
+
"enabled": true,
+
"lightStyle": "https://tiles.immich.cloud/v1/style/light.json"
+
},
+
"metadata": {
+
"faces": {
+
"import": false
+
}
+
},
+
"newVersionCheck": {
+
"enabled": false
+
},
+
"nightlyTasks": {
+
"clusterNewFaces": true,
+
"databaseCleanup": true,
+
"generateMemories": true,
+
"missingThumbnails": true,
+
"startTime": "00:00",
+
"syncQuotaUsage": true
+
},
+
"notifications": {
+
"smtp": {
+
"enabled": true,
+
"from": "dishNet Photos <immich@pyrox.dev>",
+
"replyTo": "",
+
"transport": {
+
"host": "mail.pyrox.dev",
+
"ignoreCert": false,
+
"port": 25,
+
"secure": true,
+
"username": "immich@pyrox.dev"
+
}
+
}
+
},
+
"oauth": {
+
"autoLaunch": false,
+
"autoRegister": true,
+
"buttonText": "Login with Pocket-ID",
+
"clientId": "f1312240-d9fc-4336-aca6-b98316867848",
+
"defaultStorageQuota": null,
+
"enabled": true,
+
"issuerUrl": "https://auth.pyrox.dev",
+
"mobileOverrideEnabled": false,
+
"mobileRedirectUri": "",
+
"profileSigningAlgorithm": "none",
+
"roleClaim": "immich_role",
+
"scope": "openid email profile immich_role",
+
"signingAlgorithm": "RS256",
+
"storageLabelClaim": "preferred_username",
+
"storageQuotaClaim": "immich_quota",
+
"timeout": 30000,
+
"tokenEndpointAuthMethod": "client_secret_post"
+
},
+
"passwordLogin": {
+
"enabled": true
+
},
+
"reverseGeocoding": {
+
"enabled": true
+
},
+
"server": {
+
"externalDomain": "https://img.pyrox.dev",
+
"loginPageMessage": "",
+
"publicUsers": true
+
},
+
"storageTemplate": {
+
"enabled": false,
+
"hashVerificationEnabled": true,
+
"template": "{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}"
+
},
+
"templates": {
+
"email": {
+
"albumInviteTemplate": "",
+
"albumUpdateTemplate": "",
+
"welcomeTemplate": ""
+
}
+
},
+
"theme": {
+
"customCss": ""
+
},
+
"trash": {
+
"days": 30,
+
"enabled": true
+
},
+
"user": {
+
"deleteDelay": 7
+
}
+
}
+51
hosts/marvin/services/immich.nix
···
+
{
+
self,
+
config,
+
lib,
+
...
+
}:
+
let
+
d = self.lib.data.services.immich;
+
in
+
{
+
services = {
+
immich = {
+
inherit (d) port;
+
enable = true;
+
host = "0.0.0.0";
+
redis.enable = true;
+
mediaLocation = "/var/media/photos/";
+
accelerationDevices = [ "/dev/dri/renderD128" ];
+
settings = lib.recursiveUpdate (builtins.fromJSON (builtins.readFile ./immich-config.json)) {
+
oauth.clientSecret._secret = config.age.secrets.immich-oauth-secret.path;
+
notifications.smtp.transport.password._secret = config.age.secrets.immich-mail-pw.path;
+
server.externalDomain = "https://${d.extUrl}";
+
};
+
};
+
immich-public-proxy = {
+
enable = true;
+
port = d.pubProxy;
+
immichUrl = "http://localhost:${toString d.port}";
+
settings.ipp = {
+
downloadedFilename = 1;
+
};
+
};
+
};
+
systemd.services.immich-public-proxy.environment.PUBLIC_BASE_URL = "https://${d.extUrl}";
+
users.users.immich.extraGroups = [
+
"video"
+
"render"
+
];
+
age.secrets = {
+
immich-oauth-secret = {
+
file = ./secrets/immich/oauth-secret.age;
+
owner = "immich";
+
group = "immich";
+
};
+
immich-mail-pw = {
+
file = ./secrets/immich/mail-pw.age;
+
owner = "immich";
+
group = "immich";
+
};
+
};
+
}
-2
hosts/marvin/services/miniflux.nix
···
{
config,
-
self',
self,
...
}:
···
services.anubis.instances.miniflux = {
settings = {
BIND = ":${toString d.anubis}";
-
POLICY_FNAME = "${self'.packages.anubis-files}/policies/miniflux.yaml";
TARGET = "http://localhost:${toString d.port}";
};
};
-11
hosts/marvin/services/minio.nix
···
-
{ config, ... }:
-
{
-
services.minio = {
-
enable = true;
-
region = "us-east-1";
-
browser = true;
-
listenAddress = ":6990";
-
consoleAddress = ":6991";
-
rootCredentialsFile = config.age.secrets.minio-root.path;
-
};
-
}
+1 -2
hosts/marvin/services/nextcloud/default.nix
···
];
services.nextcloud = {
enable = true;
-
package = pkgs.nextcloud31;
+
package = pkgs.nextcloud32;
phpPackage = lib.mkForce pkgs.php82;
appstoreEnable = true;
caching.redis = true;
···
configureRedis = true;
database.createLocally = true;
hostName = d.extUrl;
-
nginx.recommendedHttpHeaders = true;
};
age.secrets.nextcloud-admin-pw = {
file = ./nextcloud-admin-pw.age;
+1 -1
hosts/marvin/services/nextcloud/office.nix
···
{
services.collabora-online = {
enable = true;
-
port = d.port;
+
inherit (d) port;
settings = {
ssl.enable = false;
ssl.termination = true;
+1 -1
hosts/marvin/services/pinchflat.nix
···
{
services.pinchflat = {
enable = true;
-
port = d.port;
+
inherit (d) port;
secretsFile = age.pinchflat-secrets.path;
mediaDir = "/var/media/youtube";
extraConfig = {
-130
hosts/marvin/services/pingvin-share.nix
···
-
{
-
config,
-
pkgs,
-
self',
-
self,
-
...
-
}:
-
let
-
d = self.lib.data.services.pingvin-share;
-
cfg = config.services.pingvin-share;
-
configFormat = pkgs.formats.yaml { };
-
configFile = configFormat.generate "config.yaml" {
-
general = {
-
appName = "dishNet Share";
-
appUrl = "https://share.pyrox.dev";
-
secureCookies = "true";
-
showHomePage = "false";
-
};
-
share = {
-
allowRegistration = "false";
-
allowUnauthenticatedShares = "false";
-
maxSize = "10000000000";
-
};
-
email.enableShareEmailRecipients = "true";
-
smtp = {
-
enabled = "true";
-
host = "mail.pyrox.dev";
-
port = "465";
-
email = "share@pyrox.dev";
-
username = "share@pyrox.dev";
-
password = "SMTP_PASSWORD";
-
};
-
ldap.enabled = "false";
-
legal.enabled = "false";
-
s3.enabled = "false";
-
oauth = {
-
ignoreTotp = "true";
-
oidc-enabled = "true";
-
oidc-clientSecret = "CLIENT_SECRET";
-
oidc-clientId = "d83006a6-9b08-47eb-af56-418065db09b5";
-
oidc-discoveryUri = "https://auth.pyrox.dev/.well-known/openid-configuration";
-
oidc-signOut = "false";
-
oidc-scope = "openid email profile groups";
-
oidc-rolePath = "groups";
-
oidc-roleAdminAccess = "admins";
-
};
-
initUser.enabled = false;
-
};
-
in
-
{
-
virtualisation.oci-containers.containers = {
-
pingvin-share-server = {
-
image = "ghcr.io/stonith404/pingvin-share:latest";
-
ports = [
-
"${toString d.port}:3000"
-
"${toString d.be-port}:8080"
-
];
-
volumes = [
-
"/var/lib/pingvin-share/data:/opt/app/backend/data"
-
"/var/lib/pingvin-share/data/images:/opt/app/frontend/public/img"
-
"/var/lib/pingvin-share/config.yaml:/opt/app/config.yaml"
-
];
-
environment = {
-
API_URL = "https://share.pyrox.dev";
-
PUID = "962";
-
PGID = "959";
-
};
-
};
-
};
-
users.users.pingvin = {
-
uid = 962;
-
group = cfg.group;
-
isSystemUser = true;
-
};
-
users.groups.pingvin = {
-
gid = 959;
-
};
-
-
services = {
-
pingvin-share = {
-
enable = false;
-
backend.port = d.be-port;
-
frontend.port = d.port;
-
hostname = "share.pyrox.dev";
-
https = true;
-
};
-
anubis.instances = {
-
pingvin-share-be = {
-
settings = {
-
BIND = ":${toString d.be-anubis}";
-
POLICY_FNAME = "${self'.packages.anubis-files}/policies/pingvin-share.yaml";
-
TARGET = "http://localhost:${toString d.be-port}";
-
};
-
};
-
pingvin-share-fe = {
-
settings = {
-
BIND = ":${toString d.anubis}";
-
POLICY_FNAME = "${self'.packages.anubis-files}/policies/pingvin-share.yaml";
-
TARGET = "http://localhost:${toString d.port}";
-
};
-
};
-
};
-
};
-
systemd.services.init-pingvin-config = {
-
enable = true;
-
description = "Pingvin Share configuration setup";
-
wantedBy = [ "multi-user.target" ];
-
before = [
-
"docker-pingvin-share-server.service"
-
];
-
path = [ pkgs.gnused ];
-
script = ''
-
rm ${cfg.dataDir}/config.yaml
-
cp ${configFile} ${cfg.dataDir}/config.yaml
-
sed -i "s/SMTP_PASSWORD/\"$SMTP_PASSWORD\"/" ${cfg.dataDir}/config.yaml
-
sed -i "s/CLIENT_SECRET/\"$CLIENT_SECRET\"/" ${cfg.dataDir}/config.yaml
-
'';
-
serviceConfig = {
-
EnvironmentFile = config.age.secrets.pingvin-secrets.path;
-
User = cfg.user;
-
Group = cfg.group;
-
ReadWritePaths = [ "${cfg.dataDir}" ];
-
};
-
};
-
age.secrets.pingvin-secrets = {
-
file = ./secrets/pingvin-secrets.age;
-
owner = cfg.user;
-
group = cfg.group;
-
};
-
}
+97 -30
hosts/marvin/services/planka.nix
···
{
+
lib,
config,
-
self',
self,
+
self',
+
pkgs,
...
}:
let
-
dataDir = "/var/lib/planka";
d = self.lib.data.services.planka;
+
+
commonServiceConfig = {
+
EnvironmentFile = config.age.secrets.planka-env.path;
+
StateDirectory = "planka";
+
WorkingDirectory = "/var/lib/planka";
+
User = "planka";
+
Group = "planka";
+
+
# Hardening
+
LockPersonality = true;
+
NoNewPrivileges = true;
+
PrivateDevices = true;
+
PrivateMounts = true;
+
PrivateTmp = true;
+
PrivateUsers = true;
+
ProtectClock = true;
+
ProtectControlGroups = true;
+
ProtectHome = true;
+
ProtectHostname = true;
+
ProtectKernelLogs = true;
+
ProtectKernelModules = true;
+
ProtectKernelTunables = true;
+
ProtectProc = "invisible";
+
RemoveIPC = true;
+
RestrictRealtime = true;
+
RestrictSUIDSGID = true;
+
UMask = "0660";
+
RestrictAddressFamilies = [
+
"AF_UNIX"
+
"AF_INET"
+
"AF_INET6"
+
];
+
};
in
{
-
virtualisation.oci-containers.containers = {
-
planka-server = {
-
image = "ghcr.io/plankanban/planka:latest";
-
ports = [ "${toString d.port}:1337" ];
-
environment = {
-
BASE_URL = "https://${d.extUrl}";
-
DATABASE_URL = "postgresql://planka@planka-db/planka";
-
# Default Admin
-
DEFAULT_ADMIN_EMAIL = "pyrox@pyrox.dev";
-
DEFAULT_ADMIN_USERNAME = "pyrox";
+
systemd = {
+
tmpfiles.settings = {
+
"10-planka"."/var/lib/planka".d = {
+
group = "planka";
+
user = "planka";
+
mode = "0755";
};
-
environmentFiles = [ config.age.secrets.planka-env.path ];
-
volumes = [
-
"${dataDir}/user-avatars:/app/public/user-avatars"
-
"${dataDir}/project-background-images:/app/public/project-background-images"
-
"${dataDir}/attachments:/app/private/attachments"
-
];
-
extraOptions = [ "--network=planka" ];
};
-
planka-db = {
-
image = "postgres:16-alpine";
-
volumes = [ "${dataDir}/db:/var/lib/postgresql/data" ];
-
environment = {
-
POSTGRES_USER = "planka";
-
POSTGRES_DB = "planka";
-
POSTGRES_HOST_AUTH_METHOD = "trust";
+
services = {
+
planka-init-db = {
+
wantedBy = [ "multi-user.target" ];
+
after = [ "postgres.target" ];
+
description = "Planka Kanban Database Init Script";
+
path = [
+
pkgs.nodejs
+
];
+
script = ''
+
if [ ! -f /var/lib/planka/db-init-ran ]; then
+
node run ${self'.packages.planka}/lib/node_modules/planka/db/init.js && \
+
touch /var/lib/planka/db-init-ran
+
fi
+
'';
+
serviceConfig = commonServiceConfig // {
+
Type = "oneshot";
+
SyslogIdentifier = "planka-init-db";
+
};
+
};
+
planka-server = {
+
after = [ "planka-init-db.service" ];
+
wantedBy = [ "multi-user.target" ];
+
description = "Planka Kanban Server";
+
documentation = [ "https://docs.planka.cloud" ];
+
environment = {
+
DATABASE_URL = "postgresql://%2Frun%2Fpostgresql/planka";
+
DEFAULT_ADMIN_EMAIL = "pyrox@pyrox.dev";
+
DEFAULT_ADMIN_USERNAME = "pyrox";
+
TRUST_PROXY = "true";
+
DEFAULT_LANGUAGE = "en-US";
+
BASE_URL = "https://${d.extUrl}";
+
NODE_ENV = "production";
+
};
+
serviceConfig = commonServiceConfig // {
+
Type = "simple";
+
ExecStart = "${lib.getExe self'.packages.planka} --port ${toString d.port}";
+
SyslogIdentifier = "planka";
+
};
};
-
extraOptions = [ "--network=planka" ];
};
};
+
users.users.planka = {
+
isSystemUser = true;
+
group = "planka";
+
};
+
users.groups.planka = { };
+
services.postgresql = {
+
ensureUsers = [
+
{
+
name = "planka";
+
ensureDBOwnership = true;
+
ensureClauses.login = true;
+
}
+
];
+
ensureDatabases = [ "planka" ];
+
};
age.secrets.planka-env = {
file = ./secrets/planka-env.age;
-
owner = "thehedgehog";
-
group = "misc";
+
owner = "planka";
+
group = "planka";
};
services.anubis.instances.planka = {
settings = {
COOKIE_DOMAIN = ".cs2a.club";
BIND = ":${toString d.anubis}";
-
POLICY_FNAME = "${self'.packages.anubis-files}/policies/planka.yaml";
TARGET = "http://localhost:${toString d.port}";
};
};
-2
hosts/marvin/services/pocket-id.nix
···
{
config,
-
self',
self,
...
}:
···
pocket-id = {
settings = {
BIND = ":${toString d.anubis}";
-
POLICY_FNAME = "${self'.packages.anubis-files}/policies/pocket-id.yaml";
TARGET = "http://localhost:${toString d.port}";
};
};
+23 -23
hosts/marvin/services/postgres.nix
···
-
{ pkgs, config, ... }:
-
let
-
cfg = config.services.postgresql;
-
in
+
{ pkgs, ... }:
+
# let
+
# cfg = config.services.postgresql;
+
# in
{
services.postgresql = {
enable = true;
···
max_parallel_maintenance_workers = 4;
};
};
-
systemd.timers.pg-autovacuum = {
-
description = "Timer for Postgres Autovacuum";
-
timerConfig = {
-
OnCalendar = "*-*-* 01:00:00";
-
Unit = "pg-autovacuum.service";
-
};
-
};
-
systemd.services.pg-autovacuum = {
-
description = "Vacuum all Postgres databases.";
-
requisite = [ "postgresql.service" ];
-
wantedBy = [ "multi-user.target" ];
-
serviceConfig = {
-
Type = "oneshot";
-
User = "postgres";
-
Group = "postgres";
-
SyslogIdentifier = "pg-autovacuum";
-
ExecStart = "${cfg.package}/bin/vacuumdb --all --echo --jobs=6 --parallel=5 --analyze --verbose";
-
};
-
};
+
# systemd.timers.pg-autovacuum = {
+
# description = "Timer for Postgres Autovacuum";
+
# timerConfig = {
+
# OnCalendar = "*-*-* 01:00:00";
+
# Unit = "pg-autovacuum.service";
+
# };
+
# };
+
# systemd.services.pg-autovacuum = {
+
# description = "Vacuum all Postgres databases.";
+
# requisite = [ "postgresql.service" ];
+
# wantedBy = [ "multi-user.target" ];
+
# serviceConfig = {
+
# Type = "oneshot";
+
# User = "postgres";
+
# Group = "postgres";
+
# SyslogIdentifier = "pg-autovacuum";
+
# ExecStart = "${cfg.package}/bin/vacuumdb --all --echo --jobs=6 --parallel=5 --analyze --verbose";
+
# };
+
# };
}
-14
hosts/marvin/services/prosody.nix
···
-
{
-
# deadnix: skip
-
config,
-
# deadnix: skip
-
pkgs,
-
# deadnix: skip
-
lib,
-
...
-
}:
-
{
-
services.prosody = {
-
enable = true;
-
};
-
}
-12
hosts/marvin/services/redlib.nix
···
-
{ pkgs, self, ... }:
-
let
-
d = self.lib.data.services.redlib;
-
in
-
{
-
services.libreddit = {
-
inherit (d) port;
-
enable = true;
-
package = pkgs.redlib;
-
openFirewall = false;
-
};
-
}
+1 -1
hosts/marvin/services/scrutiny.nix
···
settings = {
web = {
listen = {
-
port = d.port;
+
inherit (d) port;
};
influxdb.tls.insecure_skip_verify = true;
};
-23
hosts/marvin/services/secrets/iceshrimp-db-password.age
···
-
age-encryption.org/v1
-
-> ssh-ed25519 iqBxIA g+DkjSGDd+i/sdqRCuU2I2Qzmq4Q+FI7wSyfkdM9q0Q
-
cG52xAS/VPjCNgHdky0/jbMvF5tF+cB8BxFNCHYlf2s
-
-> ssh-rsa fFaiTA
-
r5mQer6QBi+HdSS16OLHfv/oh0hbug5drdX/BuQHMORogiDfHEM03K6pmg9064Ep
-
CJgl6z3IS9hlLX7cSq2kVSvP9gk+l5AmI+pMZkJyT9ED43g6wtRI7yiy1ALO0rqB
-
z/CPaoLkFNFlt7sDg5rijAB+t6DNAxULfFj8KR3b+NvGrrW6Vbaio+T5mg1A2PTd
-
60eEfuqdn9dHVI82FQFmai1LwoyButrUNn3UiP8aIdvFUueixcqsAXSK1zjPJZ5B
-
VeAkshwhB9+HKMH1cyRa6LUbzJYxAQBhkgTFqS/r64h3ZAYHTc0lY44VtVhbnEQI
-
76PBEOcQXXjvPR6yvbcVZfpqCkqfo9hb7wogPfJiRMjKM/qlpR19KOf21T0hsV6q
-
b7nYf01yBscx6GKXREkZoxgpo6iLLzVQqU5SzQgs7nxW089JdJ62WoZvJwTxv2G8
-
AdzImnsw73q55MgOYtv/A3hGM8O1Jw4Q4UfMSS43xB+cuvtlEmSqi5mFh0gPbqQR
-
LN8+OcDLz0SR8U6xHj9ufXfhHc4nwO8iZpzav5nZXMEb3Gmva3k8U+nnmuPKqsrL
-
VxFmGNxqmWPfxO0FJC/cxLKME/Lj2MU9r6KT8RQ00BjHUfoDgbFzHVLqIEbIE+Vr
-
/Glcmz/Ecrt3kTwfAhEDpj6g0XVNHt7HA+r4SDWjI00
-
-> ssh-ed25519 wpmdHA LUF/UncaQTEMQepVAhEqFm345dICeW3d3QGhiflTSH8
-
ImxpR4innOw1jMSF4gvmOGRDl0BzqAhOyz+GFstsJG4
-
-> Cg-grease k7q9
-
MLRf60C4nbEc9XHo26cg7UYySbZtOMP2kZtZmvLiS1XFeIqQaR0RgRcUOoTblYzo
-
KQ
-
--- PV6HHY8kDdpFcgNu83K/cwz4qQCW38jcHkTOkCunxrk
-
�*ǜ�lq��^��fʀ���l�� R��C}Մ�ɧ���F�ĩ�&�~h�
-
̟�r��6ʞac,����lc� >
hosts/marvin/services/secrets/iceshrimp-secret-config.age

This is a binary file and will not be displayed.

+19
hosts/marvin/services/secrets/immich/mail-pw.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 iqBxIA 3PVJMF6BgxuDxN9NAEYqcZaYEUhK9TB5XprRyW13Kx0
+
AIQQG+4/9SVPcfq9ZtL/JsWDmLvW03UiAJaJ1nHSckQ
+
-> ssh-rsa fFaiTA
+
ZPBI1w2a48Md+Rt92ssVcfxN26zTLCEalT+jG8SJBv07ouOzd4ibPq65m6uOQU/+
+
EEgHe23fGsPP4oISWDUgVFxesLA3wjsTWmbVrkrBzGQNeNnevIRMcJu7vWDtby/+
+
dVxPQIoXH0jPlcDQCm2lwOGD+du+Nb4PnVseRPDaXRypKKmx+J057FQemYBk4OWx
+
yUfbKV2gHHcuRTVUQG6XAQwWvhh4e25fyc+MzKZNPUK4c/SVibjAsUH+Edd+NaV5
+
yxku5k4TFZkU69sl2zCdgWfYVTowTGYGyf4Kf+I/kl9m13zIk9vRpocgt4APaJnv
+
p+KxJvbYRiprWl+IzZg6TwXY5mA1IbvlppR4aak1pwaIE76CgF5mGNDGkviGndtP
+
+eCMIocp6lk2U0dJEYkBtmjNbxFh3dxOcirgdNDypYPlZTSGvSRGhpL4nUJRsR+l
+
A7rJ5aHH2B4Vi93zgSV0PWiWSA7899bzgN1kQKKIgYln6Tl8UxQSNt5L3L4VajuW
+
3UqCltyGWt/926BMS+GrDZSWCEtVsDs5XQqDKEx6D+iviHZJXniI+RhH/eM7FLjp
+
iXgCRkBIALo2lOiScpr2rtfGDViq3Nh64cIslEPiewjVFTCxkxH+LuQ1stukrNki
+
IF0+pZ65rgatMAdnZRFXfRxmywKD99z4WRHAxvYloXc
+
-> ssh-ed25519 wpmdHA SQlzD3yqbnoF0JHqPFFDUugbm8jlBsdntLzF/WlJbjo
+
FggpB1k5xbq62QNlwkocwjiWhEqNjHAxR/GwoPhXbC8
+
--- 1g4f2OQbS5iXm/cqBamEWuapvZHorxfX7wHizfPcYsc
+
�z�92�LN=9���$O���fP���E���~�.��}7�eڰq��y�N�I�L����"%�V�lz'�أ�
+19
hosts/marvin/services/secrets/immich/oauth-secret.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 iqBxIA 4osfKV5/wFT7mCdc4TjP7pJHdD8wzV7VKKiBSGRqImk
+
wU6RSxJh8SBbXbiwCl4lXD/m1THoAg5n1Y7pyKFPiec
+
-> ssh-rsa fFaiTA
+
RTHaBLsBWbDEmY80LktVL/C6CeFinLm3/4t/hoWmbzLLoElBL86EGVdrE5ovjUYl
+
j5+ZacmqahwjCtF/ZGBt8MFkWOK9u90YDfLp+kb2ILVy/E+CcQ3xPpH9bf83pPl/
+
aZmttaRlhnhSDYVXB0lHx3u/cCrYhTf6TjEoVGZ/XrLW0BRmO6GSwcmTrachZzdJ
+
je+pf2ug//mnAJR0y4MxjGlNPD/Vaj/UiaFQjPT+7ZvUUSkbv/QpPqyhhosFA11e
+
1EGp21ppwUnJSNdYh2vulpQGurB5bPlv6Y8FpcFKivq/qKmA4ydyER3NcCca5Ly+
+
01jQ1HRqWylYJj7K4hnxSjnNlOXCrJATuPJYoNdt2U1DnolUAqL6JIP/qNmYx8Fb
+
ZrfFINBmPsNc9XJn14T4J+VB6e68ODBOvZdbzoBQOWAObnP5OH+zLYCB3II+aLPp
+
Zo5WsNBBdZih4EbO0Y9PNWBjyCzxqs7zXPg1PjjDVHN/tIpSGnqoCqCPGuePhgRV
+
h1gnP/lqOW2U1oL004hi3etsUsk3kXHjr35GXMVBeay+3uGXkZqhNYYSluQnJSrs
+
rzahZZ8/q0FDdlUixWHb2uQjL1XMTqUcw8wPsUak8shkx8s7GPKNxtEKFcK46jk4
+
ac9TCyee4HzPC/SWkLGFl0bt9s9lGTBSNQrVzogY/sg
+
-> ssh-ed25519 wpmdHA C6npqn5aqimGJlo+UlvYOoqXSu/hW1JVNAmBPP1Vvjk
+
gWzXqL92jI83iqSr3dydJo+UAz5OGBo6kw6QC4KRWgM
+
--- ltHFDmeAbJsQtyY4CKFEz8OGAkPkue/8upHNOOQgn5I
+
��O�ӌ#&`���P�IZ�#�[��+�tdeG�ui�����?n"��(��b� ]s� y줔���
-20
hosts/marvin/services/secrets/pingvin-secrets.age
···
-
age-encryption.org/v1
-
-> ssh-ed25519 iqBxIA HdZwcvp9cLpqrUp0M7sK7ipTslMxK0EYqFfS8xtYeDk
-
Ud7ismLtRG4RlugV3P5wRNjRe8HcJW0rAz/adadWCNc
-
-> ssh-rsa fFaiTA
-
KwjETLhUBpq8Hfp41rg3++syweOB+yNIIdd0KeS2YjxjbDfgwzRVoM+wlB/C3b4X
-
W0561y9+wsnB5A6k/peXLASfVodw30vI9LdW+nHejQr9v/UooXPztoJNrfgaKUow
-
PsLbLUj+M8Y4i22GRKrY6rrCfJk8F4a+2b0PzDc1EqUcZOjMV7aE+fQ4U7+FD1jv
-
xGmrKNRXNUL1j5GpPAi7E7YXuGj2SxjZOiisKqyep5KTEFyIJ04lrN/rtbi2vkEJ
-
ejAFg2jIvxAWiEzEUbjOLFzeIdpb8pPqQJ3OUF4U0crT/r5dxmJKxB0J7ktS6eEY
-
NZ4/CtY/kLXjo9sWc6G2UtWAm+myXKsxETxFtp/RQ6LXMjS+3xbzGvkAoY/fzVMt
-
zLGdOV0X/paLb1jGl9CHkflq7qrpkdgqc6I5nmsOCRLHrsiVWLaCVCvu2T1fpjCh
-
tP+Mwdjv5ONXduoGUOxjCT8IVv7ceTt93S/9cZakpDIFJ38I1XymrjuFLfbhLMVK
-
VMfo9cLhWyz2/DAKA4gKnmagUhnYO2vdNBzzM9dg0/ysrLoX71ujEcxB0tx21pkE
-
eB3LEfFH94Izzn9crNJ1YMUFCpFayedN2uQjv89LN2oHx+mUKemXCdl+AV2sLP7P
-
pi4/UDjKOcIeK8cSvqJtsemjUn7QJdOamH4/IpgFh5o
-
-> ssh-ed25519 wpmdHA X+4vtGSjMeIuSearcEfYA8Mv5kmghhItcE1n5BPWLSo
-
uYkj1VkPXs8mJu99J4GFth6LyqhWymEH5fsN0+5TDsw
-
--- Ql8rRuZH0kS1eDQ9EYB7mW+GvcHtjXcW/Wu1ZGhjpKI
-
虌d0dj̭�ھ�f����� g�D�+�q��W��d������%5��1�?�U��)�tܫ��[
-
S�DV�+��U�".� q�i�,g{}#y�@���3O/M~��CЎBV�š� }�=����*#�7�?Q��
+2 -3
hosts/marvin/services/secrets/secrets.nix
···
"golink-authkey.age".publicKeys = marvinDefault;
"grafana-admin-password.age".publicKeys = marvinDefault;
"grafana-smtp-password.age".publicKeys = marvinDefault;
-
"iceshrimp-secret-config.age".publicKeys = marvinDefault;
-
"iceshrimp-db-password.age".publicKeys = marvinDefault;
+
"immich/oauth-secret.age".publicKeys = marvinDefault;
+
"immich/mail-pw.age".publicKeys = marvinDefault;
"jellyfin-exporter-config.age".publicKeys = marvinDefault;
"minio-root.age".publicKeys = marvinDefault;
"miniflux-admin.age".publicKeys = marvinDefault;
"../nextcloud/nextcloud-admin-pw.age".publicKeys = marvinDefault;
"nix-serve-priv.age".publicKeys = marvinDefault;
"pinchflat-secrets.age".publicKeys = marvinDefault;
-
"pingvin-secrets.age".publicKeys = marvinDefault;
"planka-env.age".publicKeys = marvinDefault;
"pocket-id-secrets.age".publicKeys = marvinDefault;
"vaultwarden-vars.age".publicKeys = marvinDefault;
+27 -23
hosts/marvin/services/tangled.nix
···
...
}:
let
-
cfg = config.services.tangled-knot;
+
cfg = config.services.tangled.knot;
dk = self.lib.data.services.tangled-knot;
ds = self.lib.data.services.tangled-spindle;
in
{
services = {
-
tangled-knot = {
-
enable = true;
-
gitUser = "git";
-
stateDir = "/var/lib/tangled-knot";
-
repo.scanPath = "${cfg.stateDir}/repos";
-
server = {
-
listenAddr = "0.0.0.0:${toString dk.port}";
-
hostname = dk.extUrl;
-
internalListenAddr = "127.0.0.1:${toString dk.intListenPort}";
-
owner = "did:plc:5cqzysioqzttihsnbsaxrggu";
+
tangled = {
+
knot = {
+
enable = true;
+
gitUser = "git";
+
stateDir = "/var/lib/tangled-knot";
+
repo.scanPath = "${cfg.stateDir}/repos";
+
server = {
+
listenAddr = "0.0.0.0:${toString dk.port}";
+
hostname = dk.extUrl;
+
internalListenAddr = "127.0.0.1:${toString dk.intListenPort}";
+
owner = "did:plc:5cqzysioqzttihsnbsaxrggu";
+
};
};
-
};
-
tangled-spindle = {
-
enable = true;
-
server = {
-
listenAddr = "0.0.0.0:${toString ds.port}";
-
hostname = ds.extUrl;
-
owner = "did:plc:5cqzysioqzttihsnbsaxrggu";
+
spindle = {
+
enable = true;
+
server = {
+
listenAddr = "0.0.0.0:${toString ds.port}";
+
hostname = ds.extUrl;
+
owner = "did:plc:5cqzysioqzttihsnbsaxrggu";
+
};
+
pipelines.workflowTimeout = "10m";
};
-
pipelines.workflowTimeout = "10m";
};
-
openssh.enable = lib.mkForce cfg.enable;
-
openssh.ports = [ 2222 ];
-
openssh.settings.AllowUsers = [ "git" ];
-
openssh.settings.AllowGroups = [ "git" ];
+
openssh = {
+
enable = lib.mkForce cfg.enable;
+
ports = [ 2222 ];
+
settings.AllowUsers = [ "git" ];
+
settings.AllowGroups = [ "git" ];
+
};
};
}
+2 -27
hosts/marvin/services/vaultwarden.nix
···
{
-
pkgs,
config,
self,
self',
···
services.vaultwarden = {
enable = true;
dbBackend = "postgresql";
-
webVaultPackage = pkgs.vaultwarden-vault;
config = {
# Web Server Settings
domain = "https://${d.extUrl}";
-
webVaultFolder = "${pkgs.vaultwarden-vault}/share/vaultwarden/vault";
rocketAddress = "0.0.0.0";
rocketCliColors = false;
rocketPort = d.port;
-
websocketEnabled = true;
-
ipHeader = "X-Real-IP";
reloadTemplates = false;
logTimestampFormat = "%Y-%m-%d %H:%M:%S.%3f";
# # Ratelimiting
···
# Logging
useSyslog = true;
-
logLevel = "info";
extendedLogging = true;
# Features
···
# Invitations
invitationsAllowed = true;
-
invitationOrgName = "PyroNet Vault";
+
invitationOrgName = "dishNet Vault";
invitationExpirationHours = 168;
# Database
···
# Signups
signupsAllowed = false;
signupsVerify = true;
-
signupsVerifyResendTime = 3600;
-
signupsVerifyResendLimit = 5;
signupsDomainWhitelist = "pyrox.dev";
# Passwords
···
# Mail
smtpFrom = "vault@pyrox.dev";
-
smtpFromName = "PyroNet Vault <vault@pyrox.dev>";
+
smtpFromName = "dishNet Vault <vault@pyrox.dev>";
smtpUsername = "vault@pyrox.dev";
smtpSecurity = "force_tls";
smtpPort = 465;
···
smtpTimeout = 20;
smtpEmbedImages = true;
useSendmail = false;
-
smtpDebug = false;
-
smtpAcceptInvalidCerts = false;
-
smtpAcceptInvalidHostnames = false;
# Authentication
-
authenticatorDisableTimeDrift = false;
-
disable2faRemember = false;
incomplete2faTimeLimit = 5;
# # Email 2FA
-
emailAttemptsLimit = 3;
emailExpirationTime = 180;
emailTokenSize = 7;
requireDeviceEmail = true;
-
# Icons
-
disableIconDownload = false;
-
iconService = "internal";
-
iconRedirectCode = 302;
-
iconDownloadTimeout = 10;
-
iconBlacklistNonGlobalIps = true;
-
# # 30 Day TTL
-
iconCacheTtl = 30 * 24 * 60 * 60;
-
iconCacheNegttl = 30 * 24 * 60 * 60;
-
# Misc Settings
trashAutoDeleteDays = 14;
};
environmentFile = config.age.secrets.vaultwarden-vars.path;
};
systemd.services.vaultwarden.environment.PGPASSFILE = config.age.secrets.vaultwarden-pgpass.path;
-
environment.systemPackages = with pkgs; [ vaultwarden-vault ];
age.secrets.vaultwarden-vars = vaultwardenSecret // {
file = ./secrets/vaultwarden-vars.age;
};
-23
hosts/marvin/services/webmentiond.nix
···
-
{ config, self, ... }:
-
let
-
d = self.lib.data.services.webmentiond;
-
p = toString d.port;
-
in
-
{
-
virtualisation.oci-containers.containers.webmentiond = {
-
image = "zerok/webmentiond:latest";
-
volumes = [ "/var/lib/webmentiond:/data" ];
-
environmentFiles = [ config.age.secrets.webmentiond-env.path ];
-
ports = [ "${p}:${p}" ];
-
cmd = [
-
"--addr 0.0.0.0:${p}"
-
"--public-url https://${d.extUrl}"
-
"--auth-admin-emails pyrox@pyrox.dev"
-
];
-
};
-
config.age.secrets = {
-
webmentiond-env.path = ./secrets/webmentiond-env.age;
-
owner = "thehedgehog";
-
group = "misc";
-
};
-
}
+4 -4
hosts/prefect/bootloader.nix
···
supportedFilesystems = fileSystems;
kernelPackages = pkgs.linuxPackages_6_1;
kernel.sysctl = {
-
"net.ipv4.ip_forward" = 1;
-
"net.ipv6.conf.all.forwarding" = 1;
-
"net.ipv4.conf.default.rp_filter" = 0;
-
"net.ipv4.conf.all.rp_filter" = 0;
+
"net.ipv4.ip_forward" = true;
+
"net.ipv6.conf.all.forwarding" = true;
+
"net.ipv4.conf.default.rp_filter" = false;
+
"net.ipv4.conf.all.rp_filter" = false;
};
};
services.udev.extraRules = ''
+2 -8
hosts/prefect/default.nix
···
{
pkgs,
-
system,
inputs,
...
}:
···
# Running Services
./services/acme.nix
-
# ./services/blog-update.nix
./services/caddy.nix
-
# ./services/dn42-peerfinder.nix
./services/fail2ban.nix
-
# ./services/headscale.nix
./services/mailserver
-
./services/mailserver/stalwart
-
# ./services/netdata.nix
-
# ./services/nginx
./services/prometheus.nix
./services/secrets.nix
./services/tailscale.nix
-
# ./services/zerotier.nix
];
fileSystems = {
"/" = {
···
};
services.scrutiny.collector.enable = false;
};
+
security.tpm2.enable = false;
+
security.tpm2.abrmd.enable = false;
}
-109
hosts/prefect/dn42/bgp.nix
···
-
_: {
-
sessions = [
-
# Chrismoos
-
{
-
multi = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "chrismoos";
-
neigh = "fe80::1588%wg42_chris";
-
as = "4242421588";
-
link = "1";
-
}
-
# Kioubit
-
{
-
multi = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "kioubit";
-
neigh = "fe80::ade0%wg42_kioubit";
-
as = "4242423914";
-
link = "3";
-
}
-
# IEDON
-
{
-
multi = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "ideon";
-
neigh = "fe80::2189:e8%wg42_iedon";
-
as = "4242422189";
-
link = "5";
-
}
-
# SUNNET
-
{
-
multi = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "sunnet";
-
neigh = "fe80::3088:193%wg42_sunnet";
-
as = "4242423088";
-
link = "3";
-
}
-
# C4TG1RL5
-
{
-
multi = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "c4tg1rl5";
-
neigh = "fe80::4242%wg42_catgirls";
-
as = "4242421411";
-
link = "6";
-
}
-
# Potat0
-
{
-
multi = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "potato";
-
neigh = "fe80::1816%wg42_potato";
-
as = "4242421816";
-
link = "2";
-
}
-
# Uffsalot-v6
-
{
-
multi = false;
-
v4 = false;
-
v6 = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "uffsalot_v6";
-
neigh = "fe80::780%wg42_uffsalot";
-
as = "4242420780";
-
link = "5";
-
}
-
# Uffsalot-v6
-
{
-
multi = false;
-
v4 = true;
-
v6 = false;
-
multihop = false;
-
gracefulRestart = true;
-
name = "uffsalot_v4";
-
neigh = "172.20.191.129";
-
as = "4242420780";
-
link = "5";
-
}
-
# Bandura
-
{
-
multi = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "bandura";
-
neigh = "fe80::2926%wg42_bandura";
-
as = "4242422923";
-
link = "4";
-
}
-
# Bluemedia
-
{
-
multi = true;
-
multihop = false;
-
gracefulRestart = true;
-
name = "bluemedia";
-
neigh = "fe80::42:3343:20:1%wg42_bluemedia";
-
as = "4242423343";
-
link = "5";
-
}
-
];
-
extraConfig = "";
-
}
-315
hosts/prefect/dn42/bird.conf
···
-
log stderr all;
-
debug protocols all;
-
timeformat protocol iso long;
-
################################################
-
# Variable header #
-
################################################
-
-
define OWNAS = 4242422459;
-
define OWNIP = 172.20.43.96;
-
define OWNIPv6 = fd21:1500:66b0::1;
-
define OWNNET = 172.20.43.96/27;
-
define OWNNETv6 = fd21:1500:66b0::/48;
-
define OWNNETSET = [172.20.43.96/29+];
-
define OWNNETSETv6 = [fd21:1500:66b0::/48+];
-
define DN42_REGION = 42;
-
-
################################################
-
# Header end #
-
################################################
-
-
router id OWNIP;
-
-
protocol device {
-
scan time 10;
-
}
-
-
/*
-
* Utility functions
-
*/
-
-
function is_self_net() {
-
return net ~ OWNNETSET;
-
}
-
-
function is_self_net_v6() {
-
return net ~ OWNNETSETv6;
-
}
-
-
function is_valid_network() {
-
return net ~ [
-
172.20.0.0/14{21,29}, # dn42
-
172.20.0.0/24{28,32}, # dn42 Anycast
-
172.21.0.0/24{28,32}, # dn42 Anycast
-
172.22.0.0/24{28,32}, # dn42 Anycast
-
172.23.0.0/24{28,32}, # dn42 Anycast
-
172.31.0.0/16+, # ChaosVPN
-
10.100.0.0/14+, # ChaosVPN
-
10.127.0.0/16{16,32}, # neonetwork
-
10.0.0.0/8{15,24} # Freifunk.net
-
];
-
}
-
-
roa4 table dn42_roa;
-
roa6 table dn42_roa_v6;
-
-
protocol static {
-
roa4 { table dn42_roa; };
-
include "/etc/bird/roa_dn42.conf";
-
};
-
-
protocol static {
-
roa6 { table dn42_roa_v6; };
-
include "/etc/bird/roa_dn42_v6.conf";
-
};
-
-
function is_valid_network_v6() {
-
return net ~ [
-
fd00::/8{44,64} # ULA address space as per RFC 4193
-
];
-
}
-
-
protocol kernel {
-
scan time 20;
-
-
ipv6 {
-
import none;
-
export filter {
-
if source = RTS_STATIC then reject;
-
krt_prefsrc = OWNIPv6;
-
accept;
-
};
-
};
-
};
-
-
protocol kernel {
-
scan time 20;
-
ipv4 {
-
import none;
-
export filter {
-
if source = RTS_STATIC then reject;
-
krt_prefsrc = OWNIP;
-
accept;
-
};
-
};
-
}
-
-
protocol static {
-
route OWNNET reject;
-
-
ipv4 {
-
import all;
-
export none;
-
};
-
}
-
-
protocol static {
-
route OWNNETv6 reject;
-
-
ipv6 {
-
import all;
-
export none;
-
};
-
}
-
-
template bgp dnpeers {
-
local as OWNAS;
-
path metric 1;
-
}
-
-
protocol ospf v3 {
-
ipv4 {
-
export filter {
-
if source = RTS_STATIC || source = RTS_BGP then reject;
-
accept;
-
};
-
};
-
-
area 0 {
-
interface "lo" {
-
stub;
-
};
-
-
interface "ospf_*"{
-
type pointopoint;
-
};
-
};
-
}
-
-
protocol ospf v3 {
-
ipv6 {
-
export filter {
-
if source = RTS_STATIC || source = RTS_BGP then reject;
-
accept;
-
};
-
};
-
-
area 0 {
-
interface "lo" {
-
stub;
-
};
-
-
interface "ospf_*" {
-
type pointopoint;
-
};
-
-
};
-
}
-
-
-
function update_latency(int link_latency) {
-
bgp_community.add((64511, link_latency));
-
if (64511, 9) ~ bgp_community then { bgp_community.delete([(64511, 1..8)]); return 9; }
-
else if (64511, 8) ~ bgp_community then { bgp_community.delete([(64511, 1..7)]); return 8; }
-
else if (64511, 7) ~ bgp_community then { bgp_community.delete([(64511, 1..6)]); return 7; }
-
else if (64511, 6) ~ bgp_community then { bgp_community.delete([(64511, 1..5)]); return 6; }
-
else if (64511, 5) ~ bgp_community then { bgp_community.delete([(64511, 1..4)]); return 5; }
-
else if (64511, 4) ~ bgp_community then { bgp_community.delete([(64511, 1..3)]); return 4; }
-
else if (64511, 3) ~ bgp_community then { bgp_community.delete([(64511, 1..2)]); return 3; }
-
else if (64511, 2) ~ bgp_community then { bgp_community.delete([(64511, 1..1)]); return 2; }
-
else return 1;
-
}
-
-
function update_bandwidth(int link_bandwidth) {
-
bgp_community.add((64511, link_bandwidth));
-
if (64511, 21) ~ bgp_community then { bgp_community.delete([(64511, 22..29)]); return 21; }
-
else if (64511, 22) ~ bgp_community then { bgp_community.delete([(64511, 23..29)]); return 22; }
-
else if (64511, 23) ~ bgp_community then { bgp_community.delete([(64511, 24..29)]); return 23; }
-
else if (64511, 24) ~ bgp_community then { bgp_community.delete([(64511, 25..29)]); return 24; }
-
else if (64511, 25) ~ bgp_community then { bgp_community.delete([(64511, 26..29)]); return 25; }
-
else if (64511, 26) ~ bgp_community then { bgp_community.delete([(64511, 27..29)]); return 26; }
-
else if (64511, 27) ~ bgp_community then { bgp_community.delete([(64511, 28..29)]); return 27; }
-
else if (64511, 28) ~ bgp_community then { bgp_community.delete([(64511, 29..29)]); return 28; }
-
else return 29;
-
}
-
-
function update_crypto(int link_crypto) {
-
bgp_community.add((64511, link_crypto));
-
if (64511, 31) ~ bgp_community then { bgp_community.delete([(64511, 32..34)]); return 31; }
-
else if (64511, 32) ~ bgp_community then { bgp_community.delete([(64511, 33..34)]); return 32; }
-
else if (64511, 33) ~ bgp_community then { bgp_community.delete([(64511, 34..34)]); return 33; }
-
else return 34;
-
}
-
-
function get_region() {
-
if (64511, 41) ~ bgp_community then { return 41; }
-
else if (64511, 42) ~ bgp_community then { return 42; }
-
else if (64511, 43) ~ bgp_community then { return 43; }
-
else if (64511, 44) ~ bgp_community then { return 44; }
-
else if (64511, 45) ~ bgp_community then { return 45; }
-
else if (64511, 46) ~ bgp_community then { return 46; }
-
else if (64511, 47) ~ bgp_community then { return 47; }
-
else if (64511, 48) ~ bgp_community then { return 48; }
-
else if (64511, 49) ~ bgp_community then { return 49; }
-
else if (64511, 50) ~ bgp_community then { return 50; }
-
else if (64511, 51) ~ bgp_community then { return 51; }
-
else if (64511, 52) ~ bgp_community then { return 52; }
-
else if (64511, 53) ~ bgp_community then { return 53; }
-
else return DN42_REGION;
-
}
-
-
-
function calculate_local_pref(int dn42_latency)
-
int pref;
-
{
-
pref = 100;
-
if (is_self_net() || is_self_net_v6()) then {
-
pref = 2000;
-
}
-
else if (bgp_path.len = 1) then {
-
pref = 1000;
-
}
-
else if (DN42_REGION = get_region()) then {
-
pref= 500;
-
}
-
else {
-
if (DN42_REGION > get_region()) then {
-
pref = 500 - ((DN42_REGION - get_region()) * 10);
-
}
-
else {
-
pref = 500 - ((get_region() - DN42_REGION) * 10);
-
}
-
}
-
pref = pref - 10*dn42_latency - 10* bgp_path.len;
-
if pref > 2000 then {
-
pref = 10;
-
}
-
return pref;
-
}
-
-
function update_flags(int link_latency; int link_bandwidth; int link_crypto)
-
int dn42_latency;
-
int dn42_bandwidth;
-
int dn42_crypto;
-
{
-
dn42_latency = update_latency(link_latency);
-
dn42_bandwidth = update_bandwidth(link_bandwidth) - 20;
-
dn42_crypto = update_crypto(link_crypto) - 30;
-
if dn42_bandwidth > 5 then dn42_bandwidth = 5;
-
bgp_local_pref = calculate_local_pref(dn42_latency);
-
return true;
-
}
-
-
-
function dn42_import_filter(int link_latency; int link_bandwidth; int link_crypto) {
-
if (is_valid_network() && !is_self_net()) || (is_valid_network_v6() && !is_self_net_v6()) then {
-
if roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID && roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID then {
-
print "[dn42] Import : ROA check failed for ", net, " ASN ", bgp_path.last, " on ", proto;
-
reject;
-
}
-
update_flags(link_latency, link_bandwidth, link_crypto);
-
if (65535, 666) ~ bgp_community then dest = RTD_BLACKHOLE;
-
accept;
-
}
-
print "[dn42] Import : Invalid Network for ", net, " ASN ", bgp_path.last, " on ", proto;
-
reject;
-
}
-
-
function dn42_export_filter(int link_latency; int link_bandwith; int link_crypto) {
-
if is_valid_network() || is_valid_network_v6() then {
-
# if roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID && roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID then {
-
# print "[dn42] Export : ROA check failed for ", net, " ASN ", bgp_path.last, " on ", proto;
-
# reject;
-
# }
-
if source = RTS_STATIC then bgp_community.add((64511, DN42_REGION));
-
update_flags(link_latency, link_bandwith, link_crypto);
-
accept;
-
}
-
reject;
-
}
-
-
protocol bgp route_collector from dnpeers {
-
neighbor fd42:4242:2601:ac12::1 as 4242422602;
-
multihop;
-
ipv4 {
-
# export all available paths to the collector
-
add paths tx;
-
-
# import/export filters
-
import none;
-
export filter {
-
# export all valid routes
-
if ( is_valid_network() && source ~ [ RTS_STATIC, RTS_BGP ] )
-
then {
-
accept;
-
}
-
reject;
-
};
-
};
-
-
ipv6 {
-
# export all available paths to the collector
-
add paths tx;
-
-
# import/export filters
-
import none;
-
export filter {
-
# export all valid routes
-
if ( is_valid_network_v6() && source ~ [ RTS_STATIC, RTS_BGP ] )
-
then {
-
accept;
-
}
-
reject;
-
};
-
};
-
}
+56 -20
hosts/prefect/dn42/default.nix
···
-
{ pkgs, ... }:
+
{ pkgs, config, ... }:
+
let
+
cfg42 = config.dn42;
+
in
{
imports = [
-
./services.nix
-
./wireguard.nix
+
./peers
];
-
networking.interfaces.lo = {
-
ipv4.addresses = [
-
{
-
address = "172.20.43.96";
-
prefixLength = 32;
-
}
-
];
-
ipv6.addresses = [
-
{
-
address = "fd21:1500:66b0::1";
-
prefixLength = 128;
-
}
-
{
-
address = "fe80::1";
-
prefixLength = 128;
-
}
-
];
+
networking = {
+
interfaces.lo = {
+
ipv4.addresses = [
+
{
+
address = "172.20.43.96";
+
prefixLength = 32;
+
}
+
];
+
ipv6.addresses = [
+
{
+
address = "fd21:1500:66b0::1";
+
prefixLength = 128;
+
}
+
{
+
address = "fe80::1";
+
prefixLength = 128;
+
}
+
];
+
};
};
+
environment.systemPackages = with pkgs; [
dnsutils
mtr
tcpdump
wireguard-tools
];
+
dn42 = {
+
enable = true;
+
# ASN corresponding to DN42 PYRONET
+
as = 4242422459;
+
# Communities config
+
# https://dn42.dev/howto/BGP-communities
+
region = 42;
+
country = 1840;
+
routerId = cfg42.addr.v4;
+
# Primary IP Addresses
+
addr = {
+
v4 = "172.20.43.96";
+
v6 = "fd21:1500:66b0::1";
+
};
+
# Owned IP Ranges
+
nets = {
+
v4 = [ "172.20.43.96/27" ];
+
v6 = [ "fd21:1500:66b0::/48" ];
+
};
+
# Enable StayRTR
+
# https://github.com/bgp/stayrtr
+
stayrtr.enable = true;
+
# Peer with GRC
+
# https://dn42.dev/services/Route-Collector
+
collector.enable = true;
+
+
wg.tunnelDefaults = {
+
privateKeyFile = "/run/agenix/dn42-privkey";
+
localAddrs.v4 = cfg42.addr.v4;
+
};
+
};
}
+25
hosts/prefect/dn42/peers/bandura.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.bandura = {
+
as = 4242422923;
+
addr.v6 = "fe80::2926";
+
interface = "wg42_bandura";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::11";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."55ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.bandura = {
+
listenPort = 44923;
+
peerPubKey = "xPW1/cWYDkk/IAss1GbdwVMW7fzKtyHA+qrfCriOB2k=";
+
peerEndpoint = "aurora.mk16.de:52459";
+
peerAddrs.v6 = "fe80::2926";
+
localAddrs.v6 = "fe80::11";
+
};
+
};
+
}
+26
hosts/prefect/dn42/peers/catgirls.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.catgirls = {
+
as = 4242421411;
+
addr.v6 = "fe80::2189:124";
+
interface = "wg42_catgirls";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::111";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."148ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.catgirls = {
+
enable = false;
+
listenPort = 43411;
+
peerPubKey = "";
+
peerEndpoint = "";
+
peerAddrs.v6 = "fe80::111";
+
localAddrs.v6 = "fe80::7";
+
};
+
};
+
}
+26
hosts/prefect/dn42/peers/chrismoos.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.chrismoos = {
+
as = 4242421588;
+
addr.v6 = "fe80::1588";
+
interface = "wg42_chrismoos";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::100";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."2.7ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.chrismoos = {
+
listenPort = 43588;
+
peerPubKey = "itmJ4Z8V1aNN368P6kMzuQM+GdzWbBKZjJiXrgSeGlw=";
+
peerEndpoint = "us-qas01.dn42.tech9.io:58768";
+
peerAddrs.v4 = "172.20.16.143";
+
peerAddrs.v6 = "fe80::1588";
+
localAddrs.v6 = "fe80::100";
+
};
+
};
+
}
+29
hosts/prefect/dn42/peers/darkpoint.nix
···
+
{ dn42Types, ... }:
+
let
+
peerv6 = "fe80::150";
+
localv6 = "fe80::113";
+
in
+
{
+
config.dn42 = {
+
peers.darkpoint = {
+
as = 4242420150;
+
addr.v6 = peerv6;
+
interface = "wg42_darkpoint";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = localv6;
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."2.7ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.darkpoint = {
+
listenPort = 42150;
+
peerPubKey = "1o0XfQvBM1gqknqzfuOnVmf2RjRTHuyMZYNipSSb2TQ=";
+
peerEndpoint = "iad.darkpoint.xyz:22459";
+
peerAddrs.v6 = peerv6;
+
localAddrs.v6 = localv6;
+
};
+
};
+
}
+23
hosts/prefect/dn42/peers/default.nix
···
+
_:
+
let
+
dn42Types = import ../types.nix;
+
in
+
{
+
# Port numbers are 42000 + `last 4 digits of ASN`
+
imports = [
+
# keep-sorted start
+
(import ./bandura.nix { inherit dn42Types; })
+
# (import ./catgirls.nix { inherit dn42Types; })
+
(import ./chrismoos.nix { inherit dn42Types; })
+
(import ./darkpoint.nix { inherit dn42Types; })
+
(import ./iedon.nix { inherit dn42Types; })
+
(import ./kioubit.nix { inherit dn42Types; })
+
(import ./lare.nix { inherit dn42Types; })
+
(import ./potato.nix { inherit dn42Types; })
+
(import ./prefixlabs.nix { inherit dn42Types; })
+
(import ./routedbits.nix { inherit dn42Types; })
+
(import ./sunnet.nix { inherit dn42Types; })
+
(import ./uffsalot.nix { inherit dn42Types; })
+
# keep-sorted end
+
];
+
}
+26
hosts/prefect/dn42/peers/iedon.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.iedon = {
+
as = 4242422189;
+
addr.v6 = "fe80::2189:124";
+
interface = "wg42_iedon";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::6";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."20ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.iedon = {
+
listenPort = 44198;
+
peerPubKey = "2Wmv10a9eVSni9nfZ7YPsyl3ZC5z7vHq0sTZGgk5WGo=";
+
peerEndpoint = "us-nyc.dn42.iedon.net:48883";
+
peerAddrs.v4 = "172.23.91.124";
+
peerAddrs.v6 = "fe80::2189:124";
+
localAddrs.v6 = "fe80::6";
+
};
+
};
+
}
+27
hosts/prefect/dn42/peers/kioubit.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.kioubit = {
+
as = 4242423914;
+
addr.v6 = "fe80::ade0";
+
interface = "wg42_kioubit";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::ade1";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."7.3ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.kioubit = {
+
listenPort = 45914;
+
peerPubKey = "6Cylr9h1xFduAO+5nyXhFI1XJ0+Sw9jCpCDvcqErF1s=";
+
peerEndpoint = "us2.g-load.eu:22459";
+
peerAddrs.v4 = "172.20.53.98";
+
peerAddrs.v6 = "fe80::ade0";
+
localAddrs.v4 = "192.168.220.70";
+
localAddrs.v6 = "fe80::ade1";
+
};
+
};
+
}
+25
hosts/prefect/dn42/peers/lare.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.lare = {
+
as = 4242423035;
+
addr.v6 = "fe80::3035:137";
+
interface = "wg42_lare";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::112";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."20ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.lare = {
+
listenPort = 45035;
+
peerPubKey = "AREskFoxP2cd6DXoJ7druDsiWKX+8TwrkQqfi4JxRRw=";
+
peerEndpoint = "use2.dn42.lare.cc:22459";
+
peerAddrs.v6 = "fe80::3035:137";
+
localAddrs.v6 = "fe80::112";
+
};
+
};
+
}
+26
hosts/prefect/dn42/peers/potato.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.potato = {
+
as = 4242421816;
+
addr.v6 = "fe80::1816";
+
interface = "wg42_potato";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::111";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."148ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.potato = {
+
enable = false;
+
listenPort = 43816;
+
peerPubKey = "LUwqKS6QrCPv510Pwt1eAIiHACYDsbMjrkrbGTJfviU=";
+
peerEndpoint = "las.node.potat0.cc:22459";
+
peerAddrs.v6 = "fe80::1816";
+
localAddrs.v6 = "fe80::9";
+
};
+
};
+
}
+26
hosts/prefect/dn42/peers/prefixlabs.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.prefixlabs = {
+
as = 4242421240;
+
addr.v6 = "fe80::1240:2";
+
interface = "wg42_prefixlabs";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::240";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."7.3ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.prefixlabs = {
+
listenPort = 43240;
+
peerPubKey = "uRYzFGi+/B6pD0FR2SW3G/OzC5LPJXePNIt0s+nJfW0=";
+
peerEndpoint = "us-01.prefixlabs.net:22459";
+
peerAddrs.v4 = "172.20.209.11";
+
peerAddrs.v6 = "fe80::1240:2";
+
localAddrs.v6 = "fe80::240";
+
};
+
};
+
}
+26
hosts/prefect/dn42/peers/routedbits.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.routedbits = {
+
as = 4242420207;
+
addr.v6 = "fe80::207";
+
interface = "wg42_routedbits";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::5";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."2.7ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.routedbits = {
+
listenPort = 42207;
+
peerPubKey = "/RLM4EcF8b7FKKcxnvHIYyDoES59HXIBqhKEWt4yRy0=";
+
peerEndpoint = "router.iad1.routedbits.com:52459";
+
peerAddrs.v4 = "172.20.19.73";
+
peerAddrs.v6 = "fe80::207";
+
localAddrs.v6 = "fe80::5";
+
};
+
};
+
}
+26
hosts/prefect/dn42/peers/sunnet.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.sunnet = {
+
as = 4242423088;
+
addr.v6 = "fe80::3088:193";
+
interface = "wg42_sunnet";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::abcd";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."148ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.sunnet = {
+
listenPort = 45088;
+
peerPubKey = "QSAeFPotqFpF6fFe3CMrMjrpS5AL54AxWY2w1+Ot2Bo=";
+
peerEndpoint = "lax1-us.dn42.6700.cc:22459";
+
peerAddrs.v4 = "172.21.100.193";
+
peerAddrs.v6 = "fe80::3088:193";
+
localAddrs.v6 = "fe80::abcd";
+
};
+
};
+
}
+26
hosts/prefect/dn42/peers/uffsalot.nix
···
+
{ dn42Types, ... }:
+
{
+
config.dn42 = {
+
peers.uffsalot = {
+
as = 4242420780;
+
addr.v6 = "fe80::780";
+
interface = "wg42_uffsalot";
+
extendedNextHop = true;
+
# My side
+
srcAddr.v6 = "fe80::10";
+
# Communities
+
crypto = dn42Types.crypto.safePFS;
+
latency = dn42Types.latency."148ms";
+
bandwidth = dn42Types.bandwidth."1000mb";
+
transit = true;
+
};
+
wg.tunnels.uffsalot = {
+
listenPort = 42780;
+
peerPubKey = "7V65FxvD9AQetyUr0qSiu+ik8samB4Atrw2ekvC0xQM=";
+
peerEndpoint = "dn42-de-fra4.brand-web.net:42459";
+
peerAddrs.v4 = "172.20.191.129";
+
peerAddrs.v6 = "fe80::780";
+
localAddrs.v6 = "fe80::10";
+
};
+
};
+
}
-71
hosts/prefect/dn42/services.nix
···
-
{ pkgs, lib, ... }:
-
let
-
script = pkgs.writeShellScriptBin "update-roa" ''
-
mkdir -p /etc/bird/
-
${pkgs.curl}/bin/curl -sfSLR {-o,-z}/etc/bird/roa_dn42_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf
-
${pkgs.curl}/bin/curl -sfSLR {-o,-z}/etc/bird/roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf
-
${pkgs.bird2}/bin/birdc c
-
${pkgs.bird2}/bin/birdc reload in all
-
'';
-
bgp = import ./bgp.nix { };
-
in
-
{
-
systemd = {
-
timers.dn42-roa = {
-
description = "Trigger a ROA table update";
-
-
timerConfig = {
-
OnBootSec = "5m";
-
OnUnitInactiveSec = "1h";
-
Unit = "dn42-roa.service";
-
};
-
-
wantedBy = [ "timers.target" ];
-
before = [ "bird.service" ];
-
};
-
services = {
-
dn42-roa = {
-
after = [ "network.target" ];
-
description = "DN42 ROA Updated";
-
unitConfig = {
-
Type = "one-shot";
-
};
-
serviceConfig = {
-
ExecStart = "${script}/bin/update-roa";
-
};
-
};
-
};
-
};
-
-
services = {
-
bird = {
-
enable = true;
-
package = pkgs.bird2;
-
checkConfig = false;
-
config =
-
builtins.readFile ./bird.conf
-
+ lib.concatStrings (
-
builtins.map (
-
x:
-
"\n protocol bgp ${x.name} from dnpeers {\n ${
-
if x.multihop then "multihop;" else ""
-
}\n ${
-
if x.gracefulRestart then "graceful restart on;" else ""
-
}\n neighbor ${x.neigh} as ${x.as};\n ${
-
if x.multi || x.v4 then
-
"\n ipv4 {\n extended next hop on;\n import where dn42_import_filter(${x.link},25,34);\n export where dn42_export_filter(${x.link},25,34);\n import keep filtered;\n };\n "
-
else
-
""
-
}\n ${
-
if x.multi || x.v6 then
-
"\n ipv6 {\n extended next hop on;\n import where dn42_import_filter(${x.link},25,34);\n export where dn42_export_filter(${x.link},25,34);\n import keep filtered;\n };\n "
-
else
-
""
-
}\n }\n "
-
) bgp.sessions
-
)
-
+ bgp.extraConfig;
-
};
-
};
-
users.users.thehedgehog.extraGroups = [ "bird2" ];
-
}
-86
hosts/prefect/dn42/tunnels.nix
···
-
{ tunnel, ... }:
-
let
-
# deadnix: skip
-
defaultPubKey = "e6kp9sca4XIzncKa9GEQwyOnMjje299Xg9ZdgXWMwHg=";
-
defaultPrivKeyFile = "/run/agenix/dn42-privkey";
-
defaultLocalIPv4 = "172.20.43.96";
-
in
-
{
-
wg42_chris =
-
# Ports 485-486 available
-
-
tunnel 487 defaultPrivKeyFile "itmJ4Z8V1aNN368P6kMzuQM+GdzWbBKZjJiXrgSeGlw=" defaultLocalIPv4
-
"fe80::100"
-
"us-qas01.dn42.tech9.io:52322"
-
"wg42_chris"
-
"172.20.16.143"
-
"fe80::1588";
-
-
wg42_kioubit =
-
tunnel 488 defaultPrivKeyFile "6Cylr9h1xFduAO+5nyXhFI1XJ0+Sw9jCpCDvcqErF1s=" defaultLocalIPv4
-
"fe80::3"
-
"us2.g-load.eu:22459"
-
"wg42_kioubit"
-
"172.20.53.98"
-
"fe80::ade0";
-
-
# Ports 489-490 available
-
-
wg42_iedon =
-
tunnel 491 defaultPrivKeyFile "Sz0UhewjDk2yRKI0QL9rB+5daWpXFVlbbz9cLfVVLn4=" defaultLocalIPv4
-
"fe80::6"
-
"us-sjc.dn42.kuu.moe:35470"
-
"wg42_iedon"
-
"172.23.91.117"
-
"fe80::2189:e8";
-
-
wg42_sunnet =
-
tunnel 492 defaultPrivKeyFile "QSAeFPotqFpF6fFe3CMrMjrpS5AL54AxWY2w1+Ot2Bo=" defaultLocalIPv4
-
"fe80::abcd"
-
"v6.lax1-us.dn42.6700.cc:22459"
-
"wg42_sunnet"
-
"172.21.100.193"
-
"fe80::3088:193";
-
-
wg42_catgirls =
-
tunnel 493 defaultPrivKeyFile "jo8eAfY8LeA4FAEJ4laYYMNkMd4z3oO/zN5DN0Mo+RQ=" defaultLocalIPv4
-
"fe80::7"
-
"karx.xyz:22459"
-
"wg42_catgirls"
-
""
-
"fe80::4242";
-
-
# Port 494 Available
-
-
wg42_potato =
-
tunnel 495 defaultPrivKeyFile "LUwqKS6QrCPv510Pwt1eAIiHACYDsbMjrkrbGTJfviU=" defaultLocalIPv4
-
"fe80::9"
-
"las.node.potat0.cc:22459"
-
"wg42_potato"
-
""
-
"fe80::1816";
-
-
wg42_uffsalot =
-
tunnel 496 defaultPrivKeyFile "7V65FxvD9AQetyUr0qSiu+ik8samB4Atrw2ekvC0xQM=" defaultLocalIPv4
-
"fe80::10"
-
"dn42-de-fra4.brand-web.net:42459"
-
"wg42_uffsalot"
-
"172.20.191.129"
-
"fe80::780";
-
-
wg42_bandura =
-
tunnel 497 defaultPrivKeyFile "xPW1/cWYDkk/IAss1GbdwVMW7fzKtyHA+qrfCriOB2k=" defaultLocalIPv4
-
"fe80::11"
-
"aurora.mk16.de:52459"
-
"wg42_bandura"
-
""
-
"fe80::2926";
-
-
wg42_bluemedia =
-
tunnel 498 defaultPrivKeyFile "7HNg2+uMI2WfntN+WlMnlTDG6xra/Dusee82cuXWMBY=" defaultLocalIPv4
-
"fe80::12"
-
"de-fra01.dn42.bluemedia.dev:22459"
-
"wg42_bluemedia"
-
"172.22.167.82"
-
"fe80::42:3343:20:1";
-
}
+63
hosts/prefect/dn42/types.nix
···
+
# DN42 Community Standard BGP Communities
+
# See main lists here: https://dn42.dev/howto/BGP-communities
+
{
+
latency = {
+
"2.7ms" = 1;
+
"7.3ms" = 2;
+
"20ms" = 3;
+
"55ms" = 4;
+
"148ms" = 5;
+
"403ms" = 6;
+
"1097ms" = 7;
+
"2981ms" = 8;
+
"gt2981" = 9;
+
};
+
bandwidth = {
+
"0.1mb" = 21;
+
"1mb" = 22;
+
"10mb" = 23;
+
"100mb" = 24;
+
"1000mb" = 25;
+
};
+
crypto = {
+
unencrypted = 31;
+
unsafeVPN = 32;
+
safeNoPFS = 33;
+
safePFS = 34;
+
};
+
region = {
+
europe = 41;
+
northAmericaEast = 42;
+
northAmericaCentral = 43;
+
northAmericaWest = 44;
+
centralAmerica = 45;
+
southAmericaEast = 46;
+
southAmericaWest = 47;
+
africaNorth = 48;
+
africaSouth = 49;
+
asiaSouth = 50;
+
asiaSouthEast = 51;
+
asiaEast = 52;
+
pacificOceania = 53;
+
antarctica = 54;
+
asiaNorth = 55;
+
asiaWest = 56;
+
centralAsia = 57;
+
};
+
country = {
+
canada = 1124;
+
china = 1156;
+
taiwan = 1158;
+
france = 1250;
+
germany = 1276;
+
hongKong = 1344;
+
japan = 1392;
+
netherlands = 1528;
+
norway = 1578;
+
russianFederation = 1643;
+
singapore = 1702;
+
switzerland = 1756;
+
unitedKingdom = 1826;
+
unitedStatesOfAmerica = 1840;
+
};
+
}
-59
hosts/prefect/dn42/wireguard.nix
···
-
{ pkgs, lib, ... }:
-
let
-
defaultLocalIPv4 = "172.20.43.96/32";
-
defaultLocalIPv6 = "fe80::1/64";
-
privKeyFile = "/run/agenix/dn42-privkey";
-
# deadnix: skip
-
defaultPubKey = "e6kp9sca4XIzncKa9GEQwyOnMjje299Xg9ZdgXWMwHg=";
-
in
-
{
-
environment.systemPackages = [ pkgs.wireguard-tools ];
-
-
networking.wireguard.interfaces = import ./tunnels.nix rec {
-
customTunnel =
-
listenPort: privKeyFile: peerPubKey: endpoint: name: peerIPv4: peerIPv6: localIPv4: localIPv6: isOspf: {
-
inherit listenPort;
-
privateKeyFile = privKeyFile;
-
allowedIPsAsRoutes = false;
-
peers = [
-
{
-
inherit endpoint;
-
publicKey = peerPubKey;
-
allowedIPs = [
-
"0.0.0.0/0"
-
"::/0"
-
];
-
dynamicEndpointRefreshSeconds = 5;
-
persistentKeepalive = 15;
-
}
-
];
-
postSetup =
-
''
-
${
-
if peerIPv4 != "" then
-
"${pkgs.iproute2}/bin/ip addr add ${localIPv4} peer ${peerIPv4} dev ${name}"
-
else
-
""
-
}
-
${
-
if peerIPv6 != "" then
-
"${pkgs.iproute2}/bin/ip -6 addr add ${localIPv6} peer ${peerIPv6} dev ${name}"
-
else
-
""
-
}
-
''
-
+ lib.optionalString isOspf "${pkgs.iproute2}/bin/ip -6 addr add ${defaultLocalIPv6} dev ${name}";
-
};
-
# deadnix: skip
-
tunnel =
-
listenPort: privKey: peerPubKey: localIPv4: localIPv6: endpoint: name: peerIPv4: peerIPv6:
-
customTunnel listenPort privKeyFile peerPubKey endpoint name peerIPv4 peerIPv6 localIPv4 localIPv6
-
false;
-
# deadnix: skip
-
ospf =
-
listenPort: privKey: peerPubKey: endpoint: name: peerIPv4: peerIPv6: ULAIPv6:
-
customTunnel listenPort privKeyFile peerPubKey endpoint name peerIPv4 peerIPv6 defaultLocalIPv4
-
ULAIPv6
-
true;
-
};
-
}
+2 -17
hosts/prefect/firewall.nix
···
];
allowedUDPPortRanges = [
{
-
from = 480;
-
to = 510;
+
from = 42000;
+
to = 52000;
}
];
trustedInterfaces = [
-
"tailscale0"
"wg0"
-
-
# DN42 Interfaces
-
"wg42_bandura"
-
"wg42_bluemedia"
-
"wg42_catgirls"
-
"wg42_chris"
-
"wg42_iedon"
-
"wg42_kioubit"
-
"wg42_liki"
-
"wg42_lutoma"
-
"wg42_potato"
-
"wg42_sunnet"
-
"wg42_uffsalot"
-
"wg42_usman"
];
extraForwardRules = ''
meta iifname "wg42_*" meta oifname "wg42_*" accept
-1
hosts/prefect/secrets/secrets.nix
···
let
yubi-back = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDTVGi3PItsbUhFgnFZlqo1iUggL4npMg94+9FsyhEPfShcQwJK2/jJzjv5S9KPuk3cY7aoqyVFLbnasSBZPXmscJmOiVNvtWvHoC3QPXvf3IAcVZ5KOLpY2NJlPx/pAb31C6ewtg8v3VlyhL4zEp6M+AGwXX51tFDh2GnYD+7SNF+aMhKCrX63syAhgPy3F8mZ2RIDLAu+lsYlwdpWRkSEv9kcjX/6+3QgUWjfPBaKEeYID22ihSuj7+AiuAt0gM4q0TY/Hpcx+qDLonrIuBnm1hMZDgbv//D0sHIUxJQkGTKTEbkZxoh0Qri7UV/V6l3mETaG40deuemMU7RFY7Khl8RajNZ+9z0FdquS/HCt8+fYQk6eLneJrMIQ1bI4awrtblG3P2Yf2QUu+H3kfCQe44R3WjUugTbNtumVgyQBzl2dzlIVn1pZBeyZy70XCgbaFKkDR8Y/qZiUoZ0afP3vTOXhkn5UBfutTKwUiSGh3S8Ge5YhNgKHWE2eQp1ckEm0IMJV/q5Nsw/yBBXj/kfD8ekz96LQ+gP5JFLq4EaipXI7FM4aZNOBUZU1l/sCEuq7m997nrBucTKqGm7Ho3rq7bgdj4f6GyUJXSMOM1cN61LLrRumZGGTH8WghVL7ligxZyNFcQoudR8jfpf4mrgRxipQOe1A2umvuufMr+l/bw==";
-
yubi-main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBBsOIMMZVmleClXfqUMrnmyh8PFuyiJqHKEZ51Xy746";
prefect = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP532AB5mkNvE29MkDDY8HEf8ZdktGWiI0PzLrvbmLQe";
ssh-new = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAxOg9nOtfbedq9AlnXNVUfyU8Mwfj4IB7HX/4VoWeXP";
default = [
-30
hosts/prefect/services/blog-update.nix
···
-
{ pkgs, lib, ... }:
-
{
-
systemd.timers.blog-update = {
-
enable = false;
-
after = [ "network.target" ];
-
wantedBy = [ "multi-user.target" ];
-
description = "Blog Update Timer";
-
timerConfig = {
-
Unit = "blog-update.service";
-
OnUnitActiveSec = 300;
-
};
-
};
-
-
systemd.services.blog-update = {
-
enable = false;
-
wantedBy = [ "multi-user.target" ];
-
description = "Blog Update Service";
-
path = [
-
"${pkgs.git}"
-
];
-
serviceConfig = {
-
WorkingDirectory = "/var/www/blog";
-
User = "caddy";
-
Group = "caddy";
-
Type = "oneshot";
-
ExecStartPre = "${lib.getExe pkgs.git} fetch origin pages";
-
ExecStart = "${lib.getExe pkgs.git} reset --hard origin/pages";
-
};
-
};
-
}
-5
hosts/prefect/services/blog-update.sh
···
-
node scripts/precommit.js
-
node scripts/predeploy.js
-
hugo -d out
-
cp -fvr out/ /var/www/blog/
-
exit 0
+13 -18
hosts/prefect/services/caddy.nix
···
{ pkgs, self, ... }:
let
pns = self.lib.data.services;
-
mail = self.lib.data.mail;
+
inherit (self.lib.data) mail;
marvin = "http://${self.lib.data.hosts.marvin.ts.ip4}";
marvinIP = self.lib.data.hosts.marvin.ts.ip4;
-
tsNet = self.lib.data.tsNet;
+
inherit (self.lib.data) tsNet;
in
{
services.caddy = {
···
plugins = [
"github.com/caddy-dns/desec@v1.0.1"
"github.com/greenpau/caddy-security@v1.1.31"
-
"github.com/tailscale/caddy-tailscale@v0.0.0-20250508175905-642f61fea3cc"
-
"github.com/mholt/caddy-l4@v0.0.0-20250902102621-4a517a98d7fa"
+
"github.com/tailscale/caddy-tailscale@v0.0.0-20251016213337-01d084e119cb"
+
"github.com/mholt/caddy-l4@v0.0.0-20251001194302-2e3e6cf60b25"
"github.com/mohammed90/caddy-git-fs@v0.0.0-20240805164056-529acecd1830"
];
-
hash = "sha256-mmiBqKgzWm6HehThvd3zMuF7Vi0NiT1zcrJMw6K305I=";
+
hash = "sha256-kvChIK67UKn5vMFMcLszSl5AfW1BNHTRm1aXX5t5Wyc=";
};
email = "pyrox@pyrox.dev";
virtualHosts = {
···
# Authentication
${pns.pocket-id.extUrl} = {
extraConfig = ''
-
reverse_proxy / ${marvin}:${toString pns.pocket-id.port} {
-
header_up X-Real-IP {remote_host}
-
header_up X-Http-Version {http.request.proto}
-
}
+
reverse_proxy ${marvin}:${toString pns.pocket-id.port}
'';
};
···
'';
};
-
# Pingvin Share
-
${pns.pingvin-share.extUrl} = {
+
# Immich
+
${pns.immich.extUrl} = {
extraConfig = ''
-
reverse_proxy /api/* ${marvin}:${toString pns.pingvin-share.be-anubis} {
-
header_up X-Real-IP {remote_host}
-
header_up X-Http-Version {http.request.proto}
-
}
-
reverse_proxy /* ${marvin}:${toString pns.pingvin-share.anubis} {
-
header_up X-Real-IP {remote_host}
-
header_up X-Http-Version {http.request.proto}
+
@public path /share /share/*
+
handle @public {
+
reverse_proxy ${marvin}:${toString pns.immich.pubProxy}
}
+
reverse_proxy ${marvin}:${toString pns.immich.port}
'';
};
+
# Tangled Services
${pns.tangled-knot.extUrl} = {
extraConfig = ''
-4
hosts/prefect/services/dn42-peerfinder.nix
···
-
{ config, ... }:
-
{
-
config.py.services.dn42-pingfinder.uuidFile = config.age.secrets.dn42-peerfinder-uuid.path;
-
}
+21
hosts/prefect/services/mailserver/acme.nix
···
+
# ACME for certs, using TLS-ALPN-01 Challenges(one fewer ports open)
+
# https://stalw.art/docs/server/tls/acme/configuration
+
{ cfg, sec }:
+
{
+
letsencrypt = {
+
directory = "https://acme-staging-v02.api.letsencrypt.org/directory";
+
challenge = "dns-01";
+
contact = [ "pyrox@pyrox.dev" ];
+
domains = [
+
"mail.pyrox.dev"
+
"mta-sts.pyrox.dev"
+
"autoconfig.pyrox.dev"
+
"autodiscover.pyrox.dev"
+
];
+
cache = "${cfg.dataDir}/acme/certs";
+
renew-before = "30d";
+
default = true;
+
provider = "desec";
+
secret = "%{file:${sec.stalwart-desec-token.path}}%";
+
};
+
}
+21
hosts/prefect/services/mailserver/auth.nix
···
+
{ ifThen, otherwise }:
+
let
+
relVer = [
+
(ifThen "protocol = 'smtp'" "relaxed")
+
(otherwise "disable")
+
];
+
in
+
{
+
dkim = {
+
sign = [
+
(ifThen "sender_domain = 'pyrox.dev'" "['rsa', 'ed25519']")
+
(otherwise false)
+
];
+
};
+
spf.verify.ehlo = relVer;
+
spf.verify.mail-from = relVer;
+
dmarc.verify = relVer;
+
iprev.verify = relVer;
+
arc.seal = "'ed25519'";
+
arc.verify = "relaxed";
+
}
+25
hosts/prefect/services/mailserver/auto-ban.nix
···
+
# Strict Auto-ban
+
# https://stalw.art/docs/server/auto-ban
+
{
+
auth.rate = "15/1d";
+
abuse.rate = "15/1d";
+
loiter.rate = "15/1d";
+
scan = {
+
rate = "20/1d";
+
paths = [
+
"*.php*"
+
"*.cgi*"
+
"*.asp*"
+
"*/wp-*"
+
"*/php*"
+
"*/cgi-bin*"
+
"*xmlrpc*"
+
"*../*"
+
"*/..*"
+
"*joomla*"
+
"*wordpress*"
+
"*drupal*"
+
"/.git*"
+
];
+
};
+
}
+25
hosts/prefect/services/mailserver/calendar.nix
···
+
# Calendar settings
+
# https://stalw.art/docs/collaboration/calendar
+
{
+
max-recurrence-expansions = 2048;
+
# 512 KiB
+
max-size = 524288;
+
max-attendees-per-instance = 20;
+
default.href-name = "default";
+
default.display-name = "Personal";
+
# Scheduling
+
# https://stalw.art/docs/collaboration/scheduling
+
scheduling.enable = true;
+
# 1 MiB
+
scheduling.inbound.max-size = 1048576;
+
scheduling.outbound.max-recipients = 100;
+
scheduling.inbox.auto-expunge = "30d";
+
scheduling.http-rsvp.enable = true;
+
scheduling.http-rsvp.expiration = "7d";
+
# Notifications
+
# https://stalw.art/docs/collaboration/notifications
+
alarms.enable = true;
+
alarms.minimum-interval = "1h";
+
alarms.from.name = "PyroNet Calendars";
+
alarms.from.email = "calendar-notifs@pyrox.dev";
+
}
+203 -105
hosts/prefect/services/mailserver/default.nix
···
-
{ lib, pkgs, ... }:
+
{
+
config,
+
lib,
+
self,
+
...
+
}:
+
let
+
d = self.lib.data.mail;
+
cfg = config.services.stalwart-mail;
+
sec = config.age.secrets;
+
credsDir = "/run/credentials/stalwart-mail.service";
+
certDir = config.security.acme.certs."pyroxdev-mail".directory;
+
isAuthenticated = d: {
+
"if" = "!is_empty(authenticated_as)";
+
"then" = d;
+
};
+
otherwise = d: {
+
"else" = d;
+
};
+
ifThen = f: d: {
+
"if" = f;
+
"then" = d;
+
};
+
smSecret = {
+
owner = "stalwart-mail";
+
group = "stalwart-mail";
+
};
+
in
{
-
imports = [
-
./logins.nix
-
./monitoring.nix
-
./overrides.nix
-
];
-
mailserver = {
-
enable = false;
-
fqdn = "mail.pyrox.dev";
-
systemName = "PyroNet Mail";
-
systemDomain = "mail.pyrox.dev";
-
openFirewall = true;
-
stateVersion = 3;
-
-
# All domains this server runs email for
-
domains = [ "pyrox.dev" ];
-
-
# Enable STARTTLS
-
enableImap = true;
-
enableSubmission = true;
-
-
# Disable POP3, I don't use it and neither should you
-
enablePop3 = false;
-
enablePop3Ssl = false;
-
-
# Enable ManageSieve so that we don't need to change the config to update sieves
-
enableManageSieve = true;
-
-
# Set directories for services
-
mailDirectory = "/srv/mail/vmail";
-
sieveDirectory = "/srv/mail/sieve";
-
indexDir = "/var/lib/dovecot/indices";
-
dkimKeyDirectory = "/srv/mail/dkim";
-
-
# Set all no-reply addresses
-
rejectRecipients = [
-
"no-reply@pyrox.dev"
-
"dmarc-noreply@pyrox.dev"
-
];
-
-
# DKIM Settings
-
dkimKeyBits = 4096;
-
dkimSelector = "mail";
-
dkimSigning = true;
-
-
# DMARC Settings
-
dmarcReporting = {
-
enable = true;
+
services.stalwart-mail = {
+
credentials = {
+
cert = "${certDir}/cert.pem";
+
key = "${certDir}/key.pem";
};
-
-
# Mailboxes for all users
-
mailboxes = {
-
Drafts = {
-
auto = "subscribe";
-
specialUse = "Drafts";
+
enable = true;
+
dataDir = "/var/lib/stalwart";
+
settings = {
+
tracer.stdout.level = "info";
+
authentication.fallback-admin = {
+
user = "fallback";
+
secret = "%{file:${sec.stalwart-fallback-admin-pw.path}}%";
};
-
Junk = {
-
auto = "subscribe";
-
specialUse = "Junk";
+
config = {
+
local-keys = [
+
"asn.*"
+
"auth.*"
+
"authentication.*"
+
"auto-ban.*"
+
"calendar.*"
+
"certificate.*"
+
"changes.*"
+
"cluster.*"
+
"config.*"
+
"contacts.*"
+
"directory.*"
+
"http.*"
+
"imap.*"
+
"jmap.*"
+
"queue.*"
+
"report.*"
+
"resolver.*"
+
"server.*"
+
"session.*"
+
"signature.*"
+
"storage.*"
+
"store.*"
+
"tracer.*"
+
"webadmin.*"
+
"form.*"
+
"email.*"
+
"spam-filter.*"
+
];
};
-
Sent = {
-
auto = "subscribe";
-
specialUse = "Sent";
+
certificate = {
+
default = {
+
default = true;
+
cert = "%{file:${credsDir}/cert}%";
+
private-key = "%{file:${credsDir}/key}%";
+
subjects = [
+
"dav.pyrox.dev"
+
"mail.pyrox.dev"
+
"mta-sts.pyrox.dev"
+
"autoconfig.pyrox.dev"
+
"autodiscover.pyrox.dev"
+
];
+
};
};
-
Trash = {
-
auto = "subscribe";
-
specialUse = "Trash";
+
server = import ./server.nix { inherit d; };
+
# Use NixOS-generated certs now, since stalwart can't do it on its own
+
# (DeSec API Errors abound)
+
# acme = import ./acme.nix { inherit cfg sec; };
+
# HTTP Configuration
+
# https://stalw.art/docs/http/overview
+
http = {
+
url = "'https://${d.extUrl}'";
+
hsts = true;
+
rate-limit = {
+
account = "10000/1m";
+
};
};
-
};
-
-
# Full-Text-Search Settings
-
fullTextSearch = {
-
enable = true;
-
autoIndex = true;
-
enforced = "body";
-
memoryLimit = 2048;
+
# Disable HTTP Forms submission
+
# https://stalw.art/docs/http/form-submission
+
form.enable = false;
+
# DKIM Signatures
+
signature = import ./signature.nix { inherit sec; };
+
# Storage Settings
+
# https://stalw.art/docs/storage/overview
+
store = {
+
data = {
+
type = "rocksdb";
+
path = "${cfg.dataDir}/db";
+
purge.frequency = "0 3 *";
+
};
+
blob = {
+
type = "fs";
+
path = "${cfg.dataDir}/blobs";
+
depth = 2;
+
compression = "lz4";
+
purge.frequency = "0 4 *";
+
};
+
db.path = "${cfg.dataDir}/db2";
+
};
+
storage = {
+
data = "data";
+
blob = "blob";
+
fts = "data";
+
lookup = "data";
+
directory = "default";
+
};
+
directory = {
+
default = {
+
type = "internal";
+
store = "data";
+
};
+
};
+
# ASN/GeoIP Lookups
+
# https://stalw.art/docs/server/asn
+
asn = {
+
type = "dns";
+
separator = "|";
+
zone.ipv4 = "origin.asn.cymru.com";
+
zone.ipv6 = "origin6.asn.cymru.com";
+
index.asn = 0;
+
index.asn-name = 1;
+
index.country = 2;
+
};
+
auto-ban = import ./auto-ban.nix;
+
# JMAP Settings
+
# https://stalw.art/docs/email/jmap
+
jmap = {
+
mailbox.max-depth = 10;
+
mailbox.max-name-length = 255;
+
# 50 MB
+
email.max-attachment-size = 50 * 1000 * 1000;
+
# 75 MB
+
email.max-size = 75 * 1000 * 1000;
+
email.parse.max-items = 10;
+
};
+
imap = import ./imap.nix;
+
# Maintainance
+
# https://stalw.art/docs/email/maintenance
+
email.auto-expunge = "180d";
+
changes.max-history = 10000;
+
session = import ./session.nix { inherit isAuthenticated otherwise ifThen; };
+
queue = import ./queue.nix { inherit d ifThen otherwise; };
+
# DNS Settings
+
# https://stalw.art/docs/mta/outbound/dns
+
resolver = {
+
custom = [
+
"tls://dns11.quad9.net"
+
"tcp://1.1.1.1"
+
];
+
concurrency = 2;
+
preserve-intermediates = true;
+
timeout = "5s";
+
attempts = 3;
+
edns = true;
+
};
+
report = import ./report.nix { inherit d; };
+
calendar = import ./calendar.nix;
+
# Authentication
+
auth = import ./auth.nix { inherit ifThen otherwise; };
+
# Contacts
+
# https://stalw.art/docs/collaboration/contact
+
contacts = {
+
# 512 KiB
+
max-size = 524288;
+
default.href-name = "default";
+
default.display-name = "Contacts";
+
};
+
# Spam Filtering
+
# https://stalw.art/docs/spamfilter/overview
+
spam-filter = {
+
card-is-ham = true;
+
};
};
-
-
# Certificate Settings
-
certificateScheme = "manual";
-
certificateFile = "/var/lib/mail/mail.crt";
-
keyFile = "/var/lib/mail/mail.key";
};
-
-
services.opendkim = {
-
user = lib.mkForce "virtualMail";
-
group = lib.mkForce "virtualMail";
+
systemd.services.stalwart-mail.serviceConfig = {
+
Restart = lib.mkForce "always";
+
RestartSec = lib.mkForce 1;
};
-
-
# Copy mail certs every month so that they don't expire
-
systemd = {
-
timers."copy-mail-certs" = {
-
wantedBy = [ "timers.target" ];
-
timerConfig = {
-
OnBootSec = "5m";
-
OnCalendar = "daily";
-
Unit = "copy-mail-certs.service";
-
};
+
age.secrets = {
+
stalwart-secret-rsa = smSecret // {
+
file = ../../secrets/stalwart-secret-rsa.age;
};
-
-
services."copy-mail-certs" = {
-
script = ''
-
set -eu
-
cp -fvr /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.pyrox.dev/mail.pyrox.dev.crt /var/lib/mail/mail.crt
-
chmod a+r /var/lib/mail/mail.crt
-
cp -fvr /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.pyrox.dev/mail.pyrox.dev.key /var/lib/mail/mail.key
-
chmod a+r /var/lib/mail/mail.key
-
chown -hR virtualMail:virtualMail /var/lib/mail/
-
'';
-
serviceConfig = {
-
Type = "oneshot";
-
User = "root";
-
};
+
stalwart-secret-ed25519 = smSecret // {
+
file = ../../secrets/stalwart-secret-ed25519.age;
+
};
+
stalwart-desec-token = smSecret // {
+
file = ../../secrets/stalwart-desec-token.age;
+
};
+
stalwart-fallback-admin-pw = smSecret // {
+
file = ../../secrets/stalwart-fallback-admin-pw.age;
};
};
-
}
+42
hosts/prefect/services/mailserver/imap.nix
···
+
# https://stalw.art/docs/email/imap
+
{
+
# 50 MiB
+
request.max-size = 52428800;
+
auth.max-failures = 3;
+
auth.allow-plain-text = false;
+
folders =
+
let
+
folder = {
+
create = true;
+
subscribe = true;
+
};
+
in
+
{
+
inbox = folder // {
+
name = "Inbox";
+
};
+
drafts = folder // {
+
name = "Drafts";
+
};
+
sent = folder // {
+
name = "Sent";
+
};
+
trash = folder // {
+
name = "Trash";
+
};
+
archive = folder // {
+
name = "Archive";
+
};
+
junk = folder // {
+
name = "Junk";
+
};
+
shared = {
+
name = "Shared Folders";
+
create = true;
+
subscribe = false;
+
};
+
};
+
timeout.authenticated = "30m";
+
timeout.anonymous = "1m";
+
timeout.idle = "30m";
+
}
-41
hosts/prefect/services/mailserver/logins.nix
···
-
{
-
mailserver.loginAccounts = {
-
"pyrox@pyrox.dev" = {
-
hashedPassword = "$2b$05$8k04quBe6adg8d1yznEp3uNYM54MOVJTwDGIWvzocQFoWbmcCvebC";
-
aliases = [
-
"pyrox"
-
"postmaster@pyrox.dev"
-
"abuse@pyrox.dev"
-
"domains@pyrox.dev"
-
];
-
};
-
"social@pyrox.dev" = {
-
hashedPassword = "$2b$05$kFDeXvSKU9oXuQXlitA7v.kkbzgCDTrm4O3Nb1kifPe7yAR7.KimO";
-
sendOnly = true;
-
};
-
"auth@pyrox.dev" = {
-
hashedPassword = "$2b$05$O049hbSwRJ5VYeAA8lLR4e6.fqVWf4PotgIUAO356j5K.OoGH5PF.";
-
sendOnly = true;
-
};
-
"vault@pyrox.dev" = {
-
hashedPassword = "$2b$05$MHo03BG3AVpBh4NE97zQ8.gTPx2sCoa6Jsw.DRxHBOBaKZ8DbfPrS";
-
sendOnly = true;
-
};
-
"library@pyrox.dev" = {
-
hashedPassword = "$2b$05$IHsSbEla8KL4gwExvFECFuuoP0ESk66K29R.vawTpbxEpuw1ahii.";
-
sendOnly = true;
-
};
-
"cloud@pyrox.dev" = {
-
hashedPassword = "$2b$05$kmbsJ2X3Y2l0KYO8jjy1SOJP29coEeKFaMqU6qvRzz/dLJp78CAk6";
-
sendOnly = true;
-
};
-
"git@pyrox.dev" = {
-
hashedPassword = "$2b$05$uZoLVdCo48rLVBFdG0.UXua8a.84w1PzmLYOpJ1qTNo25KCdQlflm";
-
sendOnly = true;
-
};
-
"share@pyrox.dev" = {
-
hashedPassword = "$2b$05$LDvYYmxYcTgqPMDvvhA.uO8UFh8yLqPzVuOdeYBq0x/WJ/85X3DEC";
-
sendOnly = true;
-
};
-
};
-
}
-46
hosts/prefect/services/mailserver/monitoring.nix
···
-
{ config, pkgs, ... }:
-
# let
-
# cfg = config.mailserver;
-
# in
-
{
-
mailserver.monitoring = {
-
enable = true;
-
alertAddress = "pyrox@pyrox.dev";
-
config = ''
-
set daemon 120 with start delay 60
-
set mailserver
-
localhost
-
set alert ${config.mailserver.monitoring.alertAddress}
-
-
set httpd port 2812 and use address localhost
-
allow localhost
-
allow admin:obwjoawijerfoijsiwfj29jf2f2jd
-
-
check filesystem root with path /
-
if space usage > 80% then alert
-
if inode usage > 80% then alert
-
-
check system $HOST
-
if cpu usage > 95% for 10 cycles then alert
-
if memory usage > 75% for 5 cycles then alert
-
if swap usage > 20% for 10 cycles then alert
-
if loadavg (1min) > 90 for 15 cycles then alert
-
if loadavg (5min) > 80 for 10 cycles then alert
-
if loadavg (15min) > 70 for 8 cycles then alert
-
-
check process postfix with pidfile /var/lib/postfix/queue/pid/master.pid
-
start program = "${pkgs.systemd}/bin/systemctl start postfix"
-
stop program = "${pkgs.systemd}/bin/systemctl stop postfix"
-
if failed port 25 protocol smtp for 5 cycles then restart
-
-
check process dovecot with pidfile /var/run/dovecot2/master.pid
-
start program = "${pkgs.systemd}/bin/systemctl start dovecot2"
-
stop program = "${pkgs.systemd}/bin/systemctl stop dovecot2"
-
if failed host ${config.mailserver.fqdn} port 993 type tcpssl sslauto protocol imap for 5 cycles then restart
-
-
check process rspamd with matching "rspamd: main process"
-
start program = "${pkgs.systemd}/bin/systemctl start rspamd"
-
stop program = "${pkgs.systemd}/bin/systemctl stop rspamd"
-
'';
-
};
-
}
-21
hosts/prefect/services/mailserver/overrides.nix
···
-
{ lib, ... }:
-
let
-
inherit (lib) mkForce;
-
tlsProtocols = ">=TLSv1.2";
-
excludeCiphers = "MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL, AES128-SHA, AES256-SHA";
-
in
-
{
-
services.postfix.config = {
-
# only support TLS 1.3/1.2
-
smtpd_tls_protocols = mkForce tlsProtocols;
-
smtp_tls_protocols = mkForce tlsProtocols;
-
smtpd_tls_mandatory_protocols = mkForce tlsProtocols;
-
smtp_tls_mandatory_protocols = mkForce tlsProtocols;
-
-
# Exclude insecure ciphers
-
smtpd_tls_mandatory_exclude_ciphers = mkForce excludeCiphers;
-
smtpd_tls_exclude_ciphers = mkForce excludeCiphers;
-
smtp_tls_mandatory_exclude_ciphers = mkForce excludeCiphers;
-
smtp_tls_exclude_ciphers = mkForce excludeCiphers;
-
};
-
}
+97
hosts/prefect/services/mailserver/queue.nix
···
+
{
+
d,
+
ifThen,
+
otherwise,
+
}:
+
# Queue Management
+
# https://stalw.art/docs/mta/outbound/overview
+
{
+
# Virtual Queues
+
# https://stalw.art/docs/mta/outbound/queue
+
virtual.default.threads-per-node = 100;
+
virtual.admin.threads-per-node = 10;
+
virtual.local.threads-per-node = 100;
+
# Schedules
+
# https://stalw.art/docs/mta/outbound/schedule
+
schedule =
+
let
+
queue = {
+
retry = [
+
"1m"
+
"2m"
+
"5m"
+
"10m"
+
"15m"
+
"30m"
+
"1h"
+
"2h"
+
];
+
notify = [
+
"1d"
+
"3d"
+
];
+
max-attempts = 15;
+
};
+
in
+
{
+
default = queue // {
+
queue-name = "default";
+
};
+
admin = queue // {
+
queue-name = "admin";
+
};
+
local = queue // {
+
queue-name = "local";
+
};
+
};
+
# Routes
+
# https://stalw.art/docs/mta/outbound/routing
+
route = {
+
local.type = "local";
+
remote = {
+
type = "mx";
+
ip-lookup = "ipv6_then_ipv4";
+
tls.implicit = false;
+
tls.allow-invalid-certs = false;
+
};
+
};
+
# Strategies
+
# https://stalw.art/docs/mta/outbound/strategy
+
strategy = {
+
schedule = [
+
(ifThen "is_local_domain('', rcpt_domain)" "'local'")
+
(ifThen "source = 'dsn'" "'admin'")
+
(ifThen "source = 'report'" "'admin'")
+
(ifThen "source = 'autogenerated'" "'admin'")
+
(otherwise "'default'")
+
];
+
route = [
+
(ifThen "is_local_domain('', rcpt_domain)" "'local'")
+
(otherwise "'remote'")
+
];
+
connection = "'default'";
+
tls = "'default'";
+
};
+
# Remote Connection
+
# https://stalw.art/docs/mta/outbound/connection
+
connection.default = {
+
ehlo-hostname = d.extUrl;
+
source-ips = d.extIPs;
+
timeout = {
+
connect = "3m";
+
greeting = "3m";
+
ehlo = "3m";
+
mail-from = "3m";
+
rcpt-to = "3m";
+
data = "10m";
+
};
+
};
+
tls.default = {
+
dane = "optional";
+
mta-sts = "optional";
+
starttls = "optional";
+
allow-invalid-certs = false;
+
timeout.tls = "3m";
+
timeout.mta-sts = "3m";
+
};
+
}
+64
hosts/prefect/services/mailserver/report.nix
···
+
{ d }:
+
# Reports
+
# https://stalw.art/docs/mta/reports/overview
+
{
+
domain = "pyrox.dev";
+
submitter = "'${d.extUrl}'";
+
analysis = {
+
addresses = [
+
"dmarc@"
+
"reports@"
+
"spf@"
+
"dkim@"
+
"abuse@"
+
];
+
forward = true;
+
store = "30d";
+
};
+
dsn = {
+
from-name = "'PyroNet Mail'";
+
from-address = "'mail@pyrox.dev'";
+
sign = "['rsa', 'ed25519']";
+
};
+
dkim = {
+
from-name = "'PyroNet Mail Reports'";
+
from-address = "'noreply-dkim@pyrox.dev'";
+
subject = "'DKIM Authentication Failure Report'";
+
sign = "['rsa', 'ed25519']";
+
send = "1/1d";
+
};
+
spf = {
+
from-name = "'PyroNet Mail Reports'";
+
from-address = "'noreply-spf@pyrox.dev'";
+
subject = "'SPF Authentication Failure Report'";
+
sign = "['rsa', 'ed25519']";
+
send = "1/1d";
+
};
+
dmarc = {
+
from-name = "'PyroNet Mail Reports'";
+
from-address = "'noreply-dmarc@pyrox.dev'";
+
subject = "'DMARC Authentication Failure Report'";
+
sign = "['rsa', 'ed25519']";
+
send = "1/1d";
+
aggregate = {
+
from-name = "'DMARC Report'";
+
from-address = "'noreply-dmarc@pyrox.dev'";
+
org-name = "'PyroNet Mail'";
+
contact-info = "'pyrox@pyrox.dev'";
+
send = "daily";
+
# 25 MiB
+
max-size = 26214400;
+
sign = "['rsa', 'ed25519']";
+
};
+
};
+
tls.aggregate = {
+
from-name = "'PyroNet Mail Reports'";
+
from-address = "'noreply-tls@pyrox.dev'";
+
org-name = "'PyroNet Mail'";
+
contact-info = "'pyrox@pyrox.dev'";
+
send = "daily";
+
# 25 MiB
+
max-size = 26214400;
+
sign = "['rsa', 'ed25519']";
+
};
+
}
+69
hosts/prefect/services/mailserver/server.nix
···
+
{ d }:
+
{
+
hostname = d.extUrl;
+
# TLS
+
# https://stalw.art/docs/server/tls/overview
+
tls = {
+
enable = true;
+
implicit = false;
+
ignore-client-order = true;
+
};
+
# Listeners
+
# https://stalw.art/docs/server/listener
+
listener = {
+
smtp = {
+
bind = [
+
"[::]:${toString d.intSMTP}"
+
"[::]:40025"
+
];
+
protocol = "smtp";
+
# Explicit TLS
+
tls.implicit = false;
+
};
+
smtps = {
+
bind = "[::]:${toString d.intSMTPS}";
+
protocol = "smtp";
+
# Implicit TLS
+
tls.implicit = true;
+
};
+
imap = {
+
bind = "[::]:${toString d.intIMAP}";
+
protocol = "imap";
+
# Explicit TLS
+
tls.implicit = false;
+
};
+
imaps = {
+
bind = "[::]:${toString d.intIMAPS}";
+
protocol = "imap";
+
# Implicit TLS
+
tls.implicit = true;
+
};
+
managesieve = {
+
bind = "[::]:${toString d.intManageSieve}";
+
protocol = "managesieve";
+
# Explicit TLS
+
tls.implicit = false;
+
};
+
https = {
+
bind = "[::]:${toString d.intHTTPS}";
+
protocol = "http";
+
# Implicit TLS
+
tls.implicit = true;
+
};
+
http = {
+
bind = "[::]:${toString d.intHTTP}";
+
protocol = "http";
+
# Implicit TLS
+
tls.implicit = false;
+
};
+
};
+
# Proxy Protocol from Caddy
+
# Only accepts proxy protocol from Tailscale IP Ranges
+
# https://tailscale.com/kb/1015/100.x-addresses
+
# https://tailscale.com/kb/1033/ip-and-dns-addresses
+
proxy.trusted-networks = [
+
"fd7a:115c:a1e0::/48"
+
"100.64.0.0/10"
+
"127.0.0.1/8"
+
];
+
}
+63
hosts/prefect/services/mailserver/session.nix
···
+
{
+
isAuthenticated,
+
otherwise,
+
ifThen,
+
}:
+
# MTA Settings
+
# https://stalw.art/docs/mta/overview
+
{
+
# Inbound
+
# https://stalw.art/docs/mta/inbound/overview
+
# # EHLO Stage
+
# # https://stalw.art/docs/mta/inbound/ehlo
+
ehlo = {
+
require = true;
+
reject-non-fqdn = [
+
(ifThen "protocol = 'smtp'" true)
+
(otherwise false)
+
];
+
};
+
# # RCPT Stage
+
# # https://stalw.art/docs/mta/inbound/rcpt
+
rcpt = {
+
relay = [
+
(isAuthenticated true)
+
(otherwise false)
+
];
+
subaddressing = true;
+
};
+
auth = {
+
mechanisms = [
+
(ifThen "local_port != 40025 && is_tls" "[plain, login, oauthbearer, xoauth2]")
+
(ifThen "local_port != 40025" "[oauthbearer, xoauth2]")
+
(otherwise false)
+
];
+
directory = "'default'";
+
require = [
+
(ifThen "local_port != 40025" true)
+
(otherwise false)
+
];
+
must-match-sender = true;
+
};
+
extensions =
+
let
+
ifAuthed = [
+
(isAuthenticated true)
+
(otherwise false)
+
];
+
in
+
{
+
pipelining = true;
+
chunking = true;
+
requiretls = true;
+
no-soliciting = "";
+
dsn = ifAuthed;
+
deliver-by = [
+
(isAuthenticated "15d")
+
(otherwise false)
+
];
+
mt-priority = false;
+
vrfy = ifAuthed;
+
expn = ifAuthed;
+
};
+
}
+42
hosts/prefect/services/mailserver/signature.nix
···
+
{ sec }:
+
let
+
headers = [
+
"From"
+
"To"
+
"Cc"
+
"Date"
+
"Subject"
+
"Message-ID"
+
"Organization"
+
"MIME-Version"
+
"Content-Type"
+
"In-Reply-To"
+
"References"
+
"List-Id"
+
"User-Agent"
+
"Thread-Topic"
+
"Thread-Index"
+
];
+
in
+
{
+
rsa = {
+
inherit headers;
+
private-key = "%{file:${sec.stalwart-secret-rsa.path}}%";
+
domain = "pyrox.dev";
+
selector = "rsa-default";
+
algorithm = "rsa-sha256";
+
canonicalization = "relaxed/relaxed";
+
expire = "10d";
+
report = true;
+
};
+
ed25519 = {
+
inherit headers;
+
private-key = "%{file:${sec.stalwart-secret-ed25519.path}}%";
+
domain = "pyrox.dev";
+
selector = "default";
+
algorithm = "ed25519-sha256";
+
canonicalization = "relaxed/relaxed";
+
expire = "10d";
+
report = true;
+
};
+
}
-21
hosts/prefect/services/mailserver/stalwart/acme.nix
···
-
# ACME for certs, using TLS-ALPN-01 Challenges(one fewer ports open)
-
# https://stalw.art/docs/server/tls/acme/configuration
-
{ cfg, sec }:
-
{
-
letsencrypt = {
-
directory = "https://acme-staging-v02.api.letsencrypt.org/directory";
-
challenge = "dns-01";
-
contact = [ "pyrox@pyrox.dev" ];
-
domains = [
-
"mail.pyrox.dev"
-
"mta-sts.pyrox.dev"
-
"autoconfig.pyrox.dev"
-
"autodiscover.pyrox.dev"
-
];
-
cache = "${cfg.dataDir}/acme/certs";
-
renew-before = "30d";
-
default = true;
-
provider = "desec";
-
secret = "%{file:${sec.stalwart-desec-token.path}}%";
-
};
-
}
-21
hosts/prefect/services/mailserver/stalwart/auth.nix
···
-
{ ifThen, otherwise }:
-
let
-
relVer = [
-
(ifThen "protocol = 'smtp'" "relaxed")
-
(otherwise "disable")
-
];
-
in
-
{
-
dkim = {
-
sign = [
-
(ifThen "sender_domain = 'pyrox.dev'" "['rsa', 'ed25519']")
-
(otherwise false)
-
];
-
};
-
spf.verify.ehlo = relVer;
-
spf.verify.mail-from = relVer;
-
dmarc.verify = relVer;
-
iprev.verify = relVer;
-
arc.seal = "'ed25519'";
-
arc.verify = "relaxed";
-
}
-25
hosts/prefect/services/mailserver/stalwart/auto-ban.nix
···
-
# Strict Auto-ban
-
# https://stalw.art/docs/server/auto-ban
-
{
-
auth.rate = "15/1d";
-
abuse.rate = "15/1d";
-
loiter.rate = "15/1d";
-
scan = {
-
rate = "20/1d";
-
paths = [
-
"*.php*"
-
"*.cgi*"
-
"*.asp*"
-
"*/wp-*"
-
"*/php*"
-
"*/cgi-bin*"
-
"*xmlrpc*"
-
"*../*"
-
"*/..*"
-
"*joomla*"
-
"*wordpress*"
-
"*drupal*"
-
"/.git*"
-
];
-
};
-
}
-25
hosts/prefect/services/mailserver/stalwart/calendar.nix
···
-
# Calendar settings
-
# https://stalw.art/docs/collaboration/calendar
-
{
-
max-recurrence-expansions = 2048;
-
# 512 KiB
-
max-size = 524288;
-
max-attendees-per-instance = 20;
-
default.href-name = "default";
-
default.display-name = "Personal";
-
# Scheduling
-
# https://stalw.art/docs/collaboration/scheduling
-
scheduling.enable = true;
-
# 1 MiB
-
scheduling.inbound.max-size = 1048576;
-
scheduling.outbound.max-recipients = 100;
-
scheduling.inbox.auto-expunge = "30d";
-
scheduling.http-rsvp.enable = true;
-
scheduling.http-rsvp.expiration = "7d";
-
# Notifications
-
# https://stalw.art/docs/collaboration/notifications
-
alarms.enable = true;
-
alarms.minimum-interval = "1h";
-
alarms.from.name = "PyroNet Calendars";
-
alarms.from.email = "calendar-notifs@pyrox.dev";
-
}
-217
hosts/prefect/services/mailserver/stalwart/default.nix
···
-
{
-
config,
-
lib,
-
self,
-
...
-
}:
-
let
-
d = self.lib.data.mail;
-
cfg = config.services.stalwart-mail;
-
sec = config.age.secrets;
-
creds = config.services.stalwart-mail.credentials;
-
credsDir = "/run/credentials/stalwart-mail.service";
-
certDir = config.security.acme.certs."pyroxdev-mail".directory;
-
isAuthenticated = d: {
-
"if" = "!is_empty(authenticated_as)";
-
"then" = d;
-
};
-
otherwise = d: {
-
"else" = d;
-
};
-
ifThen = f: d: {
-
"if" = f;
-
"then" = d;
-
};
-
smSecret = {
-
owner = "stalwart-mail";
-
group = "stalwart-mail";
-
};
-
in
-
{
-
services.stalwart-mail = {
-
credentials = {
-
cert = "${certDir}/cert.pem";
-
key = "${certDir}/key.pem";
-
};
-
enable = true;
-
dataDir = "/var/lib/stalwart";
-
settings = {
-
tracer.stdout.level = "info";
-
authentication.fallback-admin = {
-
user = "fallback";
-
secret = "%{file:${sec.stalwart-fallback-admin-pw.path}}%";
-
};
-
config = {
-
local-keys = [
-
"asn.*"
-
"auth.*"
-
"authentication.*"
-
"auto-ban.*"
-
"calendar.*"
-
"certificate.*"
-
"changes.*"
-
"cluster.*"
-
"config.*"
-
"contacts.*"
-
"directory.*"
-
"http.*"
-
"imap.*"
-
"jmap.*"
-
"queue.*"
-
"report.*"
-
"resolver.*"
-
"server.*"
-
"session.*"
-
"signature.*"
-
"storage.*"
-
"store.*"
-
"tracer.*"
-
"webadmin.*"
-
"form.*"
-
"email.*"
-
"spam-filter.*"
-
];
-
};
-
certificate = {
-
default = {
-
default = true;
-
cert = "%{file:${credsDir}/cert}%";
-
private-key = "%{file:${credsDir}/key}%";
-
subjects = [
-
"dav.pyrox.dev"
-
"mail.pyrox.dev"
-
"mta-sts.pyrox.dev"
-
"autoconfig.pyrox.dev"
-
"autodiscover.pyrox.dev"
-
];
-
};
-
};
-
server = import ./server.nix { inherit d; };
-
# Use NixOS-generated certs now, since stalwart can't do it on its own
-
# (DeSec API Errors abound)
-
# acme = import ./acme.nix { inherit cfg sec; };
-
# HTTP Configuration
-
# https://stalw.art/docs/http/overview
-
http = {
-
url = "'https://${d.extUrl}'";
-
hsts = true;
-
rate-limit = {
-
account = "10000/1m";
-
};
-
};
-
# Disable HTTP Forms submission
-
# https://stalw.art/docs/http/form-submission
-
form.enable = false;
-
# DKIM Signatures
-
signature = import ./signature.nix { inherit sec; };
-
# Storage Settings
-
# https://stalw.art/docs/storage/overview
-
store = {
-
data = {
-
type = "rocksdb";
-
path = "${cfg.dataDir}/db";
-
purge.frequency = "0 3 *";
-
};
-
blob = {
-
type = "fs";
-
path = "${cfg.dataDir}/blobs";
-
depth = 2;
-
compression = "lz4";
-
purge.frequency = "0 4 *";
-
};
-
db.path = "${cfg.dataDir}/db2";
-
};
-
storage = {
-
data = "data";
-
blob = "blob";
-
fts = "data";
-
lookup = "data";
-
directory = "default";
-
};
-
directory = {
-
default = {
-
type = "internal";
-
store = "data";
-
};
-
};
-
# ASN/GeoIP Lookups
-
# https://stalw.art/docs/server/asn
-
asn = {
-
type = "dns";
-
separator = "|";
-
zone.ipv4 = "origin.asn.cymru.com";
-
zone.ipv6 = "origin6.asn.cymru.com";
-
index.asn = 0;
-
index.asn-name = 1;
-
index.country = 2;
-
};
-
auto-ban = import ./auto-ban.nix;
-
# JMAP Settings
-
# https://stalw.art/docs/email/jmap
-
jmap = {
-
mailbox.max-depth = 10;
-
mailbox.max-name-length = 255;
-
# 50 MB
-
email.max-attachment-size = 50 * 1000 * 1000;
-
# 75 MB
-
email.max-size = 75 * 1000 * 1000;
-
email.parse.max-items = 10;
-
};
-
imap = import ./imap.nix;
-
# Maintainance
-
# https://stalw.art/docs/email/maintenance
-
email.auto-expunge = "180d";
-
changes.max-history = 10000;
-
session = import ./session.nix { inherit isAuthenticated otherwise ifThen; };
-
queue = import ./queue.nix { inherit d ifThen otherwise; };
-
# DNS Settings
-
# https://stalw.art/docs/mta/outbound/dns
-
resolver = {
-
custom = [
-
"tls://dns11.quad9.net"
-
"tcp://1.1.1.1"
-
];
-
concurrency = 2;
-
preserve-intermediates = true;
-
timeout = "5s";
-
attempts = 3;
-
edns = true;
-
};
-
report = import ./report.nix { inherit d; };
-
calendar = import ./calendar.nix;
-
# Authentication
-
auth = import ./auth.nix { inherit ifThen otherwise; };
-
# Contacts
-
# https://stalw.art/docs/collaboration/contact
-
contacts = {
-
# 512 KiB
-
max-size = 524288;
-
default.href-name = "default";
-
default.display-name = "Contacts";
-
};
-
# Spam Filtering
-
# https://stalw.art/docs/spamfilter/overview
-
spam-filter = {
-
card-is-ham = true;
-
};
-
};
-
};
-
systemd.services.stalwart-mail.serviceConfig = {
-
Restart = lib.mkForce "always";
-
RestartSec = lib.mkForce 1;
-
};
-
age.secrets = {
-
stalwart-secret-rsa = smSecret // {
-
file = ../../../secrets/stalwart-secret-rsa.age;
-
};
-
stalwart-secret-ed25519 = smSecret // {
-
file = ../../../secrets/stalwart-secret-ed25519.age;
-
};
-
stalwart-desec-token = smSecret // {
-
file = ../../../secrets/stalwart-desec-token.age;
-
};
-
stalwart-fallback-admin-pw = smSecret // {
-
file = ../../../secrets/stalwart-fallback-admin-pw.age;
-
};
-
};
-
}
-42
hosts/prefect/services/mailserver/stalwart/imap.nix
···
-
# https://stalw.art/docs/email/imap
-
{
-
# 50 MiB
-
request.max-size = 52428800;
-
auth.max-failures = 3;
-
auth.allow-plain-text = false;
-
folders =
-
let
-
folder = {
-
create = true;
-
subscribe = true;
-
};
-
in
-
{
-
inbox = folder // {
-
name = "Inbox";
-
};
-
drafts = folder // {
-
name = "Drafts";
-
};
-
sent = folder // {
-
name = "Sent";
-
};
-
trash = folder // {
-
name = "Trash";
-
};
-
archive = folder // {
-
name = "Archive";
-
};
-
junk = folder // {
-
name = "Junk";
-
};
-
shared = {
-
name = "Shared Folders";
-
create = true;
-
subscribe = false;
-
};
-
};
-
timeout.authenticated = "30m";
-
timeout.anonymous = "1m";
-
timeout.idle = "30m";
-
}
-97
hosts/prefect/services/mailserver/stalwart/queue.nix
···
-
{
-
d,
-
ifThen,
-
otherwise,
-
}:
-
# Queue Management
-
# https://stalw.art/docs/mta/outbound/overview
-
{
-
# Virtual Queues
-
# https://stalw.art/docs/mta/outbound/queue
-
virtual.default.threads-per-node = 100;
-
virtual.admin.threads-per-node = 10;
-
virtual.local.threads-per-node = 100;
-
# Schedules
-
# https://stalw.art/docs/mta/outbound/schedule
-
schedule =
-
let
-
queue = {
-
retry = [
-
"1m"
-
"2m"
-
"5m"
-
"10m"
-
"15m"
-
"30m"
-
"1h"
-
"2h"
-
];
-
notify = [
-
"1d"
-
"3d"
-
];
-
max-attempts = 15;
-
};
-
in
-
{
-
default = queue // {
-
queue-name = "default";
-
};
-
admin = queue // {
-
queue-name = "admin";
-
};
-
local = queue // {
-
queue-name = "local";
-
};
-
};
-
# Routes
-
# https://stalw.art/docs/mta/outbound/routing
-
route = {
-
local.type = "local";
-
remote = {
-
type = "mx";
-
ip-lookup = "ipv6_then_ipv4";
-
tls.implicit = false;
-
tls.allow-invalid-certs = false;
-
};
-
};
-
# Strategies
-
# https://stalw.art/docs/mta/outbound/strategy
-
strategy = {
-
schedule = [
-
(ifThen "is_local_domain('', rcpt_domain)" "'local'")
-
(ifThen "source = 'dsn'" "'admin'")
-
(ifThen "source = 'report'" "'admin'")
-
(ifThen "source = 'autogenerated'" "'admin'")
-
(otherwise "'default'")
-
];
-
route = [
-
(ifThen "is_local_domain('', rcpt_domain)" "'local'")
-
(otherwise "'remote'")
-
];
-
connection = "'default'";
-
tls = "'default'";
-
};
-
# Remote Connection
-
# https://stalw.art/docs/mta/outbound/connection
-
connection.default = {
-
ehlo-hostname = d.extUrl;
-
source-ips = d.extIPs;
-
timeout = {
-
connect = "3m";
-
greeting = "3m";
-
ehlo = "3m";
-
mail-from = "3m";
-
rcpt-to = "3m";
-
data = "10m";
-
};
-
};
-
tls.default = {
-
dane = "optional";
-
mta-sts = "optional";
-
starttls = "optional";
-
allow-invalid-certs = false;
-
timeout.tls = "3m";
-
timeout.mta-sts = "3m";
-
};
-
}
-64
hosts/prefect/services/mailserver/stalwart/report.nix
···
-
{ d }:
-
# Reports
-
# https://stalw.art/docs/mta/reports/overview
-
{
-
domain = "pyrox.dev";
-
submitter = "'${d.extUrl}'";
-
analysis = {
-
addresses = [
-
"dmarc@"
-
"reports@"
-
"spf@"
-
"dkim@"
-
"abuse@"
-
];
-
forward = true;
-
store = "30d";
-
};
-
dsn = {
-
from-name = "'PyroNet Mail'";
-
from-address = "'mail@pyrox.dev'";
-
sign = "['rsa', 'ed25519']";
-
};
-
dkim = {
-
from-name = "'PyroNet Mail Reports'";
-
from-address = "'noreply-dkim@pyrox.dev'";
-
subject = "'DKIM Authentication Failure Report'";
-
sign = "['rsa', 'ed25519']";
-
send = "1/1d";
-
};
-
spf = {
-
from-name = "'PyroNet Mail Reports'";
-
from-address = "'noreply-spf@pyrox.dev'";
-
subject = "'SPF Authentication Failure Report'";
-
sign = "['rsa', 'ed25519']";
-
send = "1/1d";
-
};
-
dmarc = {
-
from-name = "'PyroNet Mail Reports'";
-
from-address = "'noreply-dmarc@pyrox.dev'";
-
subject = "'DMARC Authentication Failure Report'";
-
sign = "['rsa', 'ed25519']";
-
send = "1/1d";
-
aggregate = {
-
from-name = "'DMARC Report'";
-
from-address = "'noreply-dmarc@pyrox.dev'";
-
org-name = "'PyroNet Mail'";
-
contact-info = "'pyrox@pyrox.dev'";
-
send = "daily";
-
# 25 MiB
-
max-size = 26214400;
-
sign = "['rsa', 'ed25519']";
-
};
-
};
-
tls.aggregate = {
-
from-name = "'PyroNet Mail Reports'";
-
from-address = "'noreply-tls@pyrox.dev'";
-
org-name = "'PyroNet Mail'";
-
contact-info = "'pyrox@pyrox.dev'";
-
send = "daily";
-
# 25 MiB
-
max-size = 26214400;
-
sign = "['rsa', 'ed25519']";
-
};
-
}
-69
hosts/prefect/services/mailserver/stalwart/server.nix
···
-
{ d }:
-
{
-
hostname = d.extUrl;
-
# TLS
-
# https://stalw.art/docs/server/tls/overview
-
tls = {
-
enable = true;
-
implicit = false;
-
ignore-client-order = true;
-
};
-
# Listeners
-
# https://stalw.art/docs/server/listener
-
listener = {
-
smtp = {
-
bind = [
-
"[::]:${toString d.intSMTP}"
-
"[::]:40025"
-
];
-
protocol = "smtp";
-
# Explicit TLS
-
tls.implicit = false;
-
};
-
smtps = {
-
bind = "[::]:${toString d.intSMTPS}";
-
protocol = "smtp";
-
# Implicit TLS
-
tls.implicit = true;
-
};
-
imap = {
-
bind = "[::]:${toString d.intIMAP}";
-
protocol = "imap";
-
# Explicit TLS
-
tls.implicit = false;
-
};
-
imaps = {
-
bind = "[::]:${toString d.intIMAPS}";
-
protocol = "imap";
-
# Implicit TLS
-
tls.implicit = true;
-
};
-
managesieve = {
-
bind = "[::]:${toString d.intManageSieve}";
-
protocol = "managesieve";
-
# Explicit TLS
-
tls.implicit = false;
-
};
-
https = {
-
bind = "[::]:${toString d.intHTTPS}";
-
protocol = "http";
-
# Implicit TLS
-
tls.implicit = true;
-
};
-
http = {
-
bind = "[::]:${toString d.intHTTP}";
-
protocol = "http";
-
# Implicit TLS
-
tls.implicit = false;
-
};
-
};
-
# Proxy Protocol from Caddy
-
# Only accepts proxy protocol from Tailscale IP Ranges
-
# https://tailscale.com/kb/1015/100.x-addresses
-
# https://tailscale.com/kb/1033/ip-and-dns-addresses
-
proxy.trusted-networks = [
-
"fd7a:115c:a1e0::/48"
-
"100.64.0.0/10"
-
"127.0.0.1/8"
-
];
-
}
-63
hosts/prefect/services/mailserver/stalwart/session.nix
···
-
{
-
isAuthenticated,
-
otherwise,
-
ifThen,
-
}:
-
# MTA Settings
-
# https://stalw.art/docs/mta/overview
-
{
-
# Inbound
-
# https://stalw.art/docs/mta/inbound/overview
-
# # EHLO Stage
-
# # https://stalw.art/docs/mta/inbound/ehlo
-
ehlo = {
-
require = true;
-
reject-non-fqdn = [
-
(ifThen "protocol = 'smtp'" true)
-
(otherwise false)
-
];
-
};
-
# # RCPT Stage
-
# # https://stalw.art/docs/mta/inbound/rcpt
-
rcpt = {
-
relay = [
-
(isAuthenticated true)
-
(otherwise false)
-
];
-
subaddressing = true;
-
};
-
auth = {
-
mechanisms = [
-
(ifThen "local_port != 40025 && is_tls" "[plain, login, oauthbearer, xoauth2]")
-
(ifThen "local_port != 40025" "[oauthbearer, xoauth2]")
-
(otherwise false)
-
];
-
directory = "'default'";
-
require = [
-
(ifThen "local_port != 40025" true)
-
(otherwise false)
-
];
-
must-match-sender = true;
-
};
-
extensions =
-
let
-
ifAuthed = [
-
(isAuthenticated true)
-
(otherwise false)
-
];
-
in
-
{
-
pipelining = true;
-
chunking = true;
-
requiretls = true;
-
no-soliciting = "";
-
dsn = ifAuthed;
-
deliver-by = [
-
(isAuthenticated "15d")
-
(otherwise false)
-
];
-
mt-priority = false;
-
vrfy = ifAuthed;
-
expn = ifAuthed;
-
};
-
}
-42
hosts/prefect/services/mailserver/stalwart/signature.nix
···
-
{ sec }:
-
let
-
headers = [
-
"From"
-
"To"
-
"Cc"
-
"Date"
-
"Subject"
-
"Message-ID"
-
"Organization"
-
"MIME-Version"
-
"Content-Type"
-
"In-Reply-To"
-
"References"
-
"List-Id"
-
"User-Agent"
-
"Thread-Topic"
-
"Thread-Index"
-
];
-
in
-
{
-
rsa = {
-
inherit headers;
-
private-key = "%{file:${sec.stalwart-secret-rsa.path}}%";
-
domain = "pyrox.dev";
-
selector = "rsa-default";
-
algorithm = "rsa-sha256";
-
canonicalization = "relaxed/relaxed";
-
expire = "10d";
-
report = true;
-
};
-
ed25519 = {
-
inherit headers;
-
private-key = "%{file:${sec.stalwart-secret-ed25519.path}}%";
-
domain = "pyrox.dev";
-
selector = "default";
-
algorithm = "ed25519-sha256";
-
canonicalization = "relaxed/relaxed";
-
expire = "10d";
-
report = true;
-
};
-
}
-7
hosts/prefect/services/netdata.nix
···
-
{
-
services.netdata = {
-
enable = true;
-
python.enable = true;
-
enableAnalyticsReporting = false;
-
};
-
}
-38
hosts/prefect/services/nginx/default.nix
···
-
{ lib, ... }:
-
{
-
services.nginx = {
-
enable = true;
-
additionalModules = [ ];
-
recommendedOptimisation = true;
-
recommendedTlsSettings = true;
-
recommendedGzipSettings = true;
-
recommendedProxySettings = true;
-
virtualHosts = lib.mkForce { };
-
streamConfig = ''
-
server {
-
listen 34197 udp;
-
proxy_pass 100.123.15.72:34197;
-
proxy_responses 0;
-
}
-
'';
-
appendHttpConfig = ''
-
# Add X-Frame-Options to prevent clickjacking
-
add_header X-Frame-Options SAMEORIGIN;
-
-
# Prevent mime type sniffing
-
add_header X-Content-Type-Options nosniff;
-
-
# Never send Referer header
-
add_header Referrer-Policy no-referrer;
-
-
# Require CORS or CORP headers for cross-origin resources
-
add_header Cross-Origin-Embedder-Policy require-corp;
-
-
# Keep our own Browsing Context Group
-
add_header Cross-Origin-Opener-Policy same-origin;
-
-
# Sites that require CORP will not load my assets
-
add_header Cross-Origin-Resource-Policy same-origin;
-
'';
-
};
-
}
-1
hosts/prefect/services/nginx/pyrox.dev.nix
···
-
{ }
-1
hosts/prefect/services/tailscale.nix
···
networking.firewall = {
trustedInterfaces = [ "tailscale0" ];
allowedUDPPorts = [ config.services.tailscale.port ];
-
checkReversePath = "loose";
};
}
-6
hosts/prefect/services/zerotier.nix
···
-
{
-
services.zerotierone = {
-
enable = true;
-
joinNetworks = [ "a84ac5c10a3b1d69" ];
-
};
-
}
-10
hosts/thought/secrets/secrets.nix
···
-
let
-
# deadnix: skip
-
yubi-back = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDTVGi3PItsbUhFgnFZlqo1iUggL4npMg94+9FsyhEPfShcQwJK2/jJzjv5S9KPuk3cY7aoqyVFLbnasSBZPXmscJmOiVNvtWvHoC3QPXvf3IAcVZ5KOLpY2NJlPx/pAb31C6ewtg8v3VlyhL4zEp6M+AGwXX51tFDh2GnYD+7SNF+aMhKCrX63syAhgPy3F8mZ2RIDLAu+lsYlwdpWRkSEv9kcjX/6+3QgUWjfPBaKEeYID22ihSuj7+AiuAt0gM4q0TY/Hpcx+qDLonrIuBnm1hMZDgbv//D0sHIUxJQkGTKTEbkZxoh0Qri7UV/V6l3mETaG40deuemMU7RFY7Khl8RajNZ+9z0FdquS/HCt8+fYQk6eLneJrMIQ1bI4awrtblG3P2Yf2QUu+H3kfCQe44R3WjUugTbNtumVgyQBzl2dzlIVn1pZBeyZy70XCgbaFKkDR8Y/qZiUoZ0afP3vTOXhkn5UBfutTKwUiSGh3S8Ge5YhNgKHWE2eQp1ckEm0IMJV/q5Nsw/yBBXj/kfD8ekz96LQ+gP5JFLq4EaipXI7FM4aZNOBUZU1l/sCEuq7m997nrBucTKqGm7Ho3rq7bgdj4f6GyUJXSMOM1cN61LLrRumZGGTH8WghVL7ligxZyNFcQoudR8jfpf4mrgRxipQOe1A2umvuufMr+l/bw==";
-
# deadnix: skip
-
yubi-main = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBBsOIMMZVmleClXfqUMrnmyh8PFuyiJqHKEZ51Xy746";
-
# deadnix: skip
-
backup = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCyTiGctsHaTUlRJn2XQ/745dD0UWGWO8W0en8J5rf7BLI8lL/hPUmbNt45vC5754LXcBjnp1t/1FNgiGhvNZIWJpC+elBmhyMhg8z1exRZPD+as7XaH7scnij2vSbSphQFUqH433ggAGe77x5bc7wKFp9n7vj8G1u0JJxMEe1M7kNFY0+ShNtaHna3LxiQOVcW7qVlNKZP8Ol1V7kZLblRADCJMTYOXDIbktA8bbGRfGhbNjJGkL665qz36haYwb2i6A4sC7Y583N8ro8hIDG/ByJqwbl/Sz4rSxkT6G4+OdBvS6sa7TovNXHjmQCculMIltdog7UhgyBsim1sTzxAen3YyFRi1Cz/kLM0oH39m/W4IoMvJcNZCJ3ItLgy+lEVMd87jVOqfuq/hyjHVI0wJtU2Si2HTxv7aKL8gPzqXwbNH+nhkhlQ0ZH8zKVBunOgLDgsmGIky5X/T3bpWZpIoFkOR7AYrId/5dOeGM3pHhHb6woZ3SRubZ43Ah/VdJM=";
-
# deadnix: skip
-
thought = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGkJcLykggEp427h2IywoiR74Yl3N+FU6Pwx9ZFQ3vjq";
-
in
{
imports = [ ../../common/secrets/secrets.nix ];
# "headscale-oidc-secret.age".publicKeys = [ prefect yubi-main yubi-back ];
+3
hosts/zaphod/bootloader.nix
···
kernelPackages = pkgs.linuxPackages_latest;
extraModulePackages = with config.boot.kernelPackages; [
v4l2loopback
+
framework-laptop-kmod
];
kernelModules = [
"v4l2loopback"
"btusb"
+
"cros_ec"
+
"cros_ec_lpcs"
];
supportedFilesystems = fileSystems;
initrd = {
-1
hosts/zaphod/default.nix
···
# Machine-specific programs.
./programs/ssh.nix
-
./programs/sway.nix
./programs/zsh.nix
# Agenix secrets
+7 -4
hosts/zaphod/hardware.nix
···
powerOnBoot = true;
};
gpgSmartcards.enable = true;
+
amdgpu = {
+
opencl.enable = false;
+
initrd.enable = true;
+
};
graphics = {
enable = true;
extraPackages = [
···
];
};
wirelessRegulatoryDatabase = true;
+
framework.enableKmod = false;
+
keyboard.qmk.enable = true;
+
keyboard.qmk.keychronSupport = true;
};
services.udev.packages = [
pkgs.qmk-udev-rules
pkgs.logitech-udev-rules
];
-
hardware.amdgpu = {
-
opencl.enable = false;
-
initrd.enable = true;
-
};
}
+9 -6
hosts/zaphod/misc.nix
···
"pyrox"
];
# users.extraGroups.libvirtd.members = ["thehedgehog" "pyrox"];
-
# xdg.portal.extraPortals = [
-
# pkgs.xdg-desktop-portal-gtk
-
# ];
-
xdg.portal.wlr.enable = true;
xdg.portal.xdgOpenUsePortal = true;
-
-
users.users.root.hashedPassword = "$6$6EtuZhVOJdfI9DYP$1Qnd7R8qdN.E5yE2kDQCNg2zgJ5cIjNBKsIW/qJgb8wcKlUpIoVg/fEKvBkAgCiLyojVG2kzfu4J9LR8rA8a2/";
# Nix-LD
programs.nix-ld.enable = true;
···
programs.steam.extraPackages = [
pkgs.pixman
];
+
+
services.upower = {
+
enable = true;
+
percentageLow = 30;
+
percentageCritical = 15;
+
};
+
+
# For caelestia screen recording
+
programs.gpu-screen-recorder.enable = true;
}
+6 -8
hosts/zaphod/packages.nix
···
{
pkgs,
-
inputs,
+
inputs',
...
}:
{
environment.systemPackages = [
-
inputs.agenix.packages.${pkgs.system}.default
-
pkgs.deadnix
+
inputs'.agenix.packages.default
pkgs.file
-
pkgs.gamescope
pkgs.gnupg
-
pkgs.goverlay
pkgs.libappindicator
pkgs.kdePackages.kdenlive
pkgs.libappindicator-gtk3
-
pkgs.mangohud
-
pkgs.networkmanagerapplet
pkgs.nixpkgs-track
pkgs.pmutils
pkgs.qbittorrent
-
pkgs.scrcpy
pkgs.steam-run
+
# Tools for working with Framework computers
+
pkgs.framework-tool-tui
+
pkgs.fw-ectool
+
pkgs.framework-tool
];
}
-7
hosts/zaphod/programs/sway.nix
···
-
{
-
programs.sway = {
-
enable = false;
-
wrapperFeatures.base = true;
-
wrapperFeatures.gtk = true;
-
};
-
}
+1 -1
hosts/zaphod/services/fprintd.nix
···
{ pkgs, ... }:
{
services.fprintd = {
-
enable = true;
+
enable = false;
tod.enable = false;
tod.driver = pkgs.libfprint-2-tod1-goodix;
};
+9 -3
hosts/zaphod/services/misc.nix
···
{ config, lib, ... }:
{
services = {
-
blueman.enable = true;
+
blueman.enable = false;
fstrim.enable = lib.mkDefault true;
tlp.enable = lib.mkDefault (
-
(lib.versionOlder (lib.versions.majorMinor lib.version) "21.05")
-
|| !config.services.power-profiles-daemon.enable
+
(lib.versionOlder (lib.versions.majorMinor lib.version) "21.05") || !config.services.power-profiles-daemon.enable
);
libinput.enable = lib.mkDefault true;
+
logind.settings.Login = {
+
HandlePowerKey = "ignore";
+
HandlePowerKeyLongPress = "ignore";
+
HandleLidSwitch = "ignore";
+
HandleLidSwitchExternalPower = "ignore";
+
HandleLidSwitchDocked = "ignore";
+
};
};
}
img.png

This is a binary file and will not be displayed.

+7
lib/data/services.toml
···
# anubis: What port the anubis service for this domain will use, int
# tsHost: (optional) What Tailscale host this service will run on, for services only available via Tailscale.
# # Should only be set if this is available externally, if at all, since TS-only services aren't able to be scraped.
+
# Current lowest unassigned port: 6938
[authentik]
port = 6908
host = "marvin"
···
port = 6923
host = "marvin"
extUrl = "soc.pyrox.dev"
+
+
[immich]
+
port = 6936
+
host = "marvin"
+
extUrl = "img.pyrox.dev"
+
pubProxy = 6937
[jellyfin]
port = 8096
+1 -4
lib/default.nix
···
-
{
-
...
-
}:
-
{
+
_: {
flake = {
lib.data = import ./data;
};
+1 -1
lib/deploy/default.nix
···
let
inherit (inputs) deploy-rs;
in
-
rec {
+
{
## Create deployment configuration for use with deploy-rs.
##
## ```nix
+3
nixosModules/default-config/bootloader.nix
···
# Should hardon and improve performance
"page_alloc.shuffle=1"
];
+
# Don't use either of these so disable them
+
kexec.enable = false;
+
bcache.enable = false;
};
}
+5 -2
nixosModules/default-config/default.nix
···
./ssh.nix
./users.nix
];
-
system.stateVersion = "25.05";
-
system.disableInstallerTools = true;
+
system = {
+
stateVersion = "26.05";
+
disableInstallerTools = true;
+
tools.nixos-rebuild.enable = true;
+
};
catppuccin = {
flavor = "mocha";
accent = "mauve";
+2 -6
nixosModules/default-config/nixConfig.nix
···
{
nix = {
enable = true;
-
# We use `nh.clean` instead, so this is disabled
-
gc.automatic = false;
+
gc.automatic = true;
registry = lib.mapAttrs (_: v: { flake = v; }) flakeInputs;
settings = {
# Don't auto-accept flake-defined nix settings, they're a CVE waiting to happen.
···
keep-going = true;
# More direnv gc root stuff
keep-outputs = true;
-
# Show fewer log lines from failed builds since I get them from nh
-
log-lines = 10;
+
log-lines = 20;
# Limit the max amount of builds
max-jobs = lib.mkDefault 4;
# Extra system features
···
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
-
"cache.flakehub.com-3:hJuILl5sVK4iKm86JzgdXW12Y2Hwd5G07qKtHTOcDCM="
];
# Extra substituters
trusted-substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
-
"https://install.determinate.systems"
];
# These users have additional daemon rights
trusted-users = userList;
+2
nixosModules/default-config/nixpkgsConfig.nix
···
nixpkgs = {
overlays = [
inputs.self.overlays.openssh-fixperms
+
inputs.self.overlays.hy3-fixes
inputs.golink.overlays.default
+
inputs.quickshell.overlays.default
];
config = {
allowUnfree = true;
-1
nixosModules/default-config/programs/default.nix
···
{
imports = [
./ssh.nix
-
./nh.nix
];
programs.fish.enable = true;
}
-8
nixosModules/default-config/programs/nh.nix
···
-
{ pkgs, ... }:
-
{
-
programs.nh = {
-
enable = true;
-
clean.enable = true;
-
clean.extraArgs = "-k 5";
-
};
-
}
+8 -5
nixosModules/default-config/security.nix
···
-
{ pkgs, ... }:
+
{ pkgs, lib, ... }:
+
let
+
inherit (lib) mkDefault;
+
in
{
# Everything should use doas instead of sudo
# Sudo is kept enabled for tools that ~can't~ won't use doas.
···
# TPM configuration
tpm2 = {
-
enable = true;
-
abrmd.enable = true;
-
applyUdevRules = true;
-
pkcs11.enable = false;
+
enable = mkDefault true;
+
abrmd.enable = mkDefault true;
+
applyUdevRules = mkDefault true;
+
pkcs11.enable = mkDefault false;
};
# Set up extra certificates for DN42 specifically
+6
nixosModules/default-config/services/default.nix
···
./ntp.nix
./tailscale.nix
];
+
services = {
+
# Perlless user management
+
userborn = {
+
enable = true;
+
};
+
};
}
+2 -2
nixosModules/default-users/default.nix
···
"wireshark"
"input"
];
-
hashedPassword = "$6$6EtuZhVOJdfI9DYP$1Qnd7R8qdN.E5yE2kDQCNg2zgJ5cIjNBKsIW/qJgb8wcKlUpIoVg/fEKvBkAgCiLyojVG2kzfu4J9LR8rA8a2/";
+
hashedPassword = "$y$j9T$Lwu/kwfIYVH6ApPNFv5TL.$xXtWoVxOKDW0xQtw7yf2JGWP3JI6r9WIqV19W0/zrg5";
shell = pkgs.fish;
openssh = {
authorizedKeys = {
···
"wireshark"
"input"
];
-
hashedPassword = "$6$6EtuZhVOJdfI9DYP$1Qnd7R8qdN.E5yE2kDQCNg2zgJ5cIjNBKsIW/qJgb8wcKlUpIoVg/fEKvBkAgCiLyojVG2kzfu4J9LR8rA8a2/";
+
hashedPassword = "$y$j9T$Lwu/kwfIYVH6ApPNFv5TL.$xXtWoVxOKDW0xQtw7yf2JGWP3JI6r9WIqV19W0/zrg5";
shell = pkgs.fish;
openssh = {
authorizedKeys = {
+3 -4
nixosModules/default.nix
···
-
{
-
...
-
}:
-
{
+
_: {
flake.nixosModules = {
# Top-level
defaultConfig = import ./default-config;
defaultUsers = import ./default-users;
profiles = import ./profiles;
+
+
dn42Wireguard = import ./dn42Wireguard;
# Programs
chromium = import ./programs/chromium;
+125
nixosModules/dn42Wireguard/default.nix
···
+
{
+
config,
+
lib,
+
pkgs,
+
...
+
}:
+
let
+
inherit (lib) types;
+
cfg = config.networking.dn42.wg;
+
+
tunnelDef = {
+
options = {
+
enable = lib.mkOption {
+
description = "Whether to enable this wireguard tunnel";
+
type = types.bool;
+
default = true;
+
example = false;
+
};
+
listenPort = lib.mkOption {
+
description = "The port this tunnel listens on";
+
type = types.port;
+
example = 42000;
+
};
+
privateKeyFile = lib.mkOption {
+
description = "Path to the tunnel's private key";
+
type = types.nullOr types.path;
+
example = "/path/to/private/key";
+
default = null;
+
};
+
peerPubKey = lib.mkOption {
+
description = "Public key of the peer you're connecting to";
+
type = types.str;
+
example = "e6kp9sca4XIzncKa9GEQwyOnMjje299Xg9ZdgXWMwHg=";
+
};
+
peerEndpoint = lib.mkOption {
+
description = "The endpoint of the peer you're connecting to";
+
type = types.str;
+
example = "example.com:42000";
+
};
+
peerAddrs = {
+
v4 = lib.mkOption {
+
description = "The peer IPv4 address to connect to in the tunnel";
+
type = types.nullOr types.str;
+
example = "192.168.1.1";
+
default = null;
+
};
+
v6 = lib.mkOption {
+
description = "The peer IPv6 address to connect to in the tunnel";
+
type = types.nullOr types.str;
+
example = "fe80::42";
+
default = null;
+
};
+
};
+
localAddrs = {
+
v4 = lib.mkOption {
+
description = "The local IPv4 address to listen on in the tunnel";
+
type = types.nullOr types.str;
+
example = "192.168.1.1";
+
default = null;
+
};
+
v6 = lib.mkOption {
+
description = "The local IPv6 address to listen on in the tunnel";
+
type = types.nullOr types.str;
+
example = "fe80::42";
+
default = null;
+
};
+
};
+
};
+
};
+
in
+
{
+
options.networking.dn42.wg = {
+
tunnelDefaults = lib.mkOption {
+
description = "The default settings to apply to all tunnels";
+
type = types.submodule tunnelDef;
+
};
+
tunnels = lib.mkOption {
+
description = "DN42 WireGuard tunnels configuration";
+
type = types.attrsOf (types.submodule tunnelDef);
+
};
+
};
+
config.networking = {
+
wireguard.interfaces = lib.mapAttrs' (
+
name: value:
+
let
+
# Merge defaults with tunnel config, right side has priority
+
# so tunnel config overrides defaults
+
fc = cfg.tunnelDefaults // (lib.filterAttrs (_: v: v != null) value);
+
in
+
lib.nameValuePair "wg42_${name}" {
+
inherit (fc) listenPort privateKeyFile;
+
allowedIPsAsRoutes = false;
+
peers = [
+
{
+
endpoint = fc.peerEndpoint;
+
publicKey = fc.peerPubKey;
+
allowedIPs = [
+
"0.0.0.0/0"
+
"::/0"
+
];
+
dynamicEndpointRefreshSeconds = 5;
+
persistentKeepalive = 15;
+
}
+
];
+
postSetup = ''
+
${lib.optionalString (
+
fc.peerAddrs.v4 != null && fc.localAddrs.v4 != null
+
) "${pkgs.iproute2}/bin/ip addr add ${fc.localAddrs.v4} peer ${fc.peerAddrs.v4} dev wg42_${name}"}
+
${lib.optionalString (
+
fc.peerAddrs.v6 != null && fc.localAddrs.v6 != null
+
) "${pkgs.iproute2}/bin/ip addr add ${fc.localAddrs.v6} peer ${fc.peerAddrs.v6} dev wg42_${name}"}
+
'';
+
}
+
) (lib.filterAttrs (_: v: v.enable) cfg.tunnels);
+
firewall = {
+
trustedInterfaces = lib.mapAttrsToList (name: _: "wg42_" + name) (lib.filterAttrs (_: v: v.enable) cfg.tunnels);
+
checkReversePath = false;
+
extraInputRules = ''
+
ip saddr 172.20.0.0/14 accept
+
ip6 saddr fd00::/8 accept
+
ip6 saddr fe80::/64 accept
+
'';
+
};
+
};
+
}
+1 -1
nixosModules/homes/pyrox/default.nix
···
inputs.self.homeModules.allModules
{
home.username = "pyrox";
-
home.stateVersion = "25.11";
+
home.stateVersion = "26.05";
py.profiles.server.enable = lib.mkDefault true;
py.profiles.desktop.enable = lib.mkDefault false;
}
-36
nixosModules/homes/pyrox-zaphod/default.nix
···
pkgs.mindustry
];
py.profiles.desktop.enable = true;
-
py.services.kanshi.settings = [
-
{
-
profile = {
-
name = "laptop-only";
-
outputs = [
-
{
-
criteria = "eDP-1";
-
status = "enable";
-
scale = 1.2;
-
position = "0,0";
-
adaptiveSync = true;
-
}
-
];
-
};
-
}
-
{
-
profile = {
-
name = "office";
-
outputs = [
-
{
-
criteria = "eDP-1";
-
status = "enable";
-
scale = 1.2;
-
position = "0,0";
-
adaptiveSync = true;
-
}
-
{
-
criteria = "Acer Technologies SA241Y 0x1497CF17";
-
status = "enable";
-
scale = 1.0;
-
position = "2160,0";
-
}
-
];
-
};
-
}
-
];
};
}
+1 -1
nixosModules/homes/thehedgehog/default.nix
···
inputs.self.homeModules.allModules
{
home.username = "thehedgehog";
-
home.stateVersion = "25.11";
+
home.stateVersion = "26.05";
py.profiles.server.enable = lib.mkDefault true;
py.profiles.desktop.enable = lib.mkDefault false;
}
+18 -49
nixosModules/homes/thehedgehog-zaphod/default.nix
···
{
pkgs,
-
config,
+
lib,
+
inputs,
+
self',
...
}:
let
-
hmConfig = config.home-manager.users.thehedgehog;
+
shell = "caelestia";
in
{
home-manager.users.thehedgehog = {
home.packages = [
pkgs.mindustry
pkgs.signal-desktop
+
self'.packages.glide-browser-bin
];
-
services.wpaperd = {
+
home.sessionVariables = {
+
QT_QPA_PLATFORM = "wayland;xcb";
+
GDK_BACKEND = "wayland,x11,*";
+
NIXOS_OZONE_WL = "1";
+
};
+
py.profiles.desktop = {
+
inherit shell;
enable = true;
-
settings = {
-
default = {
-
path = "${hmConfig.home.homeDirectory}/bgs/wallpapers";
-
duration = "3h";
-
sorting = "random";
-
queue-size = 50;
-
recursive = true;
-
};
-
};
+
};
+
programs.dankMaterialShell.plugins = lib.mkIf (shell == "dms") {
+
dms-wallpaper-shuffler.src = inputs.dms-wp-shuffler;
+
dms-power-usage.src = inputs.dms-power-usage;
+
DankPomodoroTimer.src = "${inputs.dms-plugins}/DankPomodoroTimer";
+
DankBatteryAlerts.src = "${inputs.dms-plugins}/DankBatteryAlerts";
};
-
py.profiles.desktop.enable = true;
-
py.services.kanshi.settings = [
-
{
-
profile = {
-
name = "laptop-only";
-
outputs = [
-
{
-
criteria = "eDP-1";
-
status = "enable";
-
scale = 1.2;
-
position = "0,0";
-
adaptiveSync = true;
-
}
-
];
-
};
-
}
-
{
-
profile = {
-
name = "office";
-
outputs = [
-
{
-
criteria = "eDP-1";
-
status = "enable";
-
scale = 1.2;
-
position = "0,0";
-
adaptiveSync = true;
-
}
-
{
-
criteria = "Acer Technologies SA241Y 0x1497CF17";
-
status = "enable";
-
scale = 1.0;
-
position = "2160,0";
-
}
-
];
-
};
-
}
-
];
};
}
-2
nixosModules/programs/firefox/extensions.nix
···
"{30280527-c46c-4e03-bb16-2e3ed94fa57c}" = mkAMO "protondb-for-steam";
"redirector@einaregilsson.com" = mkAMO "redirector";
"{a4c4eda4-fb84-4a84-b4a1-f7c1cbf2a1ad}" = mkAMO "refined-github-";
-
"{762f9885-5a13-4abd-9c77-433dcd38b8fd}" = mkAMO "return-youtube-dislikes";
-
"{48748554-4c01-49e8-94af-79662bf34d50}" = mkAMO "privacy-pass";
"sponsorBlocker@ajay.app" = mkAMO "sponsorblock";
"firefox-extension@steamdb.info" = mkAMO "steam-database";
"{7a7a4a92-a2a0-41d1-9fd7-1e92480d612d}" = mkAMO "styl-us" // {
-1
nixosModules/programs/hyprland/default.nix
···
enable = true;
xwayland.enable = true;
};
-
programs.hyprlock.enable = cfg.enable;
};
}
+29 -11
nixosModules/programs/misc/default.nix
···
-
{ config, lib, ... }:
+
{
+
config,
+
lib,
+
pkgs,
+
...
+
}:
let
cfg = config.py.programs;
inherit (lib) mkEnableOption mkIf;
···
steam.enable = mkEnableOption "Steam";
wireshark.enable = mkEnableOption "Wireshark";
};
-
config.programs = {
-
appimage = mkIf cfg.appimage.enable {
-
enable = true;
-
binfmt = true;
+
config = {
+
programs = {
+
appimage = mkIf cfg.appimage.enable {
+
enable = true;
+
binfmt = true;
+
};
+
dconf.enable = mkIf cfg.dconf.enable true;
+
fish.enable = mkIf cfg.fish.enable true;
+
less.enable = mkIf cfg.less.enable true;
+
noisetorch.enable = mkIf cfg.noisetorch.enable true;
+
steam = mkIf cfg.steam.enable {
+
enable = true;
+
protontricks.enable = true;
+
gamescopeSession.enable = true;
+
extraCompatPackages = with pkgs; [
+
steamtinkerlaunch
+
];
+
};
+
wireshark.enable = mkIf cfg.wireshark.enable true;
};
-
dconf.enable = mkIf cfg.dconf.enable true;
-
fish.enable = mkIf cfg.fish.enable true;
-
less.enable = mkIf cfg.less.enable true;
-
noisetorch.enable = mkIf cfg.noisetorch.enable true;
-
steam.enable = mkIf cfg.steam.enable true;
-
wireshark.enable = mkIf cfg.wireshark.enable true;
+
environment.systemPackages = lib.optionals cfg.steam.enable [
+
pkgs.steamtinkerlaunch
+
pkgs.protonplus
+
];
};
}
-1
nixosModules/programs/neovim/default.nix
···
{
-
pkgs,
lib,
config,
...
+1 -3
nixosModules/services/forgejo-runner/default.nix
···
};
cache = {
enabled = true;
-
dir = "/var/lib/forgejo/runners/cache/";
-
host = "";
port = 0;
};
container = {
···
};
config.services.gitea-actions-runner = lib.mkIf cfg.enable {
-
package = pkgs.forgejo-actions-runner;
+
package = pkgs.forgejo-runner;
instances = {
"${config.networking.hostName}-default" = runnerBase // {
inherit (cfg) tokenFile;
+4
optnix.toml
···
+
[scopes.flake-parts]
+
description = "flake-parts config"
+
options-list-cmd = "nix eval --json .#debug.options-doc"
+
evaluator = "nix eval .#debug.config.{{ .Option }}"
+1 -1
overlays/cinny/default.nix
···
-
_: final: prev: {
+
_: _final: prev: {
cinny-unwrapped = prev.cinny-unwrapped.overrideAttrs (old: {
patches = (old.patches or [ ]) ++ [ ./nix-commands.patch ];
});
+1
overlays/default.nix
···
flake.overlays = {
cinny = import ./cinny;
openssh-fixperms = import ./openssh-fixperms;
+
hy3-fixes = import ./hy3-fixes;
};
}
+12
overlays/hy3-fixes/default.nix
···
+
_final: prev: {
+
hyprlandPlugins = prev.hyprlandPlugins // {
+
hy3 = prev.hyprlandPlugins.hy3.overrideAttrs (old: {
+
patches = (old.patches or [ ]) ++ [
+
(prev.fetchpatch {
+
url = "https://github.com/outfoxxed/hy3/commit/8a3f46a40984e74094f71b5bd38df3dbe5daa97f.patch?full_index=1";
+
hash = "sha256-zNGCMcidRx7zV3mnlQT4EjA36g7MeBf6A9gyvITeZ4c=";
+
})
+
];
+
});
+
};
+
}
-2
overlays/nix-index/default.nix
···
-
# deadnix: skip
-
{ inputs, ... }: final: prev: { inherit (inputs.nix-index.packages.${prev.system}) nix-index; }
+1 -1
overlays/openssh-fixperms/default.nix
···
-
final: prev: {
+
_final: prev: {
openssh-patched = prev.openssh.overrideAttrs (old: {
patches = (old.patches or [ ]) ++ [ ./permfix.patch ];
doCheck = false;
-20
packages/anubis-files/default.nix
···
-
{
-
stdenv,
-
...
-
}:
-
stdenv.mkDerivation {
-
pname = "pyronet-anubis-files";
-
version = "1.0.0";
-
-
src = ./src;
-
-
buildPhase = ''
-
substituteInPlace policies/*.yaml \
-
--replace-fail "CUSTOM" $out/rules
-
'';
-
-
installPhase = ''
-
mkdir $out
-
cp -r * $out/
-
'';
-
}
+20
packages/anubis-files/package.nix
···
+
{
+
stdenv,
+
...
+
}:
+
stdenv.mkDerivation {
+
pname = "pyronet-anubis-files";
+
version = "1.0.0";
+
+
src = ./src;
+
+
buildPhase = ''
+
substituteInPlace policies/*.yaml \
+
--replace-fail "CUSTOM" $out
+
'';
+
+
installPhase = ''
+
mkdir $out
+
cp -r * $out/
+
'';
+
}
+56
packages/anubis-files/src/policies/default.yaml
···
+
bots:
+
- import: CUSTOM/policies/meta/base.yaml
+
dnsbl: false
+
openGraph:
+
enabled: true
+
considerHost: false
+
ttl: 24h
+
status_codes:
+
CHALLENGE: 200
+
DENY: 200
+
thresholds:
+
- name: minimal-suspicion
+
expression: weight <= 0
+
action: ALLOW
+
- name: mild-suspicion
+
expression:
+
all:
+
- weight > 0
+
- weight < 10
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/metarefresh
+
algorithm: metarefresh
+
difficulty: 1
+
report_as: 1
+
- name: moderate-suspicion
+
expression:
+
all:
+
- weight >= 10
+
- weight < 20
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 2 # two leading zeros, very fast for most clients
+
report_as: 2
+
- name: mild-proof-of-work
+
expression:
+
all:
+
- weight >= 20
+
- weight < 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 4
+
report_as: 4
+
# For clients that are browser like and have gained many points from custom rules
+
- name: extreme-suspicion
+
expression: weight >= 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 6
+
report_as: 5
+59 -6
packages/anubis-files/src/policies/forgejo.yaml
···
bots:
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
+
- import: CUSTOM/policies/meta/base.yaml
- import: (data)/clients/git.yaml
-
- import: (data)/common/keep-internet-working.yaml
- import: (data)/apps/gitea-rss-feeds.yaml
-
- import: (data)/crawlers/internet-archive.yaml
-
- import: (data)/crawlers/kagibot.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
+
+
# Allow forgejo runner connections from localhost and tailscale
+
- name: forgejo-runner
+
user_agent_regex: connect-go
+
action: ALLOW
dnsbl: false
+
openGraph:
+
enabled: true
+
considerHost: false
+
ttl: 24h
+
status_codes:
+
CHALLENGE: 200
+
DENY: 200
+
thresholds:
+
- name: minimal-suspicion
+
expression: weight <= 0
+
action: ALLOW
+
- name: mild-suspicion
+
expression:
+
all:
+
- weight > 0
+
- weight < 10
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/metarefresh
+
algorithm: metarefresh
+
difficulty: 1
+
report_as: 1
+
- name: moderate-suspicion
+
expression:
+
all:
+
- weight >= 10
+
- weight < 20
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 2 # two leading zeros, very fast for most clients
+
report_as: 2
+
- name: mild-proof-of-work
+
expression:
+
all:
+
- weight >= 20
+
- weight < 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 4
+
report_as: 4
+
# For clients that are browser like and have gained many points from custom rules
+
- name: extreme-suspicion
+
expression: weight >= 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 6
+
report_as: 5
-7
packages/anubis-files/src/policies/grafana.yaml
···
-
bots:
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
-
- import: (data)/common/keep-internet-working.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
-
-
dnsbl: false
+54
packages/anubis-files/src/policies/meta/base.yaml
···
+
# keep-sorted start
+
- import: (data)/bots/_deny-pathological.yaml
+
- import: (data)/bots/aggressive-brazilian-scrapers.yaml
+
- import: (data)/clients/x-firefox-ai.yaml
+
- import: (data)/common/keep-internet-working.yaml
+
- import: (data)/common/rfc-violations.yaml
+
- import: (data)/crawlers/_allow-good.yaml
+
- import: (data)/meta/ai-block-aggressive.yaml
+
# keep-sorted end
+
- name: realistic-browser-catchall
+
expression:
+
all:
+
- '"User-Agent" in headers'
+
- '( userAgent.contains("Firefox") ) || ( userAgent.contains("Chrome") ) || ( userAgent.contains("Safari") )'
+
- '"Accept" in headers'
+
- '"Sec-Fetch-Dest" in headers'
+
- '"Sec-Fetch-Mode" in headers'
+
- '"Sec-Fetch-Site" in headers'
+
- '"Accept-Encoding" in headers'
+
- '( headers["Accept-Encoding"].contains("zstd") || headers["Accept-Encoding"].contains("br") )'
+
- '"Accept-Language" in headers'
+
action: WEIGH
+
weight:
+
adjust: -10
+
# The Upgrade-Insecure-Requests header is typically sent by browsers, but not always
+
- name: upgrade-insecure-requests
+
expression: '"Upgrade-Insecure-Requests" in headers'
+
action: WEIGH
+
weight:
+
adjust: -2
+
# Chrome should behave like Chrome
+
- name: chrome-is-proper
+
expression:
+
all:
+
- userAgent.contains("Chrome")
+
- '"Sec-Ch-Ua" in headers'
+
- 'headers["Sec-Ch-Ua"].contains("Chromium")'
+
- '"Sec-Ch-Ua-Mobile" in headers'
+
- '"Sec-Ch-Ua-Platform" in headers'
+
action: WEIGH
+
weight:
+
adjust: -5
+
- name: should-have-accept
+
expression: '!("Accept" in headers)'
+
action: WEIGH
+
weight:
+
adjust: 5
+
# Generic catchall rule
+
- name: generic-browser
+
user_agent_regex: >-
+
Mozilla|Opera|Chrome|Chromium
+
action: WEIGH
+
weight:
+
adjust: 10
packages/anubis-files/src/policies/meta/openGraph.yaml

This is a binary file and will not be displayed.

-7
packages/anubis-files/src/policies/miniflux.yaml
···
-
bots:
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
-
- import: (data)/common/keep-internet-working.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
-
-
dnsbl: false
+50 -7
packages/anubis-files/src/policies/nextcloud-office.yaml
···
bots:
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
-
+
- import: CUSTOM/policies/meta/base.yaml
# Allow requests from the nextcloud server to bypass checks
- name: allow-nextcloud-server
user_agent_regex: ^Nextcloud Server / richdocuments$
action: ALLOW
-
-
- import: (data)/common/keep-internet-working.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
-
dnsbl: false
+
status_codes:
+
CHALLENGE: 200
+
DENY: 200
+
thresholds:
+
- name: minimal-suspicion
+
expression: weight <= 0
+
action: ALLOW
+
- name: mild-suspicion
+
expression:
+
all:
+
- weight > 0
+
- weight < 10
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/metarefresh
+
algorithm: metarefresh
+
difficulty: 1
+
report_as: 1
+
- name: moderate-suspicion
+
expression:
+
all:
+
- weight >= 10
+
- weight < 20
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 2 # two leading zeros, very fast for most clients
+
report_as: 2
+
- name: mild-proof-of-work
+
expression:
+
all:
+
- weight >= 20
+
- weight < 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 4
+
report_as: 4
+
# For clients that are browser like and have gained many points from custom rules
+
- name: extreme-suspicion
+
expression: weight >= 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 6
+
report_as: 5
+54 -12
packages/anubis-files/src/policies/nextcloud.yaml
···
bots:
-
# Block scrapers and abusive cloud providers
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
-
+
- import: CUSTOM/policies/meta/base.yaml
# Allow android apps that I use
- name: allow-android-apps
user_agent_regex: Nextcloud-android|DAVx5|ICSx5
action: ALLOW
-
# Allow the Thunderbird Filelink app
- name: allow-thunderbird-filelink
user_agent_regex: ^Filelink for \*cloud.*$
action: ALLOW
-
# Allow anyone accessing the **authenticated** DAV endpoint.
- name: allow-dav
path_regex: ^/remote.php/dav/.*$
action: ALLOW
-
# Allow public shares so that I can more easily send them
- name: allow-public-shares
path_regex: ^/s/.*$
action: ALLOW
-
# Allow clients to load assets to not break public shares
- name: allow-assets
action: ALLOW
···
- 'path.startsWith("/apps/theming/")'
# Public DAV endpoint
- 'path.startsWith("/public.php/dav/files/")'
-
-
- import: (data)/common/keep-internet-working.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
-
dnsbl: false
+
openGraph:
+
enabled: true
+
considerHost: false
+
ttl: 24h
+
status_codes:
+
CHALLENGE: 200
+
DENY: 200
+
thresholds:
+
- name: minimal-suspicion
+
expression: weight <= 0
+
action: ALLOW
+
- name: mild-suspicion
+
expression:
+
all:
+
- weight > 0
+
- weight < 10
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/metarefresh
+
algorithm: metarefresh
+
difficulty: 1
+
report_as: 1
+
- name: moderate-suspicion
+
expression:
+
all:
+
- weight >= 10
+
- weight < 20
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 2 # two leading zeros, very fast for most clients
+
report_as: 2
+
- name: mild-proof-of-work
+
expression:
+
all:
+
- weight >= 20
+
- weight < 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 4
+
report_as: 4
+
# For clients that are browser like and have gained many points from custom rules
+
- name: extreme-suspicion
+
expression: weight >= 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 6
+
report_as: 5
-7
packages/anubis-files/src/policies/pingvin-share.yaml
···
-
bots:
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
-
- import: (data)/common/keep-internet-working.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
-
-
dnsbl: false
-7
packages/anubis-files/src/policies/planka.yaml
···
-
bots:
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
-
- import: (data)/common/keep-internet-working.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
-
-
dnsbl: false
-7
packages/anubis-files/src/policies/pocket-id.yaml
···
-
bots:
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
-
- import: (data)/common/keep-internet-working.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
-
-
dnsbl: false
+54 -7
packages/anubis-files/src/policies/vaultwarden.yaml
···
bots:
-
- import: (data)/bots/ai-robots-txt.yaml
-
- import: CUSTOM/block/alibaba-cloud.yaml
-
+
- import: CUSTOM/policies/meta/base.yaml
# Allow bitwarden apps
- name: allow-bitwarden-mobile
user_agent_regex: Bitwarden_Mobile
···
- name: allow-bitwarden-webext
user_agent_regex: Mozilla
action: ALLOW
-
-
- import: (data)/common/keep-internet-working.yaml
-
- import: CUSTOM/challenge/generic-browser.yaml
-
dnsbl: false
+
openGraph:
+
enabled: true
+
considerHost: false
+
ttl: 24h
+
status_codes:
+
CHALLENGE: 200
+
DENY: 200
+
thresholds:
+
- name: minimal-suspicion
+
expression: weight <= 0
+
action: ALLOW
+
- name: mild-suspicion
+
expression:
+
all:
+
- weight > 0
+
- weight < 10
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/metarefresh
+
algorithm: metarefresh
+
difficulty: 1
+
report_as: 1
+
- name: moderate-suspicion
+
expression:
+
all:
+
- weight >= 10
+
- weight < 20
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 2 # two leading zeros, very fast for most clients
+
report_as: 2
+
- name: mild-proof-of-work
+
expression:
+
all:
+
- weight >= 20
+
- weight < 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 4
+
report_as: 4
+
# For clients that are browser like and have gained many points from custom rules
+
- name: extreme-suspicion
+
expression: weight >= 30
+
action: CHALLENGE
+
challenge:
+
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
+
algorithm: fast
+
difficulty: 6
+
report_as: 5
-828
packages/anubis-files/src/rules/block/alibaba-cloud.yaml
···
-
- name: alibaba-cloud
-
action: DENY
-
remote_addresses:
-
[
-
"45.196.28.0/24",
-
"161.117.128.0/17",
-
"8.209.42.0/23",
-
"47.89.125.0/24",
-
"8.222.48.0/20",
-
"47.79.16.0/21",
-
"149.129.16.0/23",
-
"8.212.0.0/17",
-
"47.89.0.0/19",
-
"47.240.128.0/17",
-
"8.213.176.0/20",
-
"47.77.8.0/22",
-
"47.79.96.0/19",
-
"47.246.198.0/23",
-
"47.91.128.0/17",
-
"47.89.104.0/21",
-
"47.89.102.0/24",
-
"8.222.96.0/19",
-
"170.33.31.0/24",
-
"8.215.168.0/24",
-
"8.222.40.0/21",
-
"47.235.1.0/24",
-
"240b:400f::/32",
-
"170.33.32.0/24",
-
"8.208.0.0/18",
-
"47.79.24.0/21",
-
"47.91.16.0/20",
-
"47.252.0.0/17",
-
"8.213.176.0/21",
-
"8.212.0.0/18",
-
"8.211.192.0/18",
-
"47.79.54.0/23",
-
"47.235.18.0/24",
-
"47.88.0.0/17",
-
"43.96.21.0/24",
-
"47.235.22.0/24",
-
"240b:4001::/33",
-
"47.79.64.0/20",
-
"139.95.4.0/23",
-
"47.254.128.0/19",
-
"47.81.64.0/18",
-
"47.77.128.0/18",
-
"240b:4009::/33",
-
"47.246.90.0/23",
-
"47.89.32.0/19",
-
"205.204.125.0/24",
-
"47.79.56.0/23",
-
"240b:400c:100::/41",
-
"47.235.26.0/23",
-
"8.209.64.0/19",
-
"8.222.16.0/20",
-
"47.235.12.0/23",
-
"116.251.64.0/18",
-
"139.95.64.0/24",
-
"47.235.31.0/24",
-
"8.208.32.0/19",
-
"240b:400c:f00::/48",
-
"47.235.6.0/24",
-
"47.246.160.0/21",
-
"47.246.196.0/22",
-
"2404:2280:3000::/37",
-
"47.74.0.0/21",
-
"240b:4007:8000::/33",
-
"47.91.0.0/20",
-
"2400:3200:baba::/48",
-
"198.11.137.0/24",
-
"47.84.168.0/21",
-
"240b:4006:1020::/44",
-
"149.129.192.0/18",
-
"8.219.40.0/21",
-
"43.96.3.0/24",
-
"240b:4004::/32",
-
"47.77.64.0/20",
-
"47.83.48.0/21",
-
"47.77.104.0/21",
-
"240b:4001:8000::/33",
-
"43.96.5.0/24",
-
"240b:400c:180::/41",
-
"43.96.25.0/24",
-
"47.77.96.0/21",
-
"8.211.160.0/19",
-
"47.245.32.0/19",
-
"8.215.0.0/16",
-
"47.79.32.0/20",
-
"8.213.160.0/21",
-
"47.74.0.0/19",
-
"43.96.4.0/24",
-
"170.33.75.0/24",
-
"8.211.128.0/18",
-
"8.217.0.0/16",
-
"47.81.0.0/19",
-
"47.82.96.0/19",
-
"47.83.56.0/21",
-
"203.107.64.0/24",
-
"240b:4006:1020::/45",
-
"240b:4004::/33",
-
"47.242.0.0/15",
-
"47.80.128.0/17",
-
"8.215.0.0/17",
-
"240b:4000::/32",
-
"47.246.192.0/23",
-
"47.246.176.0/21",
-
"8.212.224.0/19",
-
"47.90.0.0/17",
-
"170.33.107.0/24",
-
"47.237.32.0/20",
-
"47.240.0.0/16",
-
"47.253.0.0/16",
-
"161.117.0.0/16",
-
"47.77.12.0/22",
-
"47.88.128.0/17",
-
"8.220.147.0/24",
-
"47.236.0.0/16",
-
"149.129.192.0/19",
-
"170.33.73.0/24",
-
"47.87.160.0/19",
-
"47.79.0.0/20",
-
"47.246.153.0/24",
-
"47.235.29.0/24",
-
"47.81.128.0/18",
-
"43.96.35.0/24",
-
"8.212.128.0/18",
-
"8.219.0.0/16",
-
"47.246.155.0/24",
-
"8.216.64.0/18",
-
"8.213.253.0/24",
-
"8.220.116.0/24",
-
"8.222.128.0/18",
-
"240b:400e:8000::/33",
-
"43.96.33.0/24",
-
"47.77.192.0/18",
-
"47.81.32.0/19",
-
"47.77.8.0/21",
-
"47.79.16.0/20",
-
"240b:400f:8000::/33",
-
"47.246.145.0/24",
-
"47.88.128.0/18",
-
"170.33.104.0/24",
-
"8.219.0.0/17",
-
"47.82.0.0/18",
-
"139.95.10.0/23",
-
"47.238.0.0/16",
-
"240b:4006:1002::/47",
-
"8.221.188.0/22",
-
"8.213.251.0/24",
-
"47.254.192.0/19",
-
"47.79.32.0/21",
-
"8.212.128.0/19",
-
"47.246.83.0/24",
-
"47.87.64.0/19",
-
"8.222.192.0/18",
-
"170.33.68.0/24",
-
"240b:400c:f01::/48",
-
"170.33.136.0/24",
-
"2400:b200:4101::/48",
-
"2401:8680:4100::/48",
-
"240b:400c::/32",
-
"47.89.92.0/22",
-
"8.223.128.0/18",
-
"47.89.124.0/23",
-
"47.74.32.0/19",
-
"47.244.0.0/17",
-
"43.96.80.0/24",
-
"8.211.104.0/21",
-
"8.213.224.0/19",
-
"47.86.0.0/17",
-
"8.222.64.0/21",
-
"240b:400e::/33",
-
"161.117.143.0/24",
-
"47.246.152.0/23",
-
"47.246.93.0/24",
-
"240b:4006:1010::/45",
-
"47.254.224.0/19",
-
"8.209.40.0/22",
-
"149.129.64.0/18",
-
"43.96.20.0/24",
-
"240b:4000:8000::/33",
-
"47.251.0.0/16",
-
"240b:4002::/32",
-
"8.222.16.0/21",
-
"203.107.66.0/24",
-
"8.222.24.0/21",
-
"47.89.128.0/19",
-
"240b:400c:8000::/33",
-
"8.218.128.0/17",
-
"8.216.128.0/17",
-
"47.91.128.0/18",
-
"8.221.64.0/18",
-
"2404:2280:4000::/36",
-
"8.211.80.0/21",
-
"8.217.128.0/17",
-
"8.220.229.0/24",
-
"170.33.66.0/24",
-
"47.237.0.0/16",
-
"47.235.28.0/23",
-
"170.33.74.0/24",
-
"47.90.64.0/18",
-
"47.246.82.0/23",
-
"8.209.38.0/23",
-
"240b:4005:8000::/33",
-
"8.220.128.0/18",
-
"139.95.14.0/23",
-
"8.216.192.0/18",
-
"8.218.0.0/16",
-
"47.91.192.0/18",
-
"8.221.48.0/21",
-
"149.129.8.0/21",
-
"43.91.0.0/16",
-
"8.223.64.0/18",
-
"8.216.148.0/24",
-
"8.222.80.0/21",
-
"2401:b180:4100::/48",
-
"47.91.0.0/19",
-
"47.246.154.0/24",
-
"47.246.152.0/24",
-
"47.250.64.0/18",
-
"8.216.128.0/18",
-
"170.33.72.0/24",
-
"139.95.12.0/23",
-
"240b:400c::/40",
-
"8.221.128.0/18",
-
"43.96.32.0/24",
-
"47.90.128.0/17",
-
"47.251.0.0/17",
-
"43.96.34.0/24",
-
"47.245.0.0/18",
-
"47.85.112.0/23",
-
"8.209.56.0/21",
-
"8.213.252.0/24",
-
"47.77.128.0/17",
-
"139.95.2.0/23",
-
"43.96.69.0/24",
-
"161.117.126.0/24",
-
"47.75.0.0/16",
-
"47.89.82.0/23",
-
"47.89.224.0/19",
-
"8.209.0.0/20",
-
"47.246.128.0/22",
-
"8.221.0.0/21",
-
"139.95.8.0/23",
-
"47.253.128.0/17",
-
"156.236.12.0/24",
-
"203.107.65.0/24",
-
"47.241.128.0/17",
-
"8.222.88.0/21",
-
"47.87.128.0/18",
-
"47.254.128.0/18",
-
"8.221.192.0/18",
-
"240b:4001::/32",
-
"47.235.16.0/24",
-
"240b:4007::/32",
-
"47.235.13.0/24",
-
"47.235.24.0/23",
-
"47.91.80.0/20",
-
"43.96.11.0/24",
-
"47.235.5.0/24",
-
"8.209.160.0/19",
-
"47.246.88.0/23",
-
"47.77.4.0/22",
-
"156.236.17.0/24",
-
"8.209.224.0/19",
-
"14.1.115.0/24",
-
"149.129.96.0/19",
-
"47.254.192.0/18",
-
"47.245.192.0/18",
-
"8.208.0.0/16",
-
"47.83.0.0/16",
-
"47.87.96.0/19",
-
"47.252.64.0/18",
-
"47.89.192.0/18",
-
"47.89.122.0/24",
-
"47.85.114.0/23",
-
"2404:2280:1000::/36",
-
"47.81.128.0/17",
-
"47.246.147.0/24",
-
"47.87.64.0/18",
-
"47.235.9.0/24",
-
"47.52.0.0/17",
-
"47.246.156.0/22",
-
"47.246.96.0/22",
-
"47.74.0.0/18",
-
"8.214.0.0/17",
-
"47.246.192.0/22",
-
"47.246.150.0/24",
-
"43.91.0.0/17",
-
"170.33.138.0/24",
-
"8.213.0.0/18",
-
"47.90.192.0/18",
-
"47.85.0.0/16",
-
"47.235.24.0/22",
-
"47.235.16.0/23",
-
"47.85.128.0/17",
-
"103.81.186.0/23",
-
"8.221.0.0/18",
-
"43.96.7.0/24",
-
"47.79.56.0/21",
-
"240b:4013::/32",
-
"47.89.108.0/22",
-
"47.235.28.0/24",
-
"47.246.82.0/24",
-
"47.91.48.0/20",
-
"185.78.106.0/23",
-
"47.84.160.0/21",
-
"140.205.1.0/24",
-
"47.88.43.0/24",
-
"47.83.32.0/21",
-
"47.91.64.0/19",
-
"43.96.100.0/24",
-
"43.96.72.0/24",
-
"47.87.0.0/18",
-
"8.210.0.0/16",
-
"47.88.192.0/18",
-
"47.88.42.0/24",
-
"170.33.92.0/24",
-
"149.129.32.0/19",
-
"47.52.128.0/17",
-
"47.246.108.0/22",
-
"8.221.56.0/21",
-
"47.253.0.0/17",
-
"110.76.23.0/24",
-
"170.33.65.0/24",
-
"240b:4006::/48",
-
"47.245.0.0/19",
-
"47.77.64.0/19",
-
"8.209.39.0/24",
-
"47.77.96.0/20",
-
"47.80.128.0/18",
-
"170.33.83.0/24",
-
"47.77.32.0/19",
-
"8.212.64.0/18",
-
"43.96.40.0/24",
-
"2400:b200:4102::/48",
-
"43.96.81.0/24",
-
"8.214.0.0/16",
-
"161.117.128.0/24",
-
"43.96.75.0/24",
-
"8.215.160.0/24",
-
"47.77.0.0/22",
-
"47.239.0.0/16",
-
"47.89.76.0/22",
-
"47.82.14.0/23",
-
"43.91.128.0/17",
-
"47.89.88.0/22",
-
"47.79.8.0/21",
-
"240b:4004:8000::/33",
-
"47.246.140.0/22",
-
"43.96.74.0/24",
-
"161.117.127.0/24",
-
"8.212.192.0/19",
-
"240b:4006:1000::/44",
-
"47.80.192.0/18",
-
"47.79.48.0/21",
-
"47.254.64.0/18",
-
"47.246.144.0/23",
-
"47.246.92.0/24",
-
"47.246.66.0/24",
-
"47.246.150.0/23",
-
"47.91.96.0/20",
-
"47.89.98.0/23",
-
"47.77.80.0/20",
-
"8.210.240.0/24",
-
"8.213.0.0/17",
-
"47.250.99.0/24",
-
"47.88.41.0/24",
-
"47.80.32.0/19",
-
"47.250.0.0/17",
-
"43.96.8.0/24",
-
"14.1.112.0/22",
-
"240b:4006:1008::/45",
-
"8.211.224.0/19",
-
"47.84.144.0/21",
-
"47.88.109.0/24",
-
"2400:3200::/48",
-
"47.56.0.0/16",
-
"8.220.192.0/18",
-
"8.223.0.0/17",
-
"8.222.72.0/21",
-
"47.246.69.0/24",
-
"240b:4002:8000::/33",
-
"43.96.66.0/24",
-
"47.246.92.0/23",
-
"47.246.136.0/22",
-
"205.204.117.0/24",
-
"8.222.80.0/20",
-
"47.85.112.0/22",
-
"47.79.128.0/19",
-
"240b:400d:8000::/33",
-
"170.33.64.0/24",
-
"8.222.56.0/21",
-
"240b:400d::/33",
-
"8.222.64.0/20",
-
"47.75.128.0/17",
-
"8.209.48.0/21",
-
"47.57.0.0/16",
-
"139.95.0.0/23",
-
"47.79.192.0/18",
-
"170.33.30.0/24",
-
"47.77.152.0/21",
-
"8.212.192.0/18",
-
"8.213.128.0/19",
-
"47.77.6.0/23",
-
"47.246.32.0/22",
-
"140.205.122.0/24",
-
"47.244.0.0/16",
-
"47.246.158.0/23",
-
"8.209.192.0/19",
-
"170.33.77.0/24",
-
"8.216.69.0/24",
-
"8.213.192.0/19",
-
"47.77.16.0/22",
-
"47.235.10.0/24",
-
"202.144.199.0/24",
-
"47.254.0.0/17",
-
"43.98.128.0/17",
-
"240b:400c::/41",
-
"47.250.128.0/17",
-
"47.89.101.0/24",
-
"47.90.128.0/18",
-
"240b:4013:8000::/33",
-
"8.209.44.0/23",
-
"240b:400c:80::/41",
-
"161.117.129.0/24",
-
"47.91.64.0/20",
-
"8.209.36.0/24",
-
"8.221.8.0/21",
-
"47.82.32.0/19",
-
"47.77.4.0/23",
-
"47.79.72.0/21",
-
"8.212.160.0/19",
-
"170.33.80.0/24",
-
"47.246.156.0/23",
-
"8.220.192.0/19",
-
"47.246.68.0/24",
-
"47.254.160.0/19",
-
"47.82.56.0/21",
-
"8.223.128.0/17",
-
"47.74.128.0/18",
-
"47.77.24.0/23",
-
"170.33.93.0/24",
-
"47.89.72.0/23",
-
"47.84.152.0/21",
-
"240b:400e::/32",
-
"149.129.224.0/19",
-
"2400:b200:4103::/48",
-
"47.87.32.0/19",
-
"47.86.0.0/16",
-
"47.235.4.0/24",
-
"139.95.6.0/23",
-
"47.252.67.0/24",
-
"47.246.123.0/24",
-
"47.81.96.0/19",
-
"43.96.10.0/24",
-
"8.223.0.0/18",
-
"240b:4005::/32",
-
"47.246.130.0/23",
-
"47.91.96.0/19",
-
"240b:400b::/33",
-
"47.246.132.0/23",
-
"8.213.184.0/21",
-
"47.246.124.0/24",
-
"8.209.64.0/18",
-
"2404:2280:3000::/36",
-
"47.89.78.0/23",
-
"47.250.128.0/18",
-
"47.79.128.0/20",
-
"240b:4011::/33",
-
"47.244.128.0/17",
-
"47.246.151.0/24",
-
"8.211.226.0/24",
-
"47.88.135.0/24",
-
"47.80.0.0/18",
-
"43.96.88.0/24",
-
"47.235.6.0/23",
-
"205.204.111.0/24",
-
"240b:4006:1000::/45",
-
"47.250.0.0/18",
-
"47.89.76.0/23",
-
"47.89.99.0/24",
-
"8.211.0.0/17",
-
"47.89.123.0/24",
-
"8.209.128.0/19",
-
"47.246.160.0/20",
-
"43.99.0.0/16",
-
"47.236.0.0/15",
-
"240b:400e:fffe::/48",
-
"47.80.96.0/19",
-
"47.246.184.0/21",
-
"47.235.8.0/24",
-
"8.222.48.0/21",
-
"47.89.94.0/23",
-
"47.245.64.0/18",
-
"47.77.128.0/21",
-
"47.74.192.0/18",
-
"2404:2280:4000::/37",
-
"8.211.88.0/21",
-
"8.213.192.0/18",
-
"8.223.192.0/18",
-
"240b:4002::/33",
-
"149.129.64.0/19",
-
"47.241.0.0/16",
-
"240b:4006:1018::/45",
-
"8.216.0.0/17",
-
"149.129.0.0/21",
-
"47.254.0.0/18",
-
"8.220.64.0/18",
-
"43.96.22.0/24",
-
"170.33.33.0/24",
-
"47.91.32.0/19",
-
"47.246.76.0/22",
-
"47.246.68.0/23",
-
"47.246.146.0/23",
-
"47.254.113.0/24",
-
"47.89.128.0/18",
-
"47.77.144.0/21",
-
"47.89.104.0/22",
-
"8.211.96.0/21",
-
"47.80.0.0/19",
-
"47.246.104.0/22",
-
"47.80.64.0/18",
-
"161.117.0.0/17",
-
"170.33.88.0/24",
-
"47.77.2.0/23",
-
"47.241.0.0/17",
-
"47.79.224.0/19",
-
"170.33.105.0/24",
-
"47.82.12.0/23",
-
"47.246.146.0/24",
-
"8.213.144.0/20",
-
"43.99.0.0/17",
-
"47.89.88.0/23",
-
"8.220.64.0/19",
-
"47.89.90.0/23",
-
"47.235.19.0/24",
-
"8.215.128.0/17",
-
"47.235.21.0/24",
-
"47.81.192.0/18",
-
"8.211.0.0/18",
-
"47.246.72.0/22",
-
"8.211.64.0/18",
-
"203.107.68.0/24",
-
"59.82.136.0/23",
-
"8.209.44.0/22",
-
"8.209.36.0/23",
-
"47.89.0.0/18",
-
"8.216.0.0/18",
-
"47.246.104.0/21",
-
"240b:400b::/32",
-
"47.246.72.0/21",
-
"8.214.128.0/17",
-
"8.209.48.0/20",
-
"170.33.86.0/24",
-
"110.76.21.0/24",
-
"8.209.128.0/18",
-
"8.222.96.0/20",
-
"47.89.100.0/24",
-
"47.89.192.0/19",
-
"8.213.128.0/20",
-
"2400:b200:4100::/48",
-
"8.208.0.0/17",
-
"170.33.90.0/24",
-
"47.83.0.0/17",
-
"240b:400c:100::/40",
-
"170.33.82.0/24",
-
"8.222.32.0/21",
-
"47.246.86.0/23",
-
"47.52.0.0/16",
-
"47.79.192.0/19",
-
"2404:2280:1800::/37",
-
"8.222.112.0/20",
-
"170.33.24.0/24",
-
"47.89.92.0/23",
-
"47.78.0.0/17",
-
"47.84.0.0/16",
-
"240b:400b:8000::/33",
-
"8.209.38.0/24",
-
"47.235.7.0/24",
-
"47.235.23.0/24",
-
"47.237.34.0/24",
-
"47.79.144.0/20",
-
"43.96.71.0/24",
-
"5.181.224.0/23",
-
"47.246.88.0/22",
-
"47.246.96.0/21",
-
"47.82.0.0/19",
-
"8.209.40.0/23",
-
"47.77.48.0/20",
-
"8.209.16.0/20",
-
"240b:4009::/32",
-
"47.246.176.0/20",
-
"47.250.192.0/18",
-
"47.246.168.0/21",
-
"47.89.160.0/19",
-
"8.222.32.0/20",
-
"223.5.5.0/24",
-
"47.81.0.0/18",
-
"47.89.96.0/24",
-
"47.77.0.0/23",
-
"43.96.24.0/24",
-
"8.221.128.0/17",
-
"47.246.144.0/24",
-
"47.246.125.0/24",
-
"240b:400e:ffff::/48",
-
"47.84.0.0/17",
-
"170.33.106.0/24",
-
"156.227.20.0/24",
-
"170.33.35.0/24",
-
"240b:4006:1028::/45",
-
"170.33.78.0/24",
-
"198.11.128.0/18",
-
"8.210.0.0/17",
-
"47.83.40.0/21",
-
"47.89.80.0/23",
-
"43.98.0.0/16",
-
"47.88.0.0/18",
-
"47.89.74.0/23",
-
"43.96.67.0/24",
-
"47.79.48.0/20",
-
"2404:2280:3800::/37",
-
"47.235.11.0/24",
-
"8.220.160.0/19",
-
"43.96.84.0/24",
-
"8.221.208.0/21",
-
"139.95.18.0/23",
-
"47.246.84.0/22",
-
"47.77.16.0/21",
-
"170.33.69.0/24",
-
"47.78.128.0/17",
-
"8.220.96.0/19",
-
"8.209.0.0/19",
-
"240b:400d::/32",
-
"205.204.102.0/23",
-
"47.87.128.0/19",
-
"47.83.128.0/17",
-
"8.218.0.0/17",
-
"47.235.10.0/23",
-
"8.208.128.0/17",
-
"170.33.137.0/24",
-
"8.209.37.0/24",
-
"8.220.128.0/19",
-
"47.79.112.0/20",
-
"47.243.0.0/16",
-
"47.246.196.0/23",
-
"170.33.79.0/24",
-
"47.252.0.0/18",
-
"47.87.0.0/19",
-
"2404:2280:2000::/36",
-
"47.79.58.0/23",
-
"170.33.34.0/24",
-
"47.246.132.0/22",
-
"240b:4012::/48",
-
"47.91.112.0/20",
-
"47.77.32.0/20",
-
"240b:4005::/33",
-
"8.222.8.0/21",
-
"47.246.194.0/23",
-
"2404:2280:1000::/37",
-
"8.221.200.0/21",
-
"43.96.23.0/24",
-
"47.82.64.0/18",
-
"147.139.128.0/17",
-
"8.211.192.0/19",
-
"47.251.128.0/17",
-
"240b:4011::/32",
-
"8.222.0.0/20",
-
"47.235.12.0/24",
-
"43.99.128.0/17",
-
"47.246.80.0/24",
-
"47.246.67.0/24",
-
"47.246.122.0/24",
-
"156.245.1.0/24",
-
"8.210.128.0/17",
-
"8.213.64.0/18",
-
"45.199.179.0/24",
-
"47.235.0.0/22",
-
"47.246.136.0/21",
-
"8.213.164.0/22",
-
"8.209.192.0/18",
-
"47.77.24.0/22",
-
"47.82.64.0/19",
-
"47.244.73.0/24",
-
"47.89.72.0/22",
-
"47.76.128.0/17",
-
"47.76.0.0/16",
-
"47.245.128.0/17",
-
"47.75.0.0/17",
-
"47.245.96.0/19",
-
"47.235.20.0/24",
-
"47.79.52.0/23",
-
"47.79.80.0/20",
-
"47.82.32.0/21",
-
"47.251.224.0/22",
-
"47.74.128.0/17",
-
"223.6.6.0/24",
-
"47.246.128.0/23",
-
"147.139.128.0/18",
-
"47.246.84.0/23",
-
"240b:4007::/33",
-
"170.33.85.0/24",
-
"43.96.102.0/24",
-
"43.98.0.0/17",
-
"203.107.67.0/24",
-
"8.222.0.0/21",
-
"2404:2280:2800::/37",
-
"43.96.101.0/24",
-
"170.33.84.0/24",
-
"8.219.128.0/17",
-
"47.80.64.0/19",
-
"43.96.85.0/24",
-
"43.96.96.0/24",
-
"43.96.73.0/24",
-
"47.246.100.0/22",
-
"47.79.60.0/23",
-
"47.77.26.0/23",
-
"8.222.128.0/17",
-
"161.117.138.0/24",
-
"47.235.18.0/23",
-
"47.235.0.0/23",
-
"240b:4006:1010::/44",
-
"47.76.0.0/17",
-
"8.221.216.0/21",
-
"47.82.8.0/23",
-
"2404:2280:4800::/37",
-
"170.33.29.0/24",
-
"47.245.128.0/18",
-
"47.79.80.0/21",
-
"47.89.221.0/24",
-
"198.11.184.0/21",
-
"240b:4009:8000::/33",
-
"8.215.162.0/23",
-
"8.211.128.0/19",
-
"47.79.83.0/24",
-
"2408:4009:500::/48",
-
"47.81.64.0/19",
-
"8.208.0.0/19",
-
"47.240.0.0/17",
-
"47.79.64.0/21",
-
"47.90.0.0/18",
-
"43.96.70.0/24",
-
"149.129.0.0/20",
-
"240b:400c::/33",
-
"2408:4000:1000::/48",
-
"170.33.76.0/24",
-
"205.204.96.0/19",
-
"47.88.64.0/18",
-
"8.209.96.0/19",
-
"47.79.104.0/21",
-
"47.82.10.0/23",
-
"47.79.88.0/21",
-
"47.245.64.0/19",
-
"139.95.16.0/23",
-
"47.77.20.0/22",
-
"240b:400f::/33",
-
"47.235.2.0/23",
-
"8.221.0.0/17",
-
"8.213.160.0/22",
-
"8.215.169.0/24",
-
"170.33.81.0/24",
-
"47.89.124.0/24",
-
"47.235.30.0/24",
-
"47.79.62.0/23",
-
"43.96.68.0/24",
-
"47.246.120.0/24",
-
"8.221.192.0/21",
-
"8.221.184.0/22",
-
"47.77.136.0/21",
-
"8.220.224.0/19",
-
"156.240.76.0/23",
-
"8.208.141.0/24",
-
"2404:2280:2000::/37",
-
"47.84.128.0/17",
-
"47.85.0.0/17",
-
"8.217.0.0/17",
-
"47.89.84.0/24",
-
"47.238.0.0/15",
-
"47.86.128.0/17",
-
"240b:4011:8000::/33",
-
"240b:4006:1000::/47",
-
"47.246.134.0/23",
-
"47.79.96.0/20",
-
"47.79.0.0/21",
-
"47.89.103.0/24",
-
"47.89.97.0/24",
-
"240b:4000::/33",
-
"47.242.0.0/16",
-
"47.56.0.0/15",
-
"47.91.32.0/20",
-
"147.139.192.0/18",
-
"240b:4013::/33",
-
"47.79.40.0/21",
-
"8.209.46.0/23",
-
"47.82.48.0/21",
-
"47.82.40.0/21",
-
"47.87.192.0/22",
-
"47.87.192.0/23",
-
"47.87.194.0/23",
-
"47.87.196.0/22",
-
"47.87.196.0/23",
-
"47.87.198.0/23",
-
"240b:400c:ffff::/48",
-
"47.87.208.0/23",
-
"47.87.210.0/23",
-
"47.87.208.0/22",
-
"47.87.222.0/23",
-
"47.87.216.0/23",
-
"47.87.200.0/23",
-
"47.87.220.0/23",
-
"47.87.216.0/22",
-
"47.87.224.0/22",
-
"47.87.204.0/22",
-
"47.87.212.0/23",
-
"47.87.226.0/23",
-
"47.87.200.0/22",
-
"47.87.206.0/23",
-
"43.100.0.0/16",
-
"47.87.212.0/22",
-
"47.87.218.0/23",
-
"47.87.214.0/23",
-
"43.100.0.0/15",
-
"47.87.204.0/23",
-
"47.87.220.0/22",
-
"43.101.0.0/16",
-
"47.87.224.0/23",
-
"47.87.202.0/23",
-
]
-4
packages/anubis-files/src/rules/challenge/generic-browser.yaml
···
-
- name: generic-browser
-
user_agent_regex: >-
-
Mozilla|Opera
-
action: CHALLENGE
+26
packages/bgutil-pot-server/librusty_v8.nix
···
+
# COPIED FROM nixpkgs/pkgs/by-name/router
+
{
+
lib,
+
stdenv,
+
fetchurl,
+
}:
+
+
let
+
fetch_librusty_v8 =
+
args:
+
fetchurl {
+
name = "librusty_v8-${args.version}";
+
url = "https://github.com/denoland/rusty_v8/releases/download/v${args.version}/librusty_v8_release_${stdenv.hostPlatform.rust.rustcTarget}.a";
+
sha256 = args.shas.${stdenv.hostPlatform.system};
+
meta = {
+
inherit (args) version;
+
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
+
};
+
};
+
in
+
fetch_librusty_v8 {
+
version = "130.0.7";
+
shas = {
+
x86_64-linux = "sha256-pkdsuU6bAkcIHEZUJOt5PXdzK424CEgTLXjLtQ80t10=";
+
};
+
}
+49
packages/bgutil-pot-server/package.nix
···
+
{
+
lib,
+
callPackage,
+
rustPlatform,
+
fetchFromGitHub,
+
pkg-config,
+
openssl,
+
_experimental-update-script-combinators,
+
nix-update-script,
+
}:
+
rustPlatform.buildRustPackage (finalAttrs: {
+
pname = "bgutil-pot-server";
+
version = "0.6.0";
+
+
src = fetchFromGitHub {
+
owner = "jim60105";
+
repo = "bgutil-ytdlp-pot-provider-rs";
+
tag = "v${finalAttrs.version}";
+
hash = "sha256-kEu5WqOymH8yAyMhGKtVPOq3qlTRpFU/FO71uWEX/e8=";
+
};
+
+
cargoHash = "sha256-fJZeyIsFUfpWeC1MWsU1hANb6cqC9xHQOnhcohEMTeM=";
+
+
nativeBuildInputs = [
+
pkg-config
+
];
+
+
buildInputs = [
+
openssl
+
];
+
+
env.RUSTY_V8_ARCHIVE = callPackage ./librusty_v8.nix { };
+
+
doCheck = false;
+
+
passthru.updateScript = _experimental-update-script-combinators.sequence [
+
(nix-update-script { })
+
./update-librusty.sh
+
];
+
+
meta = {
+
changelog = "https://github.com/jim60105/bgutil-ytdlp-pot-provider-rs/releases/tag/v${finalAttrs.version}";
+
description = "Proof-of-origin token provider plugin for yt-dlp in Rust";
+
homepage = "https://github.com/jim60105/bgutil-ytdlp-pot-provider-rs";
+
license = lib.licenses.gpl3Plus;
+
maintainers = with lib.maintainers; [ pyrox0 ];
+
mainProgram = "bgutil-pot";
+
};
+
})
+45
packages/bgutil-pot-server/update-librusty.sh
···
+
#!/usr/bin/env nix-shell
+
#!nix-shell -i bash -p gnugrep gnused nix jq
+
# shellcheck shell=bash
+
# COPIED FROM nixpkgs/pkgs/by-name/wi/windmill
+
+
set -eu -o pipefail
+
+
echo "librusty_v8: UPDATING"
+
+
BGUTIL_LATEST_VERSION=$(curl ${GITHUB_TOKEN:+-u ":$GITHUB_TOKEN"} --silent --fail --location "https://api.github.com/repos/jim60105/bgutil-ytdlp-pot-provider-rs/releases/latest" | jq --raw-output .tag_name)
+
CARGO_LOCK=$(curl ${GITHUB_TOKEN:+-u ":$GITHUB_TOKEN"} --silent --fail --location "https://github.com/jim60105/bgutil-ytdlp-pot-provider-rs/raw/$BGUTIL_LATEST_VERSION/Cargo.lock")
+
+
PACKAGE_DIR=$(dirname "$(readlink --canonicalize-existing "${BASH_SOURCE[0]}")")
+
OUTPUT_FILE="$PACKAGE_DIR/librusty_v8.nix"
+
NEW_VERSION=$(echo "$CARGO_LOCK" | grep --after-context 5 'name = "v8"' | grep 'version =' | sed -E 's/version = "//;s/"//')
+
+
CURRENT_VERSION=""
+
if [ -f "$OUTPUT_FILE" ]; then
+
CURRENT_VERSION="$(grep 'version =' "$OUTPUT_FILE" | sed -E 's/version = "//;s/"//')"
+
fi
+
+
if [ "$CURRENT_VERSION" == "$NEW_VERSION" ]; then
+
echo "No update needed, $CURRENT_VERSION is already latest"
+
exit 0
+
fi
+
+
x86Hash="$(nix-prefetch-url --type sha256 https://github.com/denoland/rusty_v8/releases/download/v"$NEW_V")"
+
TEMP_FILE="$OUTPUT_FILE.tmp"
+
cat >"$TEMP_FILE" <<EOF
+
# COPIED FROM nixpkgs/pkgs/by-name/wi/windmill
+
# auto-generated file -- DO NOT EDIT!
+
{ fetchLibrustyV8 }:
+
+
fetchLibrustyV8 {
+
version = "$NEW_VERSION";
+
shas = {
+
# NOTE; Follows supported platforms of package (see meta.platforms attribute)!
+
x86_64-linux = "$(nix hash convert --hash-algo sha256 --from nix32 "$x86Hash")";
+
};
+
}
+
EOF
+
+
mv "$TEMP_FILE" "$OUTPUT_FILE"
+
+
echo "librusty_v8: UPDATE DONE"
-31
packages/default.nix
···
-
{ ... }:
-
{
-
-
perSystem =
-
{
-
pkgs,
-
lib,
-
...
-
}:
-
let
-
packages = lib.makeScope pkgs.newScope (_: {
-
anubis-files = pkgs.callPackage ./anubis-files { };
-
doc2dash = pkgs.callPackage ./doc2dash { };
-
jellyfin-exporter = pkgs.callPackage ./jellyfin-exporter { };
-
pingvin-share-config = pkgs.callPackage ./pingvin-share-config { };
-
-
});
-
in
-
{
-
legacyPackages = packages;
-
packages = lib.filterAttrs (
-
_: pkg:
-
let
-
isDerivation = lib.isDerivation pkg;
-
availableOnHost = lib.meta.availableOn pkgs.stdenv.hostPlatform pkg;
-
isBroken = pkg.meta.broken or false;
-
in
-
isDerivation && !isBroken && availableOnHost
-
) packages;
-
};
-
}
-24
packages/doc2dash/default.nix
···
-
{
-
fetchFromGitHub,
-
python3Packages,
-
}: python3Packages.buildPythonApplication rec {
-
pname = "doc2dash";
-
version = "3.1.0";
-
pyproject = true;
-
-
src = fetchFromGitHub {
-
owner = "hynek";
-
repo = "doc2dash";
-
rev = version;
-
hash = "sha256-u6K+BDc9tUxq4kCekTaqQLtNN/OLVc3rh14sVSfPtoQ=";
-
};
-
-
build-system = with python3Packages; [ hatchling hatch-vcs hatch-fancy-pypi-readme];
-
-
dependencies = with python3Packages; [attrs beautifulsoup4 click rich];
-
-
nativeCheckInputs = with python3Packages; [
-
pytestCheckHook
-
pytest-cov-stub
-
];
-
}
+34
packages/doc2dash/package.nix
···
+
{
+
fetchFromGitHub,
+
python3Packages,
+
}:
+
python3Packages.buildPythonApplication rec {
+
pname = "doc2dash";
+
version = "3.1.0";
+
pyproject = true;
+
+
src = fetchFromGitHub {
+
owner = "hynek";
+
repo = "doc2dash";
+
rev = version;
+
hash = "sha256-u6K+BDc9tUxq4kCekTaqQLtNN/OLVc3rh14sVSfPtoQ=";
+
};
+
+
build-system = with python3Packages; [
+
hatchling
+
hatch-vcs
+
hatch-fancy-pypi-readme
+
];
+
+
dependencies = with python3Packages; [
+
attrs
+
beautifulsoup4
+
click
+
rich
+
];
+
+
nativeCheckInputs = with python3Packages; [
+
pytestCheckHook
+
pytest-cov-stub
+
];
+
}
+147
packages/glide-browser-bin/package.nix
···
+
{
+
lib,
+
stdenv,
+
fetchurl,
+
# keep-sorted start
+
adwaita-icon-theme,
+
alsa-lib,
+
autoPatchelfHook,
+
copyDesktopItems,
+
curl,
+
dbus-glib,
+
gtk3,
+
hicolor-icon-theme,
+
libXtst,
+
libva,
+
makeBinaryWrapper,
+
makeDesktopItem,
+
patchelfUnstable,
+
pciutils,
+
pipewire,
+
wrapGAppsHook3,
+
# keep-sorted end
+
nix-update-script,
+
...
+
}:
+
stdenv.mkDerivation (finalAttrs: {
+
pname = "glide-browser";
+
version = "0.1.55a";
+
+
src = fetchurl {
+
url = "https://github.com/glide-browser/glide/releases/download/${finalAttrs.version}/glide.linux-x86_64.tar.xz";
+
hash = "sha256-mjk8KmB/T5ZpB9AMQw1mtb9VbMXVX2VV4N+hWpWkSYI=";
+
};
+
+
nativeBuildInputs = [
+
# keep-sorted start
+
autoPatchelfHook
+
copyDesktopItems
+
makeBinaryWrapper
+
patchelfUnstable
+
wrapGAppsHook3
+
# keep-sorted end
+
];
+
+
buildInputs = [
+
# keep-sorted start
+
adwaita-icon-theme
+
alsa-lib
+
dbus-glib
+
gtk3
+
hicolor-icon-theme
+
libXtst
+
# keep-sorted end
+
];
+
+
runtimeDependencies = [
+
# keep-sorted start
+
curl
+
libva.out
+
pciutils
+
# keep-sorted end
+
];
+
+
appendRunpaths = [ "${pipewire}/lib" ];
+
+
# Firefox uses "relrhack" to manually process relocations from a fixed offset
+
patchelfFlags = [ "--no-clobber-old-sections" ];
+
+
installPhase = ''
+
runHook preInstall
+
+
mkdir -p $out/bin $out/share/icons/hicolor/ $out/lib/glide-browser-bin-${finalAttrs.version}
+
cp -t $out/lib/glide-browser-bin-${finalAttrs.version} -r *
+
chmod +x $out/lib/glide-browser-bin-${finalAttrs.version}/glide
+
iconDir=$out/share/icons/hicolor
+
browserIcons=$out/lib/glide-browser-bin-${finalAttrs.version}/browser/chrome/icons/default
+
+
for i in 16 32 48 64 128; do
+
iconSizeDir="$iconDir/''${i}x$i/apps"
+
mkdir -p $iconSizeDir
+
cp $browserIcons/default$i.png $iconSizeDir/glide-browser.png
+
done
+
+
+
ln -s $out/lib/glide-browser-bin-${finalAttrs.version}/glide $out/bin/glide
+
ln -s $out/bin/glide $out/bin/glide-browser
+
+
runHook postInstall
+
'';
+
+
desktopItems = [
+
(makeDesktopItem {
+
name = "glide-browser-bin";
+
exec = "glide-browser --name glide-browser %U";
+
icon = "glide-browser";
+
desktopName = "Glide Browser";
+
genericName = "Web Browser";
+
terminal = false;
+
startupNotify = true;
+
startupWMClass = "glide-browser";
+
categories = [
+
"Network"
+
"WebBrowser"
+
];
+
mimeTypes = [
+
"text/html"
+
"text/xml"
+
"application/xhtml+xml"
+
"application/vnd.mozilla.xul+xml"
+
"x-scheme-handler/http"
+
"x-scheme-handler/https"
+
];
+
actions = {
+
new-window = {
+
name = "New Window";
+
exec = "glide-browser --new-window %U";
+
};
+
new-private-window = {
+
name = "New Private Window";
+
exec = "glide-browser --private-window %U";
+
};
+
profile-manager-window = {
+
name = "Profile Manager";
+
exec = "glide-browser --ProfileManager";
+
};
+
};
+
})
+
];
+
+
passthru.updateScript = nix-update-script {
+
extraArgs = [
+
"--url"
+
"https://github.com/glide-browser/glide"
+
];
+
};
+
+
meta = {
+
changelog = "https://glide-browser.app/changelog#${finalAttrs.version}";
+
description = "Extensible and keyboard-focused web browser, based on Firefox (binary package)";
+
homepage = "https://glide-browser.app/";
+
license = lib.licenses.mpl20;
+
sourceProvenance = [ lib.sourceTypes.binaryNativeCode ];
+
platforms = [ "x86_64-linux" ];
+
maintainers = with lib.maintainers; [ pyrox0 ];
+
mainProgram = "glide-browser";
+
};
+
})
-34
packages/jellyfin-exporter/default.nix
···
-
{
-
lib,
-
buildGoModule,
-
fetchFromGitHub,
-
...
-
}:
-
buildGoModule (finalAttrs: {
-
pname = "jellyfin-exporter";
-
version = "1.3.8";
-
-
src = fetchFromGitHub {
-
owner = "rebelcore";
-
repo = "jellyfin_exporter";
-
tag = "v${finalAttrs.version}";
-
hash = "sha256-7fIrjcy6y/Ayj43WeuPNCx3uVJyl5Wf6bWs5ta2PpWc=";
-
};
-
-
# We need to patch the tests since we don't move the binary to `$GOPATH/bin`, but to `$out/bin` instead.
-
postPatch = ''
-
substituteInPlace jellyfin_exporter_test.go \
-
--replace-fail "GOPATH" "out"
-
'';
-
-
vendorHash = "sha256-JSOKDbefQyDLNy2y1oW7HUplQw8uhhOGZ+ueWyUYYQ0=";
-
-
meta = {
-
changelog = "https://github.com/rebelcore/jellyfin_exporter/blob/v${finalAttrs.version}/CHANGELOG.md";
-
description = "Jellyfin Media System metrics exporter for prometheus";
-
homepage = "https://github.com/rebelcore/jellyfin_exporter";
-
license = lib.licenses.asl20;
-
maintainers = with lib.maintainers; [ pyrox0 ];
-
mainProgram = "jellyfin_exporter";
-
};
-
})
+34
packages/jellyfin-exporter/package.nix
···
+
{
+
lib,
+
buildGoModule,
+
fetchFromGitHub,
+
...
+
}:
+
buildGoModule (finalAttrs: {
+
pname = "jellyfin-exporter";
+
version = "1.3.9";
+
+
src = fetchFromGitHub {
+
owner = "rebelcore";
+
repo = "jellyfin_exporter";
+
tag = "v${finalAttrs.version}";
+
hash = "sha256-oHPzdV+Fe7XmSyRWm5jh7oGqlY9uyLy7u9tCTlkfhQk=";
+
};
+
+
# We need to patch the tests since we don't move the binary to `$GOPATH/bin`, but to `$out/bin` instead.
+
postPatch = ''
+
substituteInPlace jellyfin_exporter_test.go \
+
--replace-fail "GOPATH" "out"
+
'';
+
+
vendorHash = "sha256-Z3XM4vTsm5R/Me1jR9oqLcWqmEn1bd653UNvDKLM80g=";
+
+
meta = {
+
changelog = "https://github.com/rebelcore/jellyfin_exporter/blob/v${finalAttrs.version}/CHANGELOG.md";
+
description = "Jellyfin Media System metrics exporter for prometheus";
+
homepage = "https://github.com/rebelcore/jellyfin_exporter";
+
license = lib.licenses.asl20;
+
maintainers = with lib.maintainers; [ pyrox0 ];
+
mainProgram = "jellyfin_exporter";
+
};
+
})
-19
packages/pingvin-share-config/default.nix
···
-
{
-
pkgs,
-
stdenv,
-
settings ? { },
-
...
-
}:
-
let
-
format = pkgs.formats.yaml { };
-
file = format.generate "config.yaml" settings;
-
in
-
stdenv.mkDerivation {
-
pname = "pingvin-share-config";
-
version = "1.0.0";
-
-
installPhase = ''
-
mkdir $out
-
cp ${file} $out/config.yaml
-
'';
-
}
+19
packages/pingvin-share-config/package.nix
···
+
{
+
pkgs,
+
stdenv,
+
settings ? { },
+
...
+
}:
+
let
+
format = pkgs.formats.yaml { };
+
file = format.generate "config.yaml" settings;
+
in
+
stdenv.mkDerivation {
+
pname = "pingvin-share-config";
+
version = "1.0.0";
+
+
installPhase = ''
+
mkdir $out
+
cp ${file} $out/config.yaml
+
'';
+
}
+138
packages/planka/package.nix
···
+
{
+
lib,
+
stdenv,
+
fetchFromGitHub,
+
fetchNpmDeps,
+
nix-update-script,
+
npmHooks,
+
dart-sass,
+
nodejs,
+
python3,
+
}:
+
let
+
version = "2.0.0-rc.4";
+
src = fetchFromGitHub {
+
owner = "plankanban";
+
repo = "planka";
+
tag = "v${version}";
+
hash = "sha256-RUOIOXrpoNGxoKwUlgkPsk4kTnA95E+iwYIjBzSBoTA=";
+
};
+
meta = {
+
description = "Kanban-style project mastering tool for everyone";
+
homepage = "https://docs.planka.cloud/";
+
license = {
+
fullName = "Planka Community License";
+
url = "https://github.com/plankanban/planka/blob/master/LICENSE.md";
+
free = false;
+
redistributable = true;
+
};
+
maintainers = with lib.maintainers; [ pyrox0 ];
+
};
+
+
frontend = stdenv.mkDerivation (finalAttrs: {
+
pname = "planka-frontend";
+
inherit version src meta;
+
+
sourceRoot = "${finalAttrs.src.name}/client";
+
+
npmDeps = fetchNpmDeps {
+
inherit (finalAttrs) src sourceRoot;
+
hash = "sha256-XtVwO8253XBVtG0jrikeVr1yaS1PpphCbN5B6jz54qc=";
+
};
+
+
npmFlags = [
+
"--ignore-scripts"
+
];
+
+
nativeBuildInputs = [
+
npmHooks.npmConfigHook
+
nodejs
+
dart-sass
+
];
+
+
buildPhase = ''
+
runHook preBuild
+
+
npx patch-package
+
+
# Replace dart path in sass-embedded since node_modules doesn't have the native binary
+
substituteInPlace node_modules/sass-embedded/dist/lib/src/compiler-path.js \
+
--replace-fail 'compilerCommand = (() => {' 'compilerCommand = (() => { return ["${lib.getExe dart-sass}"];'
+
+
npm run build
+
+
runHook postBuild
+
'';
+
+
installPhase = ''
+
runHook preInstall
+
+
mkdir $out/
+
mv dist $out/dist
+
+
runHook postInstall
+
'';
+
});
+
+
serverPython = python3.withPackages (ps: [ ps.apprise ]);
+
in
+
stdenv.mkDerivation (finalAttrs: {
+
pname = "planka";
+
inherit version src;
+
+
sourceRoot = "${finalAttrs.src.name}/server";
+
+
npmDeps = fetchNpmDeps {
+
inherit (finalAttrs) src sourceRoot;
+
hash = "sha256-yW9uzPALGdPrrUV129ToXayLyeLbAK9mCl2emCPYUdc=";
+
};
+
+
npmFlags = [ "--ignore-scripts" ];
+
+
nativeBuildInputs = [
+
npmHooks.npmConfigHook
+
nodejs
+
];
+
+
buildInputs = [
+
serverPython
+
nodejs
+
];
+
+
preBuild = ''
+
# Patch notifs helper to use nixpkgs' python
+
substituteInPlace api/helpers/utils/send-notifications.js \
+
--replace-fail '(`$' '(`' \
+
--replace-fail "{sails.config.appPath}/.venv/bin/python3" "${lib.getExe serverPython}"
+
'';
+
+
buildPhase = ''
+
runHook preBuild
+
+
npx patch-package
+
+
runHook postBuild
+
'';
+
+
installPhase = ''
+
runHook preInstall
+
+
npm prune --omit=dev --no-save $npmFlags "$${npmFlagsArray[@]}"
+
find node_modules -maxdepth 1 -type d -empty -delete
+
+
mkdir -p $out/lib/node_modules/planka
+
mkdir $out/bin
+
mv * $out/lib/node_modules/planka
+
cp -t $out/lib/node_modules/planka/public -r ${frontend}/dist/*
+
cp ${frontend}/dist/index.html $out/lib/node_modules/planka/views/index.html
+
+
ln -s $out/lib/node_modules/planka/start.sh $out/bin/planka
+
+
runHook postInstall
+
'';
+
+
passthru.updateScript = nix-update-script { extraArgs = [ "--version=unstable" ]; };
+
meta = meta // {
+
mainProgram = "planka";
+
};
+
})
+26
packages.nix
···
+
{
+
perSystem =
+
{
+
pkgs,
+
lib,
+
...
+
}:
+
let
+
packages = lib.packagesFromDirectoryRecursive {
+
inherit (pkgs) callPackage;
+
directory = ./packages;
+
};
+
in
+
{
+
legacyPackages = packages;
+
packages = lib.filterAttrs (
+
_: pkg:
+
let
+
isDerivation = lib.isDerivation pkg;
+
availableOnHost = lib.meta.availableOn pkgs.stdenv.hostPlatform pkg;
+
isBroken = pkg.meta.broken or false;
+
in
+
isDerivation && !isBroken && availableOnHost
+
) packages;
+
};
+
}