135 Commits

Author SHA1 Message Date
ef247cb3dd speed up
All checks were successful
Check Flake / check-flake (push) Successful in 2h31m6s
2024-06-17 21:11:06 -06:00
cad04680c4 try again
Some checks failed
Check Flake / check-flake (push) Failing after 3h11m0s
2024-06-16 21:30:10 -06:00
a2d176a4fc try again
Some checks failed
Check Flake / check-flake (push) Failing after 4s
2024-06-16 21:22:17 -06:00
1f813395ee try again
Some checks failed
Check Flake / check-flake (push) Failing after 16s
2024-06-16 21:21:19 -06:00
0d5bce2a4f try again
Some checks failed
Check Flake / check-flake (push) Failing after 7s
2024-06-16 21:05:33 -06:00
0c2f7cd1b2 try again
Some checks failed
Check Flake / check-flake (push) Failing after 7s
2024-06-16 21:01:29 -06:00
b80b31d3c3 try again
Some checks failed
Check Flake / check-flake (push) Failing after 4s
2024-06-16 20:58:18 -06:00
caacb4b7a7 try again
Some checks failed
Check Flake / check-flake (push) Failing after 2s
2024-06-16 20:55:50 -06:00
25dba0ee19 Use custom action
Some checks failed
Check Flake / check-flake (push) Failing after 1s
2024-06-16 20:54:47 -06:00
4bed47ae43 Try to install attic for gitea builder
Some checks failed
Check Flake / check-flake (push) Failing after 6s
2024-06-16 20:44:31 -06:00
7c4d2d53f2 Use attic as nixos binary cache and update CI accordingly
Some checks failed
Check Flake / check-flake (push) Failing after 8s
2024-06-16 20:39:11 -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
7e812001f0 Add librechat
All checks were successful
Check Flake / check-flake (push) Successful in 6m12s
2024-02-09 19:57:09 -07:00
14c19b80ef Stop auto upgrade
All checks were successful
Check Flake / check-flake (push) Successful in 1m2s
2024-02-05 11:32:16 -07:00
e8dd0cb5ff Increase gitea session length
All checks were successful
Check Flake / check-flake (push) Successful in 2m17s
2024-02-04 15:48:06 -07:00
dc9f5e969a Update nextcloud
All checks were successful
Check Flake / check-flake (push) Successful in 2m48s
2024-02-04 14:34:42 -07:00
03150667b6 Enable gitea index and lfs. Fix warning.
All checks were successful
Check Flake / check-flake (push) Successful in 4m49s
2024-02-04 13:59:39 -07:00
1dfd7bc8a2 Increase seed ratio
All checks were successful
Check Flake / check-flake (push) Successful in 2m58s
2024-02-03 14:15:49 -07:00
fa649b1e2a Add missing locale settings to perl stops complaining
All checks were successful
Check Flake / check-flake (push) Successful in 12m4s
2024-02-03 14:11:26 -07:00
e34752c791 Fix transmission running in a container
https://github.com/NixOS/nixpkgs/issues/258793
2024-02-03 14:10:35 -07:00
75031567bd Two radio endpoints
All checks were successful
Check Flake / check-flake (push) Successful in 50s
2024-02-02 20:23:40 -07:00
800a95d431 Update to nixos 23.11
All checks were successful
Check Flake / check-flake (push) Successful in 1m24s
2024-02-01 21:42:33 -07:00
932b05a42e Basic oauth proxy for frigate
All checks were successful
Check Flake / check-flake (push) Successful in 1m13s
2024-01-30 22:12:18 -07:00
b5cc4d4609 Emulate ARM systems for building 2024-01-30 21:59:09 -07:00
ba3d15d82a PoC: Frigate + PCIe Coral + ESPCam, Home Assistant, ESPHome, MQTT, zigbee2mqtt
All checks were successful
Check Flake / check-flake (push) Successful in 3m24s
2023-12-17 21:29:45 -07:00
e80fb7b3db PoC: Frigate + PCIe Coral + ESPCam, Home Assistant, ESPHome, MQTT, zigbee2mqtt
Some checks failed
Check Flake / check-flake (push) Failing after 1m1s
2023-12-17 14:29:45 -07:00
84e1f6e573 wireless role was removed 2023-12-02 10:26:44 -07:00
c4847bd39b Use dashy for services homepage
All checks were successful
Check Flake / check-flake (push) Successful in 5m25s
2023-11-08 21:35:10 -07:00
c0c1ec5c67 Enable autologin for zoidberg 2023-11-08 21:34:13 -07:00
6739115cfb Fix sddm barrier service for current nixpkgs version 2023-11-08 21:33:38 -07:00
4606cc32ba Enable adb debugging 2023-11-08 21:32:26 -07:00
2d27bf7505 Allow other users to access public samba mount 2023-11-08 21:32:00 -07:00
d07af6d101 Should use tailscale eventually for remote luks unlocking 2023-11-08 21:31:14 -07:00
4890dc20e0 Add basic nix utilities
All checks were successful
Check Flake / check-flake (push) Successful in 2m21s
2023-10-20 20:13:08 -06:00
8b01a9b240 Use podman instead of docker 2023-10-20 20:12:14 -06:00
8dfba8646c Fix CI builder
All checks were successful
Check Flake / check-flake (push) Successful in 1m5s
2023-10-20 19:52:33 -06:00
63c0f52955 s0: use eth1
Some checks failed
Check Flake / check-flake (push) Failing after 9s
2023-10-16 20:21:00 -06:00
5413a8e7db Remove mounts that fail. These never worked 2023-10-16 20:20:32 -06:00
330c801e43 Fix issue where wg vpn starts slightly too early for internet access 2023-10-16 20:19:34 -06:00
8ba08ce982 Zoidberg move /boot device
Some checks failed
Check Flake / check-flake (push) Failing after 6m57s
2023-10-15 19:23:24 -06:00
2b50aeba93 Zoidberg auto login 2023-10-15 19:22:51 -06:00
c1aef574b1 Try to build only x84_64 for now
Some checks failed
Check Flake / check-flake (push) Failing after 8m22s
2023-10-15 19:09:40 -06:00
52ed25f1b9 Push derivations built during nix flake check to binary cache
Some checks failed
Check Flake / check-flake (push) Failing after 1m17s
2023-10-15 18:00:38 -06:00
0446d18712 Use official nixos module for gitea actions runner 2023-10-15 17:58:03 -06:00
d2bbbb827e Disable router 2023-10-15 17:55:44 -06:00
6fba594625 Target nixpkgs 23.05 2023-10-15 17:55:04 -06:00
fa6e092c06 Update zoidberg keyfile
Some checks failed
Check Flake / check-flake (push) Failing after 6m52s
2023-09-04 17:18:42 -06:00
3a6dae2b82 Enable barrier for use system wide
Some checks failed
Check Flake / check-flake (push) Failing after 7m29s
2023-09-03 21:59:31 -06:00
62bb740634 Enable ROCm 2023-09-03 21:58:52 -06:00
577e0d21bc Xbox wireless controller support 2023-09-03 21:58:08 -06:00
b481a518f5 Samba mount 2023-09-03 21:57:24 -06:00
f93b2c6908 Steam login option 2023-09-03 21:56:37 -06:00
890b24200e Retroarch
Some checks failed
Check Flake / check-flake (push) Failing after 8m51s
2023-08-13 18:03:45 -06:00
d3259457de Use latest kernel so amdgpu doesn't crash 2023-08-12 23:17:26 -06:00
8eb42ee68b Add common user for kodi 2023-08-12 23:16:52 -06:00
9d4c48badb Use Barrier 2023-08-12 23:16:26 -06:00
9cf2b82e92 Update nixpkgs and cleanup
Some checks failed
Check Flake / check-flake (push) Failing after 10m41s
2023-08-12 19:40:22 -06:00
61ca918cca flake.lock: Update
Flake lock file updates:

• Updated input 'agenix':
    'github:ryantm/agenix/2994d002dcff5353ca1ac48ec584c7f6589fe447' (2023-04-21)
  → 'github:ryantm/agenix/d8c973fd228949736dedf61b7f8cc1ece3236792' (2023-07-24)
• Added input 'agenix/home-manager':
    'github:nix-community/home-manager/32d3e39c491e2f91152c84f8ad8b003420eab0a1' (2023-04-22)
• Added input 'agenix/home-manager/nixpkgs':
    follows 'agenix/nixpkgs'
• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/c2ea4e642dc50fd44b537e9860ec95867af30d39' (2023-04-21)
  → 'github:serokell/deploy-rs/724463b5a94daa810abfc64a4f87faef4e00f984' (2023-06-14)
• Updated input 'flake-utils':
    'github:numtide/flake-utils/cfacdce06f30d2b68473a46042957675eebb3401' (2023-04-11)
  → 'github:numtide/flake-utils/919d646de7be200f3bf08cb76ae1f09402b6f9b4' (2023-07-11)
• Updated input 'nix-index-database':
    'github:Mic92/nix-index-database/e3e320b19c192f40a5b98e8776e3870df62dee8a' (2023-04-25)
  → 'github:Mic92/nix-index-database/6c626d54d0414d34c771c0f6f9d771bc8aaaa3c4' (2023-08-06)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/297187b30a19f147ef260abb5abd93b0706af238' (2023-04-30)
  → 'github:NixOS/nixpkgs/a4d0fe7270cc03eeb1aba4e8b343fe47bfd7c4d5' (2023-08-13)
2023-08-12 19:00:16 -06:00
ef61792da4 Add maestral
Some checks failed
Check Flake / check-flake (push) Failing after 30s
2023-08-12 18:27:24 -06:00
3dc97f4960 Enable kde scaling 2023-08-12 18:27:01 -06:00
f4a26a8d15 Enable zfs scrubbing 2023-08-12 18:26:13 -06:00
37782a26d5 Add pavucontrol-qt 2023-08-12 18:25:46 -06:00
1434bd2df1 Share userspace packages
Some checks failed
Check Flake / check-flake (push) Failing after 19s
2023-08-11 20:48:27 -06:00
e49ea3a7c4 Share userspace packages
Some checks failed
Check Flake / check-flake (push) Failing after 8s
2023-08-11 20:45:34 -06:00
9a6cde1e89 Get zoidberg ready
Some checks failed
Check Flake / check-flake (push) Failing after 1m34s
2023-08-11 19:51:42 -06:00
35972b6d68 Xbox controller support
Some checks failed
Check Flake / check-flake (push) Failing after 18s
2023-08-10 20:39:41 -06:00
b8021c1756 Samba mount for zoidberg
Some checks failed
Check Flake / check-flake (push) Failing after 18s
2023-08-10 19:45:11 -06:00
4b21489141 Increase boot timeout for zoidberg
Some checks failed
Check Flake / check-flake (push) Failing after 19s
2023-08-10 19:44:44 -06:00
a256ab7728 Rekey secrets 2023-08-10 19:44:20 -06:00
da7ebe7baa Add Zoidberg
Some checks failed
Check Flake / check-flake (push) Failing after 2m43s
2023-08-10 19:40:01 -06:00
1922bbbcfd Local arduino development 2023-08-10 18:05:45 -06:00
b17be86927 Cleanup 2023-08-10 18:04:46 -06:00
ec73a63e09 Define vscodium extensions
All checks were successful
Check Flake / check-flake (push) Successful in 30m4s
2023-05-10 12:05:46 -06:00
af26a004e5 Forwards 2023-05-10 12:04:57 -06:00
d83782f315 Set up Nix build worker
All checks were successful
Check Flake / check-flake (push) Successful in 19m33s
2023-04-30 12:49:15 -06:00
162b544249 Set binary cache priority 2023-04-30 09:13:49 -06:00
0c58e62ed4 flake.lock: Update
All checks were successful
Check Flake / check-flake (push) Successful in 1m27s
Flake lock file updates:

• Updated input 'nix-index-database':
    'github:Mic92/nix-index-database/68ec961c51f48768f72d2bbdb396ce65a316677e' (2023-04-15)
  → 'github:Mic92/nix-index-database/e3e320b19c192f40a5b98e8776e3870df62dee8a' (2023-04-25)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/8dafae7c03d6aa8c2ae0a0612fbcb47e994e3fb8' (2023-04-22)
  → 'github:NixOS/nixpkgs/297187b30a19f147ef260abb5abd93b0706af238' (2023-04-30)
2023-04-29 20:34:11 -06:00
96de109d62 Basic binary cache
All checks were successful
Check Flake / check-flake (push) Successful in 7m55s
2023-04-29 20:33:10 -06:00
0efcf8f3fc Flake check gitea action
All checks were successful
Check Flake / check-flake (push) Successful in 1m28s
2023-04-29 19:20:48 -06:00
2009180827 Add mail user 2023-04-29 18:24:20 -06:00
306ce8bc3f Move s0 to systemd-boot 2023-04-25 23:41:08 -06:00
b5dd983ba3 Automatically set machine hostname 2023-04-24 20:52:17 -06:00
832894edfc Gitea runner 2023-04-23 10:29:18 -06:00
feb6270952 Update options for newer nixpkgs 2023-04-23 10:28:55 -06:00
b4dd2d4a92 update TODOs 2023-04-23 10:16:54 -06:00
38c2e5aece Fix properties.nix path loading 2023-04-21 23:24:05 -06:00
0ef689b750 flake.lock: Update
Flake lock file updates:

• Updated input 'agenix':
    'github:ryantm/agenix/b7ffcfe77f817d9ee992640ba1f270718d197f28' (2023-01-31)
  → 'github:ryantm/agenix/2994d002dcff5353ca1ac48ec584c7f6589fe447' (2023-04-21)
• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/8c9ea9605eed20528bf60fae35a2b613b901fd77' (2023-01-19)
  → 'github:serokell/deploy-rs/c2ea4e642dc50fd44b537e9860ec95867af30d39' (2023-04-21)
• Updated input 'flake-utils':
    'github:numtide/flake-utils/5aed5285a952e0b949eb3ba02c12fa4fcfef535f' (2022-11-02)
  → 'github:numtide/flake-utils/cfacdce06f30d2b68473a46042957675eebb3401' (2023-04-11)
• Added input 'flake-utils/systems':
    'github:nix-systems/default/da67096a3b9bf56a91d16901293e51ba5b49a27e' (2023-04-09)
• Updated input 'nix-index-database':
    'github:Mic92/nix-index-database/4306fa7c12e098360439faac1a2e6b8e509ec97c' (2023-02-26)
  → 'github:Mic92/nix-index-database/68ec961c51f48768f72d2bbdb396ce65a316677e' (2023-04-15)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/78c4d33c16092e535bc4ba1284ba49e3e138483a' (2023-03-03)
  → 'github:NixOS/nixpkgs/8dafae7c03d6aa8c2ae0a0612fbcb47e994e3fb8' (2023-04-22)
2023-04-21 21:22:00 -06:00
e72e19b7e8 Fix auto upgrade 2023-04-21 18:58:54 -06:00
03603119e5 Fix invalid import issue. 2023-04-21 18:57:06 -06:00
71baa09bd2 Refactor imports and secrets. Add per system properties and role based secret access.
Highlights
- No need to update flake for every machine anymore, just add a properties.nix file.
- Roles are automatically generated from all machine configurations.
- Roles and their secrets automatically are grouped and show up in agenix secrets.nix
- Machines and their service configs may now query the properties of all machines.
- Machine configuration and secrets are now competely isolated into each machine's directory.
- Safety checks to ensure no mixing of luks unlocking secrets and hosts with primary ones.
- SSH pubkeys no longer centrally stored but instead per machine where the private key lies for better cleanup.
2023-04-21 12:58:11 -06:00
a02775a234 Update install steps 2023-04-19 21:17:45 -06:00
5800359214 Update install steps 2023-04-19 21:17:03 -06:00
0bd42f1850 Update install steps 2023-04-19 21:15:58 -06:00
40f0e5d2ac Add Phil 2023-04-19 18:12:42 -06:00
f90b9f85fd try out appvm 2023-04-18 23:15:21 -06:00
5b084fffcc moonlander 2023-04-18 23:15:03 -06:00
4dd6401f8c update TODOs 2023-04-18 23:14:49 -06:00
260bbc1ffd Use doas instead of sudo 2023-04-10 22:03:57 -06:00
c8132a67d0 Use lf as terminal file explorer 2023-04-10 22:03:29 -06:00
3412d5caf9 Use hashed passwordfile just to be safe 2023-04-09 23:00:10 -06:00
1065cc4b59 Enable gitea email notifications 2023-04-09 22:05:23 -06:00
154b37879b Cross off finished TODOs 2023-04-09 22:04:51 -06:00
a34238b3a9 Easily run restic commands on a backup group 2023-04-09 13:06:15 -06:00
42e2ebd294 Allow marking folders as omitted from backup 2023-04-09 12:35:20 -06:00
378cf47683 restic backups 2023-04-08 21:25:55 -06:00
f68a4f4431 nixpkgs-fmt everything 2023-04-04 23:30:28 -06:00
3c683e7b9e NixOS router is now in active use :) 2023-04-04 20:53:38 -06:00
68bd70b525 Basic router working using the wip hostapd module from upstream 2023-04-04 12:57:16 -06:00
2189ab9a1b Improve cifs mounts. Newer protocol version, helpful commands, better network connection resiliency. 2023-03-31 11:43:12 -06:00
acbbb8a37a encrypted samba vault with gocryptfs 2023-03-25 15:49:07 -06:00
d1e6d21d66 iperf server 2023-03-25 15:48:39 -06:00
1a98e039fe Cleanup fio tests 2023-03-25 15:48:24 -06:00
146 changed files with 12655 additions and 1219 deletions

View File

@@ -0,0 +1,28 @@
name: Check Flake
on: [push]
env:
DEBIAN_FRONTEND: noninteractive
PATH: /run/current-system/sw/bin/
jobs:
check-flake:
runs-on: nixos
steps:
- name: Checkout the repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- run: attic -V
- name: Setup Attic Cache
uses: https://git.neet.dev/zuckerberg/attic-action@v0.2.5
with:
endpoint: ${{ secrets.ATTIC_ENDPOINT }}
cache: ${{ secrets.ATTIC_CACHE }}
token: ${{ secrets.ATTIC_TOKEN }}
- name: Check Flake
run: nix flake check --all-systems --print-build-logs --log-format raw --show-trace

27
Makefile Normal file
View File

@@ -0,0 +1,27 @@
# 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

View File

@@ -6,7 +6,6 @@
- `/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.
- `/server` - config that creates new nixos services or extends existing ones to meet my needs
- `/ssh.nix` - all ssh public host and user keys for all `/machines`
- `/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`
- `/secrets` - encrypted shared secrets unlocked through `/machines` ssh host keys

38
TODO.md
View File

@@ -10,24 +10,12 @@
- https://nixos.wiki/wiki/Comparison_of_NixOS_setups
### Housekeeping
- Format everything here using nixfmt
- Cleanup the line between hardware-configuration.nix and configuration.nix in machine config
- CI https://gvolpe.com/blog/nixos-binary-cache-ci/
- remove `options.currentSystem`
- allow `hostname` option for webservices to be null to disable configuring nginx
### NAS
- helios64 extra led lights
- safely turn off NAS on power disconnect
- hardware de/encoding for rk3399 helios64 https://forum.pine64.org/showthread.php?tid=14018
- tor unlock
### bcachefs
- bcachefs health alerts via email
- bcachefs periodic snapshotting
- use mount.bcachefs command for mounting
- bcachefs native encryption
- just need a kernel module? https://github.com/firestack/bcachefs-tools-flake/blob/kf/dev/mvp/nixos/module/bcachefs.nix#L40
### Shell Comands
- tailexitnode = `sudo tailscale up --exit-node=<exit-node-ip> --exit-node-allow-lan-access=true`
@@ -53,7 +41,6 @@
- replace nextcloud with seafile
### Archive
- https://www.backblaze.com/b2/cloud-storage.html
- email
- https://github.com/Disassembler0/dovecot-archive/blob/main/src/dovecot_archive.py
- http://kb.unixservertech.com/software/dovecot/archiveserver
@@ -62,7 +49,32 @@
- https://christine.website/blog/paranoid-nixos-2021-07-18
- https://nixos.wiki/wiki/Impermanence
# Setup CI
- CI
- hydra
- https://docs.cachix.org/continuous-integration-setup/
- Binary Cache
- Maybe use cachix https://gvolpe.com/blog/nixos-binary-cache-ci/
- Self hosted binary cache? https://www.tweag.io/blog/2019-11-21-untrusted-ci/
- https://github.com/edolstra/nix-serve
- https://nixos.wiki/wiki/Binary_Cache
- https://discourse.nixos.org/t/introducing-attic-a-self-hostable-nix-binary-cache-server/24343
- Both
- https://garnix.io/
- https://nixbuild.net
# Secrets
- consider using headscale
- Replace luks over tor for remote unlock with luks over tailscale using ephemeral keys
- Rollover luks FDE passwords
- /secrets on personal computers should only be readable using a trusted ssh key, preferably requiring a yubikey
- Rollover shared yubikey secrets
- offsite backup yubikey, pw db, and ssh key with /secrets access
### Misc
- for automated kernel upgrades on luks systems, need to kexec with initrd that contains luks key
- https://github.com/flowztul/keyexec/blob/master/etc/default/kexec-cryptroot
- https://github.com/pop-os/system76-scheduler
- improve email a little bit https://helloinbox.email
- remap razer keys https://github.com/sezanzeb/input-remapper

View File

@@ -4,11 +4,12 @@
let
cfg = config.system.autoUpgrade;
in {
in
{
config = lib.mkIf cfg.enable {
system.autoUpgrade = {
flake = "git+https://git.neet.dev/zuckerberg/nix-config.git";
flags = [ "--recreate-lock-file" ]; # ignore lock file, just pull the latest
flags = [ "--recreate-lock-file" "--no-write-lock-file" ]; # ignore lock file, just pull the latest
};
};
}

78
common/backups.nix Normal file
View File

@@ -0,0 +1,78 @@
{ config, lib, pkgs, ... }:
let
cfg = config.backup;
hostname = config.networking.hostName;
mkRespository = group: "s3:s3.us-west-004.backblazeb2.com/D22TgIt0-main-backup/${group}";
mkBackup = group: paths: {
repository = mkRespository group;
inherit paths;
initialize = true;
timerConfig = {
OnCalendar = "daily";
RandomizedDelaySec = "1h";
};
extraBackupArgs = [
''--exclude-if-present ".nobackup"''
];
pruneOpts = [
"--keep-daily 7" # one backup for each of the last n days
"--keep-weekly 5" # one backup for each of the last n weeks
"--keep-monthly 12" # one backup for each of the last n months
"--keep-yearly 75" # one backup for each of the last n years
];
environmentFile = "/run/agenix/backblaze-s3-backups";
passwordFile = "/run/agenix/restic-password";
};
# example usage: "sudo restic_samba unlock" (removes lockfile)
mkResticGroupCmd = group: pkgs.writeShellScriptBin "restic_${group}" ''
if [ "$EUID" -ne 0 ]
then echo "Run as root"
exit
fi
. /run/agenix/backblaze-s3-backups
export AWS_SECRET_ACCESS_KEY
export AWS_ACCESS_KEY_ID
export RESTIC_PASSWORD_FILE=/run/agenix/restic-password
export RESTIC_REPOSITORY="${mkRespository group}"
exec ${pkgs.restic}/bin/restic "$@"
'';
in
{
options.backup = {
group = lib.mkOption {
default = null;
type = lib.types.nullOr (lib.types.attrsOf (lib.types.submodule {
options = {
paths = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
Paths to backup
'';
};
};
}));
};
};
config = lib.mkIf (cfg.group != null) {
services.restic.backups = lib.concatMapAttrs
(group: groupCfg: {
${group} = mkBackup group groupCfg.paths;
})
cfg.group;
age.secrets.backblaze-s3-backups.file = ../secrets/backblaze-s3-backups.age;
age.secrets.restic-password.file = ../secrets/restic-password.age;
environment.systemPackages = map mkResticGroupCmd (builtins.attrNames cfg.group);
};
}

17
common/binary-cache.nix Normal file
View File

@@ -0,0 +1,17 @@
{ config, lib, ... }:
{
nix = {
settings = {
substituters = [
"https://cache.nixos.org/"
"https://nix-community.cachix.org"
"http://s0.koi-bebop.ts.net:28338/nixos"
];
trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"nixos:IDhKojUaMz+UIiri1/DQk9EpqDokih8dwxmp41uJnls="
];
};
};
}

View File

@@ -3,24 +3,27 @@
with lib;
let
cfg = config.bios;
in {
in
{
options.bios = {
enable = mkEnableOption "enable bios boot";
device = mkOption {
type = types.str;
};
configurationLimit = mkOption {
default = 20;
type = types.int;
};
};
config = mkIf cfg.enable {
# Use GRUB 2 for BIOS
boot.loader = {
timeout = 2;
grub = {
enable = true;
device = cfg.device;
version = 2;
useOSProber = true;
configurationLimit = 20;
configurationLimit = cfg.configurationLimit;
theme = pkgs.nixos-grub2-theme;
};
};

View File

@@ -3,24 +3,27 @@
with lib;
let
cfg = config.efi;
in {
in
{
options.efi = {
enable = mkEnableOption "enable efi boot";
configurationLimit = mkOption {
default = 20;
type = types.int;
};
};
config = mkIf cfg.enable {
# Use GRUB2 for EFI
boot.loader = {
efi.canTouchEfiVariables = true;
timeout = 2;
grub = {
enable = true;
device = "nodev";
version = 2;
efiSupport = true;
useOSProber = true;
# memtest86.enable = true;
configurationLimit = 20;
configurationLimit = cfg.configurationLimit;
theme = pkgs.nixos-grub2-theme;
};
};

View File

@@ -3,7 +3,8 @@
with lib;
let
cfg = config.firmware;
in {
in
{
options.firmware.x86_64 = {
enable = mkEnableOption "enable x86_64 firmware";
};

View File

@@ -1,8 +1,11 @@
{ config, pkgs, lib, ... }:
# TODO: use tailscale instead of tor https://gist.github.com/antifuchs/e30d58a64988907f282c82231dde2cbc
let
cfg = config.remoteLuksUnlock;
in {
in
{
options.remoteLuksUnlock = {
enable = lib.mkEnableOption "enable luks root remote decrypt over ssh/tor";
enableTorUnlock = lib.mkOption {
@@ -32,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;
@@ -61,18 +59,22 @@ in {
copy_bin_and_libs ${pkgs.haveged}/bin/haveged
'';
boot.initrd.network.postCommands = lib.mkMerge [
(''
(
''
# Add nice prompt for giving LUKS passphrase over ssh
echo 'read -s -p "Unlock Passphrase: " passphrase && echo $passphrase > /crypt-ramfs/passphrase && exit' >> /root/.profile
'')
''
)
(let torRc = (pkgs.writeText "tor.rc" ''
(
let torRc = (pkgs.writeText "tor.rc" ''
DataDirectory /etc/tor
SOCKSPort 127.0.0.1:9050 IsolateDestAddr
SOCKSPort 127.0.0.1:9063
HiddenServiceDir /etc/tor/onion/bootup
HiddenServicePort 22 127.0.0.1:22
''); in lib.mkIf cfg.enableTorUnlock ''
''); in
lib.mkIf cfg.enableTorUnlock ''
echo "tor: preparing onion folder"
# have to do this otherwise tor does not want to start
chmod -R 700 /etc/tor
@@ -87,7 +89,8 @@ in {
echo "tor: starting tor"
tor -f ${torRc} --verify-config
tor -f ${torRc} &
'')
''
)
];
};
}

View File

@@ -1,12 +1,9 @@
{ config, pkgs, ... }:
let
ssh = import ./ssh.nix;
sshUserKeys = ssh.users;
sshHigherTrustKeys = ssh.higherTrustUserKeys;
in
{
imports = [
./backups.nix
./binary-cache.nix
./flakes.nix
./auto-update.nix
./shell.nix
@@ -14,11 +11,14 @@ in
./boot
./server
./pc
./machine-info
./nix-builder.nix
./ssh.nix
];
nix.flakes.enable = true;
system.stateVersion = "21.11";
system.stateVersion = "23.11";
networking.useDHCP = false;
@@ -26,7 +26,13 @@ in
networking.firewall.allowPing = true;
time.timeZone = "America/Denver";
i18n.defaultLocale = "en_US.UTF-8";
i18n = {
defaultLocale = "en_US.UTF-8";
extraLocaleSettings = {
LANGUAGE = "en_US.UTF-8";
LC_ALL = "en_US.UTF-8";
};
};
services.openssh = {
enable = true;
@@ -40,7 +46,8 @@ in
wget
kakoune
htop
git git-lfs
git
git-lfs
dnsutils
tmux
nethogs
@@ -53,6 +60,10 @@ in
helix
lm_sensors
picocom
lf
gnumake
tree
attic
];
nixpkgs.config.allowUnfree = true;
@@ -65,17 +76,25 @@ in
"dialout" # serial
];
shell = pkgs.fish;
openssh.authorizedKeys.keys = sshUserKeys;
openssh.authorizedKeys.keys = config.machines.ssh.userKeys;
hashedPassword = "$6$TuDO46rILr$gkPUuLKZe3psexhs8WFZMpzgEBGksE.c3Tjh1f8sD0KMC4oV89K2pqAABfl.Lpxu2jVdr5bgvR5cWnZRnji/r/";
uid = 1000;
};
users.users.root = {
openssh.authorizedKeys.keys = sshHigherTrustKeys;
openssh.authorizedKeys.keys = config.machines.ssh.deployKeys;
};
nix.settings = {
trusted-users = [ "root" "googlebot" ];
};
# don't use sudo
security.doas.enable = true;
security.sudo.enable = false;
security.doas.extraRules = [
# don't ask for password every time
{ groups = [ "wheel" ]; persist = true; }
];
nix.gc.automatic = true;
security.acme.acceptTerms = true;

View File

@@ -2,14 +2,14 @@
with lib;
let
cfg = config.nix.flakes;
in {
in
{
options.nix.flakes = {
enable = mkEnableOption "use nix flakes";
};
config = mkIf cfg.enable {
nix = {
package = pkgs.nixFlakes;
extraOptions = ''
experimental-features = nix-command flakes
'';

View File

@@ -0,0 +1,200 @@
# Gathers info about each machine to constuct overall configuration
# Ex: Each machine already trusts each others SSH fingerprint already
{ config, lib, pkgs, ... }:
let
machines = config.machines.hosts;
in
{
imports = [
./ssh.nix
./roles.nix
];
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.
'';
};
};
});
};
};
config = {
assertions = (lib.concatLists (lib.mapAttrsToList
(
name: cfg: [
{
assertion = builtins.length cfg.hostNames > 0;
message = ''
Error with config for ${name}
There must be at least one hostname.
'';
}
{
assertion = builtins.length cfg.systemRoles > 0;
message = ''
Error with config for ${name}
There must be at least one system role.
'';
}
{
assertion = cfg.remoteUnlock == null || cfg.remoteUnlock.hostKey != cfg.hostKey;
message = ''
Error with config for ${name}
Unlock hostkey and hostkey cannot be the same because unlock hostkey is in /boot, unencrypted.
'';
}
{
assertion = cfg.remoteUnlock == null || (cfg.remoteUnlock.clearnetHost != null || cfg.remoteUnlock.onionHost != null);
message = ''
Error with config for ${name}
At least one of clearnet host or onion host must be defined.
'';
}
{
assertion = cfg.remoteUnlock == null || cfg.remoteUnlock.clearnetHost == null || builtins.elem cfg.remoteUnlock.clearnetHost cfg.hostNames == false;
message = ''
Error with config for ${name}
Clearnet unlock hostname cannot be in the list of hostnames for security reasons.
'';
}
{
assertion = cfg.remoteUnlock == null || cfg.remoteUnlock.onionHost == null || lib.strings.hasSuffix ".onion" cfg.remoteUnlock.onionHost;
message = ''
Error with config for ${name}
Tor unlock hostname must be an onion address.
'';
}
{
assertion = builtins.elem "personal" cfg.systemRoles || builtins.length cfg.userKeys == 0;
message = ''
Error with config for ${name}
There must be at least one userkey defined for personal machines.
'';
}
{
assertion = builtins.elem "deploy" cfg.systemRoles || builtins.length cfg.deployKeys == 0;
message = ''
Error with config for ${name}
Only deploy machines are allowed to have deploy keys for security reasons.
'';
}
]
)
machines));
# Set per machine properties automatically using each of their `properties.nix` files respectively
machines.hosts =
let
properties = dir: lib.concatMapAttrs
(name: path: {
${name} =
import path
//
{ configurationPath = builtins.dirOf path; };
})
(propertiesFiles dir);
propertiesFiles = dir:
lib.foldl (lib.mergeAttrs) { } (propertiesFiles' dir);
propertiesFiles' = dir:
let
propFiles = lib.filter (p: baseNameOf p == "properties.nix") (lib.filesystem.listFilesRecursive dir);
dirName = path: builtins.baseNameOf (builtins.dirOf path);
in
builtins.map (p: { "${dirName p}" = p; }) propFiles;
in
properties ../../machines;
};
}

View File

@@ -0,0 +1,15 @@
# Allows getting machine-info outside the scope of nixos configuration
{ nixpkgs ? import <nixpkgs> { }
, assertionsModule ? <nixpkgs/nixos/modules/misc/assertions.nix>
}:
{
machines =
(nixpkgs.lib.evalModules {
modules = [
./default.nix
assertionsModule
];
}).config.machines;
}

View File

@@ -0,0 +1,19 @@
{ config, lib, ... }:
# Maps roles to their hosts
{
options.machines.roles = lib.mkOption {
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
};
config = {
machines.roles = lib.zipAttrs
(lib.mapAttrsToList
(host: cfg:
lib.foldl (lib.mergeAttrs) { }
(builtins.map (role: { ${role} = host; })
cfg.systemRoles))
config.machines.hosts);
};
}

View File

@@ -0,0 +1,44 @@
{ config, lib, ... }:
let
machines = config.machines;
sshkeys = keyType: lib.foldl (l: cfg: l ++ cfg.${keyType}) [ ] (builtins.attrValues machines.hosts);
in
{
options.machines.ssh = {
userKeys = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
List of user keys aggregated from all machines.
'';
};
deployKeys = lib.mkOption {
default = [ ];
type = lib.types.listOf lib.types.str;
description = ''
List of deploy keys aggregated from all machines.
'';
};
hostKeysByRole = lib.mkOption {
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
description = ''
Machine host keys divided into their roles.
'';
};
};
config = {
machines.ssh.userKeys = sshkeys "userKeys";
machines.ssh.deployKeys = sshkeys "deployKeys";
machines.ssh.hostKeysByRole = lib.mapAttrs
(role: hosts:
builtins.map
(host: machines.hosts.${host}.hostKey)
hosts)
machines.roles;
};
}

View File

@@ -7,7 +7,6 @@ let
in
{
imports = [
./hosts.nix
./pia-openvpn.nix
./pia-wireguard.nix
./ping.nix

View File

@@ -1,62 +0,0 @@
{ config, lib, ... }:
with builtins;
let
# TODO: remove when all systems are updated to new enough nixpkgs
concatMapAttrs =
f: with lib; flip pipe [ (mapAttrs f) attrValues (foldl' mergeAttrs { }) ];
system = (import ../ssh.nix).system;
# hostnames that resolve on clearnet for LUKS unlocking
unlock-clearnet-hosts = {
ponyo = "unlock.ponyo.neet.dev";
s0 = "s0";
};
# hostnames that resolve on tor for LUKS unlocking
unlock-onion-hosts = {
liza = "5synsrjgvfzywruomjsfvfwhhlgxqhyofkzeqt2eisyijvjvebnu2xyd.onion";
router = "jxx2exuihlls2t6ncs7rvrjh2dssubjmjtclwr2ysvxtr4t7jv55xmqd.onion";
ponyo = "cfamr6artx75qvt7ho3rrbsc7mkucmv5aawebwflsfuorusayacffryd.onion";
s0 = "r3zvf7f2ppaeithzswigma46pajt3hqytmkg3rshgknbl3jbni455fqd.onion";
};
in {
programs.ssh.knownHosts = {
ponyo = {
hostNames = [ "ponyo" "ponyo.neet.dev" "git.neet.dev" ];
publicKey = system.ponyo;
};
ponyo-unlock = {
hostNames = [ unlock-clearnet-hosts.ponyo unlock-onion-hosts.ponyo ];
publicKey = system.ponyo-unlock;
};
router = {
hostNames = [ "router" "192.168.1.228" ];
publicKey = system.router;
};
router-unlock = {
hostNames = [ unlock-onion-hosts.router ];
publicKey = system.router-unlock;
};
ray = {
hostNames = [ "ray" ];
publicKey = system.ray;
};
s0 = {
hostNames = [ "s0" ];
publicKey = system.s0;
};
s0-unlock = {
hostNames = [ unlock-onion-hosts.s0 ];
publicKey = system.s0-unlock;
};
};
# prebuilt cmds for easy ssh LUKS unlock
environment.shellAliases =
concatMapAttrs (host: addr: {"unlock-over-tor_${host}" = "torsocks ssh root@${addr}";}) unlock-onion-hosts
//
concatMapAttrs (host: addr: {"unlock_${host}" = "ssh root@${addr}";}) unlock-clearnet-hosts;
}

View File

@@ -108,6 +108,6 @@ in
};
};
};
age.secrets."pia-login.conf".file = ../../secrets/pia-login.conf;
age.secrets."pia-login.conf".file = ../../secrets/pia-login.age;
};
}

View File

@@ -11,6 +11,7 @@
# TODO implement this module such that the wireguard VPN doesn't have to live in a container
# TODO don't add forward rules if the PIA port is the same as cfg.forwardedPort
# TODO verify signatures of PIA responses
# TODO `RuntimeMaxSec = "30d";` for pia-vpn-wireguard-init isn't allowed per the systemd logs. Find alternative.
with builtins;
with lib;
@@ -72,7 +73,8 @@ let
portForwarding = cfg.forwardPortForTransmission || cfg.forwardedPort != null;
containerServiceName = "container@${config.vpn-container.containerName}.service";
in {
in
{
options.pia.wireguard = {
enable = mkEnableOption "Enable private internet access";
badPortForwardPorts = mkOption {
@@ -142,14 +144,14 @@ in {
systemd.services.pia-vpn-wireguard-init = {
description = "Creates PIA VPN Wireguard Interface";
requires = [ "network-online.target" ];
wants = [ "network-online.target" ];
after = [ "network.target" "network-online.target" ];
before = [ containerServiceName ];
requiredBy = [ containerServiceName ];
partOf = [ containerServiceName ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ wireguard-tools jq curl iproute ];
path = with pkgs; [ wireguard-tools jq curl iproute iputils ];
serviceConfig = {
Type = "oneshot";
@@ -161,6 +163,11 @@ in {
};
script = ''
echo Waiting for internet...
while ! ping -c 1 -W 1 1.1.1.1; do
sleep 1
done
# Prepare to connect by generating wg secrets and auth'ing with PIA since the container
# cannot do without internet to start with. NAT'ing the host's internet would address this
# issue but is not ideal because then leaking network outside of the VPN is more likely.
@@ -213,7 +220,7 @@ in {
vpn-container.config.systemd.services.pia-vpn-wireguard = {
description = "Initializes the PIA VPN WireGuard Tunnel";
requires = [ "network-online.target" ];
wants = [ "network-online.target" ];
after = [ "network.target" "network-online.target" ];
wantedBy = [ "multi-user.target" ];
@@ -351,6 +358,6 @@ in {
};
};
age.secrets."pia-login.conf".file = ../../secrets/pia-login.conf;
age.secrets."pia-login.conf".file = ../../secrets/pia-login.age;
};
}

View File

@@ -33,7 +33,8 @@ let
serviceList = map serviceTemplate cfg.hosts;
services = combineAttrs serviceList;
in {
in
{
options.keepalive-ping = {
enable = mkEnableOption "Enable keep alive ping task";
hosts = mkOption {

View File

@@ -11,7 +11,7 @@ in
config.services.tailscale.enable = mkDefault (!config.boot.isContainer);
# MagicDNS
config.networking.nameservers = mkIf cfg.enable [ "1.1.1.1" "8.8.8.8" "100.100.100.100" ];
config.networking.nameservers = mkIf cfg.enable [ "1.1.1.1" "8.8.8.8" ];
config.networking.search = mkIf cfg.enable [ "koi-bebop.ts.net" ];
# exit node

View File

@@ -72,9 +72,6 @@ in
config = {
imports = allModules ++ [ cfg.config ];
# speeds up evaluation
nixpkgs.pkgs = pkgs;
# networking.firewall.enable = mkForce false;
networking.firewall.trustedInterfaces = [
# completely trust internal interface to host

60
common/nix-builder.nix Normal file
View File

@@ -0,0 +1,60 @@
{ 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;
# builders don't include themselves as a remote builder
otherBuilders = lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) builders;
in
lib.mkMerge [
# configure builder
(lib.mkIf thisMachineIsABuilder {
users.users.${builderUserName} = {
description = "Distributed Nix Build User";
group = builderUserName;
isSystemUser = true;
createHome = true;
home = "/var/lib/nix-builder";
useDefaultShell = true;
openssh.authorizedKeys.keys = builtins.map
(builderCfg: builderCfg.hostKey)
(builtins.attrValues config.machines.hosts);
};
users.groups.${builderUserName} = { };
nix.settings.trusted-users = [
builderUserName
];
})
# use each builder
{
nix.distributedBuilds = true;
nix.buildMachines = builtins.map
(builderCfg: {
hostName = builtins.elemAt builderCfg.hostNames 0;
system = builderCfg.arch;
protocol = "ssh-ng";
sshUser = builderUserName;
sshKey = "/etc/ssh/ssh_host_ed25519_key";
maxJobs = 3;
speedFactor = 10;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
})
(builtins.attrValues otherBuilders);
# It is very likely that the builder's internet is faster or just as fast
nix.extraOptions = ''
builders-use-substitutes = true
'';
}
]

View File

@@ -2,7 +2,8 @@
let
cfg = config.de;
in {
in
{
config = lib.mkIf cfg.enable {
# enable pulseaudio support for packages
nixpkgs.config.pulseaudio = true;
@@ -16,45 +17,6 @@ in {
alsa.support32Bit = true;
pulse.enable = true;
jack.enable = true;
# use the example session manager (no others are packaged yet so this is enabled by default,
# no need to redefine it in your config for now)
#media-session.enable = true;
config.pipewire = {
"context.objects" = [
{
# A default dummy driver. This handles nodes marked with the "node.always-driver"
# properyty when no other driver is currently active. JACK clients need this.
factory = "spa-node-factory";
args = {
"factory.name" = "support.node.driver";
"node.name" = "Dummy-Driver";
"priority.driver" = 8000;
};
}
{
factory = "adapter";
args = {
"factory.name" = "support.null-audio-sink";
"node.name" = "Microphone-Proxy";
"node.description" = "Microphone";
"media.class" = "Audio/Source/Virtual";
"audio.position" = "MONO";
};
}
{
factory = "adapter";
args = {
"factory.name" = "support.null-audio-sink";
"node.name" = "Main-Output-Proxy";
"node.description" = "Main Output";
"media.class" = "Audio/Sink";
"audio.position" = "FL,FR";
};
}
];
};
};
users.users.googlebot.extraGroups = [ "audio" ];

View File

@@ -17,39 +17,8 @@ let
"PREFIX=$(out)"
];
};
nvidia-vaapi-driver = pkgs.stdenv.mkDerivation rec {
pname = "nvidia-vaapi-driver";
version = "0.0.5";
src = pkgs.fetchFromGitHub {
owner = "elFarto";
repo = pname;
rev = "v${version}";
sha256 = "2bycqKolVoaHK64XYcReteuaON9TjzrFhaG5kty28YY=";
};
patches = [
./use-meson-v57.patch
];
nativeBuildInputs = with pkgs; [
meson
cmake
ninja
pkg-config
];
buildInputs = with pkgs; [
nv-codec-headers-11-1-5-1
libva
gst_all_1.gstreamer
gst_all_1.gst-plugins-bad
libglvnd
];
};
in {
in
{
config = lib.mkIf cfg.enable {
# chromium with specific extensions + settings
programs.chromium = {

View File

@@ -2,22 +2,24 @@
let
cfg = config.de;
in {
in
{
imports = [
./kde.nix
./xfce.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 = {
@@ -36,22 +38,24 @@ in {
mumble
tigervnc
bluez-tools
vscodium
element-desktop
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
# For Nix IDE
nixpkgs-fmt
];
# Networking
@@ -65,12 +69,25 @@ in {
];
# Printer discovery
services.avahi.enable = true;
services.avahi.nssmdns = true;
services.avahi.nssmdns4 = true;
programs.file-roller.enable = true;
# Security
services.gnome.gnome-keyring.enable = true;
security.pam.services.googlebot.enableGnomeKeyring = true;
# Android dev
programs.adb.enable = 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;
};
}

View File

@@ -2,7 +2,8 @@
let
cfg = config.de;
in {
in
{
config = lib.mkIf cfg.enable {
users.users.googlebot.packages = [
pkgs.discord

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

@@ -2,17 +2,14 @@
let
cfg = config.de;
in {
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

View File

@@ -1,19 +1,23 @@
# mounts the samba share on s0 over tailscale
{ config, lib, ... }:
{ config, lib, pkgs, ... }:
let
cfg = config.services.mount-samba;
# prevents hanging on network split
network_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s,nostrictsync,cache=loose,handlecache,handletimeout=30000,rwpidforward,mapposix,soft,resilienthandles,echo_interval=10,noblocksend";
# prevents hanging on network split and other similar niceties to ensure a stable connection
network_opts = "nostrictsync,cache=strict,handlecache,handletimeout=30000,rwpidforward,mapposix,soft,resilienthandles,echo_interval=10,noblocksend,fsc";
systemd_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
user_opts = "uid=${toString config.users.users.googlebot.uid},file_mode=0660,dir_mode=0770,user";
auth_opts = "credentials=/run/agenix/smb-secrets";
version_opts = "vers=2.1";
auth_opts = "sec=ntlmv2i,credentials=/run/agenix/smb-secrets";
version_opts = "vers=3.1.1";
opts = "${network_opts},${user_opts},${version_opts},${auth_opts}";
in {
public_user_opts = "gid=${toString config.users.groups.users.gid}";
opts = "${systemd_opts},${network_opts},${user_opts},${version_opts},${auth_opts}";
in
{
options.services.mount-samba = {
enable = lib.mkEnableOption "enable mounting samba shares";
};
@@ -22,7 +26,7 @@ in {
fileSystems."/mnt/public" = {
device = "//s0.koi-bebop.ts.net/public";
fsType = "cifs";
options = [ opts ];
options = [ "${opts},${public_user_opts}" ];
};
fileSystems."/mnt/private" = {
@@ -32,5 +36,15 @@ in {
};
age.secrets.smb-secrets.file = ../../secrets/smb-secrets.age;
environment.shellAliases = {
# remount storage
remount_public = "sudo systemctl restart mnt-public.mount";
remount_private = "sudo systemctl restart mnt-private.mount";
# Encrypted Vault
vault_unlock = "${pkgs.gocryptfs}/bin/gocryptfs /mnt/private/.vault/ /mnt/vault/";
vault_lock = "umount /mnt/vault/";
};
};
}

View File

@@ -2,7 +2,8 @@
let
cfg = config.de;
in {
in
{
config = lib.mkIf cfg.enable {
nixpkgs.overlays = [
(self: super: {

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

@@ -2,7 +2,8 @@
let
cfg = config.de;
in {
in
{
config = lib.mkIf cfg.enable {
programs.steam.enable = true;
hardware.steam-hardware.enable = true; # steam controller

View File

@@ -2,7 +2,8 @@
let
cfg = config.de;
in {
in
{
config = lib.mkIf cfg.enable {
nixpkgs.overlays = [
(self: super: {

View File

@@ -2,13 +2,14 @@
let
cfg = config.de.touchpad;
in {
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

@@ -4,8 +4,20 @@ let
cfg = config.de;
extensions = with pkgs.vscode-extensions; [
# bbenoist.Nix # nix syntax support
# arrterian.nix-env-selector # nix dev envs
bbenoist.nix # nix syntax support
arrterian.nix-env-selector # nix dev envs
dart-code.dart-code
dart-code.flutter
golang.go
jnoortheen.nix-ide
ms-vscode.cpptools
] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
name = "platformio-ide";
publisher = "platformio";
version = "3.1.1";
sha256 = "g9yTG3DjVUS2w9eHGAai5LoIfEGus+FPhqDnCi4e90Q=";
}
];
vscodium-with-extensions = pkgs.vscode-with-extensions.override {

View File

@@ -2,7 +2,8 @@
let
cfg = config.de;
in {
in
{
config = lib.mkIf cfg.enable {
services.xserver = {
enable = true;

View File

@@ -2,7 +2,8 @@
let
cfg = config.de;
in {
in
{
config = lib.mkIf cfg.enable {
# yubikey
services.pcscd.enable = true;

View File

@@ -0,0 +1,87 @@
# Starting point:
# https://github.com/aldoborrero/mynixpkgs/commit/c501c1e32dba8f4462dcecb57eee4b9e52038e27
{ config, pkgs, lib, ... }:
let
cfg = config.services.actual-server;
stateDir = "/var/lib/${cfg.stateDirName}";
in
{
options.services.actual-server = {
enable = lib.mkEnableOption "Actual Server";
hostname = lib.mkOption {
type = lib.types.str;
default = "localhost";
description = "Hostname for the Actual Server.";
};
port = lib.mkOption {
type = lib.types.int;
default = 25448;
description = "Port on which the Actual Server should listen.";
};
stateDirName = lib.mkOption {
type = lib.types.str;
default = "actual-server";
description = "Name of the directory under /var/lib holding the server's data.";
};
upload = {
fileSizeSyncLimitMB = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
description = "File size limit in MB for synchronized files.";
};
syncEncryptedFileSizeLimitMB = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
description = "File size limit in MB for synchronized encrypted files.";
};
fileSizeLimitMB = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
description = "File size limit in MB for file uploads.";
};
};
};
config = lib.mkIf cfg.enable {
systemd.services.actual-server = {
description = "Actual Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.actual-server}/bin/actual-server";
Restart = "always";
StateDirectory = cfg.stateDirName;
WorkingDirectory = stateDir;
DynamicUser = true;
UMask = "0007";
};
environment = {
NODE_ENV = "production";
ACTUAL_PORT = toString cfg.port;
# Actual is actually very bad at configuring it's own paths despite that information being readily available
ACTUAL_USER_FILES = "${stateDir}/user-files";
ACTUAL_SERVER_FILES = "${stateDir}/server-files";
ACTUAL_DATA_DIR = stateDir;
ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB = toString (cfg.upload.fileSizeSyncLimitMB or "");
ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SIZE_LIMIT_MB = toString (cfg.upload.syncEncryptedFileSizeLimitMB or "");
ACTUAL_UPLOAD_FILE_SIZE_LIMIT_MB = toString (cfg.upload.fileSizeLimitMB or "");
};
};
services.nginx.virtualHosts.${cfg.hostname} = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://localhost:${toString cfg.port}";
};
};
}

40
common/server/atticd.nix Normal file
View File

@@ -0,0 +1,40 @@
{ config, lib, ... }:
let
cfg = config.services.atticd;
in
{
config = lib.mkIf cfg.enable {
services.atticd = {
credentialsFile = "/run/agenix/atticd-credentials";
settings = {
listen = "[::]:28338";
# Speed things up
require-proof-of-possession = false;
chunking = {
# Disable chunking for performance (I have plenty of space)
nar-size-threshold = 0;
# Chunking is disabled due to poor performance so these values don't matter but are required anyway.
# One day, when I move away from ZFS maybe this will perform well enough.
# nar-size-threshold = 64 * 1024; # 64 KiB
min-size = 16 * 1024; # 16 KiB
avg-size = 64 * 1024; # 64 KiB
max-size = 256 * 1024; # 256 KiB
};
# Disable compression for performance (I have plenty of space)
compression.type = "none";
garbage-collection = {
default-retention-period = "6 months";
};
};
};
age.secrets.atticd-credentials.file = ../../secrets/atticd-credentials.age;
};
}

View File

@@ -3,9 +3,9 @@
with lib;
let
cfg = config.ceph;
in {
options.ceph = {
};
in
{
options.ceph = { };
config = mkIf cfg.enable {
# ceph.enable = true;

53
common/server/dashy.nix Normal file
View File

@@ -0,0 +1,53 @@
{ 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

@@ -18,5 +18,10 @@
./nextcloud.nix
./iodine.nix
./searx.nix
./gitea-actions-runner.nix
./dashy.nix
./librechat.nix
./actualbudget.nix
./atticd.nix
];
}

View File

@@ -0,0 +1,137 @@
{ config, pkgs, lib, allModules, ... }:
# Gitea Actions Runner. Starts 'host' runner that runs directly on the host inside of a nixos container
# This is useful for providing a real Nix/OS builder to gitea.
# Warning, NixOS containers are not secure. For example, the container shares the /nix/store
# Therefore, this should not be used to run untrusted code.
# To enable, assign a machine the 'gitea-actions-runner' system role
# 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;
containerName = "gitea-runner";
in
{
config = lib.mkIf (thisMachineIsARunner && !config.boot.isContainer) {
# containers.${containerName} = {
# ephemeral = true;
# autoStart = true;
# # for podman
# enableTun = true;
# # privateNetwork = true;
# # hostAddress = "172.16.101.1";
# # localAddress = "172.16.101.2";
# bindMounts =
# {
# "/run/agenix/gitea-actions-runner-token" = {
# hostPath = "/run/agenix/gitea-actions-runner-token";
# isReadOnly = true;
# };
# "/var/lib/gitea-runner" = {
# hostPath = "/var/lib/gitea-runner";
# isReadOnly = false;
# };
# };
# extraFlags = [
# # Allow podman
# ''--system-call-filter=thisystemcalldoesnotexistforsure''
# ];
# additionalCapabilities = [
# "CAP_SYS_ADMIN"
# ];
# config = {
# imports = allModules;
# # speeds up evaluation
# nixpkgs.pkgs = pkgs;
# networking.hostName = lib.mkForce containerName;
# # don't use remote builders
# nix.distributedBuilds = lib.mkForce false;
# environment.systemPackages = with pkgs; [
# git
# # Gitea Actions rely heavily on node. Include it because it would be installed anyway.
# nodejs
# ];
# services.gitea-actions-runner.instances.inst = {
# enable = true;
# name = config.networking.hostName;
# url = "https://git.neet.dev/";
# tokenFile = "/run/agenix/gitea-actions-runner-token";
# labels = [
# "ubuntu-latest:docker://node:18-bullseye"
# "nixos:host"
# ];
# };
# # To allow building on the host, must override the the service's config so it doesn't use a dynamic user
# systemd.services.gitea-runner-inst.serviceConfig.DynamicUser = lib.mkForce false;
# users.users.gitea-runner = {
# home = "/var/lib/gitea-runner";
# group = "gitea-runner";
# isSystemUser = true;
# createHome = true;
# };
# users.groups.gitea-runner = { };
# virtualisation.podman.enable = true;
# boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
# };
# };
# networking.nat.enable = true;
# networking.nat.internalInterfaces = [
# "ve-${containerName}"
# ];
# networking.ip_forward = true;
# don't use remote builders
nix.distributedBuilds = lib.mkForce false;
services.gitea-actions-runner.instances.inst = {
enable = true;
name = config.networking.hostName;
url = "https://git.neet.dev/";
tokenFile = "/run/agenix/gitea-actions-runner-token";
labels = [
"ubuntu-latest:docker://node:18-bullseye"
"nixos:host"
];
};
environment.systemPackages = with pkgs; [
git
# Gitea Actions rely heavily on node. Include it because it would be installed anyway.
nodejs
attic
];
# To allow building on the host, must override the the service's config so it doesn't use a dynamic user
systemd.services.gitea-runner-inst.serviceConfig.DynamicUser = lib.mkForce false;
users.users.gitea-runner = {
home = "/var/lib/gitea-runner";
group = "gitea-runner";
isSystemUser = true;
createHome = true;
};
users.groups.gitea-runner = { };
virtualisation.podman.enable = true;
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
age.secrets.gitea-actions-runner-token.file = ../../secrets/gitea-actions-runner-token.age;
};
}

View File

@@ -1,8 +1,9 @@
{ lib, config, ... }:
{ lib, pkgs, config, ... }:
let
cfg = config.services.gitea;
in {
in
{
options.services.gitea = {
hostname = lib.mkOption {
type = lib.types.str;
@@ -11,12 +12,14 @@ in {
};
config = lib.mkIf cfg.enable {
services.gitea = {
domain = cfg.hostname;
rootUrl = "https://${cfg.hostname}/";
appName = cfg.hostname;
# lfs.enable = true;
dump.enable = true;
lfs.enable = true;
# dump.enable = true;
settings = {
server = {
ROOT_URL = "https://${cfg.hostname}/";
DOMAIN = cfg.hostname;
};
other = {
SHOW_FOOTER_VERSION = false;
};
@@ -28,15 +31,44 @@ in {
};
session = {
COOKIE_SECURE = true;
PROVIDER = "db";
SESSION_LIFE_TIME = 259200; # 3 days
GC_INTERVAL_TIME = 259200; # 3 days
};
mailer = {
ENABLED = true;
MAILER_TYPE = "smtp";
SMTP_ADDR = "mail.neet.dev";
SMTP_PORT = "465";
IS_TLS_ENABLED = true;
USER = "robot@runyan.org";
FROM = "no-reply@neet.dev";
};
actions = {
ENABLED = true;
};
indexer = {
REPO_INDEXER_ENABLED = true;
};
};
mailerPasswordFile = "/run/agenix/robots-email-pw";
};
age.secrets.robots-email-pw = {
file = ../../secrets/robots-email-pw.age;
owner = config.services.gitea.user;
};
# backups
backup.group."gitea".paths = [
config.services.gitea.stateDir
];
services.nginx.enable = true;
services.nginx.virtualHosts.${cfg.hostname} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${toString cfg.httpPort}";
proxyPass = "http://localhost:${toString cfg.settings.server.HTTP_PORT}";
};
};
};

View File

@@ -7,7 +7,8 @@
let
cfg = config.services.icecast;
in {
in
{
options.services.icecast = {
mount = lib.mkOption {
type = lib.types.str;

View File

@@ -2,7 +2,8 @@
let
cfg = config.services.iodine.server;
in {
in
{
config = lib.mkIf cfg.enable {
# iodine DNS-based vpn
services.iodine.server = {

View File

@@ -0,0 +1,62 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.librechat;
in
{
options.services.librechat = {
enable = mkEnableOption "librechat";
port = mkOption {
type = types.int;
default = 3080;
};
host = lib.mkOption {
type = lib.types.str;
example = "example.com";
};
};
config = mkIf cfg.enable {
virtualisation.oci-containers.containers = {
librechat = {
image = "ghcr.io/danny-avila/librechat:v0.6.6";
environment = {
HOST = "0.0.0.0";
MONGO_URI = "mongodb://host.containers.internal:27017/LibreChat";
ENDPOINTS = "openAI,google,bingAI,gptPlugins";
};
environmentFiles = [
"/run/agenix/librechat-env-file"
];
ports = [
"${toString cfg.port}:3080"
];
};
};
age.secrets.librechat-env-file.file = ../../secrets/librechat-env-file.age;
services.mongodb.enable = true;
services.mongodb.bind_ip = "0.0.0.0";
# easier podman maintenance
virtualisation.oci-containers.backend = "podman";
virtualisation.podman.dockerSocket.enable = true;
virtualisation.podman.dockerCompat = true;
# For mongodb access
networking.firewall.trustedInterfaces = [
"podman0" # for librechat
];
services.nginx.virtualHosts.${cfg.host} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${toString cfg.port}";
proxyWebsockets = true;
};
};
};
}

View File

@@ -15,7 +15,8 @@ let
"bsd.ninja"
"bsd.rocks"
];
in {
in
{
config = lib.mkIf cfg.enable {
# kresd doesn't work with tailscale MagicDNS
mailserver.localDnsResolver = false;
@@ -32,20 +33,41 @@ in {
inherit domains;
loginAccounts = {
"jeremy@runyan.org" = {
hashedPasswordFile = "/run/agenix/email-pw";
hashedPasswordFile = "/run/agenix/hashed-email-pw";
# catchall for all domains
aliases = map (domain: "@${domain}") domains;
};
"cris@runyan.org" = {
hashedPasswordFile = "/run/agenix/cris-hashed-email-pw";
aliases = [ "chris@runyan.org" ];
};
"robot@runyan.org" = {
aliases = [
"no-reply@neet.dev"
"robot@neet.dev"
];
sendOnly = true;
hashedPasswordFile = "/run/agenix/hashed-robots-email-pw";
};
};
rejectRecipients = [
"george@runyan.org"
"joslyn@runyan.org"
"damon@runyan.org"
"jonas@runyan.org"
"simon@neet.dev"
];
forwards = {
"amazon@runyan.org" = [
"jeremy@runyan.org"
"cris@runyan.org"
];
certificateScheme = 3; # use let's encrypt for certs
};
age.secrets.email-pw.file = ../../secrets/email-pw.age;
certificateScheme = "acme-nginx"; # use let's encrypt for certs
};
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;
# sendmail to use xxx@domain instead of xxx@mail.domain
services.postfix.origin = "$mydomain";
@@ -60,9 +82,11 @@ in {
sender_dependent_relayhost_maps = "hash:/var/lib/postfix/conf/sender_relay";
smtp_sender_dependent_authentication = "yes";
};
services.postfix.mapFiles.sender_relay = let
services.postfix.mapFiles.sender_relay =
let
relayHost = "[smtp.mailgun.org]:587";
in pkgs.writeText "sender_relay"
in
pkgs.writeText "sender_relay"
(concatStringsSep "\n" (map (domain: "@${domain} ${relayHost}") domains));
services.postfix.mapFiles.sasl_relay_passwd = "/run/agenix/sasl_relay_passwd";
age.secrets.sasl_relay_passwd.file = ../../secrets/sasl_relay_passwd.age;
@@ -79,5 +103,10 @@ in {
$config['smtp_pass'] = "%p";
'';
};
# backups
backup.group."email".paths = [
config.mailserver.mailDirectory
];
};
}

View File

@@ -3,7 +3,8 @@
let
cfg = config.services.matrix;
certs = config.security.acme.certs;
in {
in
{
options.services.matrix = {
enable = lib.mkEnableOption "enable matrix";
element-web = {
@@ -137,7 +138,8 @@ in {
];
locations."/".proxyPass = "http://localhost:${toString cfg.port}";
};
virtualHosts.${cfg.turn.host} = { # get TLS cert for TURN server
virtualHosts.${cfg.turn.host} = {
# get TLS cert for TURN server
enableACME = true;
forceSSL = true;
};

View File

@@ -3,7 +3,8 @@
let
cfg = config.services.murmur;
certs = config.security.acme.certs;
in {
in
{
options.services.murmur.domain = lib.mkOption {
type = lib.types.str;
};

View File

@@ -3,22 +3,28 @@
let
cfg = config.services.nextcloud;
in {
in
{
config = lib.mkIf cfg.enable {
services.nextcloud = {
https = true;
package = pkgs.nextcloud25;
package = pkgs.nextcloud29;
hostName = "neet.cloud";
config.dbtype = "sqlite";
config.adminuser = "jeremy";
config.adminpassFile = "/run/agenix/nextcloud-pw";
autoUpdateApps.enable = true;
enableBrokenCiphersForSSE = false;
};
age.secrets.nextcloud-pw = {
file = ../../secrets/nextcloud-pw.age;
owner = "nextcloud";
};
# backups
backup.group."nextcloud".paths = [
config.services.nextcloud.home
];
services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
enableACME = true;
forceSSL = true;

View File

@@ -5,7 +5,8 @@ let
nginxWithRTMP = pkgs.nginx.override {
modules = [ pkgs.nginxModules.rtmp ];
};
in {
in
{
options.services.nginx.stream = {
enable = lib.mkEnableOption "enable nginx rtmp/hls/dash video streaming";
port = lib.mkOption {

View File

@@ -2,7 +2,8 @@
let
cfg = config.services.nginx;
in {
in
{
config = lib.mkIf cfg.enable {
services.nginx = {
recommendedGzipSettings = true;

View File

@@ -4,7 +4,8 @@ with lib;
let
cfg = config.services.owncast;
in {
in
{
options.services.owncast = {
hostname = lib.mkOption {
type = types.str;

View File

@@ -14,7 +14,8 @@ let
cp -ar $src $out
'';
};
in {
in
{
options.services.privatebin = {
enable = lib.mkEnableOption "enable privatebin";
host = lib.mkOption {

View File

@@ -3,7 +3,8 @@
let
cfg = config.services.radio;
radioPackage = config.inputs.radio.packages.${config.currentSystem}.radio;
in {
in
{
options.services.radio = {
enable = lib.mkEnableOption "enable radio";
user = lib.mkOption {

View File

@@ -25,9 +25,7 @@
printing = cups
printcap name = cups
# horrible files
veto files = /._*/.DS_Store/ /._*/._.DS_Store/
delete veto files = yes
hide files = /.nobackup/.DS_Store/._.DS_Store/
'';
shares = {
@@ -77,6 +75,13 @@
};
};
# backups
backup.group."samba".paths = [
config.services.samba.shares.googlebot.path
config.services.samba.shares.cris.path
config.services.samba.shares.public.path
];
# Windows discovery of samba server
services.samba-wsdd = {
enable = true;
@@ -92,7 +97,7 @@
# Printer discovery
# (is this needed?)
services.avahi.enable = true;
services.avahi.nssmdns = true;
services.avahi.nssmdns4 = true;
# printer sharing
systemd.tmpfiles.rules = [

View File

@@ -2,7 +2,8 @@
let
cfg = config.services.searx;
in {
in
{
config = lib.mkIf cfg.enable {
services.searx = {
environmentFile = "/run/agenix/searx";

View File

@@ -2,7 +2,8 @@
let
cfg = config.services.thelounge;
in {
in
{
options.services.thelounge = {
fileUploadBaseUrl = lib.mkOption {
type = lib.types.str;
@@ -42,6 +43,10 @@ in {
};
};
backup.group."thelounge".paths = [
"/var/lib/thelounge/"
];
# the lounge client
services.nginx.virtualHosts.${cfg.host} = {
enableACME = true;

View File

@@ -79,8 +79,11 @@ in
"${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}:${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}/udp"
];
cmd = [
"lightspeed-webrtc" "--addr=0.0.0.0" "--ip=${domain}"
"--ports=${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}" "run"
"lightspeed-webrtc"
"--addr=0.0.0.0"
"--ip=${domain}"
"--ports=${toStr webrtc-peer-lower-port}-${toStr webrtc-peer-upper-port}"
"run"
];
# imageFile = pkgs.dockerTools.pullImage {
# imageName = "projectlightspeed/webrtc";

View File

@@ -2,7 +2,8 @@
let
cfg = config.services.zerobin;
in {
in
{
options.services.zerobin = {
host = lib.mkOption {
type = lib.types.str;

View File

@@ -21,6 +21,8 @@
shellInit = ''
# disable annoying fish shell greeting
set fish_greeting
alias sudo="doas"
'';
};
@@ -28,10 +30,12 @@
myip = "dig +short myip.opendns.com @resolver1.opendns.com";
# https://linuxreviews.org/HOWTO_Test_Disk_I/O_Performance
io_seq_read = "nix run nixpkgs#fio -- --name TEST --eta-newline=5s --filename=temp.file --rw=read --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_seq_write = "nix run nixpkgs#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 = "nix run nixpkgs#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 = "nix run nixpkgs#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";
io_seq_read = "${pkgs.fio}/bin/fio --name TEST --eta-newline=5s --filename=temp.file --rw=read --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_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 = [

View File

@@ -1,40 +1,38 @@
rec {
users = [
{ config, lib, pkgs, ... }:
{
programs.ssh.knownHosts = lib.filterAttrs (n: v: v != null) (lib.concatMapAttrs
(host: cfg: {
${host} = {
hostNames = cfg.hostNames;
publicKey = cfg.hostKey;
};
"${host}-remote-unlock" =
if cfg.remoteUnlock != null then {
hostNames = builtins.filter (h: h != null) [ cfg.remoteUnlock.clearnetHost cfg.remoteUnlock.onionHost ];
publicKey = cfg.remoteUnlock.hostKey;
} else null;
})
config.machines.hosts);
# prebuilt cmds for easy ssh LUKS unlock
environment.shellAliases =
let
unlockHosts = unlockType: lib.concatMapAttrs
(host: cfg:
if cfg.remoteUnlock != null && cfg.remoteUnlock.${unlockType} != null then {
${host} = cfg.remoteUnlock.${unlockType};
} else { })
config.machines.hosts;
in
lib.concatMapAttrs (host: addr: { "unlock-over-tor_${host}" = "torsocks ssh root@${addr}"; }) (unlockHosts "onionHost")
//
lib.concatMapAttrs (host: addr: { "unlock_${host}" = "ssh root@${addr}"; }) (unlockHosts "clearnetHost");
# 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
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFeTK1iARlNIKP/DS8/ObBm9yUM/3L1Ub4XI5A2r9OzP" # ray
] ++ higherTrustUserKeys;
system = {
ponyo = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMBBlTAIp38RhErU1wNNV5MBeb+WGH0mhF/dxh5RsAXN";
ponyo-unlock = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC9LQuuImgWlkjDhEEIbM1wOd+HqRv1RxvYZuLXPSdRi";
ray = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDQM8hwKRgl8cZj7UVYATSLYu4LhG7I0WFJ9m2iWowiB";
router = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFr2IHmWFlaLaLp5dGoSmFEYKA/eg2SwGXAogaOmLsHL";
router-unlock = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJOw5dTPmtKqiPBH6VKyz5MYBubn8leAh5Eaw7s/O85c";
s0 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwiXcUFtAvZCayhu4+AIcF+Ktrdgv9ee/mXSIhJbp4q";
s0-unlock = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNiceeFMos5ZXcYem4yFxh8PiZNNnuvhlyLbQLrgIZH";
};
higherTrustUserKeys = [
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEaGIwLiUa6wQLlEF+keQOIYy/tCmJvV6eENzUQjSqW2AAAABHNzaDo=" # ray fido
];
# groups
systems = with system; [
ponyo
ray
router
s0
];
personal = with system; [
ray
];
servers = with system; [
ponyo
router
s0
];
storage = with system; [
s0
];
}

209
flake.lock generated
View File

@@ -3,16 +3,20 @@
"agenix": {
"inputs": {
"darwin": "darwin",
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs"
],
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1675176355,
"narHash": "sha256-Qjxh5cmN56siY97mzmBLI1+cdjXSPqmfPVsKxBvHmwI=",
"lastModified": 1716561646,
"narHash": "sha256-UIGtLO89RxKt7RF2iEgPikSdU53r6v/6WYB0RW3k89I=",
"owner": "ryantm",
"repo": "agenix",
"rev": "b7ffcfe77f817d9ee992640ba1f270718d197f28",
"rev": "c2fc0762bbe8feb06a2e59a364fa81b3a57671c9",
"type": "github"
},
"original": {
@@ -21,27 +25,34 @@
"type": "github"
}
},
"archivebox": {
"attic": {
"inputs": {
"crane": "crane",
"flake-compat": [
"flake-compat"
],
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1648612759,
"narHash": "sha256-SJwlpD2Wz3zFoX2mIYCQfwIOYHaOdeiWGFeDXsLGM84=",
"ref": "refs/heads/master",
"rev": "39d338b9b24159d8ef3309eecc0d32a2a9f102b5",
"revCount": 2,
"type": "git",
"url": "https://git.neet.dev/zuckerberg/archivebox.git"
"lastModified": 1717279440,
"narHash": "sha256-kH04ReTjxOpQumgWnqy40vvQLSnLGxWP6RF3nq5Esrk=",
"owner": "zhaofengli",
"repo": "attic",
"rev": "717cc95983cdc357bc347d70be20ced21f935843",
"type": "github"
},
"original": {
"type": "git",
"url": "https://git.neet.dev/zuckerberg/archivebox.git"
"owner": "zhaofengli",
"repo": "attic",
"type": "github"
}
},
"blobs": {
@@ -60,6 +71,27 @@
"type": "gitlab"
}
},
"crane": {
"inputs": {
"nixpkgs": [
"attic",
"nixpkgs"
]
},
"locked": {
"lastModified": 1717025063,
"narHash": "sha256-dIubLa56W9sNNz0e8jGxrX3CAkPXsq7snuFA/Ie6dn8=",
"owner": "ipetkov",
"repo": "crane",
"rev": "480dff0be03dac0e51a8dfc26e882b0d123a450e",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"dailybuild_modules": {
"inputs": {
"flake-utils": [
@@ -76,11 +108,11 @@
"rev": "1290ddd9a2ff2bf2d0f702750768312b80efcd34",
"revCount": 19,
"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": {
@@ -91,11 +123,11 @@
]
},
"locked": {
"lastModified": 1673295039,
"narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=",
"lastModified": 1700795494,
"narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "87b9d090ad39b25b2400029c64825fc2a8868943",
"rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d",
"type": "github"
},
"original": {
@@ -107,21 +139,22 @@
},
"deploy-rs": {
"inputs": {
"flake-compat": "flake-compat",
"flake-compat": [
"flake-compat"
],
"nixpkgs": [
"nixpkgs"
],
"utils": [
"simple-nixos-mailserver",
"utils"
"flake-utils"
]
},
"locked": {
"lastModified": 1674127017,
"narHash": "sha256-QO1xF7stu5ZMDLbHN30LFolMAwY6TVlzYvQoUs1RD68=",
"lastModified": 1718194053,
"narHash": "sha256-FaGrf7qwZ99ehPJCAwgvNY5sLCqQ3GDiE/6uLhxxwSY=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "8c9ea9605eed20528bf60fae35a2b613b901fd77",
"rev": "3867348fa92bc892eba5d9ddb2d7a97b9e127a8a",
"type": "github"
},
"original": {
@@ -133,11 +166,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1668681692,
"narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "009399224d5e398d03b22badca40a37ac85412a1",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
@@ -147,12 +180,17 @@
}
},
"flake-utils": {
"inputs": {
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
@@ -161,6 +199,27 @@
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1703113217,
"narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nix-index-database": {
"inputs": {
"nixpkgs": [
@@ -168,11 +227,11 @@
]
},
"locked": {
"lastModified": 1677382901,
"narHash": "sha256-2idFWlTVG+qUZkU2/W50amGSIxmN56igIkMAXKbv4S4=",
"lastModified": 1716772633,
"narHash": "sha256-Idcye44UW+EgjbjCoklf2IDF+XrehV6CVYvxR1omst4=",
"owner": "Mic92",
"repo": "nix-index-database",
"rev": "4306fa7c12e098360439faac1a2e6b8e509ec97c",
"rev": "ff80cb4a11bb87f3ce8459be6f16a25ac86eb2ac",
"type": "github"
},
"original": {
@@ -181,35 +240,52 @@
"type": "github"
}
},
"nixpkgs": {
"nixos-hardware": {
"locked": {
"lastModified": 1677823547,
"narHash": "sha256-xD2qco8Pw8HAXgjf9OSi2H2N20WaTrtvgcl21525kVE=",
"lastModified": 1717248095,
"narHash": "sha256-e8X2eWjAHJQT82AAN+mCI0B68cIDBJpqJ156+VRrFO0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "78c4d33c16092e535bc4ba1284ba49e3e138483a",
"repo": "nixos-hardware",
"rev": "7b49d3967613d9aacac5b340ef158d493906ba79",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1717144377,
"narHash": "sha256-F/TKWETwB5RaR8owkPPi+SPJh83AQsm6KrQAlJ8v/uA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "805a384895c696f802a9bf5bf4720f37385df547",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-22_05": {
"nixpkgs-frigate": {
"locked": {
"lastModified": 1654936503,
"narHash": "sha256-soKzdhI4jTHv/rSbh89RdlcJmrPgH8oMb/PLqiqIYVQ=",
"lastModified": 1695825837,
"narHash": "sha256-4Ne11kNRnQsmSJCRSSNkFRSnHC4Y5gPDBIQGjjPfJiU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "dab6df51387c3878cdea09f43589a15729cae9f4",
"rev": "5cfafa12d57374f48bcc36fda3274ada276cf69e",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-22.05",
"type": "indirect"
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5cfafa12d57374f48bcc36fda3274ada276cf69e",
"type": "github"
}
},
"radio": {
@@ -256,53 +332,64 @@
"root": {
"inputs": {
"agenix": "agenix",
"archivebox": "archivebox",
"attic": "attic",
"dailybuild_modules": "dailybuild_modules",
"deploy-rs": "deploy-rs",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nix-index-database": "nix-index-database",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs",
"nixpkgs-frigate": "nixpkgs-frigate",
"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"
],
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-22_05": "nixpkgs-22_05",
"utils": "utils"
"nixpkgs-24_05": [
"nixpkgs"
],
"utils": [
"flake-utils"
]
},
"locked": {
"lastModified": 1655930346,
"narHash": "sha256-ht56HHOzEhjeIgAv5ZNFjSVX/in1YlUs0HG9c1EUXTM=",
"lastModified": 1718084203,
"narHash": "sha256-Cx1xoVfSMv1XDLgKg08CUd1EoTYWB45VmB9XIQzhmzI=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "f535d8123c4761b2ed8138f3d202ea710a334a1d",
"rev": "29916981e7b3b5782dc5085ad18490113f8ff63b",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"ref": "nixos-22.05",
"ref": "master",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"utils": {
"systems": {
"locked": {
"lastModified": 1605370193,
"narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5021eac20303a61fafe17224c087f5519baed54d",
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}

193
flake.nix
View File

@@ -1,100 +1,162 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/master";
# nixpkgs-patch-howdy.url = "https://github.com/NixOS/nixpkgs/pull/216245.diff";
# nixpkgs-patch-howdy.flake = false;
# nixpkgs
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
nixpkgs-frigate.url = "github:NixOS/nixpkgs/5cfafa12d57374f48bcc36fda3274ada276cf69e";
flake-utils.url = "github:numtide/flake-utils";
# mail server
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-22.05";
simple-nixos-mailserver.inputs.nixpkgs.follows = "nixpkgs";
# agenix
agenix.url = "github:ryantm/agenix";
agenix.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;
# 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";
# archivebox
archivebox.url = "git+https://git.neet.dev/zuckerberg/archivebox.git";
archivebox.inputs.nixpkgs.follows = "nixpkgs";
archivebox.inputs.flake-utils.follows = "flake-utils";
# 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";
# prebuilt nix-index database
nix-index-database.url = "github:Mic92/nix-index-database";
nix-index-database.inputs.nixpkgs.follows = "nixpkgs";
# 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;
};
outputs = { self, nixpkgs, ... }@inputs: {
# NixOS hardware
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
# Mail Server
simple-nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
inputs = {
nixpkgs.follows = "nixpkgs";
nixpkgs-24_05.follows = "nixpkgs";
flake-compat.follows = "flake-compat";
utils.follows = "flake-utils";
};
};
# Agenix
agenix = {
url = "github:ryantm/agenix";
inputs = {
nixpkgs.follows = "nixpkgs";
systems.follows = "systems";
};
};
# Radio
radio = {
url = "git+https://git.neet.dev/zuckerberg/radio.git?ref=main&rev=5bf607fed977d41a269942a7d1e92f3e6d4f2473";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
};
};
radio-web = {
url = "git+https://git.neet.dev/zuckerberg/radio-web.git";
flake = false;
};
# Dailybot
dailybuild_modules = {
url = "git+https://git.neet.dev/zuckerberg/dailybot.git";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
};
};
# NixOS deployment
deploy-rs = {
url = "github:serokell/deploy-rs";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-compat.follows = "flake-compat";
utils.follows = "flake-utils";
};
};
# Prebuilt nix-index database
nix-index-database = {
url = "github:Mic92/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
};
# Attic
attic = {
url = "github:zhaofengli/attic";
inputs = {
nixpkgs.follows = "nixpkgs";
nixpkgs-stable.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
flake-compat.follows = "flake-compat";
};
};
};
outputs = { self, nixpkgs, ... }@inputs:
let
machines = (import ./common/machine-info/moduleless.nix
{
inherit nixpkgs;
assertionsModule = "${nixpkgs}/nixos/modules/misc/assertions.nix";
}).machines.hosts;
in
{
nixosConfigurations =
let
modules = system: with inputs; [
modules = system: hostname: with inputs; [
./common
simple-nixos-mailserver.nixosModule
agenix.nixosModules.default
dailybuild_modules.nixosModule
archivebox.nixosModule
nix-index-database.nixosModules.nix-index
attic.nixosModules.atticd
self.nixosModules.kernel-modules
({ lib, ... }: {
config.environment.systemPackages = [
config = {
nixpkgs.overlays = [ self.overlays.default ];
environment.systemPackages = [
agenix.packages.${system}.agenix
];
networking.hostName = hostname;
};
# because nixos specialArgs doesn't work for containers... need to pass in inputs a different way
options.inputs = lib.mkOption { default = inputs; };
options.currentSystem = lib.mkOption { default = system; };
})
];
mkSystem = system: nixpkgs: path:
mkSystem = system: nixpkgs: path: hostname:
let
allModules = modules system;
allModules = modules system hostname;
# allow patching nixpkgs, remove this hack once this is solved: https://github.com/NixOS/nix/issues/3920
patchedNixpkgsSrc = nixpkgs.legacyPackages.${system}.applyPatches {
name = "nixpkgs-patched";
src = nixpkgs;
patches = [
# inputs.nixpkgs-patch-howdy
./patches/gamepadui.patch
];
};
patchedNixpkgs = nixpkgs.lib.fix (self: (import "${patchedNixpkgsSrc}/flake.nix").outputs { self = nixpkgs; });
in patchedNixpkgs.lib.nixosSystem {
in
patchedNixpkgs.lib.nixosSystem {
inherit system;
modules = allModules ++ [ path ];
specialArgs = {
inherit allModules;
lib = self.lib;
nixos-hardware = inputs.nixos-hardware;
};
};
in
{
"ray" = mkSystem "x86_64-linux" nixpkgs ./machines/ray/configuration.nix;
# "nat" = mkSystem "aarch64-linux" nixpkgs ./machines/nat/configuration.nix;
"ponyo" = mkSystem "x86_64-linux" nixpkgs ./machines/ponyo/configuration.nix;
"router" = mkSystem "x86_64-linux" nixpkgs ./machines/router/configuration.nix;
"s0" = mkSystem "x86_64-linux" nixpkgs ./machines/storage/s0/configuration.nix;
};
nixpkgs.lib.mapAttrs
(hostname: cfg:
mkSystem cfg.arch nixpkgs cfg.configurationPath hostname)
machines;
packages = let
packages =
let
mkKexec = system:
(nixpkgs.lib.nixosSystem {
inherit system;
@@ -105,28 +167,33 @@
inherit system;
modules = [ ./machines/ephemeral/iso.nix ];
}).config.system.build.isoImage;
in {
in
{
"x86_64-linux"."kexec" = mkKexec "x86_64-linux";
"x86_64-linux"."iso" = mkIso "x86_64-linux";
"aarch64-linux"."kexec" = mkKexec "aarch64-linux";
"aarch64-linux"."iso" = mkIso "aarch64-linux";
};
overlays.default = import ./overlays { inherit inputs; };
nixosModules.kernel-modules = import ./overlays/kernel-modules;
deploy.nodes =
let
mkDeploy = configName: hostname: {
mkDeploy = configName: arch: hostname: {
inherit hostname;
magicRollback = false;
sshUser = "root";
profiles.system.path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.${configName};
};
in {
s0 = mkDeploy "s0" "s0";
router = mkDeploy "router" "192.168.1.228";
ponyo = mkDeploy "ponyo" "ponyo.neet.dev";
profiles.system.path = inputs.deploy-rs.lib.${arch}.activate.nixos self.nixosConfigurations.${configName};
};
in
nixpkgs.lib.mapAttrs
(hostname: cfg:
mkDeploy hostname cfg.arch (builtins.head cfg.hostNames))
machines;
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;
lib = nixpkgs.lib.extend (final: prev: import ./lib { lib = nixpkgs.lib; });
};
}

56
lib/default.nix Normal file
View File

@@ -0,0 +1,56 @@
{ lib, ... }:
with lib;
{
# Passthrough trace for debugging
pTrace = v: traceSeq v v;
# find the total sum of a int list
sum = foldr (x: y: x + y) 0;
# splits a list of length two into two params then they're passed to a func
splitPair = f: pair: f (head pair) (last pair);
# Finds the max value in a list
maxList = foldr max 0;
# Sorts a int list. Greatest value first
sortList = sort (x: y: x > y);
# Cuts a list in half and returns the two parts in a list
cutInHalf = l: [ (take (length l / 2) l) (drop (length l / 2) l) ];
# Splits a list into a list of lists with length cnt
chunksOf = cnt: l:
if length l > 0 then
[ (take cnt l) ] ++ chunksOf cnt (drop cnt l)
else [ ];
# same as intersectLists but takes an array of lists to intersect instead of just two
intersectManyLists = ll: foldr intersectLists (head ll) ll;
# converts a boolean to a int (c style)
boolToInt = b: if b then 1 else 0;
# drops the last element of a list
dropLast = l: take (length l - 1) l;
# transposes a matrix
transpose = ll:
let
outerSize = length ll;
innerSize = length (elemAt ll 0);
in
genList (i: genList (j: elemAt (elemAt ll j) i) outerSize) innerSize;
# attriset recursiveUpdate but for a list of attrisets
combineAttrs = foldl recursiveUpdate { };
# visits every single attriset element of an attriset recursively
# and accumulates the result of every visit in a flat list
recurisveVisitAttrs = f: set:
let
visitor = n: v:
if isAttrs v then [ (f n v) ] ++ recurisveVisitAttrs f v
else [ (f n v) ];
in
concatLists (map (name: visitor name set.${name}) (attrNames set));
# merges two lists of the same size (similar to map but both lists are inputs per iteration)
mergeLists = f: a: imap0 (i: f (elemAt a i));
map2D = f: ll:
let
outerSize = length ll;
innerSize = length (elemAt ll 0);
getElem = x: y: elemAt (elemAt ll y) x;
in
genList (y: genList (x: f x y (getElem x y)) innerSize) outerSize;
}

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

@@ -1,13 +1,16 @@
{ pkgs, modulesPath, ... }:
{ config, pkgs, modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/cd-dvd/channel.nix")
../../common/machine-info
../../common/ssh.nix
];
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "e1000" "e1000e" "virtio_pci" "r8169" ];
boot.kernelParams = [
"panic=30" "boot.panic_on_fail" # reboot the machine upon fatal boot issues
"panic=30"
"boot.panic_on_fail" # reboot the machine upon fatal boot issues
"console=ttyS0,115200" # enable serial console
"console=tty1"
];
@@ -15,13 +18,16 @@
boot.kernelPackages = pkgs.linuxPackages_latest;
system.stateVersion = "21.11";
# hardware.enableAllFirmware = true;
# nixpkgs.config.allowUnfree = true;
environment.systemPackages = with pkgs; [
cryptsetup
btrfs-progs
git git-lfs
git
git-lfs
wget
htop
dnsutils
@@ -36,10 +42,12 @@
services.openssh = {
enable = true;
challengeResponseAuthentication = false;
passwordAuthentication = false;
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
};
};
services.getty.autologinUser = "root";
users.users.root.openssh.authorizedKeys.keys = (import ../../common/ssh.nix).users;
users.users.root.openssh.authorizedKeys.keys = config.machines.ssh.userKeys;
}

View File

@@ -0,0 +1,57 @@
{ config, modulesPath, pkgs, lib, ... }:
let
pinecube-uboot = pkgs.buildUBoot {
defconfig = "pinecube_defconfig";
extraMeta.platforms = [ "armv7l-linux" ];
filesToInstall = [ "u-boot-sunxi-with-spl.bin" ];
};
in
{
imports = [
(modulesPath + "/installer/sd-card/sd-image.nix")
./minimal.nix
];
sdImage.populateFirmwareCommands = "";
sdImage.populateRootCommands = ''
mkdir -p ./files/boot
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
'';
sdImage.postBuildCommands = ''
dd if=${pinecube-uboot}/u-boot-sunxi-with-spl.bin of=$img bs=1024 seek=8 conv=notrunc
'';
###
networking.hostName = "pinecube";
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
boot.consoleLogLevel = 7;
# cma is 64M by default which is waay too much and we can't even unpack initrd
boot.kernelParams = [ "console=ttyS0,115200n8" "cma=32M" ];
boot.kernelModules = [ "spi-nor" ]; # Not sure why this doesn't autoload. Provides SPI NOR at /dev/mtd0
boot.extraModulePackages = [ config.boot.kernelPackages.rtl8189es ];
zramSwap.enable = true; # 128MB is not much to work with
sound.enable = true;
environment.systemPackages = with pkgs; [
ffmpeg
(v4l_utils.override { withGUI = false; })
usbutils
];
services.getty.autologinUser = lib.mkForce "googlebot";
users.users.googlebot = {
isNormalUser = true;
extraGroups = [ "wheel" "networkmanager" "video" ];
openssh.authorizedKeys.keys = config.machines.ssh.userKeys;
};
networking.wireless.enable = true;
}

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

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

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/c801586b-f0a2-465c-8dae-532e61b83fee";
allowDiscards = true;
};
fileSystems."/" =
{
device = "/dev/disk/by-uuid/95db6950-a7bc-46cf-9765-3ea675ccf014";
fsType = "btrfs";
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/B087-2C20";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices =
[{ device = "/dev/disk/by-uuid/49fbdf62-eef4-421b-aac3-c93494afd23c"; }];
# 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,26 @@
{
hostNames = [
"howl"
];
arch = "x86_64-linux";
systemRoles = [
"personal"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEQi3q8jU6vRruExAL60J7GFO1gS8HsmXVJuKRT4ljrG";
userKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPnLt84bKhUgFxjQf10+Htro9Lo1Pabqm8mGalBUniv"
];
deployKeys = [
# TODO
];
remoteUnlock = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN0N80r0Sl2WlJaUqfxZPkOtYyGumFazkIqq7eq3Gd2o";
onionHost = "ll6yjnkh4psmfwmtkmqoutl4gq4elqzbmjxv4s6gpgoavyi3kwhjvnqd.onion";
};
}

View File

@@ -12,12 +12,14 @@
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/02a8c0c7-fd4e-4443-a83c-2d0b63848779";
{
device = "/dev/disk/by-uuid/02a8c0c7-fd4e-4443-a83c-2d0b63848779";
fsType = "btrfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/0C95-1290";
{
device = "/dev/disk/by-uuid/0C95-1290";
fsType = "vfat";
};

View File

@@ -0,0 +1,9 @@
{ config, pkgs, lib, ... }:
{
imports = [
./hardware-configuration.nix
];
networking.hostName = "phil";
}

View File

@@ -0,0 +1,46 @@
# 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 + "/profiles/qemu-guest.nix")
];
# because grub just doesn't work for some reason
boot.loader.systemd-boot.enable = true;
remoteLuksUnlock.enable = true;
remoteLuksUnlock.enableTorUnlock = false;
boot.initrd.availableKernelModules = [ "xhci_pci" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
boot.initrd.luks.devices."enc-pv" = {
device = "/dev/disk/by-uuid/d26c1820-4c39-4615-98c2-51442504e194";
allowDiscards = true;
};
fileSystems."/" =
{
device = "/dev/disk/by-uuid/851bfde6-93cd-439e-9380-de28aa87eda9";
fsType = "btrfs";
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/F185-C4E5";
fsType = "vfat";
};
swapDevices =
[{ device = "/dev/disk/by-uuid/d809e3a1-3915-405a-a200-4429c5efdf87"; }];
networking.interfaces.enp0s6.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
}

View File

@@ -0,0 +1,20 @@
{
hostNames = [
"phil"
"phil.neet.dev"
];
arch = "aarch64-linux";
systemRoles = [
"server"
"nix-builder"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlgRPpuUkZqe8/lHugRPm/m2vcN9psYhh5tENHZt9I2";
remoteUnlock = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0RodotOXLMy/w70aa096gaNqPBnfgiXR5ZAH4+wGzd";
clearnetHost = "unlock.phil.neet.dev";
};
}

View File

@@ -5,9 +5,7 @@
./hardware-configuration.nix
];
networking.hostName = "ponyo";
system.autoUpgrade.enable = true;
# system.autoUpgrade.enable = true;
# p2p mesh network
services.tailscale.exitNode = true;
@@ -52,6 +50,9 @@
file = ../../secrets/wolframalpha.age;
owner = config.services.drastikbot.user;
};
backup.group."dailybot".paths = [
config.services.drastikbot.dataDir
];
# music radio
vpn-container.enable = true;
@@ -62,7 +63,8 @@
};
};
pia.wireguard.badPortForwardPorts = [ ];
services.nginx.virtualHosts."radio.runyan.org" = {
services.nginx.virtualHosts = {
"radio.runyan.org" = {
enableACME = true;
forceSSL = true;
locations = {
@@ -75,6 +77,20 @@
"/".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 = {
@@ -95,7 +111,7 @@
};
};
# pin postgresql for matrix (will need to migrate eventually)
services.postgresql.package = pkgs.postgresql_11;
services.postgresql.package = pkgs.postgresql_15;
# iodine DNS-based vpn
services.iodine.server.enable = true;
@@ -135,4 +151,11 @@
# owncast live streaming
services.owncast.enable = true;
services.owncast.hostname = "live.neet.dev";
# librechat
services.librechat.enable = true;
services.librechat.host = "chat.neet.dev";
services.actual-server.enable = true;
services.actual-server.hostname = "actual.runyan.org";
}

View File

@@ -2,7 +2,8 @@
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
[
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ];
@@ -15,6 +16,7 @@
bios = {
enable = true;
device = "/dev/sda";
configurationLimit = 3; # Save room in /nix/store
};
remoteLuksUnlock.enable = true;
@@ -22,12 +24,14 @@
boot.initrd.luks.devices."enc-pv2".device = "/dev/disk/by-uuid/e52b01b3-81c8-4bb2-ae7e-a3d9c793cb00"; # expanded disk
fileSystems."/" =
{ device = "/dev/mapper/enc-pv";
{
device = "/dev/mapper/enc-pv";
fsType = "btrfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/d3a3777d-1e70-47fa-a274-804dc70ee7fd";
{
device = "/dev/disk/by-uuid/d3a3777d-1e70-47fa-a274-804dc70ee7fd";
fsType = "ext4";
};

View File

@@ -0,0 +1,29 @@
{
hostNames = [
"ponyo"
"ponyo.neet.dev"
"git.neet.dev"
];
arch = "x86_64-linux";
systemRoles = [
"server"
"email-server"
"iodine"
"pia"
"nextcloud"
"dailybot"
"gitea"
"librechat"
];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMBBlTAIp38RhErU1wNNV5MBeb+WGH0mhF/dxh5RsAXN";
remoteUnlock = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC9LQuuImgWlkjDhEEIbM1wOd+HqRv1RxvYZuLXPSdRi";
clearnetHost = "unlock.ponyo.neet.dev";
onionHost = "cfamr6artx75qvt7ho3rrbsc7mkucmv5aawebwflsfuorusayacffryd.onion";
};
}

View File

@@ -1,44 +0,0 @@
{ config, pkgs, lib, ... }:
{
imports = [
./hardware-configuration.nix
];
networking.hostName = "ray";
# for luks onlock over tor
services.tor.enable = true;
services.tor.client.enable = true;
# services.howdy.enable = true;
hardware.openrazer.enable = true;
hardware.openrazer.users = [ "googlebot" ];
hardware.openrazer.devicesOffOnScreensaver = false;
users.users.googlebot.packages = [ pkgs.polychromatic ];
# depthai
services.udev.extraRules = ''
SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"
'';
# 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" ];
# allow building ARM derivations
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
services.spotifyd.enable = true;
virtualisation.docker.enable = true;
services.mount-samba.enable = true;
de.enable = true;
de.touchpad.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"; }
];
# high-resolution display
hardware.video.hidpi.enable = lib.mkDefault true;
}

View File

@@ -1,15 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
networking.hostName = "router";
system.autoUpgrade.enable = true;
services.tailscale.exitNode = true;
networking.useDHCP = lib.mkForce true;
}

View File

@@ -0,0 +1,38 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./router.nix
];
# https://dataswamp.org/~solene/2022-08-03-nixos-with-live-usb-router.html
# https://github.com/mdlayher/homelab/blob/391cfc0de06434e4dee0abe2bec7a2f0637345ac/nixos/routnerr-2/configuration.nix
# https://github.com/skogsbrus/os/blob/master/sys/router.nix
# http://trac.gateworks.com/wiki/wireless/wifi
system.autoUpgrade.enable = true;
services.tailscale.exitNode = true;
router.enable = true;
router.privateSubnet = "192.168.3";
services.iperf3.enable = true;
# networking.useDHCP = lib.mkForce true;
# TODO
# networking.usePredictableInterfaceNames = true;
powerManagement.cpuFreqGovernor = "ondemand";
services.irqbalance.enable = true;
# services.miniupnpd = {
# enable = true;
# externalInterface = "eth0";
# internalIPs = [ "br0" ];
# };
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,223 @@
#!/bin/sh
# TODO allow adding custom parameters to ht_capab, vht_capab
# TODO detect bad channel numbers (preferably not at runtime)
# TODO error if 160mhz is not supported
# TODO 'b' only goes up to 40mhz
# gets the phy number using the input interface
# Ex: get_phy_number("wlan0") -> "1"
get_phy_number() {
local interface=$1
phy=$(iw dev "$interface" info | awk '/phy/ {gsub(/#/,"");print $2}')
if [[ -z "$phy" ]]; then
echo "Error: interface not found" >&2
exit 1
fi
phy=phy$phy
}
get_ht_cap_mask() {
ht_cap_mask=0
for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do
ht_cap_mask="$(($ht_cap_mask | $cap))"
done
local cap_rx_stbc
cap_rx_stbc=$((($ht_cap_mask >> 8) & 3))
ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))"
}
get_vht_cap_mask() {
vht_cap_mask=0
for cap in $(iw phy "$phy" info | awk -F "[()]" '/VHT Capabilities/ { print $2 }'); do
vht_cap_mask="$(($vht_cap_mask | $cap))"
done
local cap_rx_stbc
cap_rx_stbc=$((($vht_cap_mask >> 8) & 7))
vht_cap_mask="$(( ($vht_cap_mask & ~(0x700)) | ($cap_rx_stbc << 8) ))"
}
mac80211_add_capabilities() {
local __var="$1"; shift
local __mask="$1"; shift
local __out= oifs
oifs="$IFS"
IFS=:
for capab in "$@"; do
set -- $capab
[ "$(($4))" -gt 0 ] || continue
[ "$(($__mask & $2))" -eq "$((${3:-$2}))" ] || continue
__out="$__out[$1]"
done
IFS="$oifs"
export -n -- "$__var=$__out"
}
add_special_ht_capabilities() {
case "$hwmode" in
a)
case "$(( ($channel / 4) % 2 ))" in
1) ht_capab="$ht_capab[HT40+]";;
0) ht_capab="$ht_capab[HT40-]";;
esac
;;
*)
if [ "$channel" -lt 7 ]; then
ht_capab="$ht_capab[HT40+]"
else
ht_capab="$ht_capab[HT40-]"
fi
;;
esac
}
add_special_vht_capabilities() {
local cap_ant
[ "$(($vht_cap_mask & 0x800))" -gt 0 ] && {
cap_ant="$(( ( ($vht_cap_mask >> 16) & 3 ) + 1 ))"
[ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[SOUNDING-DIMENSION-$cap_ant]"
}
[ "$(($vht_cap_mask & 0x1000))" -gt 0 ] && {
cap_ant="$(( ( ($vht_cap_mask >> 13) & 3 ) + 1 ))"
[ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[BF-ANTENNA-$cap_ant]"
}
if [ "$(($vht_cap_mask & 12))" -eq 4 ]; then
vht_capab="$vht_capab[VHT160]"
fi
local vht_max_mpdu_hw=3895
[ "$(($vht_cap_mask & 3))" -ge 1 ] && \
vht_max_mpdu_hw=7991
[ "$(($vht_cap_mask & 3))" -ge 2 ] && \
vht_max_mpdu_hw=11454
[ "$vht_max_mpdu_hw" != 3895 ] && \
vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]"
# maximum A-MPDU length exponent
local vht_max_a_mpdu_len_exp_hw=0
[ "$(($vht_cap_mask & 58720256))" -ge 8388608 ] && \
vht_max_a_mpdu_len_exp_hw=1
[ "$(($vht_cap_mask & 58720256))" -ge 16777216 ] && \
vht_max_a_mpdu_len_exp_hw=2
[ "$(($vht_cap_mask & 58720256))" -ge 25165824 ] && \
vht_max_a_mpdu_len_exp_hw=3
[ "$(($vht_cap_mask & 58720256))" -ge 33554432 ] && \
vht_max_a_mpdu_len_exp_hw=4
[ "$(($vht_cap_mask & 58720256))" -ge 41943040 ] && \
vht_max_a_mpdu_len_exp_hw=5
[ "$(($vht_cap_mask & 58720256))" -ge 50331648 ] && \
vht_max_a_mpdu_len_exp_hw=6
[ "$(($vht_cap_mask & 58720256))" -ge 58720256 ] && \
vht_max_a_mpdu_len_exp_hw=7
vht_capab="$vht_capab[MAX-A-MPDU-LEN-EXP$vht_max_a_mpdu_len_exp_hw]"
local vht_link_adapt_hw=0
[ "$(($vht_cap_mask & 201326592))" -ge 134217728 ] && \
vht_link_adapt_hw=2
[ "$(($vht_cap_mask & 201326592))" -ge 201326592 ] && \
vht_link_adapt_hw=3
[ "$vht_link_adapt_hw" != 0 ] && \
vht_capab="$vht_capab[VHT-LINK-ADAPT-$vht_link_adapt_hw]"
}
calculate_channel_offsets() {
vht_oper_chwidth=0
vht_oper_centr_freq_seg0_idx=
local idx="$channel"
case "$channelWidth" in
40)
case "$(( ($channel / 4) % 2 ))" in
1) idx=$(($channel + 2));;
0) idx=$(($channel - 2));;
esac
vht_oper_centr_freq_seg0_idx=$idx
;;
80)
case "$(( ($channel / 4) % 4 ))" in
1) idx=$(($channel + 6));;
2) idx=$(($channel + 2));;
3) idx=$(($channel - 2));;
0) idx=$(($channel - 6));;
esac
vht_oper_chwidth=1
vht_oper_centr_freq_seg0_idx=$idx
;;
160)
case "$channel" in
36|40|44|48|52|56|60|64) idx=50;;
100|104|108|112|116|120|124|128) idx=114;;
esac
vht_oper_chwidth=2
vht_oper_centr_freq_seg0_idx=$idx
;;
esac
he_oper_chwidth=$vht_oper_chwidth
he_oper_centr_freq_seg0_idx=$vht_oper_centr_freq_seg0_idx
}
interface=$1
channel=$2
hwmode=$3
channelWidth=$4
get_phy_number $interface
get_ht_cap_mask
get_vht_cap_mask
mac80211_add_capabilities vht_capab $vht_cap_mask \
RXLDPC:0x10::1 \
SHORT-GI-80:0x20::1 \
SHORT-GI-160:0x40::1 \
TX-STBC-2BY1:0x80::1 \
SU-BEAMFORMER:0x800::1 \
SU-BEAMFORMEE:0x1000::1 \
MU-BEAMFORMER:0x80000::1 \
MU-BEAMFORMEE:0x100000::1 \
VHT-TXOP-PS:0x200000::1 \
HTC-VHT:0x400000::1 \
RX-ANTENNA-PATTERN:0x10000000::1 \
TX-ANTENNA-PATTERN:0x20000000::1 \
RX-STBC-1:0x700:0x100:1 \
RX-STBC-12:0x700:0x200:1 \
RX-STBC-123:0x700:0x300:1 \
RX-STBC-1234:0x700:0x400:1 \
mac80211_add_capabilities ht_capab $ht_cap_mask \
LDPC:0x1::1 \
GF:0x10::1 \
SHORT-GI-20:0x20::1 \
SHORT-GI-40:0x40::1 \
TX-STBC:0x80::1 \
RX-STBC1:0x300::1 \
MAX-AMSDU-7935:0x800::1 \
# TODO this is active when the driver doesn't support it?
# DSSS_CCK-40:0x1000::1 \
# TODO these are active when the driver doesn't support them?
# RX-STBC1:0x300:0x100:1 \
# RX-STBC12:0x300:0x200:1 \
# RX-STBC123:0x300:0x300:1 \
add_special_ht_capabilities
add_special_vht_capabilities
echo ht_capab=$ht_capab
echo vht_capab=$vht_capab
if [ "$channelWidth" != "20" ]; then
calculate_channel_offsets
echo he_oper_chwidth=$he_oper_chwidth
echo vht_oper_chwidth=$vht_oper_chwidth
echo he_oper_centr_freq_seg0_idx=$he_oper_centr_freq_seg0_idx
echo vht_oper_centr_freq_seg0_idx=$vht_oper_centr_freq_seg0_idx
fi

View File

@@ -10,7 +10,8 @@
# Enable serial output
boot.kernelParams = [
"panic=30" "boot.panic_on_fail" # reboot the machine upon fatal boot issues
"panic=30"
"boot.panic_on_fail" # reboot the machine upon fatal boot issues
"console=ttyS0,115200n8" # enable serial console
];
boot.loader.grub.extraConfig = "
@@ -21,7 +22,6 @@
# firmware
firmware.x86_64.enable = true;
hardware.enableAllFirmware = true;
nixpkgs.config.allowUnfree = true;
# boot
@@ -34,16 +34,17 @@
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";
{
device = "/dev/disk/by-uuid/421c82b9-d67c-4811-8824-8bb57cb10fce";
fsType = "btrfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/d97f324f-3a2e-4b84-ae2a-4b3d1209c689";
{
device = "/dev/disk/by-uuid/d97f324f-3a2e-4b84-ae2a-4b3d1209c689";
fsType = "ext3";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/45bf58dd-67eb-45e4-9a98-246e23fa7abd"; }
];
[{ device = "/dev/disk/by-uuid/45bf58dd-67eb-45e4-9a98-246e23fa7abd"; }];
nixpkgs.hostPlatform = "x86_64-linux";
}

View File

@@ -0,0 +1,21 @@
{
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";
};
}

205
machines/router/router.nix Normal file
View File

@@ -0,0 +1,205 @@
{ config, pkgs, lib, ... }:
let
cfg = config.router;
inherit (lib) mapAttrs' genAttrs nameValuePair mkOption types mkIf mkEnableOption;
in
{
options.router = {
enable = mkEnableOption "router";
privateSubnet = mkOption {
type = types.str;
default = "192.168.1";
description = "IP block (/24) to use for the private subnet";
};
};
config = mkIf cfg.enable {
networking.ip_forward = true;
networking.interfaces.enp1s0.useDHCP = true;
networking.nat = {
enable = true;
internalInterfaces = [
"br0"
];
externalInterface = "enp1s0";
};
networking.bridges = {
br0 = {
interfaces = [
"enp2s0"
"wlp4s0"
"wlan1"
];
};
};
networking.interfaces = {
br0 = {
useDHCP = false;
ipv4.addresses = [
{
address = "${cfg.privateSubnet}.1";
prefixLength = 24;
}
];
};
};
networking.firewall = {
enable = true;
trustedInterfaces = [ "br0" "tailscale0" ];
interfaces = {
enp1s0 = {
allowedTCPPorts = [ ];
allowedUDPPorts = [ ];
};
};
};
services.dnsmasq = {
enable = true;
extraConfig = ''
# sensible behaviours
domain-needed
bogus-priv
no-resolv
# upstream name servers
server=1.1.1.1
server=8.8.8.8
# local domains
expand-hosts
domain=home
local=/home/
# Interfaces to use DNS on
interface=br0
# subnet IP blocks to use DHCP on
dhcp-range=${cfg.privateSubnet}.10,${cfg.privateSubnet}.254,24h
'';
};
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,249 @@
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,11 +3,15 @@
{
imports = [
./hardware-configuration.nix
./home-automation.nix
];
networking.hostName = "s0";
system.autoUpgrade.enable = true;
# system.autoUpgrade.enable = true;
services.iperf3.enable = true;
services.iperf3.openFirewall = true;
# p2p mesh network
services.tailscale.exitNode = true;
@@ -19,9 +23,6 @@
# samba
services.samba.enable = true;
# disable suspend on lid close
services.logind.lidSwitch = "ignore";
# navidrome
services.navidrome = {
enable = true;
@@ -31,7 +32,6 @@
MusicFolder = "/data/samba/Public/Media/Music";
};
};
networking.firewall.allowedTCPPorts = [ config.services.navidrome.settings.Port ];
# allow access to transmisson data
users.users.googlebot.extraGroups = [ "transmission" ];
@@ -99,13 +99,19 @@
# "speed-limit-up-enabled" = true;
/* seeding limit */
"ratio-limit" = 2;
"ratio-limit" = 3;
"ratio-limit-enabled" = true;
"download-queue-enabled" = true;
"download-queue-size" = 20; # gotta go fast
};
};
# https://github.com/NixOS/nixpkgs/issues/258793
systemd.services.transmission.serviceConfig = {
RootDirectoryStartOnly = lib.mkForce (lib.mkForce false);
RootDirectory = lib.mkForce (lib.mkForce "");
};
users.groups.public_data.gid = 994;
users.users.public_data = {
isSystemUser = true;
@@ -143,22 +149,75 @@
# nginx
services.nginx.enable = true;
services.nginx.virtualHosts."bazarr.s0".locations."/".proxyPass = "http://vpn.containers:6767";
services.nginx.virtualHosts."radarr.s0".locations."/".proxyPass = "http://vpn.containers:7878";
services.nginx.virtualHosts."lidarr.s0".locations."/".proxyPass = "http://vpn.containers:8686";
services.nginx.virtualHosts."sonarr.s0".locations."/".proxyPass = "http://vpn.containers:8989";
services.nginx.virtualHosts."prowlarr.s0".locations."/".proxyPass = "http://vpn.containers:9696";
services.nginx.virtualHosts."music.s0".locations."/".proxyPass = "http://localhost:4533";
services.nginx.virtualHosts."jellyfin.s0".locations."/" = {
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".locations."/" = {
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;
};
};
networking.firewall.allowedTCPPorts = [
6767
7878
8686
8989
9696
4534
8097
9091
8443 # unifi
];
virtualisation.oci-containers.backend = "podman";
virtualisation.podman.dockerSocket.enable = true; # TODO needed?
services.dashy = {
enable = true;
configFile = ./dashy.yaml;
};
services.unifi = {
enable = true;
openFirewall = true;
unifiPackage = pkgs.unifi8;
};
boot.binfmt.emulatedSystems = [ "aarch64-linux" "armv7l-linux" ];
services.atticd.enable = true;
}

View File

@@ -2,11 +2,12 @@
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
[
(modulesPath + "/installer/scan/not-detected.nix")
];
# boot
efi.enable = true;
boot.loader.systemd-boot.enable = true;
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "uas" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
@@ -30,34 +31,35 @@
boot.initrd.luks.devices."enc-pv4".device = "/dev/disk/by-uuid/e2c7402a-e72c-4c4a-998f-82e4c10187bc";
# mounts
services.zfs.autoScrub.enable = true;
services.zfs.trim.enable = true;
fileSystems."/" =
{ device = "rpool/nixos/root";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/home" =
{ device = "rpool/nixos/home";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
{
device = "rpool/nixos/root";
fsType = "zfs";
options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/lib" =
{ device = "rpool/nixos/var/lib";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
{
device = "rpool/nixos/var/lib";
fsType = "zfs";
options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/var/log" =
{ device = "rpool/nixos/var/log";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/data" =
{ device = "rpool/nixos/data";
fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];
{
device = "rpool/nixos/var/log";
fsType = "zfs";
options = [ "zfsutil" "X-mount.mkdir" ];
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/4FB4-738E";
{
device = "/dev/disk/by-uuid/4FB4-738E";
fsType = "vfat";
};
swapDevices = [ ];
networking.interfaces.eth0.useDHCP = true;
networking.interfaces.eth1.useDHCP = true;
powerManagement.cpuFreqGovernor = "powersave";
}

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