122 Commits

Author SHA1 Message Date
bab2df5d7e Use programs.ssh.askPassword
All checks were successful
Check Flake / check-flake (push) Successful in 4m56s
2026-01-11 15:24:53 -08:00
adc04d1bc7 Update nixos mailserver
All checks were successful
Check Flake / check-flake (push) Successful in 18m38s
2026-01-11 14:25:17 -08:00
da9a8f8c03 Update nixpkgs 2026-01-11 14:25:03 -08:00
415cbca33e VLAN workaround for now 2026-01-10 23:04:48 -08:00
51272a172b Add system76-keyboard-configurator to fry 2026-01-10 23:03:19 -08:00
f053c677e8 Set up openwebui + ollama 2026-01-10 23:02:43 -08:00
c130ce6edd Don't generate zed user config file for now 2026-01-10 22:55:31 -08:00
4718326cb6 Configure ssh-agent to work with keepassxc ssh keys 2026-01-10 22:53:28 -08:00
61698aa7e2 Add kde connect 2026-01-10 22:52:17 -08:00
e0af023ac9 barrier was removed from nixpkgs 2026-01-10 22:51:09 -08:00
c0088553ff jellyfin-media-player was removed from nixpkgs 2026-01-10 22:49:04 -08:00
577736fcb2 Add deploy command 2026-01-10 22:46:39 -08:00
cf087b0e39 Add fry
All checks were successful
Check Flake / check-flake (push) Successful in 1h22m48s
2025-10-12 13:36:02 -07:00
cb1c4752ec Use latest kernel on Howl 2025-10-12 13:35:23 -07:00
b77fb54dc6 Disable annoying pls shell integration 2025-10-12 13:35:02 -07:00
3d6a759827 Update nixpkgs 2025-10-12 13:33:53 -07:00
0c455baebd Add languagetool
All checks were successful
Check Flake / check-flake (push) Successful in 5m13s
2025-08-16 19:04:10 -07:00
b58df0632a Add outline service
All checks were successful
Check Flake / check-flake (push) Successful in 15m2s
2025-08-10 20:49:50 -07:00
4956e41285 Add memos service 2025-08-10 19:03:35 -07:00
ead6653de1 Add services to tailscale auth 2025-08-10 19:02:47 -07:00
dd4a5729d4 Workaround for broken librespot spotify api integration
All checks were successful
Check Flake / check-flake (push) Successful in 4m49s
2025-08-10 15:18:29 -07:00
f248c129c8 Open port 8095 for music assistant too 2025-08-10 15:17:52 -07:00
c011faab18 Use flaresolverr with linkwarden 2025-08-10 15:17:27 -07:00
a5d0b3b748 Bring back APU2 router for more experimentation
All checks were successful
Check Flake / check-flake (push) Successful in 19m21s
2025-08-05 19:45:50 -07:00
ed3bee2e4e Improve minimal iso so it can boot on APU2 from sd card 2025-08-05 19:44:49 -07:00
dbde2a40f2 Add linkwarden 2025-08-05 19:42:29 -07:00
6c69d82156 Add support for Home Assistant voice (whisper + piper + cloud llm) and Music Assistant via Spotify by librespot
Music assistant has custom modifications they made to librespot that they haven't bothered to even try to upstream.
Thus, they require a custom librespot.  I tried and tried and tried and tried to just override the one already in nixpkgs
but I had trouble doing so despite copying the pattern already shown in nixpkgs for overriding the src of a cargo pkg
(See mopidy) but it just didn't work... Oh well. So I just patch nixpkgs instead with the new source. It works I guess.

This is about where I gave up...

```nix
nixpkgs.overlays = [
  (final: prev: {
    # Cannot use librespot upstream because music-assistant requires custom changes
    # that they never bothered to even try to uptream
    librespot = prev.librespot.overrideAttrs (oldAttrs: rec {
      src = prev.fetchFromGitHub {
        owner = "music-assistant";
        repo = "librespot";
        rev = "786cc46199e583f304a84c786acb0a9b37bc3fbd";
        sha256 = "sha256-xaOrqC8yCjF23Tz31RD3CzqZ3xxrDM6ncW1yoovEaGQ=";
      };

      cargoDeps = oldAttrs.cargoDeps.overrideAttrs (oldAttrs': {
        vendorStaging = oldAttrs'.vendorStaging.overrideAttrs {
          outputHash = "sha256-SqvJSHkyd1IicT6c4pE96dBJNNodULhpyG14HRGVWCk=";
        };
      });
    });
  })
];
```
2025-08-05 19:37:50 -07:00
01b01f06b4 Stop using systemd-networkd it has some flaws with NixOS' networking I need to figure out later.
It is very elegant, easy to debug/understand, and I definitely want to use it but The most significant
problem is it doesn't work with NixOS containers private networking.  So I'll need to figure that out
or maybe it will be fixed upstream soon.
2025-08-05 19:27:29 -07:00
cf560d4e53 Downgrade Howl's kernel because newer kernels just are horrible with Howl's network card 2025-08-05 19:24:46 -07:00
8cf4957e15 Add build iso helper command 2025-08-05 19:23:42 -07:00
dc02438a63 Finally a fix DHCP+VLANs thanks to systemd-networkd
All checks were successful
Check Flake / check-flake (push) Successful in 3m31s
2025-07-22 21:20:12 -07:00
948984af2d Set ghostty preferences
All checks were successful
Check Flake / check-flake (push) Successful in 22m14s
2025-07-18 19:46:18 -07:00
be23526c2c Add KeepassXC keys, remove some very old user keys, and rekey
All checks were successful
Check Flake / check-flake (push) Successful in 1m50s
2025-07-16 22:01:33 -07:00
e234577268 Disable inactive cache push experiment 2025-07-16 22:00:11 -07:00
82b67ed566 Add Whiteboard app to Nextcloud
All checks were successful
Check Flake / check-flake (push) Successful in 2m17s
2025-07-16 20:49:39 -07:00
53c2e2222c Move shell aliases 2025-07-16 20:48:26 -07:00
846da159d0 Iodine stopped working again 2025-07-16 20:47:49 -07:00
a45125421e Add collabora online and move nextcloud domain 2025-07-16 20:46:51 -07:00
f4e40955c8 Use upstreamed pcie coral and vaapi frigate configuration
All checks were successful
Check Flake / check-flake (push) Successful in 12m12s
2025-07-13 18:04:36 -07:00
af9e462b27 Allow substituters to be offline
Some checks failed
Check Flake / check-flake (push) Has been cancelled
2025-07-13 17:54:32 -07:00
2faea9d380 Update nixpkgs and other flake inputs 2025-07-13 17:52:08 -07:00
8571922796 Add new helpful utilities 2025-07-12 11:42:40 -07:00
131d5e9313 Add rest command for home assistant 2025-07-12 10:50:37 -07:00
fe0ce3a245 Get recyclarr initially running 2025-07-12 10:48:13 -07:00
7b26cfb4eb update single input cmd 2025-07-12 10:27:09 -07:00
1c9fa418b3 Make s0 easier to unlock
All checks were successful
Check Flake / check-flake (push) Successful in 1m25s
2025-03-29 22:52:00 -07:00
8c4dc9cb74 Improve usage of roles. It should be much easier to read and use now. 2025-03-29 22:48:14 -07:00
1f9fbd87ac Use upstream pykms and Actual Budget. Move Actual to s0. Add automated backups for Actual.
All checks were successful
Check Flake / check-flake (push) Successful in 1m37s
2025-03-29 18:36:13 -07:00
23c8076e4d Pinning system nixpkgs is not needed anymore. nixpkgs already does this automatically for flakes.
All checks were successful
Check Flake / check-flake (push) Successful in 1m50s
2025-03-28 21:45:46 -07:00
75ae399b5a Update nixpkgs. Move to new dashy service 2025-03-28 21:05:37 -07:00
87ddad27a4 Add Home Manager 2025-03-28 20:27:14 -07:00
8dd2a00123 Tauri development extensions 2025-03-28 20:24:33 -07:00
944a783ff2 Add nix LSPs for development 2025-03-28 20:23:07 -07:00
c2cb43fd2c Enable iperf3 server on ponyo 2025-03-28 20:22:14 -07:00
02b2fb6309 Disable gc on howl so nix backed projects don't loose their cache 2025-03-28 20:19:15 -07:00
b43660aaef Clean up very old unused config 2025-03-28 20:17:54 -07:00
567d755850 If machine role is personal set de.enable = true; automatically 2025-03-28 20:16:26 -07:00
adc9b9f2b7 Add sandman.s0.neet.dev 2025-03-28 19:39:59 -07:00
9181e3bfa3 Update librechat to v0.7.7 2025-03-28 19:38:41 -07:00
9845270512 Fix gparted 2025-03-28 19:35:35 -07:00
b3b3044690 Downgrade to dailybot to python 3.11
All checks were successful
Check Flake / check-flake (push) Successful in 1m22s
2025-02-18 22:43:47 -08:00
fb1970c316 Upgrade librechat
All checks were successful
Check Flake / check-flake (push) Successful in 6m43s
2025-02-17 12:12:46 -08:00
34f1edf3b3 Fix s0 setting the incorrect default route by using a static configuration 2025-02-17 12:11:52 -08:00
823f0a6ef2 Disable frigate detect for now. It is using excessive CPU 2025-02-17 12:10:59 -08:00
00d2ccc684 Fix sound in some games running in wine 2025-02-17 12:09:51 -08:00
b2acaff783 Fix pykms by downgrading to python 3.11 2025-02-17 12:09:20 -08:00
c51f4ad65b Unlock zoidberg using TPM2
All checks were successful
Check Flake / check-flake (push) Successful in 1m6s
2024-11-21 21:31:19 -08:00
eb6a50664c Upgrade NixOS. Use upstream libedgetpu, frigate, and gasket kernel module. Fix services broken by upgrade.
All checks were successful
Check Flake / check-flake (push) Successful in 17m43s
2024-11-19 21:28:56 -08:00
89ce0f7fc0 Change Howl's NVMe 2024-11-19 21:08:19 -08:00
8ff552818b Rollover digital ocean auth token
All checks were successful
Check Flake / check-flake (push) Successful in 1m13s
2024-10-27 16:41:02 -07:00
020689d987 Fix zigbee2mqtt auth 2024-10-27 16:40:47 -07:00
9109e356bd Backup vikunja
All checks were successful
Check Flake / check-flake (push) Successful in 2m6s
2024-10-27 16:26:32 -07:00
c7d9e84f73 Lock down access to mqtt
All checks were successful
Check Flake / check-flake (push) Successful in 1m6s
2024-10-27 16:15:23 -07:00
5b666a0565 Add nextcloud apps
Some checks failed
Check Flake / check-flake (push) Has been cancelled
2024-10-11 21:58:54 -07:00
6bc11767ca Update Actual Budget
All checks were successful
Check Flake / check-flake (push) Successful in 2m46s
2024-10-11 21:20:46 -07:00
bdd2d9bef9 Update nextcloud 2024-10-11 21:20:18 -07:00
5acc8b3fca Block email for ellen@runyan.org
All checks were successful
Check Flake / check-flake (push) Successful in 1m5s
2024-10-10 20:04:50 -07:00
1e25d8bb71 Add vikunja
Some checks failed
Check Flake / check-flake (push) Has been cancelled
2024-10-10 20:02:43 -07:00
ac1cf1c531 Open up mqtt for valetudo 2024-10-10 20:02:09 -07:00
02357198bc Change timezone 2024-10-10 20:01:41 -07:00
89b49aafc0 flake.lock: Update
All checks were successful
Check Flake / check-flake (push) Successful in 1h32m23s
Flake lock file updates:

• Updated input 'agenix':
    'github:ryantm/agenix/c2fc0762bbe8feb06a2e59a364fa81b3a57671c9' (2024-05-24)
  → 'github:ryantm/agenix/f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41' (2024-08-10)
• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/3867348fa92bc892eba5d9ddb2d7a97b9e127a8a' (2024-06-12)
  → 'github:serokell/deploy-rs/aa07eb05537d4cd025e2310397a6adcedfe72c76' (2024-09-27)
• Updated input 'flake-utils':
    'github:numtide/flake-utils/b1d9ab70662946ef0850d488da1c9019f3a9752a' (2024-03-11)
  → 'github:numtide/flake-utils/c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a' (2024-09-17)
• Updated input 'nix-index-database':
    'github:Mic92/nix-index-database/ff80cb4a11bb87f3ce8459be6f16a25ac86eb2ac' (2024-05-27)
  → 'github:Mic92/nix-index-database/5fce10c871bab6d7d5ac9e5e7efbb3a2783f5259' (2024-10-07)
• Updated input 'nixos-hardware':
    'github:NixOS/nixos-hardware/7b49d3967613d9aacac5b340ef158d493906ba79' (2024-06-01)
  → 'github:NixOS/nixos-hardware/b7ca02c7565fbf6d27ff20dd6dbd49c5b82eef28' (2024-10-04)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/805a384895c696f802a9bf5bf4720f37385df547' (2024-05-31)
  → 'github:NixOS/nixpkgs/ecbc1ca8ffd6aea8372ad16be9ebbb39889e55b6' (2024-10-06)
• Updated input 'simple-nixos-mailserver':
    'gitlab:simple-nixos-mailserver/nixos-mailserver/29916981e7b3b5782dc5085ad18490113f8ff63b' (2024-06-11)
  → 'gitlab:simple-nixos-mailserver/nixos-mailserver/af7d3bf5daeba3fc28089b015c0dd43f06b176f2' (2024-08-05)
• Removed input 'simple-nixos-mailserver/utils'
2024-10-06 20:28:24 -06:00
e56271b2c3 Add reverse proxy for valetudo
All checks were successful
Check Flake / check-flake (push) Successful in 1m6s
2024-10-06 19:16:05 -06:00
f9ef5e4b89 Clean up 2024-10-06 17:15:25 -06:00
e516bd87b5 Fix VLANs 2024-10-06 17:11:58 -06:00
7c9c657bd0 Fix audio stuttering in wine/proton
See: https://old.reddit.com/r/linux_gaming/comments/11yp7ig/pipewire_audio_stuttering_when_playing_games_or/
2024-10-06 17:07:53 -06:00
dff7d65456 vscodium WGSL support 2024-10-06 17:06:28 -06:00
d269d2e5a0 Enable wayland support in chromium based apps 2024-07-17 21:42:43 -06:00
2527b614e9 vscodium rust dev support 2024-07-17 21:15:33 -06:00
528a53a606 Fix chromium acceleration and wayland support 2024-07-17 21:15:02 -06:00
66bfc62566 Refactor frigate config to add a bunch of features
All checks were successful
Check Flake / check-flake (push) Successful in 2h20m26s
- Enable vaapi GPU video encode/decode support
- Use go2rtc. This allows for watching high resolution camera feeds
- Split nix config into pieces that are easier to understand
- Add utilities for easily adding new cameras in the future
- misc changes
2024-06-30 12:49:26 -06:00
91874b9d53 Move frigate into it's own config file 2024-06-30 07:42:23 -06:00
50fc0a53d2 Enable more hass integrations 2024-06-29 10:13:46 -06:00
0b3322afda First VLAN camera in frigate 2024-06-29 10:13:03 -06:00
b32f6fa315 Enable memtest86 2024-06-29 10:12:11 -06:00
fe41ffc788 Allow s0 to access VLANs 2024-06-29 10:11:34 -06:00
eac443f280 Fix home assisstant
All checks were successful
Check Flake / check-flake (push) Successful in 1m7s
2024-06-21 23:26:30 -06:00
d557820d6c Lockdown intranet services behind tailscale 2024-06-21 21:04:49 -06:00
4d658e10d3 Make LibreChat's auth sessions last longer 2024-06-21 19:54:47 -06:00
9ac9613d67 Add gc cmd to makefile 2024-06-16 20:37:21 -06:00
e657ebb134 Clean up flake inputs 2024-06-16 12:47:29 -06:00
d1b07ec06b Add llsblk helper cmd alias 2024-06-16 12:10:39 -06:00
89621945f8 Fix zoidberg 2024-06-16 12:09:58 -06:00
e69fd5bf8f Use Firefox
All checks were successful
Check Flake / check-flake (push) Successful in 3m2s
2024-06-09 22:43:34 -06:00
c856b762e7 Goodbye Ray
All checks were successful
Check Flake / check-flake (push) Successful in 4m30s
2024-06-08 16:39:00 -06:00
b7f82f2d44 Consolidate common PC config
All checks were successful
Check Flake / check-flake (push) Successful in 1m14s
2024-06-03 21:07:53 -06:00
588e94dcf4 Update to NixOS 24.05
All checks were successful
Check Flake / check-flake (push) Successful in 1m11s
2024-06-02 21:12:07 -06:00
fd1ead0b62 Add nixos-hardware config for Howl 2024-06-01 19:57:24 -06:00
37bd7254b9 Add Howl
All checks were successful
Check Flake / check-flake (push) Successful in 1m54s
2024-05-31 23:29:39 -06:00
74e41de9d6 Enable unify v8 service
All checks were successful
Check Flake / check-flake (push) Successful in 56s
2024-05-26 17:24:46 -06:00
0bf0b8b88b Enable ollama service 2024-05-26 17:24:07 -06:00
702129d778 Enable CUDA support 2024-05-26 17:23:38 -06:00
88c67dde84 Open C&C ports 2024-05-26 17:21:58 -06:00
8e3a0761e8 Clean up 2024-05-26 17:21:34 -06:00
a785890990 Fix esphome so that it can build again 2024-05-26 17:20:05 -06:00
b482a8c106 Restore frigate functionality by reverting to an older tensorflow version for libedgetpu 2024-05-26 17:16:59 -06:00
efe50be604 Update nixpkgs
All checks were successful
Check Flake / check-flake (push) Successful in 53s
2024-03-17 09:39:54 -06:00
99904d0066 Update 'Actual' and 'Actual Server' to 'v24.3.0'
All checks were successful
Check Flake / check-flake (push) Successful in 14m33s
2024-03-03 14:57:23 -07:00
55e44bc3d0 Add 'tree' to system pkgs 2024-03-03 14:53:14 -07:00
da7ffa839b Blackhole spammed email address
All checks were successful
Check Flake / check-flake (push) Successful in 5m18s
2024-02-20 18:13:19 -07:00
01af25a57e Add Actual server
All checks were successful
Check Flake / check-flake (push) Successful in 6m3s
2024-02-19 19:44:07 -07:00
bfc1bb2da9 Use a makefile for utility snippets
All checks were successful
Check Flake / check-flake (push) Successful in 12m54s
2024-02-18 17:30:52 -07:00
0e59fa3518 Add easy boot configuration profile limit 2024-02-18 17:30:12 -07:00
114 changed files with 2236 additions and 1917 deletions

View File

@@ -15,10 +15,5 @@ jobs:
with:
fetch-depth: 0
- run: |
pwd
ls -lah .
whoami
- name: Check Flake
run: nix flake check --show-trace
run: nix flake check --all-systems --print-build-logs --log-format raw --show-trace

42
Makefile Normal file
View File

@@ -0,0 +1,42 @@
# Lockfile utils
.PHONY: update-lockfile
update-lockfile:
nix flake update --commit-lock-file
.PHONY: update-lockfile-without-commit
update-lockfile-without-commit:
nix flake update
# Agenix utils
.PHONY: edit-secret
edit-secret:
cd secrets && agenix -e $(filter-out $@,$(MAKECMDGOALS))
.PHONY: rekey-secrets
rekey-secrets:
cd secrets && agenix -r
# NixOS utils
.PHONY: clean-old-nixos-profiles
clean-old-nixos-profiles:
doas nix-collect-garbage -d
# Garbage Collect
.PHONY: gc
gc:
nix store gc
# Update a flake input by name (ex: 'nixpkgs')
.PHONY: update-input
update-input:
nix flake update $(filter-out $@,$(MAKECMDGOALS))
# Build Custom Install ISO
.PHONY: iso
iso:
nix build .#packages.x86_64-linux.iso
# Deploy a host by name (ex: 's0')
.PHONY: deploy
deploy:
deploy --remote-build --boot --debug-logs --skip-checks .#$(filter-out $@,$(MAKECMDGOALS))

View File

@@ -4,7 +4,7 @@
- `/common` - common configuration imported into all `/machines`
- `/boot` - config related to bootloaders, cpu microcode, and unlocking LUKS root disks over tor
- `/network` - config for tailscale, and NixOS container with automatic vpn tunneling via PIA
- `/pc` - config that a graphical desktop computer should have. Use `de.enable = true;` to enable everthing.
- `/pc` - config that a graphical PC should have. Have the `personal` role set in the machine's `properties.nix` to enable everthing.
- `/server` - config that creates new nixos services or extends existing ones to meet my needs
- `/machines` - all my NixOS machines along with their machine unique configuration for hardware and services
- `/kexec` - a special machine for generating minimal kexec images. Does not import `/common`

View File

@@ -12,6 +12,13 @@
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"s0.koi-bebop.ts.net:OjbzD86YjyJZpCp9RWaQKANaflcpKhtzBMNP8I2aPUU="
];
# Allow substituters to be offline
# This isn't exactly ideal since it would be best if I could set up a system
# so that it is an error if a derivation isn't available for any substituters
# and use this flag as intended for deciding if it should build missing
# derivations locally. See https://github.com/NixOS/nix/issues/6901
fallback = true;
};
};
}

View File

@@ -10,6 +10,10 @@ in
device = mkOption {
type = types.str;
};
configurationLimit = mkOption {
default = 20;
type = types.int;
};
};
config = mkIf cfg.enable {
@@ -19,7 +23,7 @@ in
enable = true;
device = cfg.device;
useOSProber = true;
configurationLimit = 20;
configurationLimit = cfg.configurationLimit;
theme = pkgs.nixos-grub2-theme;
};
};

View File

@@ -7,6 +7,10 @@ in
{
options.efi = {
enable = mkEnableOption "enable efi boot";
configurationLimit = mkOption {
default = 20;
type = types.int;
};
};
config = mkIf cfg.enable {
@@ -19,7 +23,7 @@ in
efiSupport = true;
useOSProber = true;
# memtest86.enable = true;
configurationLimit = 20;
configurationLimit = cfg.configurationLimit;
theme = pkgs.nixos-grub2-theme;
};
};

View File

@@ -35,11 +35,6 @@ in
};
config = lib.mkIf cfg.enable {
# boot.initrd.luks.devices.${cfg.device.name} = {
# device = cfg.device.path;
# allowDiscards = cfg.device.allowDiscards;
# };
# Unlock LUKS disk over ssh
boot.initrd.network.enable = true;
boot.initrd.kernelModules = cfg.kernelModules;

View File

@@ -1,4 +1,4 @@
{ config, pkgs, ... }:
{ config, pkgs, lib, ... }:
{
imports = [
@@ -20,12 +20,12 @@
system.stateVersion = "23.11";
networking.useDHCP = false;
networking.useDHCP = lib.mkDefault true;
networking.firewall.enable = true;
networking.firewall.allowPing = true;
time.timeZone = "America/Denver";
time.timeZone = "America/Los_Angeles";
i18n = {
defaultLocale = "en_US.UTF-8";
extraLocaleSettings = {
@@ -61,6 +61,8 @@
lm_sensors
picocom
lf
gnumake
tree
];
nixpkgs.config.allowUnfree = true;
@@ -96,4 +98,7 @@
security.acme.acceptTerms = true;
security.acme.defaults.email = "zuckerberg@neet.dev";
# Enable Desktop Environment if this is a PC (machine role is "personal")
de.enable = lib.mkDefault (config.thisMachine.hasRole."personal");
}

View File

@@ -10,16 +10,9 @@ in
config = mkIf cfg.enable {
nix = {
package = pkgs.nixFlakes;
extraOptions = ''
experimental-features = nix-command flakes
'';
# pin nixpkgs for system commands such as "nix shell"
registry.nixpkgs.flake = config.inputs.nixpkgs;
# pin system nixpkgs to the same version as the flake input
nixPath = [ "nixpkgs=${config.inputs.nixpkgs}" ];
};
};
}

View File

@@ -5,6 +5,90 @@
let
machines = config.machines.hosts;
hostOptionsSubmoduleType = lib.types.submodule {
options = {
hostNames = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
List of hostnames for this machine. The first one is the default so it is the target of deployments.
Used for automatically trusting hosts for ssh connections.
'';
};
arch = lib.mkOption {
type = lib.types.enum [ "x86_64-linux" "aarch64-linux" ];
description = ''
The architecture of this machine.
'';
};
systemRoles = lib.mkOption {
type = lib.types.listOf lib.types.str; # TODO: maybe use an enum?
description = ''
The set of roles this machine holds. Affects secrets available. (TODO add service config as well using this info)
'';
};
hostKey = lib.mkOption {
type = lib.types.str;
description = ''
The system ssh host key of this machine. Used for automatically trusting hosts for ssh connections
and for decrypting secrets with agenix.
'';
};
remoteUnlock = lib.mkOption {
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {
hostKey = lib.mkOption {
type = lib.types.str;
description = ''
The system ssh host key of this machine used for luks boot unlocking only.
'';
};
clearnetHost = lib.mkOption {
default = null;
type = lib.types.nullOr lib.types.str;
description = ''
The hostname resolvable over clearnet used to luks boot unlock this machine
'';
};
onionHost = lib.mkOption {
default = null;
type = lib.types.nullOr lib.types.str;
description = ''
The hostname resolvable over tor used to luks boot unlock this machine
'';
};
};
});
};
userKeys = lib.mkOption {
default = [ ];
type = lib.types.listOf lib.types.str;
description = ''
The list of user keys. Each key here can be used to log into all other systems as `googlebot`.
TODO: consider auto populating other programs that use ssh keys such as gitea
'';
};
deployKeys = lib.mkOption {
default = [ ];
type = lib.types.listOf lib.types.str;
description = ''
The list of deployment keys. Each key here can be used to log into all other systems as `root`.
'';
};
configurationPath = lib.mkOption {
type = lib.types.path;
description = ''
The path to this machine's configuration directory.
'';
};
};
};
in
{
imports = [
@@ -13,104 +97,16 @@ in
];
options.machines = {
hosts = lib.mkOption {
type = lib.types.attrsOf
(lib.types.submodule {
options = {
hostNames = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
List of hostnames for this machine. The first one is the default so it is the target of deployments.
Used for automatically trusting hosts for ssh connections.
'';
};
arch = lib.mkOption {
type = lib.types.enum [ "x86_64-linux" "aarch64-linux" ];
description = ''
The architecture of this machine.
'';
};
systemRoles = lib.mkOption {
type = lib.types.listOf lib.types.str; # TODO: maybe use an enum?
description = ''
The set of roles this machine holds. Affects secrets available. (TODO add service config as well using this info)
'';
};
hostKey = lib.mkOption {
type = lib.types.str;
description = ''
The system ssh host key of this machine. Used for automatically trusting hosts for ssh connections
and for decrypting secrets with agenix.
'';
};
remoteUnlock = lib.mkOption {
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {
hostKey = lib.mkOption {
type = lib.types.str;
description = ''
The system ssh host key of this machine used for luks boot unlocking only.
'';
};
clearnetHost = lib.mkOption {
default = null;
type = lib.types.nullOr lib.types.str;
description = ''
The hostname resolvable over clearnet used to luks boot unlock this machine
'';
};
onionHost = lib.mkOption {
default = null;
type = lib.types.nullOr lib.types.str;
description = ''
The hostname resolvable over tor used to luks boot unlock this machine
'';
};
};
});
};
userKeys = lib.mkOption {
default = [ ];
type = lib.types.listOf lib.types.str;
description = ''
The list of user keys. Each key here can be used to log into all other systems as `googlebot`.
TODO: consider auto populating other programs that use ssh keys such as gitea
'';
};
deployKeys = lib.mkOption {
default = [ ];
type = lib.types.listOf lib.types.str;
description = ''
The list of deployment keys. Each key here can be used to log into all other systems as `root`.
'';
};
configurationPath = lib.mkOption {
type = lib.types.path;
description = ''
The path to this machine's configuration directory.
'';
};
};
});
type = lib.types.attrsOf hostOptionsSubmoduleType;
};
};
options.thisMachine.config = lib.mkOption {
# For ease of use, a direct copy of the host config from machines.hosts.${hostName}
type = hostOptionsSubmoduleType;
};
config = {
assertions = (lib.concatLists (lib.mapAttrsToList
(
@@ -196,5 +192,16 @@ in
builtins.map (p: { "${dirName p}" = p; }) propFiles;
in
properties ../../machines;
# Don't try to evaluate "thisMachine" when reflecting using moduleless.nix.
# When evaluated by moduleless.nix this will fail due to networking.hostName not
# existing. This is because moduleless.nix is not intended for reflection from the
# perspective of a perticular machine but is instead intended for reflecting on
# the properties of all machines as a whole system.
thisMachine.config = config.machines.hosts.${config.networking.hostName};
# Add ssh keys from KeepassXC
machines.ssh.userKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILACiZO7QnB4bcmziVaUkUE0ZPMR0M/yJbbHYsHIZz9g" ];
machines.ssh.deployKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID58MvKGs3GDMMcN8Iyi9S59SciSrVM97wKtOvUAl3li" ];
};
}

View File

@@ -1,19 +1,55 @@
{ config, lib, ... }:
# Maps roles to their hosts
# Maps roles to their hosts.
# machines.withRole = {
# personal = [
# "machine1" "machine3"
# ];
# cache = [
# "machine2"
# ];
# };
#
# A list of all possible roles
# machines.allRoles = [
# "personal"
# "cache"
# ];
#
# For each role has true or false if the current machine has that role
# thisMachine.hasRole = {
# personal = true;
# cache = false;
# };
{
options.machines.roles = lib.mkOption {
options.machines.withRole = lib.mkOption {
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
};
options.machines.allRoles = lib.mkOption {
type = lib.types.listOf lib.types.str;
};
options.thisMachine.hasRole = lib.mkOption {
type = lib.types.attrsOf lib.types.bool;
};
config = {
machines.roles = lib.zipAttrs
machines.withRole = lib.zipAttrs
(lib.mapAttrsToList
(host: cfg:
lib.foldl (lib.mergeAttrs) { }
(builtins.map (role: { ${role} = host; })
cfg.systemRoles))
config.machines.hosts);
machines.allRoles = lib.attrNames config.machines.withRole;
thisMachine.hasRole = lib.mapAttrs
(role: cfg:
builtins.elem config.networking.hostName config.machines.withRole.${role}
)
config.machines.withRole;
};
}

View File

@@ -39,6 +39,6 @@ in
builtins.map
(host: machines.hosts.${host}.hostKey)
hosts)
machines.roles;
machines.withRole;
};
}

View File

@@ -151,7 +151,7 @@ in
partOf = [ containerServiceName ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ wireguard-tools jq curl iproute iputils ];
path = with pkgs; [ wireguard-tools jq curl iproute2 iputils ];
serviceConfig = {
Type = "oneshot";
@@ -224,7 +224,7 @@ in
after = [ "network.target" "network-online.target" ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ wireguard-tools iproute curl jq iptables ];
path = with pkgs; [ wireguard-tools iproute2 curl jq iptables ];
serviceConfig = {
Type = "oneshot";

View File

@@ -1,18 +1,14 @@
{ config, lib, ... }:
let
builderRole = "nix-builder";
builderUserName = "nix-builder";
machinesByRole = role: lib.filterAttrs (hostname: cfg: builtins.elem role cfg.systemRoles) config.machines.hosts;
otherMachinesByRole = role: lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) (machinesByRole role);
thisMachineHasRole = role: builtins.hasAttr config.networking.hostName (machinesByRole role);
builders = machinesByRole builderRole;
thisMachineIsABuilder = thisMachineHasRole builderRole;
builderRole = "nix-builder";
builders = config.machines.withRole.${builderRole};
thisMachineIsABuilder = config.thisMachine.hasRole.${builderRole};
# builders don't include themselves as a remote builder
otherBuilders = lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) builders;
otherBuilders = lib.filter (hostname: hostname != config.networking.hostName) builders;
in
lib.mkMerge [
# configure builder
@@ -40,9 +36,9 @@ lib.mkMerge [
nix.distributedBuilds = true;
nix.buildMachines = builtins.map
(builderCfg: {
hostName = builtins.elemAt builderCfg.hostNames 0;
system = builderCfg.arch;
(builderHostname: {
hostName = builderHostname;
system = config.machines.hosts.${builderHostname}.arch;
protocol = "ssh-ng";
sshUser = builderUserName;
sshKey = "/etc/ssh/ssh_host_ed25519_key";
@@ -50,7 +46,7 @@ lib.mkMerge [
speedFactor = 10;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
})
(builtins.attrValues otherBuilders);
otherBuilders;
# It is very likely that the builder's internet is faster or just as fast
nix.extraOptions = ''

View File

@@ -19,6 +19,15 @@ in
jack.enable = true;
};
services.pipewire.extraConfig.pipewire."92-fix-wine-audio" = {
context.properties = {
default.clock.rate = 48000;
default.clock.quantum = 256;
default.clock.min-quantum = 256;
default.clock.max-quantum = 2048;
};
};
users.users.googlebot.extraGroups = [ "audio" ];
# bt headset support

View File

@@ -41,32 +41,28 @@ in
"SpellcheckLanguage" = [ "en-US" ];
};
defaultSearchProviderSuggestURL = null;
defaultSearchProviderSearchURL = " https://duckduckgo.com/?q={searchTerms}&kp=-1&kl=us-en";
defaultSearchProviderSearchURL = "https://duckduckgo.com/?q={searchTerms}&kp=-1&kl=us-en";
};
# hardware accelerated video playback (on intel)
nixpkgs.config.packageOverrides = pkgs: {
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
chromium = pkgs.chromium.override {
enableWideVine = true;
# ungoogled = true;
# --enable-native-gpu-memory-buffers # fails on AMD APU
# --enable-webrtc-vp9-support
commandLineArgs = "--use-vulkan --use-gl=desktop --enable-zero-copy --enable-hardware-overlays --enable-features=VaapiVideoDecoder,CanvasOopRasterization --ignore-gpu-blocklist --enable-accelerated-mjpeg-decode --enable-accelerated-video --enable-gpu-rasterization";
commandLineArgs = "--use-vulkan";
};
};
# todo vulkan in chrome
# todo video encoding in chrome
hardware.opengl = {
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver # LIBVA_DRIVER_NAME=iHD
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
# vaapiVdpau
libvdpau-va-gl
nvidia-vaapi-driver
];
extraPackages32 = with pkgs.pkgsi686Linux; [ vaapiIntel ];
};
};
}

View File

@@ -6,19 +6,18 @@ in
{
imports = [
./kde.nix
./xfce.nix
./yubikey.nix
./chromium.nix
# ./firefox.nix
./firefox.nix
./audio.nix
# ./torbrowser.nix
./pithos.nix
./spotify.nix
./vscodium.nix
./discord.nix
./steam.nix
./touchpad.nix
./mount-samba.nix
./udev.nix
./virtualisation.nix
];
options.de = {
@@ -26,9 +25,10 @@ in
};
config = lib.mkIf cfg.enable {
# vulkan
hardware.opengl.driSupport = true;
hardware.opengl.driSupport32Bit = true;
environment.systemPackages = with pkgs; [
# https://github.com/NixOS/nixpkgs/pull/328086#issuecomment-2235384618
gparted
];
# Applications
users.users.googlebot.packages = with pkgs; [
@@ -41,23 +41,22 @@ in
mpv
nextcloud-client
signal-desktop
minecraft
gparted
libreoffice-fresh
thunderbird
spotifyd
spotify-qt
spotify
arduino
yt-dlp
jellyfin-media-player
joplin-desktop
config.inputs.deploy-rs.packages.${config.currentSystem}.deploy-rs
lxqt.pavucontrol-qt
barrier
deskflow
file-roller
android-tools
# For Nix IDE
nixpkgs-fmt
rnix-lsp
nixd
nil
];
# Networking
@@ -71,12 +70,29 @@ in
];
# Printer discovery
services.avahi.enable = true;
services.avahi.nssmdns = true;
programs.file-roller.enable = true;
services.avahi.nssmdns4 = true;
# Security
services.gnome.gnome-keyring.enable = true;
security.pam.services.googlebot.enableGnomeKeyring = true;
# Mount personal SMB stores
services.mount-samba.enable = true;
# allow building ARM derivations
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
# for luks onlock over tor
services.tor.enable = true;
services.tor.client.enable = true;
# Enable wayland support in various chromium based applications
environment.sessionVariables.NIXOS_OZONE_WL = "1";
fonts.packages = with pkgs; [ nerd-fonts.symbols-only ];
# SSH Ask pass
programs.ssh.enableAskPassword = true;
programs.ssh.askPassword = "${pkgs.kdePackages.ksshaskpass}/bin/ksshaskpass";
};
}

View File

@@ -20,31 +20,6 @@ let
};
firefox = pkgs.wrapFirefox somewhatPrivateFF {
desktopName = "Sneed Browser";
nixExtensions = [
(pkgs.fetchFirefoxAddon {
name = "ublock-origin";
url = "https://addons.mozilla.org/firefox/downloads/file/3719054/ublock_origin-1.33.2-an+fx.xpi";
sha256 = "XDpe9vW1R1iVBTI4AmNgAg1nk7BVQdIAMuqd0cnK5FE=";
})
(pkgs.fetchFirefoxAddon {
name = "sponsorblock";
url = "https://addons.mozilla.org/firefox/downloads/file/3720594/sponsorblock_skip_sponsorships_on_youtube-2.0.12.3-an+fx.xpi";
sha256 = "HRtnmZWyXN3MKo4AvSYgNJGkBEsa2RaMamFbkz+YzQg=";
})
(pkgs.fetchFirefoxAddon {
name = "KeePassXC-Browser";
url = "https://addons.mozilla.org/firefox/downloads/file/3720664/keepassxc_browser-1.7.6-fx.xpi";
sha256 = "3K404/eq3amHhIT0WhzQtC892he5I0kp2SvbzE9dbZg=";
})
(pkgs.fetchFirefoxAddon {
name = "https-everywhere";
url = "https://addons.mozilla.org/firefox/downloads/file/3716461/https_everywhere-2021.1.27-an+fx.xpi";
sha256 = "2gSXSLunKCwPjAq4Wsj0lOeV551r3G+fcm1oeqjMKh8=";
})
];
extraPolicies = {
CaptivePortal = false;
DisableFirefoxStudies = true;
@@ -74,12 +49,6 @@ let
ExtensionRecommendations = false;
SkipOnboarding = true;
};
WebsiteFilter = {
Block = [
"http://paradigminteractive.io/"
"https://paradigminteractive.io/"
];
};
};
extraPrefs = ''

View File

@@ -5,22 +5,17 @@ let
in
{
config = lib.mkIf cfg.enable {
# kde plasma
services.xserver = {
enable = true;
desktopManager.plasma5.enable = true;
displayManager.sddm.enable = true;
};
services.displayManager.sddm.enable = true;
services.displayManager.sddm.wayland.enable = true;
services.desktopManager.plasma6.enable = true;
# kde apps
nixpkgs.config.firefox.enablePlasmaBrowserIntegration = true;
users.users.googlebot.packages = with pkgs; [
# akonadi
# kmail
# plasma5Packages.kmail-account-wizard
kate
kdePackages.kate
kdePackages.kdeconnect-kde
];
services.xserver.desktopManager.plasma5.useQtScaling = true;
};
}

View File

@@ -1,86 +0,0 @@
{ lib, config, pkgs, ... }:
with lib;
let
cfg = config.services.spotifyd;
toml = pkgs.formats.toml { };
spotifydConf = toml.generate "spotify.conf" cfg.settings;
in
{
disabledModules = [
"services/audio/spotifyd.nix"
];
options = {
services.spotifyd = {
enable = mkEnableOption "spotifyd, a Spotify playing daemon";
settings = mkOption {
default = { };
type = toml.type;
example = { global.bitrate = 320; };
description = ''
Configuration for Spotifyd. For syntax and directives, see
<link xlink:href="https://github.com/Spotifyd/spotifyd#Configuration"/>.
'';
};
users = mkOption {
type = with types; listOf str;
default = [ ];
description = ''
Usernames to be added to the "spotifyd" group, so that they
can start and interact with the userspace daemon.
'';
};
};
};
config = mkIf cfg.enable {
# username specific stuff because i'm lazy...
services.spotifyd.users = [ "googlebot" ];
users.users.googlebot.packages = with pkgs; [
spotify
spotify-tui
];
users.groups.spotifyd = {
members = cfg.users;
};
age.secrets.spotifyd = {
file = ../../secrets/spotifyd.age;
group = "spotifyd";
mode = "0440"; # group can read
};
# spotifyd to read secrets and run as user service
services.spotifyd = {
settings.global = {
username_cmd = "sed '1q;d' /run/agenix/spotifyd";
password_cmd = "sed '2q;d' /run/agenix/spotifyd";
bitrate = 320;
backend = "pulseaudio";
device_name = config.networking.hostName;
device_type = "computer";
# on_song_change_hook = "command_to_run_on_playback_events"
autoplay = true;
};
};
systemd.user.services.spotifyd-daemon = {
enable = true;
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
description = "spotifyd, a Spotify playing daemon";
environment.SHELL = "/bin/sh";
serviceConfig = {
ExecStart = "${pkgs.spotifyd}/bin/spotifyd --no-daemon --config-path ${spotifydConf}";
Restart = "always";
CacheDirectory = "spotifyd";
};
};
};
}

View File

@@ -1,25 +0,0 @@
{ lib, config, pkgs, ... }:
let
cfg = config.de;
in
{
config = lib.mkIf cfg.enable {
nixpkgs.overlays = [
(self: super: {
tor-browser-bundle-bin = super.tor-browser-bundle-bin.overrideAttrs (old: rec {
version = "10.0.10";
lang = "en-US";
src = pkgs.fetchurl {
url = "https://dist.torproject.org/torbrowser/${version}/tor-browser-linux64-${version}_${lang}.tar.xz";
sha256 = "vYWZ+NsGN8YH5O61+zrUjlFv3rieaBqjBQ+a18sQcZg=";
};
});
})
];
users.users.googlebot.packages = with pkgs; [
tor-browser-bundle-bin
];
};
}

View File

@@ -1,15 +1,11 @@
{ lib, config, pkgs, ... }:
let
cfg = config.de.touchpad;
cfg = config.de;
in
{
options.de.touchpad = {
enable = lib.mkEnableOption "enable touchpad";
};
config = lib.mkIf cfg.enable {
services.xserver.libinput.enable = true;
services.xserver.libinput.touchpad.naturalScrolling = true;
services.libinput.enable = true;
services.libinput.touchpad.naturalScrolling = true;
};
}

25
common/pc/udev.nix Normal file
View File

@@ -0,0 +1,25 @@
{ config, lib, pkgs, ... }:
let
cfg = config.de;
in
{
config = lib.mkIf cfg.enable {
services.udev.extraRules = ''
# depthai
SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"
# Moonlander
# Rules for Oryx web flashing and live training
KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", MODE="0664", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="3297", MODE="0664", GROUP="plugdev"
# Wally Flashing rules for the Moonlander and Planck EZ
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666", SYMLINK+="stm32_dfu"
'';
services.udev.packages = [ pkgs.platformio ];
users.groups.plugdev = {
members = [ "googlebot" ];
};
};
}

View File

@@ -1,22 +0,0 @@
diff --git a/meson.build b/meson.build
index dace367..8c0e290 100644
--- a/meson.build
+++ b/meson.build
@@ -8,7 +8,7 @@ project(
'warning_level=0',
],
license: 'MIT',
- meson_version: '>= 0.58.0',
+ meson_version: '>= 0.57.0',
)
cc = meson.get_compiler('c')
@@ -47,8 +47,3 @@ shared_library(
gnu_symbol_visibility: 'hidden',
)
-meson.add_devenv(environment({
- 'NVD_LOG': '1',
- 'LIBVA_DRIVER_NAME': 'nvidia',
- 'LIBVA_DRIVERS_PATH': meson.project_build_root(),
-}))

View File

@@ -0,0 +1,23 @@
{ config, lib, pkgs, ... }:
let
cfg = config.de;
in
{
config = lib.mkIf cfg.enable {
# AppVMs
virtualisation.appvm.enable = true;
virtualisation.appvm.user = "googlebot";
# Use podman instead of docker
virtualisation.podman.enable = true;
virtualisation.podman.dockerCompat = true;
# virt-manager
virtualisation.libvirtd.enable = true;
programs.dconf.enable = true;
virtualisation.spiceUSBRedirection.enable = true;
environment.systemPackages = with pkgs; [ virt-manager ];
users.users.googlebot.extraGroups = [ "libvirtd" "adbusers" ];
};
}

View File

@@ -11,12 +11,17 @@ let
golang.go
jnoortheen.nix-ide
ms-vscode.cpptools
rust-lang.rust-analyzer
vadimcn.vscode-lldb
tauri-apps.tauri-vscode
platformio.platformio-vscode-ide
vue.volar
] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
name = "platformio-ide";
publisher = "platformio";
version = "3.1.1";
sha256 = "g9yTG3DjVUS2w9eHGAai5LoIfEGus+FPhqDnCi4e90Q=";
name = "wgsl-analyzer";
publisher = "wgsl-analyzer";
version = "0.12.105";
sha256 = "sha256-NheEVNIa8CIlyMebAhxRKS44b1bZiWVt8PgC6r3ExMA=";
}
];

View File

@@ -1,23 +0,0 @@
{ lib, config, pkgs, ... }:
let
cfg = config.de;
in
{
config = lib.mkIf cfg.enable {
services.xserver = {
enable = true;
desktopManager = {
xterm.enable = false;
xfce.enable = true;
};
displayManager.sddm.enable = true;
};
# xfce apps
# TODO for some reason whiskermenu needs to be global for it to work
environment.systemPackages = with pkgs; [
xfce.xfce4-whiskermenu-plugin
];
};
}

View File

@@ -0,0 +1,16 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.actual;
in
{
config = lib.mkIf cfg.enable {
services.actual.settings = {
port = 25448;
};
backup.group."actual-budget".paths = [
"/var/lib/actual"
];
};
}

View File

@@ -1,53 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.dashy;
in
{
options.services.dashy = {
enable = mkEnableOption "dashy";
imageTag = mkOption {
type = types.str;
default = "latest";
};
port = mkOption {
type = types.int;
default = 56815;
};
configFile = lib.mkOption {
type = lib.types.path;
description = "Path to the YAML configuration file";
};
};
config = mkIf cfg.enable {
virtualisation.oci-containers.containers = {
dashy = {
image = "lissy93/dashy:${cfg.imageTag}";
environment = {
TZ = "${config.time.timeZone}";
};
ports = [
"127.0.0.1:${toString cfg.port}:80"
];
volumes = [
"${cfg.configFile}:/app/public/conf.yml"
];
};
};
services.nginx.enable = true;
services.nginx.virtualHosts."s0.koi-bebop.ts.net" = {
default = true;
addSSL = true;
serverAliases = [ "s0" ];
sslCertificate = "/secret/ssl/s0.koi-bebop.ts.net.crt";
sslCertificateKey = "/secret/ssl/s0.koi-bebop.ts.net.key";
locations."/" = {
proxyPass = "http://localhost:${toString cfg.port}";
};
};
};
}

View File

@@ -10,8 +10,6 @@
./matrix.nix
./zerobin.nix
./gitea.nix
./privatebin/privatebin.nix
./radio.nix
./samba.nix
./owncast.nix
./mailserver.nix
@@ -19,7 +17,8 @@
./iodine.nix
./searx.nix
./gitea-actions-runner.nix
./dashy.nix
./librechat.nix
./actualbudget.nix
./unifi.nix
];
}

View File

@@ -9,10 +9,7 @@
# TODO: skipping running inside of nixos container for now because of issues getting docker/podman running
let
runnerRole = "gitea-actions-runner";
runners = config.machines.roles.${runnerRole};
thisMachineIsARunner = builtins.elem config.networking.hostName runners;
thisMachineIsARunner = config.thisMachine.hasRole."gitea-actions-runner";
containerName = "gitea-runner";
in
{

View File

@@ -24,7 +24,7 @@ in
SHOW_FOOTER_VERSION = false;
};
ui = {
DEFAULT_THEME = "arc-green";
DEFAULT_THEME = "gitea-dark";
};
service = {
DISABLE_REGISTRATION = true;

View File

@@ -3,10 +3,10 @@
with lib;
let
cfg = config.services.librechat;
cfg = config.services.librechat-container;
in
{
options.services.librechat = {
options.services.librechat-container = {
enable = mkEnableOption "librechat";
port = mkOption {
type = types.int;
@@ -21,11 +21,18 @@ in
config = mkIf cfg.enable {
virtualisation.oci-containers.containers = {
librechat = {
image = "ghcr.io/danny-avila/librechat:v0.6.6";
image = "ghcr.io/danny-avila/librechat:v0.8.1";
environment = {
HOST = "0.0.0.0";
MONGO_URI = "mongodb://host.containers.internal:27017/LibreChat";
ENDPOINTS = "openAI,google,bingAI,gptPlugins";
OPENAI_MODELS = lib.concatStringsSep "," [
"gpt-4o-mini"
"o3-mini"
"gpt-4o"
"o1"
];
REFRESH_TOKEN_EXPIRY = toString (1000 * 60 * 60 * 24 * 30); # 30 days
};
environmentFiles = [
"/run/agenix/librechat-env-file"

View File

@@ -28,7 +28,6 @@ in
indexDir = "/var/lib/mailindex";
enableManageSieve = true;
fullTextSearch.enable = true;
fullTextSearch.indexAttachments = true;
fullTextSearch.memoryLimit = 500;
inherit domains;
loginAccounts = {
@@ -55,6 +54,8 @@ in
"joslyn@runyan.org"
"damon@runyan.org"
"jonas@runyan.org"
"simon@neet.dev"
"ellen@runyan.org"
];
forwards = {
"amazon@runyan.org" = [
@@ -62,18 +63,28 @@ in
"cris@runyan.org"
];
};
certificateScheme = 3; # use let's encrypt for certs
x509.useACMEHost = config.mailserver.fqdn; # use let's encrypt for certs
stateVersion = 3;
};
age.secrets.hashed-email-pw.file = ../../secrets/hashed-email-pw.age;
age.secrets.cris-hashed-email-pw.file = ../../secrets/cris-hashed-email-pw.age;
age.secrets.hashed-robots-email-pw.file = ../../secrets/hashed-robots-email-pw.age;
# Get let's encrypt cert
services.nginx = {
enable = true;
virtualHosts."${config.mailserver.fqdn}" = {
forceSSL = true;
enableACME = true;
};
};
# sendmail to use xxx@domain instead of xxx@mail.domain
services.postfix.origin = "$mydomain";
services.postfix.settings.main.myorigin = "$mydomain";
# relay sent mail through mailgun
# https://www.howtoforge.com/community/threads/different-smtp-relays-for-different-domains-in-postfix.82711/#post-392620
services.postfix.config = {
services.postfix.settings.main = {
smtp_sasl_auth_enable = "yes";
smtp_sasl_security_options = "noanonymous";
smtp_sasl_password_maps = "hash:/var/lib/postfix/conf/sasl_relay_passwd";
@@ -91,7 +102,6 @@ in
age.secrets.sasl_relay_passwd.file = ../../secrets/sasl_relay_passwd.age;
# webmail
services.nginx.enable = true;
services.roundcube = {
enable = true;
hostName = config.mailserver.fqdn;

View File

@@ -3,17 +3,44 @@
let
cfg = config.services.nextcloud;
nextcloudHostname = "runyan.org";
collaboraOnlineHostname = "collabora.runyan.org";
whiteboardHostname = "whiteboard.runyan.org";
whiteboardPort = 3002; # Seems impossible to change
# Hardcoded public ip of ponyo... I wish I didn't need this...
public_ip_address = "147.135.114.130";
in
{
config = lib.mkIf cfg.enable {
services.nextcloud = {
https = true;
package = pkgs.nextcloud28;
hostName = "neet.cloud";
package = pkgs.nextcloud32;
hostName = nextcloudHostname;
config.dbtype = "sqlite";
config.adminuser = "jeremy";
config.adminpassFile = "/run/agenix/nextcloud-pw";
# Apps
autoUpdateApps.enable = true;
extraAppsEnable = true;
extraApps = with config.services.nextcloud.package.packages.apps; {
# Want
inherit end_to_end_encryption mail spreed;
# For file and document editing (collabora online and excalidraw)
inherit richdocuments whiteboard;
# Might use
inherit calendar qownnotesapi;
# Try out
# inherit bookmarks cookbook deck memories maps music news notes phonetrack polls forms;
};
# Allows installing Apps from the UI (might remove later)
appstoreEnable = true;
};
age.secrets.nextcloud-pw = {
file = ../../secrets/nextcloud-pw.age;
@@ -29,5 +56,100 @@ in
enableACME = true;
forceSSL = true;
};
# collabora-online
# https://diogotc.com/blog/collabora-nextcloud-nixos/
services.collabora-online = {
enable = true;
port = 15972;
settings = {
# Rely on reverse proxy for SSL
ssl = {
enable = false;
termination = true;
};
# Listen on loopback interface only
net = {
listen = "loopback";
post_allow.host = [ "localhost" ];
};
# Restrict loading documents from WOPI Host
storage.wopi = {
"@allow" = true;
host = [ config.services.nextcloud.hostName ];
};
server_name = collaboraOnlineHostname;
};
};
services.nginx.virtualHosts.${config.services.collabora-online.settings.server_name} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.collabora-online.port}";
proxyWebsockets = true;
};
};
systemd.services.nextcloud-config-collabora =
let
wopi_url = "http://localhost:${toString config.services.collabora-online.port}";
public_wopi_url = "https://${collaboraOnlineHostname}";
wopi_allowlist = lib.concatStringsSep "," [
"127.0.0.1"
"::1"
public_ip_address
];
in
{
wantedBy = [ "multi-user.target" ];
after = [ "nextcloud-setup.service" "coolwsd.service" ];
requires = [ "coolwsd.service" ];
path = [
config.services.nextcloud.occ
];
script = ''
nextcloud-occ -- config:app:set richdocuments wopi_url --value ${lib.escapeShellArg wopi_url}
nextcloud-occ -- config:app:set richdocuments public_wopi_url --value ${lib.escapeShellArg public_wopi_url}
nextcloud-occ -- config:app:set richdocuments wopi_allowlist --value ${lib.escapeShellArg wopi_allowlist}
nextcloud-occ -- richdocuments:setup
'';
serviceConfig = {
Type = "oneshot";
};
};
# Whiteboard
services.nextcloud-whiteboard-server = {
enable = true;
settings.NEXTCLOUD_URL = "https://${nextcloudHostname}";
secrets = [ "/run/agenix/whiteboard-server-jwt-secret" ];
};
systemd.services.nextcloud-config-whiteboard = {
wantedBy = [ "multi-user.target" ];
after = [ "nextcloud-setup.service" ];
requires = [ "coolwsd.service" ];
path = [
config.services.nextcloud.occ
];
script = ''
nextcloud-occ -- config:app:set whiteboard collabBackendUrl --value="https://${whiteboardHostname}"
nextcloud-occ -- config:app:set whiteboard jwt_secret_key --value="$JWT_SECRET_KEY"
'';
serviceConfig = {
Type = "oneshot";
EnvironmentFile = [ "/run/agenix/whiteboard-server-jwt-secret" ];
};
};
age.secrets.whiteboard-server-jwt-secret.file = ../../secrets/whiteboard-server-jwt-secret.age;
services.nginx.virtualHosts.${whiteboardHostname} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${toString whiteboardPort}";
proxyWebsockets = true;
};
};
};
}

View File

@@ -4,6 +4,10 @@ let
cfg = config.services.nginx;
in
{
options.services.nginx = {
openFirewall = lib.mkEnableOption "Open firewall ports 80 and 443";
};
config = lib.mkIf cfg.enable {
services.nginx = {
recommendedGzipSettings = true;
@@ -12,6 +16,8 @@ in
recommendedTlsSettings = true;
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx.openFirewall = lib.mkDefault true;
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 80 443 ];
};
}

View File

@@ -1,42 +0,0 @@
;<?php http_response_code(403); /*
[main]
name = "Kode Paste"
discussion = false
opendiscussion = false
password = true
fileupload = false
burnafterreadingselected = false
defaultformatter = "plaintext"
sizelimit = 10485760
template = "bootstrap"
languageselection = false
[expire]
default = "1week"
[expire_options]
5min = 300
10min = 600
1hour = 3600
1day = 86400
1week = 604800
[formatter_options]
plaintext = "Plain Text"
syntaxhighlighting = "Source Code"
markdown = "Markdown"
[traffic]
limit = 10
dir = "/var/lib/privatebin"
[purge]
limit = 300
batchsize = 10
dir = "/var/lib/privatebin"
[model]
class = Filesystem
[model_options]
dir = "/var/lib/privatebin"

View File

@@ -1,74 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.privatebin;
privateBinSrc = pkgs.stdenv.mkDerivation {
name = "privatebin";
src = pkgs.fetchFromGitHub {
owner = "privatebin";
repo = "privatebin";
rev = "d65bf02d7819a530c3c2a88f6f9947651fe5258d";
sha256 = "7ttAvEDL1ab0cUZcqZzXFkXwB2rF2t4eNpPxt48ap94=";
};
installPhase = ''
cp -ar $src $out
'';
};
in
{
options.services.privatebin = {
enable = lib.mkEnableOption "enable privatebin";
host = lib.mkOption {
type = lib.types.str;
example = "example.com";
};
};
config = lib.mkIf cfg.enable {
users.users.privatebin = {
description = "privatebin service user";
group = "privatebin";
isSystemUser = true;
};
users.groups.privatebin = { };
services.nginx.enable = true;
services.nginx.virtualHosts.${cfg.host} = {
enableACME = true;
forceSSL = true;
locations."/" = {
root = privateBinSrc;
index = "index.php";
};
locations."~ \.php$" = {
root = privateBinSrc;
extraConfig = ''
fastcgi_pass unix:${config.services.phpfpm.pools.privatebin.socket};
fastcgi_index index.php;
'';
};
};
systemd.tmpfiles.rules = [
"d '/var/lib/privatebin' 0750 privatebin privatebin - -"
];
services.phpfpm.pools.privatebin = {
user = "privatebin";
group = "privatebin";
phpEnv = {
CONFIG_PATH = "${./conf.php}";
};
settings = {
pm = "dynamic";
"listen.owner" = config.services.nginx.user;
"pm.max_children" = 5;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 1;
"pm.max_spare_servers" = 3;
"pm.max_requests" = 500;
};
};
};
}

View File

@@ -1,75 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.radio;
radioPackage = config.inputs.radio.packages.${config.currentSystem}.radio;
in
{
options.services.radio = {
enable = lib.mkEnableOption "enable radio";
user = lib.mkOption {
type = lib.types.str;
default = "radio";
description = ''
The user radio should run as
'';
};
group = lib.mkOption {
type = lib.types.str;
default = "radio";
description = ''
The group radio should run as
'';
};
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/radio";
description = ''
Path to the radio data directory
'';
};
host = lib.mkOption {
type = lib.types.str;
description = ''
Domain radio is hosted on
'';
};
nginx = lib.mkEnableOption "enable nginx";
};
config = lib.mkIf cfg.enable {
services.icecast = {
enable = true;
hostname = cfg.host;
mount = "stream.mp3";
fallback = "fallback.mp3";
};
services.nginx.virtualHosts.${cfg.host} = lib.mkIf cfg.nginx {
enableACME = true;
forceSSL = true;
locations."/".root = config.inputs.radio-web;
};
users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
home = cfg.dataDir;
createHome = true;
};
users.groups.${cfg.group} = { };
systemd.services.radio = {
enable = true;
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig.ExecStart = "${radioPackage}/bin/radio ${config.services.icecast.listen.address}:${toString config.services.icecast.listen.port} ${config.services.icecast.mount} 5500";
serviceConfig.User = cfg.user;
serviceConfig.Group = cfg.group;
serviceConfig.WorkingDirectory = cfg.dataDir;
preStart = ''
mkdir -p ${cfg.dataDir}
chown ${cfg.user} ${cfg.dataDir}
'';
};
};
}

View File

@@ -5,30 +5,28 @@
services.samba = {
openFirewall = true;
package = pkgs.sambaFull; # printer sharing
securityType = "user";
# should this be on?
nsswins = true;
extraConfig = ''
workgroup = HOME
server string = smbnix
netbios name = smbnix
security = user
use sendfile = yes
min protocol = smb2
guest account = nobody
map to guest = bad user
settings = {
global = {
security = "user";
workgroup = "HOME";
"server string" = "smbnix";
"netbios name" = "smbnix";
"use sendfile" = "yes";
"min protocol" = "smb2";
"guest account" = "nobody";
"map to guest" = "bad user";
# printing
load printers = yes
printing = cups
printcap name = cups
# printing
"load printers" = "yes";
printing = "cups";
"printcap name" = "cups";
hide files = /.nobackup/.DS_Store/._.DS_Store/
'';
shares = {
"hide files" = "/.nobackup/.DS_Store/._.DS_Store/";
};
public = {
path = "/data/samba/Public";
browseable = "yes";
@@ -77,9 +75,9 @@
# backups
backup.group."samba".paths = [
config.services.samba.shares.googlebot.path
config.services.samba.shares.cris.path
config.services.samba.shares.public.path
config.services.samba.settings.googlebot.path
config.services.samba.settings.cris.path
config.services.samba.settings.public.path
];
# Windows discovery of samba server
@@ -97,7 +95,7 @@
# Printer discovery
# (is this needed?)
services.avahi.enable = true;
services.avahi.nssmdns = true;
services.avahi.nssmdns4 = true;
# printer sharing
systemd.tmpfiles.rules = [

26
common/server/unifi.nix Normal file
View File

@@ -0,0 +1,26 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.unifi;
in
{
options.services.unifi = {
# Open select Unifi ports instead of using openFirewall to avoid opening access to unifi's control panel
openMinimalFirewall = lib.mkEnableOption "Open bare minimum firewall ports";
};
config = lib.mkIf cfg.enable {
services.unifi.unifiPackage = pkgs.unifi;
services.unifi.mongodbPackage = pkgs.mongodb-7_0;
networking.firewall = lib.mkIf cfg.openMinimalFirewall {
allowedUDPPorts = [
3478 # STUN
10001 # used for device discovery.
];
allowedTCPPorts = [
8080 # Used for device and application communication.
];
};
};
}

View File

@@ -21,8 +21,6 @@
shellInit = ''
# disable annoying fish shell greeting
set fish_greeting
alias sudo="doas"
'';
};
@@ -34,6 +32,8 @@
io_seq_write = "${pkgs.fio}/bin/fio --name TEST --eta-newline=5s --filename=temp.file --rw=write --size=2g --io_size=10g --blocksize=1024k --ioengine=libaio --fsync=10000 --iodepth=32 --direct=1 --numjobs=1 --runtime=60 --group_reporting; rm temp.file";
io_rand_read = "${pkgs.fio}/bin/fio --name TEST --eta-newline=5s --filename=temp.file --rw=randread --size=2g --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=32 --runtime=60 --group_reporting; rm temp.file";
io_rand_write = "${pkgs.fio}/bin/fio --name TEST --eta-newline=5s --filename=temp.file --rw=randrw --size=2g --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=1 --runtime=60 --group_reporting; rm temp.file";
llsblk = "lsblk -o +uuid,fsType";
};
nixpkgs.overlays = [
@@ -41,6 +41,9 @@
# comma uses the "nix-index" package built into nixpkgs by default.
# That package doesn't use the prebuilt nix-index database so it needs to be changed.
comma = prev.comma.overrideAttrs (old: {
nativeBuildInputs = old.nativeBuildInputs ++ [
prev.makeWrapper
];
postInstall = ''
wrapProgram $out/bin/comma \
--prefix PATH : ${lib.makeBinPath [ prev.fzy config.programs.nix-index.package ]}

View File

@@ -31,8 +31,6 @@
# TODO: Old ssh keys I will remove some day...
machines.ssh.userKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMVR/R3ZOsv7TZbICGBCHdjh1NDT8SnswUyINeJOC7QG"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0dcqL/FhHmv+a1iz3f9LJ48xubO7MZHy35rW9SZOYM"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHSkKiRUUmnErOKGx81nyge/9KqjkPh8BfDk0D3oP586" # nat
];
}

272
flake.lock generated
View File

@@ -3,18 +3,22 @@
"agenix": {
"inputs": {
"darwin": "darwin",
"home-manager": "home-manager",
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1703433843,
"narHash": "sha256-nmtA4KqFboWxxoOAA6Y1okHbZh+HsXaMPFkYHsoDRDw=",
"lastModified": 1762618334,
"narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=",
"owner": "ryantm",
"repo": "agenix",
"rev": "417caa847f9383e111d1397039c9d4337d024bf0",
"rev": "fcdea223397448d35d9b31f798479227e80183f6",
"type": "github"
},
"original": {
@@ -49,17 +53,17 @@
]
},
"locked": {
"lastModified": 1651719222,
"narHash": "sha256-p/GY5vOP+HUlxNL4OtEhmBNEVQsedOHXEmjfCGONVmE=",
"lastModified": 1739947126,
"narHash": "sha256-JoiddH5H9up8jC/VKU8M7wDlk/bstKoJ3rHj+TkW4Zo=",
"ref": "refs/heads/master",
"rev": "1290ddd9a2ff2bf2d0f702750768312b80efcd34",
"revCount": 19,
"rev": "ea1ad60f1c6662103ef4a3705d8e15aa01219529",
"revCount": 20,
"type": "git",
"url": "https://git.neet.dev/zuckerberg/dailybuild_modules.git"
"url": "https://git.neet.dev/zuckerberg/dailybot.git"
},
"original": {
"type": "git",
"url": "https://git.neet.dev/zuckerberg/dailybuild_modules.git"
"url": "https://git.neet.dev/zuckerberg/dailybot.git"
}
},
"darwin": {
@@ -70,11 +74,11 @@
]
},
"locked": {
"lastModified": 1700795494,
"narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=",
"lastModified": 1744478979,
"narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d",
"rev": "43975d782b418ebf4969e9ccba82466728c2851b",
"type": "github"
},
"original": {
@@ -86,21 +90,22 @@
},
"deploy-rs": {
"inputs": {
"flake-compat": "flake-compat",
"flake-compat": [
"flake-compat"
],
"nixpkgs": [
"nixpkgs"
],
"utils": [
"simple-nixos-mailserver",
"utils"
"flake-utils"
]
},
"locked": {
"lastModified": 1704875591,
"narHash": "sha256-eWRLbqRcrILgztU/m/k7CYLzETKNbv0OsT2GjkaNm8A=",
"lastModified": 1766051518,
"narHash": "sha256-znKOwPXQnt3o7lDb3hdf19oDo0BLP4MfBOYiWkEHoik=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "1776009f1f3fb2b5d236b84d9815f2edee463a9b",
"rev": "d5eff7f948535b9c723d60cd8239f8f11ddc90fa",
"type": "github"
},
"original": {
@@ -109,26 +114,14 @@
"type": "github"
}
},
"fix-nvidia-x11-latest": {
"flake": false,
"locked": {
"narHash": "sha256-fLopADeWElHn3zRLJxyRZf2pjXsPQL4K1NaZ9Dmaj3E=",
"type": "file",
"url": "https://github.com/NixOS/nixpkgs/pull/286084.diff"
},
"original": {
"type": "file",
"url": "https://github.com/NixOS/nixpkgs/pull/286084.diff"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
@@ -139,14 +132,16 @@
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@@ -155,23 +150,71 @@
"type": "github"
}
},
"home-manager": {
"git-hooks": {
"inputs": {
"flake-compat": [
"simple-nixos-mailserver",
"flake-compat"
],
"gitignore": "gitignore",
"nixpkgs": [
"agenix",
"simple-nixos-mailserver",
"nixpkgs"
]
},
"locked": {
"lastModified": 1703113217,
"narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
"lastModified": 1763988335,
"narHash": "sha256-QlcnByMc8KBjpU37rbq5iP7Cp97HvjRP0ucfdh+M4Qc=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"simple-nixos-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"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1768068402,
"narHash": "sha256-bAXnnJZKJiF7Xr6eNW6+PhBf1lg2P1aFUO9+xgWkXfA=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
"rev": "8bc5473b6bc2b6e1529a9c4040411e1199c43b4c",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "master",
"repo": "home-manager",
"type": "github"
}
@@ -183,11 +226,11 @@
]
},
"locked": {
"lastModified": 1707016097,
"narHash": "sha256-V4lHr6hFQ3rK650dh64Xffxsf4kse9vUYWsM+ldjkco=",
"lastModified": 1765267181,
"narHash": "sha256-d3NBA9zEtBu2JFMnTBqWj7Tmi7R5OikoU2ycrdhQEws=",
"owner": "Mic92",
"repo": "nix-index-database",
"rev": "3e3dad2808379c522138e2e8b0eb73500721a237",
"rev": "82befcf7dc77c909b0f2a09f5da910ec95c5b78f",
"type": "github"
},
"original": {
@@ -196,112 +239,75 @@
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1767185284,
"narHash": "sha256-ljDBUDpD1Cg5n3mJI81Hz5qeZAwCGxon4kQW3Ho3+6Q=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "40b1a28dce561bea34858287fbb23052c3ee63fe",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1706826059,
"narHash": "sha256-N69Oab+cbt3flLvYv8fYnEHlBsWwdKciNZHUbynVEOA=",
"lastModified": 1768105724,
"narHash": "sha256-0edMCoDc1VpuqDjy0oz8cDa4kjRuhXE3040sac2iZW4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "25e3d4c0d3591c99929b1ec07883177f6ea70c9d",
"rev": "4c41b0361812441bf3b4427195e57ab271d5167f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.11",
"ref": "master",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-22_05": {
"locked": {
"lastModified": 1654936503,
"narHash": "sha256-soKzdhI4jTHv/rSbh89RdlcJmrPgH8oMb/PLqiqIYVQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "dab6df51387c3878cdea09f43589a15729cae9f4",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-22.05",
"type": "indirect"
}
},
"radio": {
"inputs": {
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1631585589,
"narHash": "sha256-q4o/4/2pEuJyaKZwNQC5KHnzG1obClzFB7zWk9XSDfY=",
"ref": "main",
"rev": "5bf607fed977d41a269942a7d1e92f3e6d4f2473",
"revCount": 38,
"type": "git",
"url": "https://git.neet.dev/zuckerberg/radio.git"
},
"original": {
"ref": "main",
"rev": "5bf607fed977d41a269942a7d1e92f3e6d4f2473",
"type": "git",
"url": "https://git.neet.dev/zuckerberg/radio.git"
}
},
"radio-web": {
"flake": false,
"locked": {
"lastModified": 1652121792,
"narHash": "sha256-j1Y9MAjUVNgyFSeGzPoqibAnEysJDjZSXukVfQ7+bsQ=",
"ref": "refs/heads/master",
"rev": "72e7a9e80b780c84ed8d4a6374bfbb242701f900",
"revCount": 5,
"type": "git",
"url": "https://git.neet.dev/zuckerberg/radio-web.git"
},
"original": {
"type": "git",
"url": "https://git.neet.dev/zuckerberg/radio-web.git"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"dailybuild_modules": "dailybuild_modules",
"deploy-rs": "deploy-rs",
"fix-nvidia-x11-latest": "fix-nvidia-x11-latest",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"home-manager": "home-manager",
"nix-index-database": "nix-index-database",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs",
"radio": "radio",
"radio-web": "radio-web",
"simple-nixos-mailserver": "simple-nixos-mailserver"
"simple-nixos-mailserver": "simple-nixos-mailserver",
"systems": "systems"
}
},
"simple-nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"flake-compat": [
"flake-compat"
],
"git-hooks": "git-hooks",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-22_05": "nixpkgs-22_05",
"utils": "utils"
]
},
"locked": {
"lastModified": 1655930346,
"narHash": "sha256-ht56HHOzEhjeIgAv5ZNFjSVX/in1YlUs0HG9c1EUXTM=",
"lastModified": 1766321686,
"narHash": "sha256-icOWbnD977HXhveirqA10zoqvErczVs3NKx8Bj+ikHY=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "f535d8123c4761b2ed8138f3d202ea710a334a1d",
"rev": "7d433bf89882f61621f95082e90a4ab91eb0bdd3",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"ref": "nixos-22.05",
"ref": "master",
"repo": "nixos-mailserver",
"type": "gitlab"
}
@@ -320,36 +326,6 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"utils": {
"locked": {
"lastModified": 1605370193,
"narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5021eac20303a61fafe17224c087f5519baed54d",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",

103
flake.nix
View File

@@ -1,46 +1,76 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
# nixpkgs
nixpkgs.url = "github:NixOS/nixpkgs/master";
flake-utils.url = "github:numtide/flake-utils";
# Common Utils Among flake inputs
systems.url = "github:nix-systems/default";
flake-utils = {
url = "github:numtide/flake-utils";
inputs.systems.follows = "systems";
};
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
# mail server
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-22.05";
simple-nixos-mailserver.inputs.nixpkgs.follows = "nixpkgs";
# NixOS hardware
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
# agenix
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
# Home Manager
home-manager = {
url = "github:nix-community/home-manager/master";
inputs.nixpkgs.follows = "nixpkgs";
};
# radio
radio.url = "git+https://git.neet.dev/zuckerberg/radio.git?ref=main&rev=5bf607fed977d41a269942a7d1e92f3e6d4f2473";
radio.inputs.nixpkgs.follows = "nixpkgs";
radio.inputs.flake-utils.follows = "flake-utils";
radio-web.url = "git+https://git.neet.dev/zuckerberg/radio-web.git";
radio-web.flake = false;
# Mail Server
simple-nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-compat.follows = "flake-compat";
};
};
# drastikbot
dailybuild_modules.url = "git+https://git.neet.dev/zuckerberg/dailybuild_modules.git";
dailybuild_modules.inputs.nixpkgs.follows = "nixpkgs";
dailybuild_modules.inputs.flake-utils.follows = "flake-utils";
# Agenix
agenix = {
url = "github:ryantm/agenix";
inputs = {
nixpkgs.follows = "nixpkgs";
systems.follows = "systems";
home-manager.follows = "home-manager";
};
};
# nixos config deployment
deploy-rs.url = "github:serokell/deploy-rs";
deploy-rs.inputs.nixpkgs.follows = "nixpkgs";
deploy-rs.inputs.utils.follows = "simple-nixos-mailserver/utils";
# Dailybot
dailybuild_modules = {
url = "git+https://git.neet.dev/zuckerberg/dailybot.git";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
};
};
# prebuilt nix-index database
nix-index-database.url = "github:Mic92/nix-index-database";
nix-index-database.inputs.nixpkgs.follows = "nixpkgs";
# NixOS deployment
deploy-rs = {
url = "github:serokell/deploy-rs";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-compat.follows = "flake-compat";
utils.follows = "flake-utils";
};
};
# https://github.com/NixOS/nixpkgs/issues/286313
fix-nvidia-x11-latest.url = "https://github.com/NixOS/nixpkgs/pull/286084.diff";
fix-nvidia-x11-latest.flake = false;
# Prebuilt nix-index database
nix-index-database = {
url = "github:Mic92/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, ... }@inputs:
let
machines = (import ./common/machine-info/moduleless.nix
machineHosts = (import ./common/machine-info/moduleless.nix
{
inherit nixpkgs;
assertionsModule = "${nixpkgs}/nixos/modules/misc/assertions.nix";
@@ -55,6 +85,7 @@
agenix.nixosModules.default
dailybuild_modules.nixosModule
nix-index-database.nixosModules.nix-index
home-manager.nixosModules.home-manager
self.nixosModules.kernel-modules
({ lib, ... }: {
config = {
@@ -65,6 +96,10 @@
];
networking.hostName = hostname;
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.googlebot = import ./home/googlebot.nix;
};
# because nixos specialArgs doesn't work for containers... need to pass in inputs a different way
@@ -82,8 +117,7 @@
name = "nixpkgs-patched";
src = nixpkgs;
patches = [
./patches/gamepadui.patch
inputs.fix-nvidia-x11-latest
./patches/dont-break-nix-serve.patch
];
};
patchedNixpkgs = nixpkgs.lib.fix (self: (import "${patchedNixpkgsSrc}/flake.nix").outputs { self = nixpkgs; });
@@ -96,13 +130,14 @@
specialArgs = {
inherit allModules;
lib = self.lib;
nixos-hardware = inputs.nixos-hardware;
};
};
in
nixpkgs.lib.mapAttrs
(hostname: cfg:
mkSystem cfg.arch nixpkgs cfg.configurationPath hostname)
machines;
machineHosts;
packages =
let
@@ -124,7 +159,7 @@
"aarch64-linux"."iso" = mkIso "aarch64-linux";
};
overlays.default = import ./overlays;
overlays.default = import ./overlays { inherit inputs; };
nixosModules.kernel-modules = import ./overlays/kernel-modules;
deploy.nodes =
@@ -139,7 +174,7 @@
nixpkgs.lib.mapAttrs
(hostname: cfg:
mkDeploy hostname cfg.arch (builtins.head cfg.hostNames))
machines;
machineHosts;
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;

58
home/googlebot.nix Normal file
View File

@@ -0,0 +1,58 @@
{ config, lib, pkgs, osConfig, ... }:
let
# Check if the current machine has the role "personal"
thisMachineIsPersonal = osConfig.thisMachine.hasRole."personal";
in
{
home.username = "googlebot";
home.homeDirectory = "/home/googlebot";
home.stateVersion = "24.11";
programs.home-manager.enable = true;
services.ssh-agent.enable = true;
# System Monitoring
programs.btop.enable = true;
programs.bottom.enable = true;
# Modern "ls" replacement
programs.pls.enable = true;
programs.pls.enableFishIntegration = false;
programs.eza.enable = true;
# Graphical terminal
programs.ghostty.enable = thisMachineIsPersonal;
programs.ghostty.settings = {
theme = "Snazzy";
font-size = 10;
};
# Advanced terminal file explorer
programs.broot.enable = true;
# Shell promt theming
programs.fish.enable = true;
programs.starship.enable = true;
programs.starship.enableFishIntegration = true;
programs.starship.enableInteractive = true;
# programs.oh-my-posh.enable = true;
# programs.oh-my-posh.enableFishIntegration = true;
# Advanced search
programs.ripgrep.enable = true;
# tldr: Simplified, example based and community-driven man pages.
programs.tealdeer.enable = true;
home.shellAliases = {
sudo = "doas";
ls2 = "eza";
explorer = "broot";
};
programs.zed-editor = {
enable = thisMachineIsPersonal;
};
}

View File

@@ -1,4 +0,0 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p bash
nix flake update --commit-lock-file

View File

@@ -29,10 +29,10 @@
text = ''
#!${pkgs.stdenv.shell}
set -e
${pkgs.kexectools}/bin/kexec -l ${image}/kernel --initrd=${image}/initrd --append="init=${builtins.unsafeDiscardStringContext config.system.build.toplevel}/init ${toString config.boot.kernelParams}"
${pkgs.kexec-tools}/bin/kexec -l ${image}/kernel --initrd=${image}/initrd --append="init=${builtins.unsafeDiscardStringContext config.system.build.toplevel}/init ${toString config.boot.kernelParams}"
sync
echo "executing kernel, filesystems will be improperly umounted"
${pkgs.kexectools}/bin/kexec -e
${pkgs.kexec-tools}/bin/kexec -e
'';
};
kexec_tarball = pkgs.callPackage (modulesPath + "/../lib/make-system-tarball.nix") {

View File

@@ -7,12 +7,20 @@
../../common/ssh.nix
];
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "e1000" "e1000e" "virtio_pci" "r8169" ];
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"e1000"
"e1000e"
"virtio_pci"
"r8169"
"sdhci"
"sdhci_pci"
"mmc_core"
"mmc_block"
];
boot.kernelParams = [
"panic=30"
"boot.panic_on_fail" # reboot the machine upon fatal boot issues
"console=ttyS0,115200" # enable serial console
"console=tty1"
];
boot.kernel.sysctl."vm.overcommit_memory" = "1";

70
machines/fry/default.nix Normal file
View File

@@ -0,0 +1,70 @@
{ config, pkgs, lib, ... }:
{
imports = [
./hardware-configuration.nix
];
# don't use remote builders
nix.distributedBuilds = lib.mkForce false;
nix.gc.automatic = lib.mkForce false;
environment.systemPackages = with pkgs; [
system76-keyboard-configurator
];
services.ollama = {
enable = true;
package = pkgs.ollama-vulkan;
host = "127.0.0.1";
};
services.open-webui = {
enable = true;
host = "127.0.0.1"; # nginx proxy
port = 12831;
environment = {
ANONYMIZED_TELEMETRY = "False";
DO_NOT_TRACK = "True";
SCARF_NO_ANALYTICS = "True";
OLLAMA_API_BASE_URL = "http://localhost:${toString config.services.ollama.port}";
};
};
# nginx
services.nginx = {
enable = true;
openFirewall = false; # All nginx services are internal
virtualHosts =
let
mkHost = external: config:
{
${external} = {
useACMEHost = "fry.neet.dev"; # Use wildcard cert
forceSSL = true;
locations."/" = config;
};
};
mkVirtualHost = external: internal:
mkHost external {
proxyPass = internal;
proxyWebsockets = true;
};
in
lib.mkMerge [
(mkVirtualHost "chat.fry.neet.dev" "http://localhost:${toString config.services.open-webui.port}")
];
};
# Get wildcard cert
security.acme.certs."fry.neet.dev" = {
dnsProvider = "digitalocean";
credentialsFile = "/run/agenix/digitalocean-dns-credentials";
extraDomainNames = [ "*.fry.neet.dev" ];
group = "nginx";
dnsResolver = "1.1.1.1:53";
dnsPropagationCheck = false; # sadly this erroneously fails
};
age.secrets.digitalocean-dns-credentials.file = ../../secrets/digitalocean-dns-credentials.age;
}

View File

@@ -0,0 +1,50 @@
{ config, lib, pkgs, modulesPath, nixos-hardware, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
nixos-hardware.nixosModules.framework-amd-ai-300-series
];
boot.kernelPackages = pkgs.linuxPackages_latest;
services.fwupd.enable = true;
# boot
boot.loader.systemd-boot.enable = true;
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" "r8169" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# thunderbolt
services.hardware.bolt.enable = true;
# firmware
firmware.x86_64.enable = true;
# disks
remoteLuksUnlock.enable = true;
boot.initrd.luks.devices."enc-pv" = {
device = "/dev/disk/by-uuid/d4f2f25a-5108-4285-968f-b24fb516d4f3";
allowDiscards = true;
};
fileSystems."/" =
{ device = "/dev/disk/by-uuid/a8901bc1-8642-442a-940a-ddd3f428cd0f";
fsType = "btrfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/13E5-C9D4";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices =
[ { device = "/dev/disk/by-uuid/03356a74-33f0-4a2e-b57a-ec9dfc9d85c5"; }
];
# Ensures that dhcp is active during initrd (Network Manager is used post boot)
boot.initrd.network.udhcpc.enable = true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@@ -0,0 +1,24 @@
{
hostNames = [
"fry"
];
arch = "x86_64-linux";
systemRoles = [
"personal"
"dns-challenge"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID/Df5lG07Il7fizEgZR/T9bMlR0joESRJ7cqM9BkOyP";
userKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5/h6YySqNemA4+e+xslhspBp34ulXKembe3RoeZ5av"
];
remoteUnlock = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL1RC1lhP4TSL2THvKAQAH7Y/eSGQPo/MjhTsZD6CEES";
clearnetHost = "192.168.1.3";
onionHost = "z7smmigsfrabqfnxqogfogmsu36jhpsyscncmd332w5ioheblw6i4lid.onion";
};
}

12
machines/howl/default.nix Normal file
View File

@@ -0,0 +1,12 @@
{ config, pkgs, lib, ... }:
{
imports = [
./hardware-configuration.nix
];
# don't use remote builders
nix.distributedBuilds = lib.mkForce false;
nix.gc.automatic = lib.mkForce false;
}

View File

@@ -0,0 +1,58 @@
{ config, lib, pkgs, modulesPath, nixos-hardware, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
nixos-hardware.nixosModules.framework-13-7040-amd
];
boot.kernelPackages = pkgs.linuxPackages_latest;
hardware.framework.amd-7040.preventWakeOnAC = true;
services.fwupd.enable = true;
# fingerprint reader has initially shown to be more of a nuisance than a help
# it makes sddm log in fail most of the time and take several minutes to finish
services.fprintd.enable = false;
# boot
boot.loader.systemd-boot.enable = true;
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# thunderbolt
services.hardware.bolt.enable = true;
# firmware
firmware.x86_64.enable = true;
# disks
remoteLuksUnlock.enable = true;
boot.initrd.luks.devices."enc-pv" = {
device = "/dev/disk/by-uuid/2e4a6960-a6b1-40ee-9c2c-2766eb718d52";
allowDiscards = true;
};
fileSystems."/" =
{
device = "/dev/disk/by-uuid/1f62386c-3243-49f5-b72f-df8fc8f39db8";
fsType = "btrfs";
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/F4D9-C5E8";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices =
[{ device = "/dev/disk/by-uuid/5f65cb11-2649-48fe-9c78-3e325b857c53"; }];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@@ -0,0 +1,22 @@
{
hostNames = [
"howl"
];
arch = "x86_64-linux";
systemRoles = [
"personal"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEQi3q8jU6vRruExAL60J7GFO1gS8HsmXVJuKRT4ljrG";
userKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPnLt84bKhUgFxjQf10+Htro9Lo1Pabqm8mGalBUniv"
];
remoteUnlock = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN0N80r0Sl2WlJaUqfxZPkOtYyGumFazkIqq7eq3Gd2o";
onionHost = "ll6yjnkh4psmfwmtkmqoutl4gq4elqzbmjxv4s6gpgoavyi3kwhjvnqd.onion";
};
}

View File

@@ -9,7 +9,4 @@
networking.hostName = "nat";
networking.interfaces.ens160.useDHCP = true;
de.enable = true;
de.touchpad.enable = true;
}

View File

@@ -9,7 +9,6 @@
systemRoles = [
"server"
"nix-builder"
"gitea-actions-runner"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlgRPpuUkZqe8/lHugRPm/m2vcN9psYhh5tENHZt9I2";

View File

@@ -10,6 +10,8 @@
# p2p mesh network
services.tailscale.exitNode = true;
services.iperf3.enable = true;
# email server
mailserver.enable = true;
@@ -54,44 +56,6 @@
config.services.drastikbot.dataDir
];
# music radio
vpn-container.enable = true;
vpn-container.config = {
services.radio = {
enable = true;
host = "radio.runyan.org";
};
};
pia.wireguard.badPortForwardPorts = [ ];
services.nginx.virtualHosts = {
"radio.runyan.org" = {
enableACME = true;
forceSSL = true;
locations = {
"/stream.mp3" = {
proxyPass = "http://vpn.containers:8001/stream.mp3";
extraConfig = ''
add_header Access-Control-Allow-Origin *;
'';
};
"/".root = config.inputs.radio-web;
};
};
"radio.neet.space" = {
enableACME = true;
forceSSL = true;
locations = {
"/stream.mp3" = {
proxyPass = "http://vpn.containers:8001/stream.mp3";
extraConfig = ''
add_header Access-Control-Allow-Origin *;
'';
};
"/".root = config.inputs.radio-web;
};
};
};
# matrix home server
services.matrix = {
enable = true;
@@ -102,7 +66,7 @@
host = "chat.neet.space";
};
jitsi-meet = {
enable = true;
enable = false; # disabled until vulnerable libolm dependency is removed/fixed
host = "meet.neet.space";
};
turn = {
@@ -114,18 +78,10 @@
services.postgresql.package = pkgs.postgresql_15;
# iodine DNS-based vpn
services.iodine.server.enable = true;
# services.iodine.server.enable = true;
# proxied web services
services.nginx.enable = true;
services.nginx.virtualHosts."jellyfin.neet.cloud" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://s0.koi-bebop.ts.net";
proxyWebsockets = true;
};
};
services.nginx.virtualHosts."navidrome.neet.cloud" = {
enableACME = true;
forceSSL = true;
@@ -139,12 +95,12 @@
root = "/var/www/tmp";
};
# redirect runyan.org to github
services.nginx.virtualHosts."runyan.org" = {
# redirect neet.cloud to nextcloud instance on runyan.org
services.nginx.virtualHosts."neet.cloud" = {
enableACME = true;
forceSSL = true;
extraConfig = ''
rewrite ^/(.*)$ https://github.com/GoogleBot42 redirect;
return 302 https://runyan.org$request_uri;
'';
};
@@ -153,6 +109,6 @@
services.owncast.hostname = "live.neet.dev";
# librechat
services.librechat.enable = true;
services.librechat.host = "chat.neet.dev";
services.librechat-container.enable = true;
services.librechat-container.host = "chat.neet.dev";
}

View File

@@ -16,6 +16,7 @@
bios = {
enable = true;
device = "/dev/sda";
configurationLimit = 3; # Save room in /nix/store
};
remoteLuksUnlock.enable = true;

View File

@@ -1,67 +0,0 @@
{ config, pkgs, lib, ... }:
{
imports = [
./hardware-configuration.nix
];
# for luks onlock over tor
services.tor.enable = true;
services.tor.client.enable = true;
# don't use remote builders
nix.distributedBuilds = lib.mkForce false;
# services.howdy.enable = true;
hardware.openrazer.enable = true;
hardware.openrazer.users = [ "googlebot" ];
hardware.openrazer.devicesOffOnScreensaver = false;
users.users.googlebot.packages = [ pkgs.polychromatic ];
services.udev.extraRules = ''
# depthai
SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"
# Moonlander
# Rules for Oryx web flashing and live training
KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", MODE="0664", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="3297", MODE="0664", GROUP="plugdev"
# Wally Flashing rules for the Moonlander and Planck EZ
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666", SYMLINK+="stm32_dfu"
'';
services.udev.packages = [ pkgs.platformio ];
users.groups.plugdev = {
members = [ "googlebot" ];
};
# virt-manager
virtualisation.libvirtd.enable = true;
programs.dconf.enable = true;
virtualisation.spiceUSBRedirection.enable = true;
environment.systemPackages = with pkgs; [ virt-manager ];
users.users.googlebot.extraGroups = [ "libvirtd" "adbusers" ];
# allow building ARM derivations
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
services.spotifyd.enable = true;
virtualisation.podman.enable = true;
virtualisation.podman.dockerCompat = true;
virtualisation.appvm.enable = true;
virtualisation.appvm.user = "googlebot";
services.mount-samba.enable = true;
de.enable = true;
de.touchpad.enable = true;
networking.firewall.allowedTCPPorts = [
# barrier
24800
];
programs.adb.enable = true;
}

View File

@@ -1,62 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
];
# boot
efi.enable = true;
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
# kernel
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# firmware
firmware.x86_64.enable = true;
hardware.enableAllFirmware = true;
# gpu
services.xserver.videoDrivers = [ "nvidia" ];
hardware.nvidia = {
modesetting.enable = true; # for nvidia-vaapi-driver
prime = {
reverseSync.enable = true;
offload.enableOffloadCmd = true;
nvidiaBusId = "PCI:1:0:0";
amdgpuBusId = "PCI:4:0:0";
};
};
# disks
remoteLuksUnlock.enable = true;
boot.initrd.luks.devices."enc-pv" = {
device = "/dev/disk/by-uuid/c1822e5f-4137-44e1-885f-954e926583ce";
allowDiscards = true;
};
fileSystems."/" =
{
device = "/dev/vg/root";
fsType = "btrfs";
options = [ "subvol=root" ];
};
fileSystems."/home" =
{
device = "/dev/vg/root";
fsType = "btrfs";
options = [ "subvol=home" ];
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/2C85-2B59";
fsType = "vfat";
};
swapDevices =
[{ device = "/dev/vg/swap"; }];
}

View File

@@ -1,22 +0,0 @@
{
hostNames = [
"ray"
];
arch = "x86_64-linux";
systemRoles = [
"personal"
"deploy"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDQM8hwKRgl8cZj7UVYATSLYu4LhG7I0WFJ9m2iWowiB";
userKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFeTK1iARlNIKP/DS8/ObBm9yUM/3L1Ub4XI5A2r9OzP"
];
deployKeys = [
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEaGIwLiUa6wQLlEF+keQOIYy/tCmJvV6eENzUQjSqW2AAAABHNzaDo="
];
}

View File

@@ -22,8 +22,7 @@
# networking.useDHCP = lib.mkForce true;
# TODO
# networking.usePredictableInterfaceNames = true;
networking.usePredictableInterfaceNames = false;
powerManagement.cpuFreqGovernor = "ondemand";

View File

@@ -10,8 +10,6 @@
# Enable serial output
boot.kernelParams = [
"panic=30"
"boot.panic_on_fail" # reboot the machine upon fatal boot issues
"console=ttyS0,115200n8" # enable serial console
];
boot.loader.grub.extraConfig = "
@@ -23,6 +21,8 @@
# firmware
firmware.x86_64.enable = true;
nixpkgs.config.allowUnfree = true;
hardware.enableRedistributableFirmware = true;
hardware.enableAllFirmware = true;
# boot
bios = {
@@ -31,20 +31,18 @@
};
# disks
remoteLuksUnlock.enable = true;
boot.initrd.luks.devices."enc-pv".device = "/dev/disk/by-uuid/9b090551-f78e-45ca-8570-196ed6a4af0c";
fileSystems."/" =
{
device = "/dev/disk/by-uuid/421c82b9-d67c-4811-8824-8bb57cb10fce";
fsType = "btrfs";
device = "/dev/disk/by-uuid/6aa7f79e-bef8-4b0f-b22c-9d1b3e8ac94b";
fsType = "ext4";
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/d97f324f-3a2e-4b84-ae2a-4b3d1209c689";
device = "/dev/disk/by-uuid/14dfc562-0333-4ddd-b10c-4eeefe1cd05f";
fsType = "ext3";
};
swapDevices =
[{ device = "/dev/disk/by-uuid/45bf58dd-67eb-45e4-9a98-246e23fa7abd"; }];
[{ device = "/dev/disk/by-uuid/adf37c64-3b54-480c-a9a7-099d61c6eac7"; }];
nixpkgs.hostPlatform = "x86_64-linux";
}

View File

@@ -0,0 +1,17 @@
{
hostNames = [
"router"
"192.168.6.159"
"192.168.3.1"
];
arch = "x86_64-linux";
systemRoles = [
"server"
"wireless"
"router"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKDCMhEvWJxFBNyvpyuljv5Uun8AdXCxBK9HvPBRe5x6";
}

View File

@@ -1,21 +0,0 @@
{
hostNames = [
"router"
"192.168.1.228"
];
arch = "x86_64-linux";
systemRoles = [
"server"
"wireless"
"router"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFr2IHmWFlaLaLp5dGoSmFEYKA/eg2SwGXAogaOmLsHL";
remoteUnlock = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJOw5dTPmtKqiPBH6VKyz5MYBubn8leAh5Eaw7s/O85c";
onionHost = "jxx2exuihlls2t6ncs7rvrjh2dssubjmjtclwr2ysvxtr4t7jv55xmqd.onion";
};
}

View File

@@ -31,8 +31,10 @@ in
networking.bridges = {
br0 = {
interfaces = [
"enp2s0"
"wlp4s0"
"eth2"
# "wlp4s0"
# "wlan1"
"wlan0"
"wlan1"
];
};
@@ -64,142 +66,173 @@ in
services.dnsmasq = {
enable = true;
extraConfig = ''
settings = {
# sensible behaviours
domain-needed
bogus-priv
no-resolv
domain-needed = true;
bogus-priv = true;
no-resolv = true;
# upstream name servers
server=1.1.1.1
server=8.8.8.8
server = [
"1.1.1.1"
"8.8.8.8"
];
# local domains
expand-hosts
domain=home
local=/home/
expand-hosts = true;
domain = "home";
local = "/home/";
# Interfaces to use DNS on
interface=br0
interface = "br0";
# subnet IP blocks to use DHCP on
dhcp-range=${cfg.privateSubnet}.10,${cfg.privateSubnet}.254,24h
'';
dhcp-range = "${cfg.privateSubnet}.10,${cfg.privateSubnet}.254,24h";
};
};
services.hostapd = {
enable = true;
radios = {
# 2.4GHz
wlp4s0 = {
band = "2g";
noScan = true;
channel = 6;
# Simple 2.4GHz AP
wlan0 = {
countryCode = "US";
wifi4 = {
capabilities = [ "LDPC" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1" "MAX-AMSDU-7935" "HT40+" ];
};
wifi5 = {
operatingChannelWidth = "20or40";
capabilities = [ "MAX-A-MPDU-LEN-EXP0" ];
};
wifi6 = {
enable = true;
singleUserBeamformer = true;
singleUserBeamformee = true;
multiUserBeamformer = true;
operatingChannelWidth = "20or40";
};
networks = {
wlp4s0 = {
ssid = "CXNK00BF9176";
authentication.saePasswordsFile = "/run/agenix/hostapd-pw-CXNK00BF9176";
};
# wlp4s0-1 = {
# ssid = "- Experimental 5G Tower by AT&T";
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
# };
# wlp4s0-2 = {
# ssid = "FBI Surveillance Van 2";
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
# };
};
settings = {
he_oper_centr_freq_seg0_idx = 8;
vht_oper_centr_freq_seg0_idx = 8;
networks.wlan0 = {
ssid = "CXNK00BF9176-1";
authentication.saePasswords = [{ passwordFile = "/run/agenix/hostapd-pw-CXNK00BF9176"; }];
};
};
# 5GHz
# WiFi 5 (5GHz) with two advertised networks
wlan1 = {
band = "5g";
noScan = true;
channel = 128;
channel = 0;
countryCode = "US";
wifi4 = {
capabilities = [ "LDPC" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1" "MAX-AMSDU-7935" "HT40-" ];
};
wifi5 = {
operatingChannelWidth = "160";
capabilities = [ "RXLDPC" "SHORT-GI-80" "SHORT-GI-160" "TX-STBC-2BY1" "SU-BEAMFORMER" "SU-BEAMFORMEE" "MU-BEAMFORMER" "MU-BEAMFORMEE" "RX-ANTENNA-PATTERN" "TX-ANTENNA-PATTERN" "RX-STBC-1" "SOUNDING-DIMENSION-3" "BF-ANTENNA-3" "VHT160" "MAX-MPDU-11454" "MAX-A-MPDU-LEN-EXP7" ];
};
wifi6 = {
enable = true;
singleUserBeamformer = true;
singleUserBeamformee = true;
multiUserBeamformer = true;
operatingChannelWidth = "160";
};
networks = {
wlan1 = {
ssid = "CXNK00BF9176";
authentication.saePasswordsFile = "/run/agenix/hostapd-pw-CXNK00BF9176";
};
# wlan1-1 = {
# ssid = "- Experimental 5G Tower by AT&T";
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
# };
# wlan1-2 = {
# ssid = "FBI Surveillance Van 5";
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
# };
};
settings = {
vht_oper_centr_freq_seg0_idx = 114;
he_oper_centr_freq_seg0_idx = 114;
networks.wlan1 = {
ssid = "CXNK00BF9176-1";
authentication.saePasswords = [{ passwordFile = "/run/agenix/hostapd-pw-CXNK00BF9176"; }];
};
};
};
};
age.secrets.hostapd-pw-experimental-tower.file = ../../secrets/hostapd-pw-experimental-tower.age;
age.secrets.hostapd-pw-CXNK00BF9176.file = ../../secrets/hostapd-pw-CXNK00BF9176.age;
hardware.firmware = [
pkgs.mt7916-firmware
];
# wlan0 5Ghz 00:0a:52:08:38:32
# wlp4s0 2.4Ghz 00:0a:52:08:38:33
nixpkgs.overlays = [
(self: super: {
mt7916-firmware = pkgs.stdenvNoCC.mkDerivation {
pname = "mt7916-firmware";
version = "custom-feb-02-23";
src = ./firmware/mediatek; # from here https://github.com/openwrt/mt76/issues/720#issuecomment-1413537674
dontBuild = true;
installPhase = ''
for i in \
mt7916_eeprom.bin \
mt7916_rom_patch.bin \
mt7916_wa.bin \
mt7916_wm.bin;
do
install -D -pm644 $i $out/lib/firmware/mediatek/$i
done
'';
meta = with lib; {
license = licenses.unfreeRedistributableFirmware;
};
};
})
];
# services.hostapd = {
# enable = true;
# radios = {
# # 2.4GHz
# wlp4s0 = {
# band = "2g";
# noScan = true;
# channel = 6;
# countryCode = "US";
# wifi4 = {
# capabilities = [ "LDPC" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1" "MAX-AMSDU-7935" "HT40+" ];
# };
# wifi5 = {
# operatingChannelWidth = "20or40";
# capabilities = [ "MAX-A-MPDU-LEN-EXP0" ];
# };
# wifi6 = {
# enable = true;
# singleUserBeamformer = true;
# singleUserBeamformee = true;
# multiUserBeamformer = true;
# operatingChannelWidth = "20or40";
# };
# networks = {
# wlp4s0 = {
# ssid = "CXNK00BF9176";
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-CXNK00BF9176";
# };
# # wlp4s0-1 = {
# # ssid = "- Experimental 5G Tower by AT&T";
# # authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
# # };
# # wlp4s0-2 = {
# # ssid = "FBI Surveillance Van 2";
# # authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
# # };
# };
# settings = {
# he_oper_centr_freq_seg0_idx = 8;
# vht_oper_centr_freq_seg0_idx = 8;
# };
# };
# # 5GHz
# wlan1 = {
# band = "5g";
# noScan = true;
# channel = 128;
# countryCode = "US";
# wifi4 = {
# capabilities = [ "LDPC" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1" "MAX-AMSDU-7935" "HT40-" ];
# };
# wifi5 = {
# operatingChannelWidth = "160";
# capabilities = [ "RXLDPC" "SHORT-GI-80" "SHORT-GI-160" "TX-STBC-2BY1" "SU-BEAMFORMER" "SU-BEAMFORMEE" "MU-BEAMFORMER" "MU-BEAMFORMEE" "RX-ANTENNA-PATTERN" "TX-ANTENNA-PATTERN" "RX-STBC-1" "SOUNDING-DIMENSION-3" "BF-ANTENNA-3" "VHT160" "MAX-MPDU-11454" "MAX-A-MPDU-LEN-EXP7" ];
# };
# wifi6 = {
# enable = true;
# singleUserBeamformer = true;
# singleUserBeamformee = true;
# multiUserBeamformer = true;
# operatingChannelWidth = "160";
# };
# networks = {
# wlan1 = {
# ssid = "CXNK00BF9176";
# authentication.saePasswordsFile = "/run/agenix/hostapd-pw-CXNK00BF9176";
# };
# # wlan1-1 = {
# # ssid = "- Experimental 5G Tower by AT&T";
# # authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
# # };
# # wlan1-2 = {
# # ssid = "FBI Surveillance Van 5";
# # authentication.saePasswordsFile = "/run/agenix/hostapd-pw-experimental-tower";
# # };
# };
# settings = {
# vht_oper_centr_freq_seg0_idx = 114;
# he_oper_centr_freq_seg0_idx = 114;
# };
# };
# };
# };
# age.secrets.hostapd-pw-experimental-tower.file = ../../secrets/hostapd-pw-experimental-tower.age;
# age.secrets.hostapd-pw-CXNK00BF9176.file = ../../secrets/hostapd-pw-CXNK00BF9176.age;
# hardware.firmware = [
# pkgs.mt7916-firmware
# ];
# nixpkgs.overlays = [
# (self: super: {
# mt7916-firmware = pkgs.stdenvNoCC.mkDerivation {
# pname = "mt7916-firmware";
# version = "custom-feb-02-23";
# src = ./firmware/mediatek; # from here https://github.com/openwrt/mt76/issues/720#issuecomment-1413537674
# dontBuild = true;
# installPhase = ''
# for i in \
# mt7916_eeprom.bin \
# mt7916_rom_patch.bin \
# mt7916_wa.bin \
# mt7916_wm.bin;
# do
# install -D -pm644 $i $out/lib/firmware/mediatek/$i
# done
# '';
# meta = with lib; {
# license = licenses.unfreeRedistributableFirmware;
# };
# };
# })
# ];
};
}

View File

@@ -0,0 +1,297 @@
{
appConfig = {
theme = "vaporware";
customColors = {
"material-dark-original" = {
primary = "#f36558";
background = "#39434C";
"background-darker" = "#eb615c";
"material-light" = "#f36558";
"item-text-color" = "#ff948a";
"curve-factor" = "5px";
};
};
enableErrorReporting = false;
layout = "auto";
iconSize = "large";
language = "en";
startingView = "default";
defaultOpeningMethod = "sametab";
statusCheck = true;
statusCheckInterval = 20;
faviconApi = "faviconkit";
routingMode = "history";
enableMultiTasking = false;
webSearch = {
disableWebSearch = false;
searchEngine = "duckduckgo";
openingMethod = "sametab";
searchBangs = { };
};
enableFontAwesome = true;
cssThemes = [ ];
externalStyleSheet = [ ];
hideComponents = {
hideHeading = false;
hideNav = false;
hideSearch = false;
hideSettings = false;
hideFooter = false;
hideSplashScreen = false;
};
auth = {
enableGuestAccess = false;
users = [ ];
enableKeycloak = false;
keycloak = { };
};
allowConfigEdit = true;
enableServiceWorker = false;
disableContextMenu = false;
disableUpdateChecks = false;
disableSmartSort = false;
};
pageInfo = {
title = "s0";
description = "s0";
};
sections = [
(
let
# Define the media section items once.
mediaItems = {
jellyfin = {
title = "Jellyfin";
icon = "hl-jellyfin";
url = "https://jellyfin.s0.neet.dev";
target = "sametab";
statusCheck = false;
id = "0_1956_jellyfin";
};
sonarr = {
title = "Sonarr";
description = "Manage TV";
icon = "hl-sonarr";
url = "https://sonarr.s0.neet.dev";
target = "sametab";
statusCheck = false;
id = "1_1956_sonarr";
};
radarr = {
title = "Radarr";
description = "Manage Movies";
icon = "hl-radarr";
url = "https://radarr.s0.neet.dev";
target = "sametab";
statusCheck = false;
id = "2_1956_radarr";
};
lidarr = {
title = "Lidarr";
description = "Manage Music";
icon = "hl-lidarr";
url = "https://lidarr.s0.neet.dev";
target = "sametab";
statusCheck = false;
id = "3_1956_lidarr";
};
prowlarr = {
title = "Prowlarr";
description = "Indexers";
icon = "hl-prowlarr";
url = "https://prowlarr.s0.neet.dev";
target = "sametab";
statusCheck = false;
id = "4_1956_prowlarr";
};
bazarr = {
title = "Bazarr";
description = "Subtitles";
icon = "hl-bazarr";
url = "https://bazarr.s0.neet.dev";
target = "sametab";
statusCheck = false;
id = "5_1956_bazarr";
};
navidrome = {
title = "Navidrome";
description = "Play Music";
icon = "hl-navidrome";
url = "https://music.s0.neet.dev";
target = "sametab";
statusCheck = false;
id = "6_1956_navidrome";
};
transmission = {
title = "Transmission";
description = "Torrenting";
icon = "hl-transmission";
url = "https://transmission.s0.neet.dev";
target = "sametab";
statusCheck = false;
id = "7_1956_transmission";
};
};
# Build the list once.
mediaList = [
mediaItems.jellyfin
mediaItems.sonarr
mediaItems.radarr
mediaItems.lidarr
mediaItems.prowlarr
mediaItems.bazarr
mediaItems.navidrome
mediaItems.transmission
];
in
{
name = "Media & Entertainment";
icon = "fas fa-photo-video";
displayData = {
sortBy = "most-used";
cols = 1;
rows = 1;
collapsed = false;
hideForGuests = false;
};
items = mediaList;
filteredItems = mediaList;
}
)
(
let
networkItems = {
gateway = {
title = "Gateway";
description = "openwrt";
icon = "hl-openwrt";
url = "http://openwrt.lan/";
target = "sametab";
statusCheck = true;
id = "0_746_gateway";
};
wireless = {
title = "Wireless";
description = "openwrt (ish)";
icon = "hl-openwrt";
url = "http://PacketProvocateur.lan";
target = "sametab";
statusCheck = true;
id = "1_746_wireless";
};
};
networkList = [
networkItems.gateway
networkItems.wireless
];
in
{
name = "Network";
icon = "fas fa-network-wired";
items = networkList;
filteredItems = networkList;
displayData = {
sortBy = "default";
rows = 1;
cols = 1;
collapsed = false;
hideForGuests = false;
};
}
)
(
let
servicesItems = {
matrix = {
title = "Matrix";
description = "";
icon = "hl-matrix";
url = "https://chat.neet.space";
target = "sametab";
statusCheck = true;
id = "0_836_matrix";
};
mumble = {
title = "Mumble";
description = "voice.neet.space";
icon = "hl-mumble";
url = "https://voice.neet.space";
target = "sametab";
statusCheck = false;
id = "2_836_mumble";
};
irc = {
title = "IRC";
description = "irc.neet.dev";
icon = "hl-thelounge";
url = "https://irc.neet.dev";
target = "sametab";
statusCheck = true;
id = "3_836_irc";
};
git = {
title = "Git";
description = "git.neet.dev";
icon = "hl-gitea";
url = "https://git.neet.dev";
target = "sametab";
statusCheck = true;
id = "4_836_git";
};
nextcloud = {
title = "Nextcloud";
description = "neet.cloud";
icon = "hl-nextcloud";
url = "https://neet.cloud";
target = "sametab";
statusCheck = true;
id = "5_836_nextcloud";
};
roundcube = {
title = "Roundcube";
description = "mail.neet.dev";
icon = "hl-roundcube";
url = "https://mail.neet.dev";
target = "sametab";
statusCheck = true;
id = "6_836_roundcube";
};
jitsimeet = {
title = "Jitsi Meet";
description = "meet.neet.space";
icon = "hl-jitsimeet";
url = "https://meet.neet.space";
target = "sametab";
statusCheck = true;
id = "7_836_jitsimeet";
};
};
servicesList = [
servicesItems.matrix
servicesItems.mumble
servicesItems.irc
servicesItems.git
servicesItems.nextcloud
servicesItems.roundcube
servicesItems.jitsimeet
];
in
{
name = "Services";
icon = "fas fa-monitor-heart-rate";
items = servicesList;
filteredItems = servicesList;
displayData = {
sortBy = "default";
rows = 1;
cols = 1;
collapsed = false;
hideForGuests = false;
};
}
)
];
}

View File

@@ -1,249 +0,0 @@
appConfig:
theme: vaporware
customColors:
material-dark-original:
primary: '#f36558'
background: '#39434C'
background-darker: '#eb615c'
material-light: '#f36558'
item-text-color: '#ff948a'
curve-factor: 5px
enableErrorReporting: false
layout: auto
iconSize: large
language: en
startingView: default
defaultOpeningMethod: sametab
statusCheck: true
statusCheckInterval: 20
faviconApi: faviconkit
routingMode: history
enableMultiTasking: false
webSearch:
disableWebSearch: false
searchEngine: duckduckgo
openingMethod: sametab
searchBangs: {}
enableFontAwesome: true
cssThemes: []
externalStyleSheet: []
hideComponents:
hideHeading: false
hideNav: false
hideSearch: false
hideSettings: false
hideFooter: false
hideSplashScreen: false
auth:
enableGuestAccess: false
users: []
enableKeycloak: false
keycloak: {}
allowConfigEdit: true
enableServiceWorker: false
disableContextMenu: false
disableUpdateChecks: false
disableSmartSort: false
pageInfo:
title: s0
description: s0
sections:
- name: Media & Entertainment
icon: fas fa-photo-video
displayData:
sortBy: most-used
cols: 1
rows: 1
collapsed: false
hideForGuests: false
items:
- &ref_0
title: Jellyfin
icon: hl-jellyfin
url: http://s0:8097
target: sametab
statusCheck: true
statusCheckUrl: http://jellyfin.s0
id: 0_1956_jellyfin
- &ref_1
title: Sonarr
description: Manage TV
icon: hl-sonarr
url: http://s0:8989
target: sametab
statusCheck: true
statusCheckUrl: http://sonarr.s0
id: 1_1956_sonarr
- &ref_2
title: Radarr
description: Manage Movies
icon: hl-radarr
url: http://s0:7878
target: sametab
statusCheck: true
statusCheckUrl: http://radarr.s0
id: 2_1956_radarr
- &ref_3
title: Lidarr
description: Manage Music
icon: hl-lidarr
url: http://s0:8686
target: sametab
statusCheck: true
statusCheckUrl: http://lidarr.s0
id: 3_1956_lidarr
- &ref_4
title: Prowlarr
description: Indexers
icon: hl-prowlarr
url: http://prowlarr.s0
target: sametab
statusCheck: true
statusCheckUrl: http://prowlarr.s0
id: 4_1956_prowlarr
- &ref_5
title: Bazarr
description: Subtitles
icon: hl-bazarr
url: http://s0:6767
target: sametab
statusCheck: true
statusCheckUrl: http://bazarr.s0
id: 5_1956_bazarr
- &ref_6
title: Navidrome
description: Play Music
icon: hl-navidrome
url: http://s0:4534
target: sametab
statusCheck: true
statusCheckUrl: http://music.s0
id: 6_1956_navidrome
- &ref_7
title: Transmission
description: Torrenting
icon: hl-transmission
url: http://s0:9091
target: sametab
statusCheck: true
statusCheckUrl: http://transmission.s0
id: 7_1956_transmission
filteredItems:
- *ref_0
- *ref_1
- *ref_2
- *ref_3
- *ref_4
- *ref_5
- *ref_6
- *ref_7
- name: Network
icon: fas fa-network-wired
items:
- &ref_8
title: Gateway
description: openwrt
icon: hl-openwrt
url: http://openwrt.lan/
target: sametab
statusCheck: true
id: 0_746_gateway
- &ref_9
title: Wireless
description: openwrt (ish)
icon: hl-openwrt
url: http://PacketProvocateur.lan
target: sametab
statusCheck: true
id: 1_746_wireless
filteredItems:
- *ref_8
- *ref_9
displayData:
sortBy: default
rows: 1
cols: 1
collapsed: false
hideForGuests: false
- name: Services
icon: fas fa-monitor-heart-rate
items:
- &ref_10
title: Matrix
description: ''
icon: hl-matrix
url: https://chat.neet.space
target: sametab
statusCheck: true
id: 0_836_matrix
- &ref_11
title: Radio
description: Radio service
icon: generative
url: https://radio.runyan.org
target: sametab
statusCheck: true
id: 1_836_radio
- &ref_12
title: Mumble
description: voice.neet.space
icon: hl-mumble
url: https://voice.neet.space
target: sametab
statusCheck: false
id: 2_836_mumble
- &ref_13
title: IRC
description: irc.neet.dev
icon: hl-thelounge
url: https://irc.neet.dev
target: sametab
statusCheck: true
id: 3_836_irc
- &ref_14
title: Git
description: git.neet.dev
icon: hl-gitea
url: https://git.neet.dev
target: sametab
statusCheck: true
id: 4_836_git
- &ref_15
title: Nextcloud
description: neet.cloud
icon: hl-nextcloud
url: https://neet.cloud
target: sametab
statusCheck: true
id: 5_836_nextcloud
- &ref_16
title: Roundcube
description: mail.neet.dev
icon: hl-roundcube
url: https://mail.neet.dev
target: sametab
statusCheck: true
id: 6_836_roundcube
- &ref_17
title: Jitsi Meet
description: meet.neet.space
icon: hl-jitsimeet
url: https://meet.neet.space
target: sametab
statusCheck: true
id: 7_836_jitsimeet
filteredItems:
- *ref_10
- *ref_11
- *ref_12
- *ref_13
- *ref_14
- *ref_15
- *ref_16
- *ref_17
displayData:
sortBy: default
rows: 1
cols: 1
collapsed: false
hideForGuests: false

View File

@@ -3,6 +3,7 @@
{
imports = [
./hardware-configuration.nix
./frigate.nix
./home-automation.nix
];
@@ -19,13 +20,13 @@
secretKeyFile = "/run/agenix/binary-cache-private-key";
};
age.secrets.binary-cache-private-key.file = ../../../secrets/binary-cache-private-key.age;
users.users.cache-push = {
isNormalUser = true;
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINpUZFFL9BpBVqeeU63sFPhR9ewuhEZerTCDIGW1NPSB" ];
};
nix.settings = {
trusted-users = [ "cache-push" ];
};
# users.users.cache-push = {
# isNormalUser = true;
# openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINpUZFFL9BpBVqeeU63sFPhR9ewuhEZerTCDIGW1NPSB" ];
# };
# nix.settings = {
# trusted-users = [ "cache-push" ];
# };
services.iperf3.enable = true;
services.iperf3.openFirewall = true;
@@ -74,9 +75,36 @@
services.lidarr.enable = true;
services.lidarr.user = "public_data";
services.lidarr.group = "public_data";
services.recyclarr = {
enable = true;
configuration = {
radarr.radarr_main = {
api_key = {
_secret = "/run/credentials/recyclarr.service/radarr-api-key";
};
base_url = "http://localhost:7878";
quality_definition.type = "movie";
};
sonarr.sonarr_main = {
api_key = {
_secret = "/run/credentials/recyclarr.service/sonarr-api-key";
};
base_url = "http://localhost:8989";
quality_definition.type = "series";
};
};
};
systemd.services.recyclarr.serviceConfig.LoadCredential = [
"radarr-api-key:/run/agenix/radarr-api-key"
"sonarr-api-key:/run/agenix/sonarr-api-key"
];
services.transmission = {
enable = true;
package = pkgs.transmission_4;
performanceNetParameters = true;
user = "public_data";
group = "public_data";
@@ -144,87 +172,200 @@
8686 # lidarr
9091 # transmission web
];
age.secrets.radarr-api-key.file = ../../../secrets/radarr-api-key.age;
age.secrets.sonarr-api-key.file = ../../../secrets/sonarr-api-key.age;
# jellyfin
# jellyfin cannot run in the vpn container and use hardware encoding
# I could not figure out how to allow the container to access the encoder
services.jellyfin.enable = true;
users.users.${config.services.jellyfin.user}.extraGroups = [ "public_data" ];
nixpkgs.config.packageOverrides = pkgs: {
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
};
hardware.opengl = {
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
vaapiIntel
vaapiVdpau
libvdpau-va-gl
intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in)
];
};
# nginx
services.nginx.enable = true;
services.nginx.virtualHosts."bazarr.s0" = {
listen = [{ addr = "0.0.0.0"; port = 6767; } { addr = "0.0.0.0"; port = 80; }];
locations."/".proxyPass = "http://vpn.containers:6767";
};
services.nginx.virtualHosts."radarr.s0" = {
listen = [{ addr = "0.0.0.0"; port = 7878; } { addr = "0.0.0.0"; port = 80; }];
locations."/".proxyPass = "http://vpn.containers:7878";
};
services.nginx.virtualHosts."lidarr.s0" = {
listen = [{ addr = "0.0.0.0"; port = 8686; } { addr = "0.0.0.0"; port = 80; }];
locations."/".proxyPass = "http://vpn.containers:8686";
};
services.nginx.virtualHosts."sonarr.s0" = {
listen = [{ addr = "0.0.0.0"; port = 8989; } { addr = "0.0.0.0"; port = 80; }];
locations."/".proxyPass = "http://vpn.containers:8989";
};
services.nginx.virtualHosts."prowlarr.s0" = {
listen = [{ addr = "0.0.0.0"; port = 9696; } { addr = "0.0.0.0"; port = 80; }];
locations."/".proxyPass = "http://vpn.containers:9696";
};
services.nginx.virtualHosts."music.s0" = {
listen = [{ addr = "0.0.0.0"; port = 4534; } { addr = "0.0.0.0"; port = 80; }];
locations."/".proxyPass = "http://localhost:4533";
};
services.nginx.virtualHosts."jellyfin.s0" = {
listen = [{ addr = "0.0.0.0"; port = 8097; } { addr = "0.0.0.0"; port = 80; }];
locations."/" = {
proxyPass = "http://localhost:8096";
proxyWebsockets = true;
};
};
services.nginx.virtualHosts."jellyfin.neet.cloud".locations."/" = {
proxyPass = "http://localhost:8096";
proxyWebsockets = true;
};
services.nginx.virtualHosts."transmission.s0" = {
listen = [{ addr = "0.0.0.0"; port = 9091; } { addr = "0.0.0.0"; port = 80; }];
locations."/" = {
proxyPass = "http://vpn.containers:9091";
proxyWebsockets = true;
services.nginx = {
enable = true;
openFirewall = false; # All nginx services are internal
virtualHosts =
let
mkHost = external: config:
{
${external} = {
useACMEHost = "s0.neet.dev"; # Use wildcard cert
forceSSL = true;
locations."/" = config;
};
};
mkVirtualHost = external: internal:
mkHost external {
proxyPass = internal;
proxyWebsockets = true;
};
mkStaticHost = external: static:
mkHost external {
root = static;
tryFiles = "$uri /index.html ";
};
in
lib.mkMerge [
(mkVirtualHost "bazarr.s0.neet.dev" "http://vpn.containers:6767")
(mkVirtualHost "radarr.s0.neet.dev" "http://vpn.containers:7878")
(mkVirtualHost "lidarr.s0.neet.dev" "http://vpn.containers:8686")
(mkVirtualHost "sonarr.s0.neet.dev" "http://vpn.containers:8989")
(mkVirtualHost "prowlarr.s0.neet.dev" "http://vpn.containers:9696")
(mkVirtualHost "transmission.s0.neet.dev" "http://vpn.containers:9091")
(mkVirtualHost "unifi.s0.neet.dev" "https://localhost:8443")
(mkVirtualHost "music.s0.neet.dev" "http://localhost:4533")
(mkVirtualHost "jellyfin.s0.neet.dev" "http://localhost:8096")
(mkStaticHost "s0.neet.dev" config.services.dashy.finalDrv)
{
# Landing page LAN redirect
"s0" = {
default = true;
redirectCode = 302;
globalRedirect = "s0.neet.dev";
};
}
(mkVirtualHost "ha.s0.neet.dev" "http://localhost:${toString config.services.home-assistant.config.http.server_port}")
(mkVirtualHost "esphome.s0.neet.dev" "http://localhost:6052")
(mkVirtualHost "zigbee.s0.neet.dev" "http://localhost:55834")
{
"frigate.s0.neet.dev" = {
# Just configure SSL, frigate module configures the rest of nginx
useACMEHost = "s0.neet.dev";
forceSSL = true;
};
}
(mkVirtualHost "vacuum.s0.neet.dev" "http://192.168.1.125") # valetudo
(mkVirtualHost "sandman.s0.neet.dev" "http://192.168.9.14:3000") # es
(mkVirtualHost "todo.s0.neet.dev" "http://localhost:${toString config.services.vikunja.port}")
(mkVirtualHost "budget.s0.neet.dev" "http://localhost:${toString config.services.actual.settings.port}") # actual budget
(mkVirtualHost "linkwarden.s0.neet.dev" "http://localhost:${toString config.services.linkwarden.port}")
(mkVirtualHost "memos.s0.neet.dev" "http://localhost:${toString config.services.memos.settings.MEMOS_PORT}")
(mkVirtualHost "outline.s0.neet.dev" "http://localhost:${toString config.services.outline.port}")
(mkVirtualHost "languagetool.s0.neet.dev" "http://localhost:${toString config.services.languagetool.port}")
];
tailscaleAuth = {
enable = true;
virtualHosts = [
"bazarr.s0.neet.dev"
"radarr.s0.neet.dev"
"lidarr.s0.neet.dev"
"sonarr.s0.neet.dev"
"prowlarr.s0.neet.dev"
"transmission.s0.neet.dev"
"unifi.s0.neet.dev"
# "music.s0.neet.dev" # messes up navidrome
"jellyfin.s0.neet.dev"
"s0.neet.dev"
# "ha.s0.neet.dev" # messes up home assistant
"esphome.s0.neet.dev"
"zigbee.s0.neet.dev"
"vacuum.s0.neet.dev"
"todo.s0.neet.dev"
"budget.s0.neet.dev"
"linkwarden.s0.neet.dev"
# "memos.s0.neet.dev" # messes up memos /auth route
# "outline.s0.neet.dev" # messes up outline /auth route
"languagetool.s0.neet.dev"
];
expectedTailnet = "koi-bebop.ts.net";
};
};
networking.firewall.allowedTCPPorts = [
6767
7878
8686
8989
9696
4534
8097
9091
];
# Get wildcard cert
security.acme.certs."s0.neet.dev" = {
dnsProvider = "digitalocean";
credentialsFile = "/run/agenix/digitalocean-dns-credentials";
extraDomainNames = [ "*.s0.neet.dev" ];
group = "nginx";
dnsResolver = "1.1.1.1:53";
dnsPropagationCheck = false; # sadly this erroneously fails
};
age.secrets.digitalocean-dns-credentials.file = ../../../secrets/digitalocean-dns-credentials.age;
virtualisation.oci-containers.backend = "podman";
virtualisation.podman.dockerSocket.enable = true; # TODO needed?
services.dashy = {
enable = true;
configFile = ./dashy.yaml;
settings = import ./dashy.nix;
};
services.unifi = {
enable = true;
openMinimalFirewall = true;
};
services.vikunja = {
enable = true;
port = 61473;
frontendScheme = "https";
frontendHostname = "todo.s0.neet.dev";
settings = {
service.enableregistration = false;
};
};
backup.group."vikunja".paths = [
"/var/lib/vikunja"
];
services.actual.enable = true;
services.linkwarden = {
enable = true;
enableRegistration = true;
port = 41709;
environment.NEXTAUTH_URL = "https://linkwarden.s0.neet.dev/api/v1/auth";
environmentFile = "/run/agenix/linkwarden-environment";
};
age.secrets.linkwarden-environment.file = ../../../secrets/linkwarden-environment.age;
services.meilisearch = {
enable = true;
package = pkgs.meilisearch;
};
services.flaresolverr = {
enable = true;
port = 48072;
};
services.memos = {
enable = true;
settings.MEMOS_PORT = "57643";
};
services.outline = {
enable = true;
forceHttps = false; # https through nginx
port = 43933;
publicUrl = "https://outline.s0.neet.dev";
storage.storageType = "local";
smtp = {
secure = true;
fromEmail = "robot@runyan.org";
username = "robot@runyan.org";
replyEmail = "robot@runyan.org";
host = "mail.neet.dev";
port = 465;
passwordFile = "/run/agenix/robots-email-pw";
};
};
age.secrets.robots-email-pw = {
file = ../../../secrets/robots-email-pw.age;
owner = config.services.outline.user;
};
services.languagetool = {
enable = true;
port = 60613;
};
boot.binfmt.emulatedSystems = [ "aarch64-linux" "armv7l-linux" ];

View File

@@ -0,0 +1,159 @@
{ config, pkgs, lib, ... }:
let
frigateHostname = "frigate.s0.neet.dev";
mkGo2RtcStream = name: url: withAudio: {
${name} = [
url
"ffmpeg:${name}#video=copy${if withAudio then "#audio=copy" else ""}"
];
};
# Assumes camera is set to output:
# - rtsp
# - H.264 + AAC
# - a downscaled substream for detection
mkCamera = name: primaryUrl: detectUrl: {
# Reference https://docs.frigate.video/configuration/reference/
services.frigate.settings = {
cameras.${name} = {
ffmpeg = {
# Camera feeds are relayed through go2rtc
inputs = [
{
path = "rtsp://127.0.0.1:8554/${name}";
# input_args = "preset-rtsp-restream";
input_args = "preset-rtsp-restream-low-latency";
roles = [ "record" ];
}
{
path = detectUrl;
roles = [ "detect" ];
}
];
output_args = {
record = "preset-record-generic-audio-copy";
};
};
detect = {
width = 1280;
height = 720;
fps = 5;
};
};
};
services.go2rtc.settings.streams = lib.mkMerge [
(mkGo2RtcStream name primaryUrl false)
# Sadly having the detection stream go through go2rpc too makes the stream unreadable by frigate for some reason.
# It might need to be re-encoded to work. But I am not interested in wasting the processing power if only frigate
# need the detection stream anyway. So just let frigate grab the stream directly since it works.
# (mkGo2RtcStream detectName detectUrl false)
];
};
mkDahuaCamera = name: address:
let
# go2rtc and frigate have a slightly different syntax for inserting env vars. So the URLs are not interchangable :(
# - go2rtc: ${VAR}
# - frigate: {VAR}
primaryUrl = "rtsp://admin:\${FRIGATE_RTSP_PASSWORD}@${address}/cam/realmonitor?channel=1&subtype=0";
detectUrl = "rtsp://admin:{FRIGATE_RTSP_PASSWORD}@${address}/cam/realmonitor?channel=1&subtype=3";
in
mkCamera name primaryUrl detectUrl;
mkEsp32Camera = name: address: {
services.frigate.settings.cameras.${name} = {
ffmpeg = {
input_args = "";
inputs = [{
path = "http://${address}:8080";
roles = [ "detect" "record" ];
}];
output_args.record = "-f segment -pix_fmt yuv420p -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v libx264 -preset ultrafast -an ";
};
};
};
in
lib.mkMerge [
(mkDahuaCamera "dog-cam" "192.168.10.31")
# (mkEsp32Camera "dahlia-cam" "dahlia-cam.lan")
{
services.frigate = {
enable = true;
hostname = frigateHostname;
# Sadly this fails because it doesn't support frigate's var substition format
# which is critical... so what's even the point of it then?
checkConfig = false;
settings = {
mqtt = {
enabled = true;
host = "localhost";
port = 1883;
user = "root";
password = "{FRIGATE_MQTT_PASSWORD}";
};
snapshots = {
enabled = true;
bounding_box = true;
};
record = {
enabled = true;
# sync_recordings = true; # detect if recordings were deleted outside of frigate (expensive)
retain = {
days = 7; # Keep video for 7 days
mode = "all";
# mode = "motion";
};
events = {
retain = {
default = 10; # Keep video with detections for 10 days
mode = "motion";
# mode = "active_objects";
};
};
};
# Make frigate aware of the go2rtc streams
go2rtc.streams = config.services.go2rtc.settings.streams;
detect.enabled = false; # :(
objects = {
track = [ "person" "dog" ];
};
};
};
services.go2rtc = {
enable = true;
settings = {
rtsp.listen = ":8554";
webrtc.listen = ":8555";
};
};
# Pass in env file with secrets to frigate/go2rtc
systemd.services.frigate.serviceConfig.EnvironmentFile = "/run/agenix/frigate-credentials";
systemd.services.go2rtc.serviceConfig.EnvironmentFile = "/run/agenix/frigate-credentials";
age.secrets.frigate-credentials.file = ../../../secrets/frigate-credentials.age;
}
{
# hardware encode/decode with amdgpu vaapi
services.frigate.vaapiDriver = "radeonsi";
services.frigate.settings.ffmpeg.hwaccel_args = "preset-vaapi";
}
{
# Coral TPU for frigate
services.frigate.settings.detectors.coral = {
type = "edgetpu";
device = "pci";
};
}
{
# Don't require authentication for frigate
# This is ok because the reverse proxy already requires tailscale access anyway
services.frigate.settings.auth.enabled = false;
}
]

View File

@@ -8,6 +8,7 @@
# boot
boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.memtest86.enable = true;
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "uas" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
@@ -21,7 +22,6 @@
# zfs
networking.hostId = "5e6791f0";
boot.supportedFilesystems = [ "zfs" ];
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
# luks
remoteLuksUnlock.enable = true;
@@ -58,8 +58,48 @@
};
swapDevices = [ ];
networking.interfaces.eth0.useDHCP = true;
networking.interfaces.eth1.useDHCP = true;
### networking ###
# systemd.network.enable = true;
networking = {
# useNetworkd = true;
dhcpcd.enable = true;
interfaces."eth0".useDHCP = true;
interfaces."eth1".useDHCP = false;
interfaces."main@eth1".useDHCP = true;
interfaces."iot@eth1".useDHCP = true;
interfaces."management@eth1".useDHCP = true;
vlans = {
main = {
id = 5;
interface = "eth1";
};
iot = {
id = 2;
interface = "eth1";
};
management = {
id = 4;
interface = "eth1";
};
};
# interfaces.eth1.ipv4.addresses = [{
# address = "192.168.1.2";
# prefixLength = 21;
# }];
# interfaces.iot.ipv4.addresses = [{
# address = "192.168.9.8";
# prefixLength = 22;
# }];
defaultGateway = {
# interface = "eth1";
address = "192.168.1.1";
};
# nameservers = [ "1.1.1.1" "8.8.8.8" ];
};
powerManagement.cpuFreqGovernor = "powersave";
}

View File

@@ -1,185 +1,155 @@
{ config, lib, pkgs, ... }:
let
frigateHostname = "frigate.s0";
frigatePort = 61617;
in
{
networking.firewall.allowedTCPPorts = [
# 1883 # mqtt
55834 # mqtt zigbee frontend
frigatePort
4180 # oauth proxy
];
services.esphome.enable = true;
services.frigate = {
enable = true;
hostname = frigateHostname;
settings = {
mqtt = {
enabled = true;
host = "localhost:1883";
};
cameras = {
dahlia-cam = {
ffmpeg = {
input_args = "";
inputs = [{
path = "http://dahlia-cam.lan:8080";
roles = [ "detect" "record" ];
}];
output_args.record = "-f segment -pix_fmt yuv420p -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v libx264 -preset ultrafast -an ";
};
rtmp.enabled = false;
snapshots = {
enabled = true;
bounding_box = true;
};
record = {
enabled = false;
retain.days = 0; # To not retain any recording if there is no detection of any events
events.retain = {
default = 3; # To retain recording for 3 days of only the events that happened
mode = "active_objects";
};
};
detect = {
enabled = true;
width = 800;
height = 600;
fps = 20;
};
objects = {
track = [ "dog" ];
filters.dog.threshold = 0.4;
};
};
};
# ffmpeg = {
# hwaccel_args = "preset-vaapi";
# };
detectors.coral = {
type = "edgetpu";
device = "pci";
};
};
};
# AMD GPU for vaapi
systemd.services.frigate.environment.LIBVA_DRIVER_NAME = "radeonsi";
# Coral TPU for frigate
services.udev.packages = [ pkgs.libedgetpu ];
users.groups.apex = { };
systemd.services.frigate.environment.LD_LIBRARY_PATH = "${pkgs.libedgetpu}/lib";
systemd.services.frigate.serviceConfig = {
SupplementaryGroups = "apex";
};
# Coral PCIe driver
kernel.enableGasketKernelModule = true;
# Allow accessing frigate UI on a specific port in addition to by hostname
services.nginx.virtualHosts.${frigateHostname} = {
listen = [{ addr = "0.0.0.0"; port = frigatePort; } { addr = "0.0.0.0"; port = 80; }];
};
services.esphome = {
enable = true;
address = "0.0.0.0";
openFirewall = true;
};
# TODO remove after upgrading nixos version
systemd.services.esphome.serviceConfig.ProcSubset = lib.mkForce "all";
systemd.services.esphome.serviceConfig.ProtectHostname = lib.mkForce false;
systemd.services.esphome.serviceConfig.ProtectKernelLogs = lib.mkForce false;
systemd.services.esphome.serviceConfig.ProtectKernelTunables = lib.mkForce false;
# TODO lock down
services.mosquitto = {
enable = true;
listeners = [
{
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
settings.allow_anonymous = true;
users.root = {
acl = [ "readwrite #" ];
hashedPassword = "$7$101$8+QnkTzCdGizaKqq$lpU4o84n6D/1uwfA9pZDVExr1NDm1D/8tNla2tE9J9HdUqkvu192yYfiySY1MFqVNgUKgWEFu5P1bUKqRnzbUw==";
};
}
];
};
networking.firewall.allowedTCPPorts = [
# mqtt
1883
# Must be exposed so some local devices (such as HA voice preview) can pair with home assistant
config.services.home-assistant.config.http.server_port
# Music assistant (must be exposed so local devices can fetch the audio stream from it)
8095
8097
];
services.zigbee2mqtt = {
enable = true;
settings = {
homeassistant = true;
permit_join = false;
serial = {
adapter = "ember";
port = "/dev/ttyACM0";
};
mqtt = {
server = "mqtt://localhost:1883";
# base_topic = "zigbee2mqtt";
user = "root";
password = "!/run/agenix/zigbee2mqtt.yaml mqtt_password";
};
frontend = {
host = "0.0.0.0";
host = "localhost";
port = 55834;
};
};
};
age.secrets."zigbee2mqtt.yaml" = {
file = ../../../secrets/zigbee2mqtt.yaml.age;
owner = "zigbee2mqtt";
};
services.home-assistant = {
enable = true;
openFirewall = true;
configWritable = true;
extraComponents = [
"default_config"
"rest_command"
"esphome"
"met"
"radio_browser"
"wled"
"mqtt"
"apple_tv" # why is this even needed? I get `ModuleNotFoundError: No module named 'pyatv'` errors otherwise for some reason.
"unifi"
"digital_ocean"
"downloader"
"mailgun"
"minecraft_server"
"mullvad"
"nextcloud"
"ollama"
"openweathermap"
"jellyfin"
"transmission"
"radarr"
"sonarr"
"syncthing"
"tailscale"
"weather"
"whois"
"youtube"
"homekit_controller"
"zha"
"bluetooth"
"whisper"
"piper"
"wyoming"
"tts"
"music_assistant"
"openai_conversation"
];
# config = null;
config = {
# Includes dependencies for a basic setup
# https://www.home-assistant.io/integrations/default_config/
default_config = { };
homeassistant = {
external_url = "https://ha.s0.neet.dev";
internal_url = "http://192.168.1.2:${toString config.services.home-assistant.config.http.server_port}";
};
# Enable reverse proxy support
http = {
use_x_forwarded_for = true;
trusted_proxies = [
"127.0.0.1"
"::1"
];
};
"automation manual" = [
];
# Allow using automations generated from the UI
"automation ui" = "!include automations.yaml";
"rest_command" = {
json_post_request = {
url = "{{ url }}";
method = "POST";
content_type = "application/json";
payload = "{{ payload | default('{}') }}";
};
};
};
};
services.oauth2_proxy =
let
nextcloudServer = "https://neet.cloud/";
in
{
enable = true;
services.wyoming.faster-whisper.servers."hass" = {
enable = true;
uri = "tcp://0.0.0.0:45785";
model = "distil-small.en";
language = "en";
};
httpAddress = "http://0.0.0.0:4180";
services.wyoming.piper.servers."hass" = {
enable = true;
uri = "tcp://0.0.0.0:45786";
voice = "en_US-joe-medium";
};
nginx.virtualHosts = [
frigateHostname
];
email.domains = [ "*" ];
cookie.secure = false;
provider = "nextcloud";
# redirectURL = "http://s0:4180/oauth2/callback"; # todo forward with nginx?
clientID = "4FfhEB2DNzUh6wWhXTjqQQKu3Ibm6TeYpS8TqcHe55PJC1DorE7vBZBELMKDjJ0X";
keyFile = "/run/agenix/oauth2-proxy-env";
loginURL = "${nextcloudServer}/index.php/apps/oauth2/authorize";
redeemURL = "${nextcloudServer}/index.php/apps/oauth2/api/v1/token";
validateURL = "${nextcloudServer}/ocs/v2.php/cloud/user?format=json";
# todo --cookie-refresh
extraConfig = {
# cookie-csrf-per-request = true;
# cookie-csrf-expire = "5m";
# user-id-claim = "preferred_username";
};
};
age.secrets.oauth2-proxy-env.file = ../../../secrets/oauth2-proxy-env.age;
services.music-assistant = {
enable = true;
providers = [
"hass"
"hass_players"
"jellyfin"
"radiobrowser"
"spotify"
];
};
networking.hosts = {
# Workaround for broken spotify api integration
# https://github.com/librespot-org/librespot/issues/1527#issuecomment-3167094158
"0.0.0.0" = [ "apresolve.spotify.com" ];
};
}

View File

@@ -1,6 +1,7 @@
{
hostNames = [
"s0"
"s0.neet.dev"
];
arch = "x86_64-linux";
@@ -11,12 +12,20 @@
"pia"
"binary-cache"
"gitea-actions-runner"
"frigate"
"zigbee"
"media-server"
"linkwarden"
"outline"
"dns-challenge"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwiXcUFtAvZCayhu4+AIcF+Ktrdgv9ee/mXSIhJbp4q";
remoteUnlock = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNiceeFMos5ZXcYem4yFxh8PiZNNnuvhlyLbQLrgIZH";
clearnetHost = "192.168.1.2";
onionHost = "r3zvf7f2ppaeithzswigma46pajt3hqytmkg3rshgknbl3jbni455fqd.onion";
};
}

View File

@@ -5,8 +5,6 @@
./hardware-configuration.nix
];
de.enable = true;
# Login DE Option: Steam
programs.steam.gamescopeSession.enable = true;
# programs.gamescope.capSysNice = true;
@@ -22,10 +20,6 @@
);
services.mount-samba.enable = true;
# Login DE Option: RetroArch
services.xserver.desktopManager.retroarch.enable = true;
services.xserver.desktopManager.retroarch.package = pkgs.retroarchFull;
# wireless xbox controller support
hardware.xone.enable = true;
boot.kernelModules = [ "xone-wired" "xone-dongle" ];
@@ -33,37 +27,15 @@
hardware.enableAllFirmware = true;
# ROCm
hardware.opengl.extraPackages = with pkgs; [
rocm-opencl-icd
rocm-opencl-runtime
hardware.graphics.extraPackages = with pkgs; [
rocmPackages.clr.icd
rocmPackages.clr
];
systemd.tmpfiles.rules = [
"L+ /opt/rocm/hip - - - - ${pkgs.rocmPackages.clr}"
];
# System wide barrier instance
systemd.services.barrier-sddm = {
description = "Barrier mouse/keyboard share";
requires = [ "display-manager.service" ];
after = [ "network.target" "display-manager.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Restart = "always";
RestartSec = 10;
# todo use user/group
};
path = with pkgs; [ barrier doas ];
script = ''
# Wait for file to show up. "display-manager.service" finishes a bit too soon
while ! [ -e /run/sddm/* ]; do sleep 1; done;
export XAUTHORITY=$(ls /run/sddm/*)
# Disable crypto is fine because tailscale is E2E encrypting better than barrier could anyway
barrierc -f --disable-crypto --name zoidberg ray.koi-bebop.ts.net
'';
};
# Login into X11 plasma so barrier works well
services.xserver.displayManager.defaultSession = "plasma";
services.displayManager.defaultSession = "plasma";
users.users.cris = {
isNormalUser = true;
@@ -83,7 +55,7 @@
};
# Auto login into Plasma in john zoidberg account
services.xserver.displayManager.sddm.settings = {
services.displayManager.sddm.settings = {
Autologin = {
Session = "plasma";
User = "john";
@@ -91,9 +63,17 @@
};
environment.systemPackages = with pkgs; [
jellyfin-media-player
config.services.xserver.desktopManager.kodi.package
spotify
retroarchFull
];
# Command and Conquer Ports
networking.firewall.allowedUDPPorts = [ 4321 27900 ];
networking.firewall.allowedTCPPorts = [ 6667 28910 29900 29920 ];
services.ollama = {
enable = true;
package = pkgs.ollama-vulkan;
host = "127.0.0.1";
};
}

View File

@@ -7,7 +7,7 @@
];
# boot
efi.enable = true;
boot.loader.systemd-boot.enable = true;
boot.loader.timeout = lib.mkForce 15;
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
@@ -17,16 +17,17 @@
boot.extraModulePackages = [ ];
boot.kernelPackages = pkgs.linuxPackages_latest;
# luks unlock with clevis
boot.initrd.systemd.enable = true;
boot.initrd.clevis = {
enable = true;
devices."enc-pv".secretFile = "/secret/decrypt.jwe";
};
# disks
remoteLuksUnlock.enable = true;
boot.initrd.luks.devices."enc-pv" = {
device = "/dev/disk/by-uuid/04231c41-2f13-49c0-8fce-0357eea67990";
allowDiscards = true;
# Fetch key from USB drive
keyFileSize = 4096;
keyFile = "/dev/disk/by-id/usb-Mass_Storage_Device_121220160204-0:0-part2";
fallbackToPassword = true;
};
fileSystems."/" =
{
@@ -35,7 +36,7 @@
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/8074-B04D";
device = "/dev/disk/by-uuid/954B-AB3E";
fsType = "vfat";
};
swapDevices =

View File

@@ -1,5 +1,7 @@
{ inputs }:
final: prev:
{
libedgetpu = prev.callPackage ./libedgetpu { };
}
let
system = prev.system;
in
{ }

View File

@@ -7,13 +7,5 @@
let
cfg = config.kernel;
gasket = config.boot.kernelPackages.callPackage ./gasket.nix { };
in
{
options.kernel.enableGasketKernelModule = lib.mkEnableOption "Enable Gasket Kernel Module";
config = lib.mkIf cfg.enableGasketKernelModule {
boot.extraModulePackages = [ gasket ];
};
}
{ }

View File

@@ -1,35 +0,0 @@
{ stdenv, lib, fetchFromGitHub, kernel }:
stdenv.mkDerivation rec {
pname = "gasket";
version = "1.0-18";
src = fetchFromGitHub {
owner = "google";
repo = "gasket-driver";
rev = "09385d485812088e04a98a6e1227bf92663e0b59";
sha256 = "fcnqCBh04e+w8g079JyuyY2RPu34M+/X+Q8ObE+42i4=";
};
makeFlags = [
"-C"
"${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"
"M=$(PWD)"
];
buildFlags = [ "modules" ];
installFlags = [ "INSTALL_MOD_PATH=${placeholder "out"}" ];
installTargets = [ "modules_install" ];
sourceRoot = "source/src";
hardeningDisable = [ "pic" "format" ];
nativeBuildInputs = kernel.moduleBuildDependencies;
meta = with lib; {
description = "The Coral Gasket Driver allows usage of the Coral EdgeTPU on Linux systems.";
homepage = "https://github.com/google/gasket-driver";
license = licenses.gpl2;
maintainers = [ lib.maintainers.kylehendricks ];
platforms = platforms.linux;
};
}

View File

@@ -1,72 +0,0 @@
{ stdenv
, lib
, fetchFromGitHub
, libusb1
, abseil-cpp
, flatbuffers
, xxd
}:
let
flatbuffers_1_12 = flatbuffers.overrideAttrs (oldAttrs: rec {
version = "1.12.0";
NIX_CFLAGS_COMPILE = "-Wno-error=class-memaccess -Wno-error=maybe-uninitialized";
cmakeFlags = (oldAttrs.cmakeFlags or [ ]) ++ [ "-DFLATBUFFERS_BUILD_SHAREDLIB=ON" ];
NIX_CXXSTDLIB_COMPILE = "-std=c++17";
configureFlags = (oldAttrs.configureFlags or [ ]) ++ [ "--enable-shared" ];
src = fetchFromGitHub {
owner = "google";
repo = "flatbuffers";
rev = "v${version}";
sha256 = "sha256-L1B5Y/c897Jg9fGwT2J3+vaXsZ+lfXnskp8Gto1p/Tg=";
};
});
in
stdenv.mkDerivation rec {
pname = "libedgetpu";
version = "grouper";
src = fetchFromGitHub {
owner = "google-coral";
repo = pname;
rev = "release-${version}";
sha256 = "sha256-73hwItimf88Iqnb40lk4ul/PzmCNIfdt6Afi+xjNiBE=";
};
patches = [ ./libedgetpu-stddef.diff ];
makeFlags = [ "-f" "makefile_build/Makefile" "libedgetpu" ];
buildInputs = [
libusb1
abseil-cpp
flatbuffers_1_12
];
nativeBuildInputs = [
xxd
];
NIX_CXXSTDLIB_COMPILE = "-std=c++17";
TFROOT = "${fetchFromGitHub {
owner = "tensorflow";
repo = "tensorflow";
rev = "v2.7.4";
sha256 = "sha256-liDbUAdaVllB0b74aBeqNxkYNu/zPy7k3CevzRF5dk0=";
}}";
enableParallelBuilding = false;
installPhase = ''
mkdir -p $out/lib
cp out/direct/k8/libedgetpu.so.1.0 $out/lib
ln -s $out/lib/libedgetpu.so.1.0 $out/lib/libedgetpu.so.1
mkdir -p $out/lib/udev/rules.d
cp debian/edgetpu-accelerator.rules $out/lib/udev/rules.d/99-edgetpu-accelerator.rules
# PCIe rule
echo 'SUBSYSTEM=="apex", MODE="0660", GROUP="apex"' > $out/lib/udev/rules.d/65-apex.rules
'';
}

View File

@@ -1,12 +0,0 @@
diff --git a/api/allocated_buffer.h b/api/allocated_buffer.h
index 97740f0..7bc0547 100644
--- a/api/allocated_buffer.h
+++ b/api/allocated_buffer.h
@@ -16,6 +16,7 @@
#define DARWINN_API_ALLOCATED_BUFFER_H_
#include <functional>
+#include <cstddef>
namespace platforms {
namespace darwinn {

View File

@@ -0,0 +1,15 @@
diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix
index f8d8f64e55da..39326d094118 100644
--- a/nixos/modules/services/video/frigate.nix
+++ b/nixos/modules/services/video/frigate.nix
@@ -609,10 +609,6 @@ in
};
};
extraConfig = ''
- # Frigate wants to connect on 127.0.0.1:5000 for unauthenticated requests
- # https://github.com/NixOS/nixpkgs/issues/370349
- listen 127.0.0.1:5000;
-
# vod settings
vod_base_url "";
vod_segments_base_url "";

View File

@@ -1,13 +0,0 @@
diff --git a/nixos/modules/programs/steam.nix b/nixos/modules/programs/steam.nix
index 29c449c16946..f6c728eb7f0c 100644
--- a/nixos/modules/programs/steam.nix
+++ b/nixos/modules/programs/steam.nix
@@ -11,7 +11,7 @@ let
in
pkgs.writeShellScriptBin "steam-gamescope" ''
${builtins.concatStringsSep "\n" exports}
- gamescope --steam ${toString cfg.gamescopeSession.args} -- steam -tenfoot -pipewire-dmabuf
+ gamescope --steam ${toString cfg.gamescopeSession.args} -- steam -gamepadui -steamdeck -pipewire-dmabuf &> /tmp/steamlog
'';
gamescopeSessionFile =

View File

@@ -1,23 +1,31 @@
age-encryption.org/v1
-> ssh-ed25519 yHDAQw BnVxLTfrWFqaT6+Tz8I0gQReC2NjADak1TlzotVHzEs
tzQGIMBFH1v91gezCWjCk3qNi6nhCFVMxaZrrxqFT+c
-> ssh-ed25519 jQaHAA BwpFr2XXWTaNeYgieI1rkRw5u/mf55vVooZnJJhMLSI
4VmJ1R5lcmD+apxg4WLnMk+aTJt3GOS+6KOE75NqjEY
-> ssh-ed25519 dMQYog oBypOzXH4ioZv9PzYGYxG4jBDRv6qIiRglj/f/uJugU
SQRv3Iel0jeONRAVp96VFtKjXGJ8PMvp80ys4otQp0U
-> ssh-ed25519 WBT1Hw wb7yUuZOQPhCYusR6WS5/e/NgC7UpBnIO0HZaO2+xxM
faHL6WBApWk8+871XmVRHcllXN4I7kgnqngY633jSI0
-> ssh-ed25519 6AT2/g +l7AjVqKk9oi96mglZDQN5AVncmVqjEjFfPXFZYdGlI
nEQtVZGMIKJlIf0Bj8T2YkUKQawpyP0bqCJ3Nj8PDPc
-> ssh-ed25519 VyYH/Q QHjWhus6HvedZXiDtkoK9DiS8EPOpUxRHix1cSwVuiU
vn0vSFHo6doBH/rzk42DxKN8XzSzMVDMMaeqQX6iuII
-> ssh-ed25519 hPp1nw FH8TXl9deDyGS9pCyG3sBvzpi8d9S0u4tprKopO6vBo
ZaricPkMTEn+xNPOJP4nLIpsHdFDVCCEqFVq4FxOPCw
-> ssh-ed25519 dMQYog FYeNrUyYZ/aYZkmjTEVJ3Fq4J5qAe+Do7IDPiYDZrgw
RroBGlF7DyNKmL4+Nd84eKKkJh7AGE9FP1VxgUO3iF4
-> htnK=h-grease F7l m it+; <4OvM
2MOngVDIi1sJJnjX2eAt4L3jObghFIbv20wJHLb7G0AMyavVmOiQ4xSehDKCb34g
10vwok0cSXaKOGmbXOFst9J2tk+z
--- nOQEybjt9MPX5X2cUnpKFgHtTSPvJSFnDGyj3ATlrEQ
ÞO¸¿"of<6F>æÕ¹|ñÜŠšÇ'_j]þëI<u‡‡:*¼†¾hœµÆ?"M‰)Ñ̦Ví*KAôN3µ@rWí¤©¨‹
tX€«Ñí…o
-> ssh-ed25519 qEbiMg V0tr/++dhQWcgmy46gcBm3t5qffN6N4ykabjMGdLLxg
oCCUu3kOopP5JgYAiytDrxHOo3LVtyAu1OAmJRg1nV8
-> ssh-ed25519 N7drjg HAu/AkGATNY7L3O2ospdN+r+KKVWD1yzi/kKmH5Fhzc
p8Y2vToiWACE/LNXa14fbAwuc5FfgR5day8Gu1uSVL8
-> ssh-ed25519 jQaHAA YuZH6pmrOAgzPNA2Mx7u827fYXOHJQ9XW8XR5h7XAFs
x1urfkuEH/1hHxBDK1Y7vjQMSUpUIj7uK7EGs/GtNk4
-> ssh-ed25519 ZDy34A AFzSzksrxlpyZfromJSB7u2HTVf7EC8Aydb7U0mQWUs
eWffyc2OIIEBxkk3y68xSzrDbheTzKnlilEt2VoNSaI
-> ssh-ed25519 w3nu8g MSI33XCDIZN4azrtb6hh6k6Gl1BYwaRK5/ROS6DHj10
kg057sgb1LLkoNgzTmCdgoM35BqV2gRjk4GLIytR8ng
-> ssh-ed25519 evqvfg Rssqwh73ihyNldaHFb65m0PGIi0VAySg7bHK8BTrHRI
bNCBI3MvfFT88sgVFbgCaOrRozcDMISdCn9IJJeACOI
-> ssh-ed25519 WBT1Hw y+gFWQQ/FbD1im+D6rcsGsVOYpfkgw0b2P6Gx4J+5WM
od9fIeEqmEbMd0Bv+iI3UdUl2MtelF/Q+ew+4wKU6nw
-> ssh-ed25519 6AT2/g +sWGzEbUwMjkY+oTFa72/wbP0VejtVpvEJocmb4ApjY
2HipJHjD9dKzUSWdBCVkDgpUtHNaQl7WJFvEPS6fpxw
-> ssh-ed25519 r848+g BTw707tEO/KQhhKsWgYYdGC+pdQyA4zhaHLt6BFen3E
ldBDOfC7/8vkOS01D/solHplEeIMvArHZsJL31FMYdg
-> ssh-ed25519 hPp1nw Sbzvkbw5FauhfNT1oQjjycUZ84c6sijyUlYgCc7bzjE
WQJ3KW8pGB8i0I7yI0/Tr99wTCsZwEtSWpUm4CiU/wA
-> ssh-ed25519 ZDy34A I4d/QR9LScC9NpN5upKITEc2BjJXKb4BiF/FZwpcW1Y
r+hmbq4s4N5RuhlmTn7/SuBBdfRv/mzDbq++tbK7s2M
-> ssh-ed25519 w3nu8g Ut4z05l9uePnZRI38zmLvcgRdvCcy+YmFkn1IiqDRk8
64uJWpnsfmfc7z5JZnTnwHNPsp52B3/YFgIvT8Bt3GY
-> ssh-ed25519 evqvfg a6ZizyN6wCKvPtpu2hgPeQ8YTBouC+y8iQFeaJ46Ygg
olN0U7gzDid2EbhO4kGhhZjo7cvI/y+I7yeahrgS63Y
--- MQfYtj3KvglxbRIcFSCtH3XdKElzS84QEfMhvcYN8ms
ÌØàÕFwH猧¿2&öÐ+é®L
çr\ÊÚ2<>q§“*Ù,
0¥}ÌanZHÅmF5ª# \îêÎnInŽiªó)<29>ÿ´xµKž}7cÁ e¶å_6;–ðŽ„>e=¢„ˆÐXiK!Š~—³ú¿Ùò÷C2gS;⇣Å8

View File

@@ -1,11 +1,11 @@
age-encryption.org/v1
-> ssh-ed25519 hPp1nw eORh0m8mAPd3H/wjnHocuh/xheMuhLgWyzepL9RNii0
154IPIdkb8WpYgX/fj5jraQY5mN7udg3iaZ3VJB+3X8
-> ssh-ed25519 dMQYog 0eg1j3jL736OwjeMB55z52A6P34mSEYL6ulrn72blj0
UdFKIbrzAKCzZhYfH41z64cwkQRp1RZztYgknIEfoDc
-> K/&@p'&{-grease yb~ xHlc7m _t xm{3f
Gi2UGm5YXyByJuH6rRRBle/D5T7GS4FDt7Kv8aBKe8dfwUCu65OcvoaXzjm08EKA
m0yx
--- f79zGG5kBOul/cF0NJu1+f/NmaI0h/JcuHDano/1ghU
U¥÷7°åóʤï1måÔE\{^£$ŸÕ Cx~2"±8¶Æõ?&öó°„ÂË‹(áä±
…aÝÀyßÝ쥘g¬â†øÇ CYX}’Ö
-> ssh-ed25519 hPp1nw qfzeHTN5gk0CDb3Fmwak0InkJkxvlS5foxkuTKIvPTY
lEwEcGfpiJQae3mSD2yLfGFm97FZD6K5tOzBHRzT8/Q
-> ssh-ed25519 ZDy34A uS/CLVSyXkRIWlPEgtFn0NK6QFKZCeLHvT7Z1509Hjg
TpW6Y5iRXu7YpDbQV63m+3/LtqIujX54kiXH0ddqF9I
-> ssh-ed25519 w3nu8g IEC1wZ/EO+CHOvED3nQHPos7LDuiyivIqo3DKAOqZC4
XAh21OtD2A8psVBsGYXBY9oBf/woIxkIEMv2VMAYucg
-> ssh-ed25519 evqvfg DC9pQv6Jknsi532+px3q5m1HAeYHje0MeZSdPoD0JXA
rbXOmY3keN63YZL+kfpmZ9sOlOxWa+GVqgYBKURckvk
--- kIbVnf+2GlZRu1BGVi1zlHEIbuBxUX3/jvAHvwNtO88
Óûy]3â(@Žíº¡äÊÛ2v»ñÀéÔmwãÌП@ñÆPf†Êˆ:[ïÆ‡×¦!ãžQ¦<51>Å Ö<E28099>÷J0²á¸Oþ§KØCþjÐ#;VåWåŽduŒÇ<C592> Äiƒ?×g£c<C2A3><EFBFBD>ˆr>Ïú‹\«¦ü´5@ÓqÙ<71>ÎH22-dË«¸<C2AB>¿ÄPœ5 <20>|>ŒÜu

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,11 @@
age-encryption.org/v1
-> ssh-ed25519 hPp1nw MMPi5i5lVf/mcXOraMoErj12pjLWQppVTc18kMFTskM
eez7lnpUwseCP/5MZRxjyPZ11gfLHBYPPGEUXUftrAU
-> ssh-ed25519 ZDy34A dzbWYENdNUIHId+2XUt+gLpnw8xaVsSHrWfIhhBTYBI
NszPXqq/beWLE9pKMhbXYSEB3WDaU2EPy66yPC+oU+Y
-> ssh-ed25519 w3nu8g HjJYUyssutwK+bO120fPZoycsIEdLL0gnX1UDMHJKlY
jjr1bEAD4HHN1Hbdtj8VR6CqfkTHXZ6huJQ1fnp83s4
-> ssh-ed25519 evqvfg nNibZIdrlMqQXZYT+qFPyd8uB1gZgDjPdfIS7RRjJCM
5LNiRyVpkJr4x1CtV+FRsLF+Tk1KUQDFIrTBQVw3N5c
--- 7dJKHwTqDkiiZaojRRK0mpxWopbhLwydPwFXtden9iI
'oºé¹òîÌä<C38C>=1õ¶Bc×°V­d qâÀ=Þÿ¸¸°µï뎀ˆÔjÿ`ǦÎéÏÎ&åÂ@Ûó ½Ç 5RQØ´Ûh™ÞOÉÓÅPŽá£Cv7ü<37>A ûw£s±¸¥QÀR<C380>Ù­O<C2AD>M"Wèí*<2A>s Ýߤâ×a`Æp¬

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,11 +1,11 @@
age-encryption.org/v1
-> ssh-ed25519 6AT2/g UG+Ub0bZK74/Ifa/YkZOc6B3cPl6oI7M4Ev1zxkFEh0
z71vjnEqhL3kuLePbP0nKQNwU0mrCOO386wLdUhH5tU
-> ssh-ed25519 dMQYog t8H6XoIhhE4H9g4913sWgZ5BaYK04uk7Mj0FYnOdtTo
U4Ygto4z3l4dcCsnGxnRo1YGBl6YZ5y5pnVBJXCSrOc
-> Bad-grease <$Y
1xw
--- wiGO0H6gfd+3D/+V/rMNLGkDk6FPFUihXi43J82LAkg
³8>`®Às«»pú¨€¿U#ü™º¯KV%jbwïxN¸@
Žî@œª€
Ow\º(@@Tòìèzá
-> ssh-ed25519 6AT2/g 3s+reqcb4Hu/3Z7rICFZBOkW02ibISthFAT1sveyLBo
Eh5ynxeqqXhNbv/ASWZxzKXAzKX41uI5iJI4KqluHRI
-> ssh-ed25519 ZDy34A cHcA2p0VrGr6jP/CUTOSU4Gef04ujh6wmJjmEWmWNE0
wwaQnj7RABFzTbU74awlIJeHHePtO7jihNd2EUkNZPU
-> ssh-ed25519 w3nu8g hN/fWUHspXoJmpibR4NAL3EXkKExe2tRjUzmLGK6VnE
F1KQnGe3M8eD9hjnHLc7hqFTw9iXh7ICz0u421DuFOs
-> ssh-ed25519 evqvfg r3AoIJ3KWCYIsV8+RTgYY+Eg+1EcBVNrX+ZRunKaug8
KSXd4uq1/0ErZzSTPrCmY/66v4TT5PmFqv9LRSHNi9A
--- 3bGqZANqdfEgdiUzu38n4dzPOShgGUzQGtO7l2S+hwU
Ì?\<5C>•Öå¢aÚ'¤¤ÐÚ{˜/}ÉýÝL„:¨|¸G`†Ó+ºMÜÈY$s¸+Uk¥áäg‡ID¾K·

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,13 +1,13 @@
age-encryption.org/v1
-> ssh-ed25519 6AT2/g gPeZnJ8arK6xAGnEK9uTcGfwBI1pYjjv6VX4o9EBIns
sKFfqnafLachTKE93Pb7gsZ5gdKis64N64BK5128LKg
-> ssh-ed25519 hPp1nw e2taazZ3R6EBCbgh6Gg0Dc9p1K7zp5R7n9LIkWF/Wj8
+/VkcMDL1HNJhbc6/OxpiUe1dlO0lrc1hgkD/RrYXjY
-> ssh-ed25519 dMQYog znMKkv1O7F/EeAyvTfULUn/pWdai2NI0uBfWn/02xg0
45W9s4Vo8J+xOTGec9h6s0ra9ZSUA6JkorAAyqqlPfg
-> T/!XI-grease GJ_O'
mAOW54Txa2H9WdEMog0g1XQjkC5z0wQIoqNlnbsjCSvM1UaPiiu6vJOJKCmJb1Z6
3wyLN6lCIjkR
--- yX7lzKnDkn+KkRVTumffcd/SJSznR5n6JtUgWkSSohk
ãQô^àèyW; â§]Š+u>¥3wŒ¨oêM:ã™øêúÀöŸÃ9,xv×KÁÜXT-K8rÔ(@Ø-|³
:PÈ<50>‡*H6€'¹&Ôi
-> ssh-ed25519 6AT2/g MrkHK56b1uQIiMoSrGmCun5QzwFWQiCFZjHQuAkdBlc
ipK76P2VS5c00f3n468l+VsTndtEUwHtJTOhR1Zntew
-> ssh-ed25519 hPp1nw iVISLjddu2lJpNPXewFDmjhORkkzBNUBmq33n2l9yXg
4oOAaQpnWNsVXfDEK4rclKhAwv8xnE3EUS7PF44/GYc
-> ssh-ed25519 ZDy34A gZY++iCMswmQVkKiIUUuuR8srojCpykELGpa0mqHMFA
MSpvndXZY7Gm8VUQUdn/x39dVOsJ0d77H4zN0Ct+b1Q
-> ssh-ed25519 w3nu8g mnrSRjcTax6g1PHvOwCV/Al6AWkCwiRwMnuZg4vPHys
S2V1O0GF7wipp9Bg+7PA6z4WNbK/zv015AM1SfA/Jrg
-> ssh-ed25519 evqvfg 8M2kGsTS/cd0daAr87u0QqS6RH00O1zkSjYdXTxjYGU
uCUwdJFCdFWWlQPpINjf4dAIYZ/pa8tfz8pVjDLPJF0
--- iyh7GvKqnNeyIgedqWGQMtYfXJGo1RphDpzuDXJbp1k
#/Þ¿ «[4èAã<±Ëi×òæ˜ækÞfÓÕ

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