1
1
Fork 0

Compare commits

...

262 Commits

Author SHA1 Message Date
Tim Van Baak 714198cd10 beatific: move mopidy.home.ktvb.site to catacomb 2024-08-31 19:26:30 +00:00
Tim Van Baak 4129847e6a catacomb: move mopidy configs from centroid 2024-08-31 19:26:02 +00:00
Tim Van Baak accfdc159c catacomb: enable sound 2024-08-31 14:51:28 +00:00
Tim Van Baak e8fda52758 catacomb: Remove more NAS components 2024-08-31 14:51:12 +00:00
Tim Van Baak 9389c21c07 catacomb: add wifi configuration 2024-08-30 20:12:57 +00:00
Tim Van Baak f7954f43d6 catacomb: don't import catapool 2024-08-30 01:58:30 +00:00
Tim Van Baak 7ab342adad catacomb: remove samba and NAS-related cron 2024-08-30 01:55:41 +00:00
Tim Van Baak c2d7910800 unfolder: qutebrowser 2024-08-28 12:33:41 -07:00
Tim Van Baak 3f7f9fe4ec unfolder: add tvb to docker group 2024-08-16 20:00:14 -07:00
Tim Van Baak f44dc7880d beatific: typo 2024-08-16 19:45:18 -07:00
Tim Van Baak 3de17049b7 unfolder: vscode module 2024-08-16 19:44:15 -07:00
Tim Van Baak 40c738b764 imperium: move distrobox to vscode module 2024-08-16 18:32:45 -07:00
Tim Van Baak e709ed2a72 imperium: add audacity 2024-08-16 18:21:14 -07:00
Tim Van Baak 293d638a67 imperium: add distrobox
Getting the C# debugger to work in vscode on NixOS was too hard when I can just run Ubuntu instead
2024-08-16 18:20:35 -07:00
Tim Van Baak 7b91747729 imperium: refactor inline modules to flake output 2024-08-16 18:18:10 -07:00
Tim Van Baak 6f9f01fe84 backyard: enable screen 2024-08-09 13:42:28 +00:00
Tim Van Baak e12dd38fe5 imperium: add vscodium 2024-08-07 19:27:37 -07:00
Tim Van Baak 5ac2fae80e beatific: add ripgrep 2024-08-07 19:25:33 -07:00
Tim Van Baak b27f99616a beatific: add ffmpeg 2024-08-07 19:25:16 -07:00
Tim Van Baak 052159afb7 beatific: comments 2024-08-07 19:24:03 -07:00
Tim Van Baak 95572febd5 beatific: move ascii banner to motd 2024-07-18 22:34:47 -07:00
Tim Van Baak b8589fba6c imperium: add gthumb 2024-07-18 22:11:25 -07:00
Jaculabilis 5c59db5e33 beatific: update 24.05
This picks up an important OpenSSH patch
2024-07-10 21:56:51 -07:00
Tim Van Baak b6c3fc21e8 backyard: upgrade to 24.05 2024-06-30 04:57:36 +00:00
Tim Van Baak 781fa50e23 imperium: upgrade to 24.05 2024-06-29 21:56:44 -07:00
Tim Van Baak 02e52163c0 backyard: disable channels 2024-06-30 04:46:57 +00:00
Tim Van Baak 507442cc8a backyard: enable cron 2024-06-30 04:46:57 +00:00
Jaculabilis 08b61ca35d beatific: remove 23.05 and stagirite 2024-06-28 23:19:08 +00:00
Jaculabilis 3776fbdeda empyrean: upgrade to 24.05 2024-06-28 23:16:05 +00:00
Tim Van Baak 50328c51b2 catacomb: upgrade to 24.05 2024-06-28 23:09:58 +00:00
Tim Van Baak aa6ccd8025 catacomb: Remove fileserver
This is now running on backyard
2024-06-28 23:09:41 +00:00
Tim Van Baak 5d6ee630bd beatific: fix clip script 2024-06-25 21:59:15 -07:00
Tim Van Baak e8698d3dc2 unfolder: add bitwarden-{cli,desktop} 2024-06-25 20:30:27 -07:00
Tim Van Baak b0115514e8 imperium: add bitwarden and bitwarden-cli 2024-06-25 20:12:52 -07:00
Tim Van Baak f6fc8e2287 unfolder: Add single-file wrapper without adding chromium 2024-06-24 19:13:32 -07:00
Tim Van Baak d17d624d98 unfolder: upgrade to 24.05 2024-06-24 19:12:24 -07:00
Tim Van Baak 6e614e70ee catacomb: add nofail test mount
this is just here so I know it works for when I use it on backyard
2024-06-24 23:03:03 +00:00
Tim Van Baak 8cbbcf70fd imperium: add ffmpeg 2024-06-19 15:24:35 -07:00
Tim Van Baak 4ea90b228e beatific: Add git aliases 2024-06-19 15:24:35 -07:00
Tim Van Baak 35e4366df9 imperium: add yt-dlp wrapper 2024-06-19 15:24:35 -07:00
Tim Van Baak 5045e27ad8 beatific: add pdf tools 2024-06-19 15:24:35 -07:00
Tim Van Baak a0b30d6ceb backyard: temporary settings for pool setup 2024-06-11 05:33:11 +00:00
Tim Van Baak 15573cbfc4 centroid: upgrade to 24.05 2024-06-01 19:27:17 +00:00
Tim Van Baak 6078624d88 beatific: wrap ebook-convert
I don't want calibre installed, it keeps setting itself as the default app for things, I just want to convert ebook formats
2024-05-26 20:51:38 -07:00
Jaculabilis 4acd2bfb63 empyrean: update intake 2024-05-15 04:56:44 +00:00
Jaculabilis 545b5f327c empyrean: disable gitea dump 2024-05-15 04:55:51 +00:00
Tim Van Baak d2047ba06c backyard: allow jellyfin to read tvb pool 2024-05-10 14:27:12 +00:00
Tim Van Baak 6b6ca51424 backyard: fix catacomb server file serving 2024-05-10 14:26:46 +00:00
Tim Van Baak 96259b6714 backyard: add yt-dlp wrapper script 2024-05-10 14:26:09 +00:00
Tim Van Baak 0882bc1b26 beatific: add missing horses 2024-04-30 12:03:37 -07:00
Tim Van Baak 3033792bac beatific: add ascii for centroid and imperium 2024-04-30 11:51:42 -07:00
Tim Van Baak d44decdf69 backyard: enable syncthing 2024-04-30 04:52:24 +00:00
Tim Van Baak 8d9201721f catacomb: disable syncthing 2024-04-30 04:51:26 +00:00
Tim Van Baak 8e877cc205 catacomb: switch zfs mountpoint type 2024-04-30 04:51:00 +00:00
Tim Van Baak de1e6be027 centroid: update jellyfin hostname 2024-04-29 14:45:52 +00:00
Tim Van Baak edf83ac18b centroid: add mopidy-bandcamp 2024-04-29 14:45:08 +00:00
Tim Van Baak d187aaba79 backyard: throw up the catacomb host index server 2024-04-29 05:32:20 +00:00
Tim Van Baak edddf6e610 backyard: serve entire tvb pool over vpn 2024-04-29 05:32:20 +00:00
Jaculabilis 3553afc8d8 catacomb: remove mirror 2024-04-27 14:32:12 +00:00
Jaculabilis 4624a26e1b empyrean: move mirror.alogo from catacomb to backyard 2024-04-27 14:31:31 +00:00
Tim Van Baak 47b79c36cc imperium: cifs mount backyard/tvb 2024-04-26 22:45:32 -07:00
Tim Van Baak 21192f1b5a backyard: make pool servable and add mirror vhost 2024-04-27 05:44:44 +00:00
Tim Van Baak 7fabf0b9a1 backyard: add pv 2024-04-24 06:22:32 +00:00
Tim Van Baak 97a643945d backyard: import pool on boot 2024-04-24 04:32:35 +00:00
Tim Van Baak 66fb553ab7 backyard: add user katydid 2024-04-24 04:32:01 +00:00
Tim Van Baak 94271348b5 backyard: enable zfs autoscrub 2024-04-23 20:43:59 +00:00
Tim Van Baak 475c0b3543 backyard: add ffmpeg and smartmontools 2024-04-23 20:41:25 +00:00
Tim Van Baak aa7719ed71 unfolder: add backyard cifs mount 2024-04-22 22:22:03 -07:00
Tim Van Baak 8ae7776ada beatific: add bat and viu 2024-04-16 20:55:00 +00:00
Tim Van Baak 13eac55616 catacomb: add ffmpeg 2024-04-16 20:53:06 +00:00
Tim Van Baak 652d8d0805 beatific: fix prompt path shortening 2024-04-16 15:39:26 +00:00
Tim Van Baak bf5170c67f backyard: enable zfs 2024-04-16 03:02:23 +00:00
Tim Van Baak 263d8ac788 backyard: add home samba share 2024-04-16 02:28:04 +00:00
Tim Van Baak 5a2c7aa559 backyard: update jellyfin vhost 2024-04-16 01:53:55 +00:00
Tim Van Baak dbc53ec73f backyard: put backyard on imperium's hardware 2024-04-16 01:53:55 +00:00
Tim Van Baak 85a567a705 imperium: put imperium on backyard's hardware 2024-04-15 18:53:18 -07:00
Tim Van Baak c2a45ec1bb imperium: Comic Momo and Gnome Terminal 2024-04-09 20:29:34 -07:00
Tim Van Baak e550e73d5d beatific: add exiftool to default programs 2024-03-13 09:49:03 -07:00
Tim Van Baak d6da7b5306 beatific: add VPN hosts for home services 2024-02-22 15:04:34 -08:00
Tim Van Baak e8239a9960 centroid: open mopidy to beatific 2024-02-22 23:03:23 +00:00
Tim Van Baak 5680da15c0 centroid: enable Nebula 2024-02-22 22:55:24 +00:00
Jaculabilis 17a863831e empyrean: add vhosts for home service stubs 2024-02-22 22:37:50 +00:00
Tim Van Baak 8841ab5c5a unfolder: add comic-mono and gnome-terminal 2024-02-22 13:44:48 -08:00
Tim Van Baak 7e983774cd imperium: follow unfolder's printing config 2024-02-19 07:29:38 -08:00
Jaculabilis 0543198e6b empyrean: enable automatic gitea archive cleanup
The backup dumps are reaching GB size, pretty sure there's not a GB of git data
2024-02-12 15:53:53 +00:00
Tim Van Baak cd76ffcd5a unfolder: enable printing and avahi 2024-02-06 08:22:36 -08:00
Tim Van Baak 982ec72e6b syncthings: init from nixpkgs 2024-02-06 08:22:36 -08:00
Jaculabilis fbf96fd83a beatific: highlight hostname of SSH sessions 2024-02-05 18:12:12 +00:00
Jaculabilis c74cb1d16d empyrean: add ecumene static site 2024-02-05 03:49:01 +00:00
Tim Van Baak 981ba9f6a5 beatific: histcontrol ignore both 2024-01-31 17:38:36 -08:00
Tim Van Baak b416859153 beatific: add sqlite to programs 2024-01-31 17:38:36 -08:00
Tim Van Baak 726e0fd9b6 backyard: add jellyfin group to tvb 2024-01-31 00:07:49 +00:00
Tim Van Baak bf4b31f4fc beatific: fix PS1 with spaces 2024-01-31 00:06:09 +00:00
Tim Van Baak 265ed5b9e7 centroid: add mopidy-jellyfin connection 2024-01-30 20:47:30 +00:00
Tim Van Baak 6a9cd5b5d2 Add cd .. aliases 2024-01-27 11:11:12 -08:00
Tim Van Baak d162e2262b beatific: system bashrc 2024-01-27 11:10:46 -08:00
Tim Van Baak 7d927ede86 beatific: alias smv 2024-01-26 13:43:18 -08:00
Tim Van Baak 8043cd2a93 beatific: alias xo=xdg-open 2024-01-26 10:00:51 -08:00
Tim Van Baak 1956c75a61 centroid: add lan revproxy 2024-01-20 04:51:10 +00:00
Tim Van Baak 89e1752d0e centroid: Add mopidy-youtube with yt-dlp stitched in 2024-01-20 04:04:59 +00:00
Tim Van Baak 612fcb7dce centroid: Set up mopidy 2024-01-20 03:46:41 +00:00
Tim Van Baak 75a6b01fc6 beatific: nixos-rebuild --fast 2024-01-19 04:36:58 +00:00
Tim Van Baak 46c862085f centroid: get pipewire sound working 2024-01-19 04:36:37 +00:00
Tim Van Baak af0918603d centroid: pin nixpkgs 2024-01-19 01:34:08 +00:00
Tim Van Baak d8628b33cc centroid: enable networkmanager 2024-01-19 01:21:34 +00:00
Tim Van Baak d4a34ffe19 Regenerate hardware-configuration.nix from nixos-generate-config 2024-01-19 00:51:37 +00:00
Tim Van Baak a13d098d4e centroid: remove root ssh key 2024-01-19 00:26:45 +00:00
Tim Van Baak 5afdd69a2f centroid: enable time, i18n, programs, ssh, hosts 2024-01-19 00:08:24 +00:00
Tim Van Baak 6f3c75e53c beatific: add centroid key 2024-01-18 23:53:57 +00:00
Tim Van Baak 22ec014c38 centroid: remove some unneeded options 2024-01-18 23:20:49 +00:00
Tim Van Baak 87da6efaed centroid: enable beatific module 2024-01-18 23:10:24 +00:00
Tim Van Baak 1c8603fd8e centroid: clean up after nixos-infect a bit 2024-01-18 23:03:00 +00:00
Tim Van Baak 969cc2ecec centroid: init via nixos-infect 2024-01-18 22:55:55 +00:00
Tim Van Baak 51f72d2d55 beatific: add an xclip copy script 2024-01-17 15:05:12 -08:00
Tim Van Baak c86cf48127 unfolder: extra programs 2024-01-17 14:57:41 -08:00
Tim Van Baak 9befa8bb16 beatific: add puddletag to extra programs 2024-01-17 14:57:27 -08:00
Jaculabilis 8335a93596 empyrean: revproxy mirror to catacomb
Keeping a full local copy of the mirror is unsustainable without expanding empyrean's relatively small storage
2024-01-17 12:32:45 +00:00
Tim Van Baak 471930cb64 catacomb: add port for mirror vhost 2024-01-17 12:13:15 +00:00
Jaculabilis a5b364fbc1 empyrean: remove newtab vhost
This doesn't appear to be used. I think the intake configuration overwrote it.
2024-01-12 18:51:42 +00:00
Tim Van Baak 12117f37bb unfolder: add obsidian 2024-01-12 10:45:58 -08:00
Jaculabilis 46c6157fab empyrean: fix HTTPS for nonexistent subdomains
nginx always chooses a server block for a connection and the listen parameters are checked before server name. This meant that HTTPS connections missed the default 444 server block because it only matched HTTP. With this, those requests now get an SSL error.
2024-01-12 18:21:52 +00:00
Jaculabilis c9242c0bea empyrean: fix cron job 2024-01-08 23:11:30 +00:00
Tim Van Baak 84fa63493f catacomb: serve mirror directly 2024-01-08 20:11:19 +00:00
Jaculabilis 44583f670f empyrean: cron job to move files from phone to NAS 2024-01-05 01:22:43 +00:00
Jaculabilis ba3c46b8f4 beatific: alias cp to -rp 2024-01-04 20:55:43 +00:00
Jaculabilis fa46c83f46 empyrean: Enable syncthing 2024-01-04 20:55:12 +00:00
Tim Van Baak 48f36f5d9e catacomb: enable syncthing 2024-01-04 19:57:13 +00:00
Tim Van Baak 17b87e606c catacomb: comment on networking.hostId 2024-01-04 19:57:13 +00:00
Tim Van Baak b4a32f04b5 catacomb: reorganize and pare down packages 2024-01-04 19:57:13 +00:00
Tim Van Baak e71acea928 beatific: Force syncthing config and database to .config 2024-01-04 19:57:08 +00:00
Tim Van Baak d47d87d91f beatific: Pin registry nixpkgs to flake input 2024-01-04 19:57:01 +00:00
Tim Van Baak 0fce9564f5 beatific: Add beatific.extraPrograms
This is partly a way to keep notes on useful software that I might otherwise forget about
2024-01-04 19:56:53 +00:00
Tim Van Baak 96d6e73346 beatific: add jq and htmlq 2023-12-29 16:28:49 -08:00
Tim Van Baak f8e09d26d1 beatific: enable default programs 2023-12-27 05:17:57 +00:00
Tim Van Baak 3a954c35c1 beatific: add more default programs 2023-12-27 05:17:45 +00:00
Tim Van Baak a8730b3a13 catacomb: workaround for a rare ZFS bug
This can be removed if a recent 23.11 is taken or 24.05
2023-12-27 05:01:34 +00:00
Tim Van Baak 5b752f7cfa beatific: add vagrant pubkey 2023-12-24 16:03:54 +00:00
Tim Van Baak 40087d26be beatific: set git default branch 2023-12-23 13:15:42 -08:00
Tim Van Baak c9f65b73d7 unfolder: enable tvb-syncthing 2023-12-23 13:02:08 -08:00
Tim Van Baak 6b5dcb6e1d beatific: refactor tvb-syncthing to module 2023-12-23 13:01:26 -08:00
Tim Van Baak e381001f0a beatific: add imperium host entry 2023-12-22 22:07:21 -08:00
Tim Van Baak 741a0bc340 imperium: add obsidian 2023-12-22 22:06:57 -08:00
Tim Van Baak 49d864839a imperium: syncthing system service 2023-12-19 20:06:54 -08:00
Tim Van Baak 532e7a5c6b beatific: allow `sudo nixos-rebuild` without password for tvb 2023-12-19 19:33:47 -08:00
Tim Van Baak 7afcfbac2b beatific: alias nixos-rebuild to nr 2023-12-18 12:39:12 -08:00
Tim Van Baak c0cbd43411 imperium: enable printing 2023-12-18 12:38:47 -08:00
Tim Van Baak 4676c9e91d imperium: Get TF2 working
Requires launch option: LD_PRELOAD=$LD_PRELOAD:/run/current-system/sw/lib/libtcmalloc_minimal.so %command%

DRG also runs through Proton but at a prohibitive framerate whenever things are onscreen
2023-12-16 11:41:49 -08:00
Jaculabilis 05357d5423 beatific: allow imperium access 2023-12-15 21:41:39 +00:00
Tim Van Baak 6804636ce5 imperium: initialize config 2023-12-15 13:18:40 -08:00
Tim Van Baak 267b3d3898 imperium: add SSH key 2023-12-15 12:53:07 -08:00
Tim Van Baak 9d2ac1f8ec backyard: Upgrade to 23.11 2023-12-15 20:52:12 +00:00
Tim Van Baak ed5fee36ed beatific: Add 23.11 input 2023-12-15 20:52:12 +00:00
Tim Van Baak bdffba6351 stagirite: Move to 23.05
stagirite's hard drive died so if it comes back it might as well be current
2023-12-15 20:52:12 +00:00
Jaculabilis 9d964dd7f7 empyrean: remove defunct redstring 2023-12-14 16:08:16 +00:00
Jaculabilis 43a14b2bec empyrean: update intake-sources 2023-12-14 16:07:04 +00:00
Tim Van Baak 311aba7975 beatific: Add bc 2023-12-08 20:44:35 -08:00
Tim Van Baak 4d5227f51b beatific: add killall 2023-12-08 20:43:34 -08:00
Tim Van Baak 14842e99a1 catacomb: add tree and exiftool 2023-11-28 16:02:51 +00:00
Tim Van Baak eeb694b08c Fix yt-dlp argument quoting 2023-11-22 19:05:15 +00:00
Tim Van Baak d553d80270 unfolder: remove chrome from system packages 2023-10-28 06:13:50 -07:00
Tim Van Baak 23e9af7564 backyard: Enable Jellyfin server 2023-10-22 20:56:06 +00:00
Tim Van Baak 721e5a3ca1 beatific: Add DNS host entries 2023-10-22 20:52:10 +00:00
Tim Van Baak 33b50d12d9 catacomb: Update catacomb-server for .m4a 2023-10-20 04:20:36 +00:00
Tim Van Baak a0979abb57 catacomb: Add an updatable yt-dlp 2023-10-20 04:20:36 +00:00
Tim Van Baak 298b91f83f catacomb: Fix ssh setting path 2023-10-20 04:20:36 +00:00
Tim Van Baak 0b5ac640b8 backyard: resurrect backyard 2023-10-19 20:31:12 -07:00
Jaculabilis 1e740188e6 empyrean: update intake 2023-10-10 02:32:12 +00:00
Jaculabilis f2feb22a86 beatific: Link /etc/nixos to the current config 2023-09-28 14:37:15 +00:00
Jaculabilis ba9bfa01f3 beatific: Use programs.<prog> where available
Based on the option source, this doesn't actually change anything, but it seems like good practice in case it becomes necessary for another program or a future version of these.
2023-09-28 14:30:33 +00:00
Jaculabilis 092250889a empyrean: Move www static files for new static site 2023-09-28 14:25:11 +00:00
Tim Van Baak 0fc5aaa8c0 unfolder: promote duf, file, and tree to defaults 2023-09-13 13:32:28 -07:00
Jaculabilis 8a3e01091c empyrean: Update intake-sources 2023-09-04 20:56:14 +00:00
Tim Van Baak a6b52340af unfolder: add syncthing 2023-08-13 16:20:29 -07:00
Tim Van Baak 57dcaf1f07 catacomb: update to 23.05 2023-08-12 04:53:07 +00:00
Tim Van Baak 06b632ec68 catacomb: regenerate hardware config 2023-08-12 02:55:59 +00:00
Jaculabilis 820417819f Replace inquisitor with intake 2023-08-08 15:47:09 +00:00
Tim Van Baak f5faefb5e5 Add empyrean ascii banner 2023-08-03 22:54:44 -07:00
Jaculabilis 72c5619671 Add unfolder ascii banner 2023-08-03 22:43:03 -07:00
Tim Van Baak ce4a568809 Add some host-specific ascii banners 2023-08-04 05:32:29 +00:00
Jaculabilis de253930e3 Remove previous beatific config 2023-08-03 21:54:49 -07:00
Jaculabilis 6215ce2961 Add unfolder machine configs 2023-08-03 21:52:49 -07:00
Jaculabilis 637fea3bbd Add gitea group to tvb 2023-08-03 22:18:06 +00:00
Jaculabilis c13fabbdbc Enable beatific.isLighthouse and defaults.nebula 2023-08-02 18:11:53 +00:00
Jaculabilis 43c19146a9 Enable defaults.tvb 2023-08-02 17:59:22 +00:00
Jaculabilis 071cb4774d Enable defaults.ssh 2023-08-02 17:55:21 +00:00
Jaculabilis 8ef887a4f0 Enable defaults.{time,i18n} 2023-08-02 17:46:48 +00:00
Jaculabilis c431fb3ca5 Add beatific module to empyrean 2023-08-02 17:45:22 +00:00
Jaculabilis a718222744 Update intake-sources 2023-08-02 17:35:29 +00:00
Tim Van Baak 0b8ef01e5e Add backyard pubkey 2023-08-02 17:30:48 +00:00
Tim Van Baak 5470f2672d Enable defaults.nebula 2023-08-02 17:27:42 +00:00
Tim Van Baak 504d1a4283 Enable defaults.tvb 2023-08-02 17:19:54 +00:00
Tim Van Baak a4089b030f Enable defaults.ssh, leave defaults.programs 2023-08-02 17:12:05 +00:00
Tim Van Baak 83cbd95c95 Enable defaults.i18n 2023-08-02 17:09:23 +00:00
Tim Van Baak 72720464ec Enable defaults.time 2023-08-02 17:07:00 +00:00
Tim Van Baak 13090dd594 Add beatific module to catacomb 2023-08-02 17:03:35 +00:00
Tim Van Baak bda35d7da4 Remove monitor@isidore key 2023-08-02 16:52:27 +00:00
Tim Van Baak db33f88300 Refactor nebula config out 2023-08-02 16:49:50 +00:00
Tim Van Baak 1d515f416a Connect backyard to nebula@beatific 2023-08-02 16:29:18 +00:00
Tim Van Baak dd265429be Enable firewall 2023-08-02 15:39:25 +00:00
Tim Van Baak 35247f7b4a Add fancy ssh banner 2023-08-02 15:23:52 +00:00
Tim Van Baak b9c6e20ef6 Use mkFlag for other options 2023-08-02 15:19:57 +00:00
Tim Van Baak d87f127954 Add default ssh config 2023-08-02 15:18:26 +00:00
Tim Van Baak ec88265631 Add default installed programs 2023-08-02 02:40:19 +00:00
Tim Van Baak 2a618ce67f Factor out i18n settings 2023-08-02 02:28:32 +00:00
Tim Van Baak 656fdeef49 Add flake enable to module 2023-08-02 02:19:18 +00:00
Tim Van Baak 7feec36673 Factor out time zone and NTP 2023-08-02 02:17:10 +00:00
Tim Van Baak 4e8a2bb7e4 Create a beatific module with options 2023-08-02 01:59:06 +00:00
Tim Van Baak 9948b73eff Move previous module out of the way 2023-08-02 01:51:00 +00:00
Tim Van Baak d63efc38b9 Remove some unused options 2023-08-01 17:31:34 -07:00
Tim Van Baak b216c2acd9 Change time zone to UTC 2023-08-01 17:31:34 -07:00
Tim Van Baak a78c36b871 Regenerate hardware config to pick up swapfile 2023-08-01 17:31:31 -07:00
Tim Van Baak 733679c944 Update backyard hostname 2023-08-01 17:17:02 -07:00
Tim Van Baak 3ba86c1115 Initialize backyard config 2023-08-01 17:13:35 -07:00
Jaculabilis 852304140a Allow unfolder access to empyrean 2023-07-05 12:44:24 +00:00
Jaculabilis c3494644cc Add openssh to intake packages so it can scp 2023-07-05 12:44:09 +00:00
Jaculabilis 041c17bfb3 Update intake to 1.0.4 2023-07-05 12:43:42 +00:00
Jaculabilis 9c990c13a7 Add unfolder pubkey 2023-07-04 22:24:02 -07:00
Jaculabilis 35d9393733 Update empyrean key
I don't know what key that used to be
2023-07-05 04:57:24 +00:00
Jaculabilis d982e1c4cd Allow catacomb access to empyrean 2023-07-05 04:55:15 +00:00
Jaculabilis 79d941b343 Add catacomb pubkey 2023-07-05 04:54:12 +00:00
Jaculabilis c0887179ce Allow access from tvb@empyrean 2023-07-03 14:15:29 +00:00
Jaculabilis ca79e62268 Remove tinc from packages 2023-07-03 14:15:09 +00:00
Jaculabilis 7e43cd2efa Update intake-sources for intake-echo 2023-06-25 04:46:10 +00:00
Jaculabilis ff1ed94c3f Update intake-sources for reddit link fix 2023-06-24 13:54:52 +00:00
Jaculabilis ba5486e372 Update intake for channel markers 2023-06-24 04:02:49 +00:00
Jaculabilis 63c50d5c67 Update intake for crontab support 2023-06-22 01:52:08 +00:00
Jaculabilis 986c2d4674 Update intake for edit fixes 2023-06-21 21:37:53 +00:00
Jaculabilis 6587d70066 Update intake to fix a PATH issue 2023-06-21 04:01:41 +00:00
Jaculabilis f134165737 Add intake-sources 2023-06-20 21:34:14 +00:00
Jaculabilis cd4cf9107c Enable intake for tvb on port 5234 2023-06-20 04:35:45 +00:00
Jaculabilis 4f9b51a94b Add intake to empyrean 2023-06-20 04:35:11 +00:00
Jaculabilis b3a1f104ff Remove gitolite 2023-06-19 23:07:11 +00:00
Jaculabilis f252a38b1b Update empyrean configs to 23.05 2023-06-09 21:27:52 +00:00
Jaculabilis e8a7aae12e Add nixpkgs-next url 2023-06-09 20:42:52 +00:00
Jaculabilis bbe12a24d3 Use a simpler ref for 22.11 2023-06-09 20:29:51 +00:00
Jaculabilis 741d6a7d95 Up Gitea session lifetime to a week 2023-06-09 20:27:03 +00:00
Jaculabilis b807fa6703 Enable SMB shares for user homes 2023-05-03 02:01:01 +00:00
Jaculabilis 3ab66e301f Regenerate hardware config 2023-05-02 02:30:57 +00:00
Jaculabilis c02b728890 Add user katydid 2023-04-29 23:12:58 +00:00
Jaculabilis ac18512e25 Move inquisitor to nebula 2023-04-22 23:19:23 +00:00
Jaculabilis e589b56f1b Update inquisitor 2023-04-22 23:19:23 +00:00
Jaculabilis 9755c7f86d Add newtab vhost 2023-04-22 23:19:23 +00:00
Jaculabilis 08c0e42639 Refactor some network configs into a common module 2023-01-16 17:16:20 +00:00
Jaculabilis d1bd491141 Refactor nginx vhosts and add wedding subdomain 2023-01-10 17:43:25 +00:00
Jaculabilis be2617aaf8 Rearrange nixos configs into one attr 2022-12-29 03:00:48 +00:00
Jaculabilis 115fc4f167 Add mirror.alogoulogoi vhost 2022-12-29 03:00:48 +00:00
Jaculabilis 1a3b50e11d Disable start menu launchers and restore upstream input 2022-12-21 18:19:58 +00:00
Tim Van Baak b6f3abccbe Move nixos-wsl module import to flake def
This avoids having to use specialArgs to pass it down to the configuration file to import there
2022-12-21 18:18:25 +00:00
Jaculabilis af6bb08705 Update nixos-wsl with fix 2022-12-20 01:13:38 +00:00
Jaculabilis 20e269c89d Disable gitea package manager 2022-12-13 22:07:59 +00:00
Jaculabilis b3542abff0 Get inquisitor from git instead of a local checkout again 2022-12-13 01:53:08 +00:00
Jaculabilis 961229b4ed Disable amanuensis and redstring temporarily 2022-12-11 13:07:19 +00:00
Jaculabilis 9f1026a73b Use a local inquisitor checkout temporarily 2022-12-11 13:06:56 +00:00
Jaculabilis 9fcd9bf01d Fix IP for catacomb forward 2022-12-11 13:06:10 +00:00
Jaculabilis 8f030a559b Update empyrean to nixpkgs 22.11 2022-12-11 00:02:38 +00:00
Jaculabilis d385788c25 Pass pkgs to inquisitor package build 2022-12-02 04:45:34 +00:00
Jaculabilis 083b85ea2c Update to tagged 22.11 2022-12-01 06:20:33 +00:00
Jaculabilis beb7245758 Add stagirite WSL configs 2022-11-28 19:12:51 +00:00
Jaculabilis 4630c8add7 Manage ssh keys in config 2022-11-27 02:51:05 +00:00
Jaculabilis d352e14cd0 Update README 2022-11-27 02:43:35 +00:00
Jaculabilis 5f9b5516b7 Fix empyrean flake build by using 21.11 nixpkgs 2022-11-27 02:35:38 +00:00
Jaculabilis 087b592239 Integrate empyrean configs into flake config 2022-11-27 01:56:48 +00:00
40 changed files with 2335 additions and 793 deletions

View File

@ -1,4 +1,2 @@
# nixos-configs # nixos-configs
Individual machine configs are branched off of `master`.

View File

@ -1,178 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
./amanuensis.nix
./redstring.nix
./catacomb.nix
./gitea.nix
./inquisitor.nix
];
# Use the GRUB 2 boot loader.
boot.loader.grub = {
enable = true;
version = 2;
device = "/dev/xvda";
extraConfig = "serial --unit=0 --speed=115200 ; terminal_input serial console ; terminal_output serial console";
};
boot.kernelParams = ["console=ttyS0"];
nix = {
package = pkgs.nixFlakes;
maxJobs = 2;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
swapDevices = [ { device = "/swap"; size = 1024; } ];
networking.hostName = "empyrean";
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true;
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "us";
};
# Set your time zone.
time.timeZone = "UTC";
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
vim htop git tinc_pre python3
gitea
];
environment.variables.EDITOR = "vim";
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
# Static pages
"www.ktvb.site" = {
enableACME = true;
forceSSL = true;
root = "/srv/wedding/";
extraConfig = ''
access_log /var/log/nginx/access.ktvb.log;
index index.html;
'';
};
"www.alogoulogoi.com" = {
enableACME = true;
forceSSL = true;
root = "/srv/www/";
extraConfig = ''
access_log /var/log/nginx/access.www.log;
index index.html;
'';
};
# Deny all other subdomains
"alogoulogoi.com" = {
default = true;
locations."/".return = "444";
};
};
};
security.acme = {
email = "tim.vanbaak+alogoulogoi@gmail.com";
acceptTerms = true;
};
services.gitolite = {
enable = true;
adminPubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDkSvOcY0eFuYqewc73MNHGP/Owzfnt+BZDSOCwr4h+gJenOBmXol695sRKdIw8phgshb6LsNyWeEAr3YISwzjdOvWNKpSsdyH/79VFIffC+/RBhPFhIPHn1zpHIwgthXji8FMmnO6B1bhJvbJxD5bUqhdBLnUeMhNgUkDj4Qi42S8yK1VZkgWRuPOTGqlzkODEdzG6OST7ndL58jEQaK8R2KRC2cZfrjingmPL+ORyf1/lGwyF6MEAmbQuE6UdspMs8FWt2e8jQJS+ZQ8dl+NDFrC1QfPRFpBJWnQceBcfAVZTtDaJpRhc4ClZstBy/bVRjiKeQiNv5NasjKRvvIvot4+LXmBKrXJs81enExtMSHMPuqPRlyVZLMMCVmdLDP/HUYOASDzlUhV/v5Wp0jjY4Wy0IWC7nm7P8EKsp1ZofwU6rJ9XPLpQJt7UUURX71h1FMaqi+lylW6xkD3LqD8oT5Bdp+Vs0bUbPQVRw1Fenjc6G1URU94GOAggyNgsWms= root@empyrean";
};
services.ntp = {
enable = true;
servers = ["time.nist.gov"];
};
services.openssh = {
enable = true;
passwordAuthentication = false;
permitRootLogin = "prohibit-password";
};
services.tinc.networks.beatific = {
listenAddress = "0.0.0.0";
chroot = false;
};
services.nebula.networks.beatific = {
enable = true;
# Network certificate and host credentials
ca = "/etc/nebula/beatific/beatific.crt";
cert = "/etc/nebula/beatific/empyrean.crt";
key = "/etc/nebula/beatific/empyrean.key";
# This host has a well-known IP at its VPS host, so it can function as a lighthouse/entry node
isLighthouse = true;
# Listen to connection requests from the public Internet
listen.port = 4242;
listen.host = "vpn.alogoulogoi.com";
# Don't filter anything at the VPN level
firewall.outbound = [ { port = "any"; proto = "any"; host = "any"; } ];
firewall.inbound = [ { port = "any"; proto = "any"; host = "any"; } ];
settings = {
# Enable UDP holepunching both ways, which allows nodes to establish more direct connections with each other
punchy = { punch = true; response = true; };
};
};
networking.firewall = {
enable = true;
allowPing = true;
allowedTCPPorts = [
22 # ssh
80 # http
443 # https
655 # tinc
];
allowedUDPPorts = [
655 # tinc
];
};
users.users.tvb = {
isNormalUser = true;
group = "tvb";
extraGroups = [ "wheel" ]; # Enable sudo for the user.
};
users.groups.tvb = {};
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "20.03"; # Did you read the comment?
}

View File

@ -1,24 +1,142 @@
{ {
"nodes": { "nodes": {
"nixpkgs": { "flake-compat": {
"flake": false,
"locked": { "locked": {
"lastModified": 1669052418, "lastModified": 1673956053,
"narHash": "sha256-M1I4BKXBQm2gey1tScemEh5TpHHE3gKptL7BpWUvL8s=", "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"intake": {
"inputs": {
"flake-compat": [
"flake-compat"
],
"nixos-shell": "nixos-shell",
"nixpkgs": [
"nixpkgs-2405"
]
},
"locked": {
"lastModified": 1719590135,
"narHash": "sha256-zwg59WLPab5WFvpXGeo3qxYJd0eUjQRzz09643L4SEo=",
"ref": "refs/heads/master",
"rev": "40464e907809b17285dbf6309a90d6b27d91853b",
"revCount": 85,
"type": "git",
"url": "ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake.git"
},
"original": {
"type": "git",
"url": "ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake.git"
}
},
"intake-sources": {
"inputs": {
"nixpkgs": [
"nixpkgs-2405"
]
},
"locked": {
"lastModified": 1719589502,
"narHash": "sha256-jdG/Z4Rctp2uqjcHkAN0l1423yPwRxAGLfAJsw+EF+I=",
"ref": "refs/heads/master",
"rev": "c94a31206c1b07a85bf43493c602c5b42afd27c5",
"revCount": 28,
"type": "git",
"url": "ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake-sources.git"
},
"original": {
"type": "git",
"url": "ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake-sources.git"
}
},
"nixos-shell": {
"inputs": {
"nixpkgs": [
"intake",
"nixpkgs"
]
},
"locked": {
"lastModified": 1686216465,
"narHash": "sha256-0A4K6xVIyxUi2YZu4+156WwzAO1GDWGcKiMvsXpBQDQ=",
"owner": "Mic92",
"repo": "nixos-shell",
"rev": "65489e7eeef8eeea43e1e4218ad1b99d58852c7c",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "nixos-shell",
"type": "github"
}
},
"nixpkgs-2311": {
"locked": {
"lastModified": 1701282334,
"narHash": "sha256-MxCVrXY6v4QmfTwIysjjaX0XUhqBbxTWWB4HXtDYsdk=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "20fc948445a6c22d4e8d5178e9a6bc6e1f5417c8", "rev": "057f9aecfb71c4437d2b27d3323df7f93c010b7e",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-2405": {
"locked": {
"lastModified": 1719838683,
"narHash": "sha256-Zw9rQjHz1ilNIimEXFeVa1ERNRBF8DoXDhLAZq5B4pE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d032c1a6dfad4eedec7e35e91986becc699d7d69",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1723362943,
"narHash": "sha256-dFZRVSgmJkyM0bkPpaYRtG/kRMRTorUIDj8BxoOt1T4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a58bc8ad779655e790115244571758e8de055e3d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "20fc948445a6c22d4e8d5178e9a6bc6e1f5417c8",
"type": "github" "type": "github"
} }
}, },
"root": { "root": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs" "flake-compat": "flake-compat",
"intake": "intake",
"intake-sources": "intake-sources",
"nixpkgs-2311": "nixpkgs-2311",
"nixpkgs-2405": "nixpkgs-2405",
"nixpkgs-unstable": "nixpkgs-unstable"
} }
} }
}, },

View File

@ -1,12 +1,97 @@
{ {
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs?rev=20fc948445a6c22d4e8d5178e9a6bc6e1f5417c8"; nixpkgs-2311.url = "github:NixOS/nixpkgs/23.11";
nixpkgs-2405.url = "github:NixOS/nixpkgs/nixos-24.05";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
intake = {
url = "git+ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake.git";
inputs.nixpkgs.follows = "nixpkgs-2405";
inputs.flake-compat.follows = "flake-compat";
};
intake-sources = {
url = "git+ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake-sources.git";
inputs.nixpkgs.follows = "nixpkgs-2405";
};
}; };
outputs = { self, nixpkgs }: { outputs = {
nixosConfigurations.catacomb = nixpkgs.lib.nixosSystem { self,
system = "aarch64-linux"; nixpkgs-2311,
modules = [ ./machine/catacomb ]; nixpkgs-2405,
nixpkgs-unstable,
flake-compat,
intake,
intake-sources,
}@inputs: {
nixosModules = {
beatific = import ./modules/beatific.nix;
tf2-gperftools = ({ ... }: {
environment.systemPackages = [ nixpkgs-2405.legacyPackages."i686-linux".gperftools ];
});
unstable-vscode = ({ ... }: let
pkgs = import nixpkgs-unstable { system = "x86_64-linux"; config.allowUnfree = true; };
in {
virtualisation.docker.enable = true;
environment.systemPackages = [
pkgs.distrobox
pkgs.vscode
pkgs.icu
];
});
};
nixosConfigurations = {
backyard = nixpkgs-2405.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
./machine/backyard
];
};
catacomb = nixpkgs-2405.lib.nixosSystem {
system = "aarch64-linux";
modules = [
self.nixosModules.beatific
./machine/catacomb
];
};
centroid = nixpkgs-2405.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
./machine/centroid
];
};
empyrean = nixpkgs-2405.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
intake.nixosModules.default
intake-sources.nixosModules.default
./machine/empyrean
];
};
imperium = nixpkgs-2405.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
self.nixosModules.tf2-gperftools
self.nixosModules.unstable-vscode
./machine/imperium
];
};
unfolder = nixpkgs-2405.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
self.nixosModules.unstable-vscode
./machine/unfolder
];
};
}; };
}; };
} }

View File

@ -1,138 +0,0 @@
{pkgs, ...}:
let
# Import the inquisitor package and build it
inquisitorSource = pkgs.fetchFromGitHub {
owner = "Jaculabilis";
repo = "Inquisitor";
rev = "a6d961aba948d3a682dbde12dbaa8805eadbbd84";
sha256 = "10n6c5zvi27f92b7am0rrdizxz0mlp3rw1y1jyd44b57ykk7x6fr";
};
inquisitor = pkgs.callPackage inquisitorSource {};
# Define the inquisitor data directory
inquisiDir = "/var/lib/inquisitor";
# Define an scp helper for executing in cron jobs
scp-helper = pkgs.writeShellScriptBin "scp-helper" ''
${pkgs.openssh}/bin/scp -i ${inquisiDir}/inquisitor.key -oStrictHostKeyChecking=no "$@"
'';
# Define the inquisitor service user
inquisitorUser = {
name = "inquisitor";
group = "inquisitor";
description = "Inquisitor service user";
isSystemUser = true;
shell = pkgs.bashInteractive;
packages = [ inquisitor pkgs.cron ];
};
# Create the inquisitor config file in the nix store, pointing to /var/lib/
inquisitorConfig = pkgs.writeTextFile {
name = "inquisitor.conf";
text = ''
DataPath = ${inquisiDir}/data/
SourcePath = ${inquisiDir}/sources/
CachePath = ${inquisiDir}/cache/
Verbose = false
LogFile = ${inquisiDir}/inquisitor.log
'';
};
# Create a setup script to ensure the service directory state
inquisitorSetup = pkgs.writeShellScriptBin "inquisitor-setup.sh" ''
# Ensure the service directory and the default source directory
${pkgs.coreutils}/bin/mkdir -p ${inquisiDir}/data/inquisitor/
${pkgs.coreutils}/bin/mkdir -p ${inquisiDir}/sources/
${pkgs.coreutils}/bin/mkdir -p ${inquisiDir}/cache/
if [ ! -f ${inquisiDir}/data/inquisitor/state ]; then
${pkgs.coreutils}/bin/echo "{}" > ${inquisiDir}/data/inquisitor/state
fi
# Ensure the service owns the folders
chown -R ${inquisitorUser.name} ${inquisiDir}
# Ensure the scp helper is present
if [ -f ${inquisiDir}/scp-helper ]; then
rm ${inquisiDir}/scp-helper
fi
ln -s -t ${inquisiDir} ${scp-helper}/bin/scp-helper
'';
# Create a run script for the server
inquisitorRun = pkgs.writeShellScriptBin "inquisitor-run.sh" ''
cd ${inquisiDir}
${inquisitor}/bin/gunicorn \
--bind=localhost:24133 \
--workers=4 \
--timeout 120 \
--log-level debug \
"inquisitor.app:wsgi()"
'';
# Create a wrapper to execute the cli as the service user
inquisitorWrapper = pkgs.writeShellScriptBin "inq" ''
sudo --user=inquisitor ${inquisitor}/bin/inquisitor "$@"
'';
in
{
users.users.inquisitor = inquisitorUser;
users.groups.inquisitor = {};
# Link the config in /etc to avoid envvar shenanigans
environment.etc."inquisitor.conf".source = "${inquisitorConfig}";
# Give all users the inq wrapper
environment.systemPackages = [ inquisitorWrapper ];
# Allow the sudo in the cli wrapper without password
security.sudo.extraRules = [{
commands = [{
command = "${inquisitor}/bin/inquisitor";
options = [ "NOPASSWD" ];
}];
runAs = "${inquisitorUser.name}";
groups = [ "users" ];
}];
# Run the setup script on activation
system.activationScripts.inquisitorSetup = "${inquisitorSetup}/bin/inquisitor-setup.sh";
# Set up the inquisitor service
systemd.services.inquisitor =
{
description = "Inquisitor server";
script = "${inquisitorRun}/bin/inquisitor-run.sh";
serviceConfig = {
User = "${inquisitorUser.name}";
Type = "simple";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
enable = true;
};
# Set up nginx to reverse proxy from the beatific url to the inq server
services.nginx.enable = true;
services.nginx.virtualHosts.inquisitorHost = {
listen = [ { addr = "10.7.3.1"; port = 80; } ];
locations."/".extraConfig = ''
access_log /var/log/nginx/access.inquisitor.log;
proxy_buffering off;
proxy_pass http://localhost:24133/;
'';
};
# Allow nginx through the firewall
networking.firewall = {
allowedTCPPorts = [
80 # http
443 # https
];
};
# Enable cron, but don't set up any system cron jobs
# Inquisitor updates will be managed manually
services.cron.enable = true;
}

14
keys/default.nix Normal file
View File

@ -0,0 +1,14 @@
{
tvb = [
./nix-on-droid.vagrant.pub
./tvb.backyard.pub
./tvb.catacomb.pub
./tvb.centroid.pub
./tvb.empyrean.pub
./tvb.imperium.pub
./tvb.palamas.pub
./tvb.stagirite.pub
./tvb.unfolder.pub
./tvb.vagrant.pub
];
}

View File

@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCzx37PqIaJVWdQs5meVgI4Cg1GRGk6srrix0AUvQeaBS9MOVtJLi+HfnNkcW4GPk9qVlz1E7ciQ7YUw+ny7QbHxcbib2Tawwfk3cx9xiNcN6UI9EzF/rTbNB2Cex8A4sEr5UvoE0BjT5yPaXyrjn8vLksGWq4dlZBM3xeJqe3KP+OxPL0vik3SVGOr/6ZQ7H9cwX5+/p6rCWQuVtwZMcaE6QyXYg5J5FQUaIrFvKbOVklJIkQSbXGzIYQO/QlQC0xWGBapJtGQw/lsQ3YqnFSMkkw8qrKbde07rg8p1FSuqTu+a1ePK+/F4klNel174+39YSobY2/6biPP3Uj/Yhorf4Tw141tIT75e3ebtK5faatQmNOyXcA7LULXK7XemJkZy8PmbNNTeBIKyoI6XQdzk95gpb2C4LEJmV040YMgXhOIiKsHQVgss9FuC+oP5jXWU/JuNXBRHa1IpJjcJhIhg7jnh6ZNZHyK0EpeUs3Zp7usv7mz6CGwb04yvTsWOhZRc+6EoHaHyrNvFPfkPeGsZzxhIbprCyDMtKWsI9GCtztcRhQWBgornUVEs5CurLJBbClQTrZLVv2fn9UnXWPYZTLYL7aFwRIGyKr8ZOOMFxbLOGdeFlqc5TGCP416e8PZvhE+BuDmxiKtQJ/dsQFqVzvOZb2WQRsYRPYvvXbvUw== monitor@isidore

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpvV9dKUVBlv5VU3LU0XIGTQK/McPf3H31HHD/vINGG nix-on-droid@vagrant

1
keys/tvb.backyard.pub Normal file
View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYv5vs78+UAeRagopi4BuvmmK1l3zZwQPY3R4rnp7oV tvb@backyard

1
keys/tvb.catacomb.pub Normal file
View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDitOuQeddhGh3Zg/fnawTrIdomMhgR6rJchbfAAEUz7JDWyrwZoU0/kMBcn9qZZBFE0MDeUSbQbF+voA7/dwZKB+3GBOurg75KSxtwDLHw4urC5U9VCZnbOrFnl5K51oopduxE7vqZdtTzJztcDVKwJILSFPS2hDC3Zt7+pnB1z0aMOJIMyqfogSk29dxREHO130tbrRWI6bCrAJKXWMFSEx6N1pGoOvOKZu4YVdiDSqTPdSYW4D4ivC5Wtt74rGz8/su5xvZKHgNf/d/hILlg/zhnGzH5gn8HvN5pqRksh2fiteGxDQoXgaRGEb93RLe6KV7XPy60vmI+uE06lsow0C7hLrSWorhLQOuLG1J5JzzF0SmFRUOYQoc6BbOLLVXVBa1VcmpupHMJiw6ldJv9yD410bXd+IwIDS9IkW1MIfvN5j35AvnaJCEHVUSrkEjgqCpkNxNPl7V3h7YRw6F/AljTvgEER91mPUvwfJrC0sMo/+DWNwIbnK+jjioD2szHXz2EpXlVhkMSwey/rNZffQpzFHWsm3Za/+4KxWBUO/2MRz2x1haDvvD37hN2kC5w0DSC6MsJucDVlyEjgDQkVEBKujkBv4fpYLpN4VoqVDYytpgnRTm0QIb+ISStG19Fq1uj3UtHFyWI5d8P3jiev4DTtqCpQo9NWa4zu/mbCw== tvb@catacomb

1
keys/tvb.centroid.pub Normal file
View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC364peKQVWeqFNzhJJkvHumKerKPkczeX2I/e9FFZyL tvb@centroid

View File

@ -1 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1h/6CedtyFIjFTT7M5e0dEKJkhPbCQ1RLhtj/83H//AK6bzRbWfnKzSH0VXpsHjaU/Ipc1Jl2fQ23r8i/QyKHUKK7xPeGcY5J7oIHVggkEKW2n9R27Ml9BriKxx6ltButnwSOVYk7dyNhz93GYTTEF3ydh4X7HP2Cv7rh5fbca3s69GXRjOVGmIuuVbaJiaMmiWhBI4LYtqwpo1zGXMjfNlXcMFw7VA4EG2UpkJkcWeyN/AI3ZS/YybcTQNCAg+Xnk94CVys/b5wTuGWRplDrRlNR00MUWpr94+u/xk+sC4/6vT7je2W4GjA1jTq4XmewTEV4cxOu+l1jtHZBgvHho5X0fOogdN52MkjuaXzByZB/Br5xTkBRv0tDf5haX4HzuBC29yU9rt62SEQRzvZxObCCGDcIYR/1HTgjDZkRuwgO/1RoRh5SvwbptvPwpBMvx25S//ZJESLO++lqxjgRZSr/05YpZ5diffEIGd1J0Jz0NGv4XBPcMBnSMKFmdwOy+5jnBbW2OjPQaPslXHEKYTfOByzCA8LgppkxvmL08GIjxYfEljioHR5by+Z6SjG1VvifMFA6FN/+DN6ZH0LmeOMa5YM1Zl3bx5RaANpnSNvi6rmxkQa1oMaK0l482FvpVkg6o1h9si/AeNTEbiX9ozHdjekfuzBSk6Jfo6xw+Q== tvb@empyrean ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCuAlVTZ4g7x8Fv3YoHn4KRr5GHfylgJjkC6lujti7Fd3JhZ34OB5L/FuCKLo0rv/1qpIcGHk01FMNT/hDcbyBRPN5QG1s7x39Bt8yBVePoJK0+malGkI90z4zV1b5LEjvRhr7+KuOskt3eVbhKcEXiJpDdqOOgqvppmQZOb6jb03+q01rPLzz0S20jUDLRSdnmlcNDv16lMXTX9zgWDeVIVErTvoLAI8RloqKUgienheLJSS6sdEk4AjL2PKldKE6mIOxZWiYSTS9+2ClqV8u3l1UTZ7+DOw8FWASmMYaaBvJRDEUzDKA/iOAjpfPO7WOn+yjRyiT7IFVFoz2XtXwZD0OEQhbgLZtPlhOHh5wn++YNnvzLYd5cYSWVya0FYzVis24hbaGjrwB5tzD0riL2lRzo3ZjktpL7RlCSLfO/2Cb14hLOxZTZZcgdM6Ef/1YatJiEpRQ7FLP45Di3hKc9QEsqQP1BrhhYQOCWwEHAgVXM8W1ncEBXiCnrelegVy0= tvb@empyrean

1
keys/tvb.imperium.pub Normal file
View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGUvJ7Gd1mN2mF/hy12dizwEw64zn+jT0vFpkhGF07s tvb@imperium

1
keys/tvb.unfolder.pub Normal file
View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCom6c/UrhM6KrzDcm8kJGZJ5ugR4wRfsFUhTJ5F4oLNQcNspvqlUfxT4Hjv4xHA5hCjvPYi7JxVWxBsOEmmIs/LAjFXRNw9Kz8m7TCf/lct+JUpf6eCn6a/orhA0OdUv4c9aiH2Dzp4ob3lR6xYvYUOH3LuffqypSXP0k5zCSetROUgTZibEpa0oE2GevcyjQAExpCjx02ZRIGkGOM20CXtm3EJsTzIs6uk4+2F9hB+HMqePFKCzsgOlFfVCNWiKNywLavXo7Gn0O9pWidufXZ9s8nCBiOEzU1n6T8pNQBat4z7G1uKFKKWNDPL6/HNEmCq0JxUuXSSjg8LIk+uqPH49Ubpf8EORON8z8nVFAAqbuI6rdYc7J9DllQ7hb7EBT9w9w+mcz3XH0BsGzJUOMD9r0P96pWOn+I6A9jPmOqoOZDzGpfYS18+zYWET/ohH4U4pABcW4nwGx0Jz7Fj6iQW3tyjOefuXcz+sJoYKo/9FOh44KYf4pgu3hfoMlGC0M= tvb@unfolder

View File

@ -0,0 +1,124 @@
{ pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./fileserver.nix
./jellyfin.nix
./samba.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# ZFS support
boot.supportedFilesystems = [ "zfs" ];
networking.hostId = "64cc144d";
# https://old.reddit.com/r/zfs/comments/1826lgs/psa_its_not_block_cloning_its_a_data_corruption/
boot.kernelParams = [ "zfs.zfs_dmu_offset_next_sync=0" ];
boot.zfs.extraPools = [ "pool" ];
beatific.hostName = "backyard";
nix.channel.enable = false;
# Enable networking
networking.networkmanager.enable = true;
networking.firewall = {
enable = true;
allowedTCPPorts = [
7474 # mirror revproxy
7475 # http serve tvb pool
7476 # tvb catacomb host server
];
};
services.nginx = {
enable = true;
virtualHosts = {
default = {
default = true;
rejectSSL = true;
locations."/".return = "444";
};
"pool.backyard.home" = {
listen = [
{ addr = "10.22.20.8"; }
# Alternative port to ensure the right vhost connects
{ addr = "10.22.20.8"; port = 7475; }
];
root = "/pool/tvb";
locations."/".extraConfig = ''
autoindex on;
autoindex_exact_size off;
'';
};
"mirror.backyard.home" = {
listen = [
{ addr = "10.22.20.8"; }
# Alternative port to ensure the right vhost connects
{ addr = "10.22.20.8"; port = 7474; }
];
root = "/pool/tvb/doc/website/mirror";
};
"files.backyard.home" = {
listen = [
{ addr = "10.22.20.8"; port = 7476; }
];
locations."/" = {
root = "/pool/tvb";
tryFiles = "\$uri @indexer";
};
locations."@indexer".proxyPass = "http://localhost:5000";
};
};
};
environment.systemPackages = with pkgs; [
pv # zfs send progress meter
smartmontools # provides smartctl drive inspector
];
programs.screen.enable = true;
services.zfs = {
autoScrub = {
enable = true;
pools = [ "pool" ];
interval = "monthly";
};
};
services.cron.enable = true;
users.users = {
tvb = {
extraGroups = [ "networkmanager" ];
packages = [
(pkgs.writeShellScriptBin "yt-dlp" ''exec $HOME/.yt-dlp/bin/yt-dlp "$@"'')
];
};
katydid = {
uid = 1102;
isNormalUser = true;
group = "katydid";
initialPassword = "katydid";
};
};
users.groups = {
katydid.gid = 1102;
tvbpoolro = {
gid = 1201;
members = [ "tvb" "jellyfin" "nginx" ];
};
};
# This value governs how some stateful data, like databases, are handled
# across different versions of NixOS. This should not be changed to a new
# release unless the sysadmin has determined that no services would be
# adversely affected by changing this.
system.stateVersion = "23.05";
}

View File

@ -0,0 +1,47 @@
# nas indexer server module
{ pkgs, ... }:
let
# Build the catacomb server package
catacombServerSource = builtins.fetchGit {
url = "https://git.alogoulogoi.com/Jaculabilis/catacomb-server.git";
ref = "develop-nix";
rev = "3d6fb16948c377f94d030648849f120c8ada3884";
};
catacombServer = pkgs.callPackage catacombServerSource {
pkgs = import (fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/405d762a1a05ffed2ac820eb4bae4bc49bc3abf2.tar.gz";
sha256 = "6c835ea038bdfe170029a8bd4276c9d3a95c275159ec05426672fa8092c7947d";
}) {
system = "x86_64-linux";
};
};
# Host-mode server run script
hostRun = pkgs.writeShellScriptBin "catacomb-run-host.sh" ''
${catacombServer}/bin/gunicorn \
--bind=localhost:5000 \
--workers=3 \
--log-level=debug \
--env CATACOMB_ROOT=/pool/tvb \
--env CATACOMB_MODE=host \
--env CATACOMB_TOKENS=/var/empty \
--env CATACOMB_GUEST_HOST=catacomb.alogoulogoi.com \
"catacomb.server:wsgi()"
'';
in
{
# Set up the host mode service
systemd.services."catacomb-host" = {
enable = true;
description = "catapool host-mode index server";
script = "${hostRun}/bin/catacomb-run-host.sh";
serviceConfig = {
Type = "simple";
User = "nginx";
};
requires = [ "zfs.target" ];
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
};
}

View File

@ -0,0 +1,39 @@
# 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.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/75addc56-2a0d-431e-a0c5-f6ee0e370e61";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/610F-1EB7";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/cc464bb4-e1c8-46c0-adbb-ea1a3cfa5b03"; }
];
# 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.eno1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -0,0 +1,39 @@
{ pkgs, ... }:
{
# Enable jellyfin
services.jellyfin.enable = true;
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
# Create a default vhost to deny traffic, so traffic has to actually match a vhost
default = {
default = true;
locations."/".return = "444";
};
"jellyfin.home.ktvb.site" = {
listen = [
# The router should have a static lease for this IP and a host entry naming it
{ addr = "192.168.1.236"; port = 80; }
# beatific module sends traffic over the vpn
{ addr = "10.22.20.8"; port = 80; }
# Also available on an extra port in case of port 80 troubles
{ addr = "10.22.20.8"; port = 8096; }
];
locations."/".extraConfig = ''
proxy_buffering off;
proxy_pass http://localhost:8096/;
'';
};
};
};
networking.firewall.allowedTCPPorts = [
80 # http
8096 # jellyfin
];
users.users.tvb.extraGroups = [ "jellyfin" ];
}

View File

@ -0,0 +1,67 @@
{ pkgs, lib, ... }:
{
# This is mostly to get smbpasswd
environment.systemPackages = [ pkgs.samba ];
services.samba-wsdd = {
enable = true;
openFirewall = true;
};
services.samba = {
enable = true;
openFirewall = true;
securityType = "user";
extraConfig = ''
workgroup = beatific
server string = backyard smb server
netbios name = backyard
deadtime = 300
local master = yes
domain master = yes
preferred master = yes
guest account = nobody
map to guest = bad user
case sensitive = yes
veto files = /^.DS_Store$/^.Trash-1000$/
load printers = no
printcap name = /dev/null
printing = bsd
log file = /var/log/samba/client-%m.log
log level = 2
max log size = 64
hide dot files = no
hosts allow = 10.22.20., 192.168.1.
map archive = no
# this must be set to false to make symlinks outside /home work
# could potentially be fixed by mounting pool to /home, bind mounting to /pool, and setting both nofail
unix extensions = no
ntlm auth = yes
'';
shares = let
homeShare = user: {
path = "/home/${user}";
comment = "${user}'s home folder";
browseable = "yes";
"read only" = "no";
"guest okay" = "no";
"create mask" = "0640";
"force create mode" = "0640";
"directory mask" = "0750";
"force directory mode" = "0750";
"valid users" = "${user}";
"follow symlinks" = "yes";
"wide links" = "yes";
};
in {
tvb = homeShare "tvb";
};
};
}

View File

@ -1,11 +1,14 @@
{ pkgs, ... }: { pkgs, lib, ... }:
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
./fileserver.nix ./mopidy.nix
]; ];
beatific.hostName = "catacomb";
beatific.defaults.tvbSync = false;
boot = { boot = {
loader = { loader = {
# Use the extlinux boot loader. (NixOS wants to enable GRUB by default) # Use the extlinux boot loader. (NixOS wants to enable GRUB by default)
@ -13,202 +16,83 @@
# Enables the generation of /boot/extlinux/extlinux.conf # Enables the generation of /boot/extlinux/extlinux.conf
generic-extlinux-compatible.enable = true; generic-extlinux-compatible.enable = true;
}; };
supportedFilesystems = ["zfs"];
zfs.enableUnstable = true;
}; };
system.stateVersion = "22.11"; # Read the usual warning system.stateVersion = "22.11"; # Read the usual warning
swapDevices = [ { device = "/swap"; size = 1024; } ]; swapDevices = [ { device = "/swap"; size = 1024; } ];
console.keyMap = "us"; environment.systemPackages = with pkgs; [
i18n.defaultLocale = "en_US.UTF-8"; lsof # list open files
mpv # cli media player
environment.systemPackages = with pkgs; smartmontools # provides smartctl
let usbutils # provides lsusb
py3-packages = python-packages: with python-packages; [
flask
];
py3-with-packages = python3.withPackages py3-packages;
in [
wget vim curl git htop bash tmux psmisc man-pages pv lsof
zip unzip
py3-with-packages
usbutils
hdparm sdparm smartmontools gptfdisk gnufdisk
dosfstools
mkpasswd samba
tinc_pre
#file-rename
rsync
rclone gnupg
]; ];
networking = { networking = {
hostName = "catacomb"; hostId = "beeeeee5"; # this must be consistent for ZFS
hostId = "beeeeee5";
firewall = { firewall = {
enable = true; enable = true;
allowPing = true; allowedTCPPorts = [ 80 139 445 ];
allowedTCPPorts = [ 22 139 445 ];
allowedUDPPorts = [ 137 138 ]; allowedUDPPorts = [ 137 138 ];
}; };
wireless = {
enable = true;
networks."mysterious humming noise".psk = "@MHN_PSK@";
environmentFile = "/root/wifi.env";
};
}; };
services.cron = { services.pipewire = {
enable = true; enable = true;
systemCronJobs = alsa.enable = true;
let alsa.support32Bit = true;
reassertPerms = pkgs.writeShellScript "reassert-nas-permissions.sh" '' pulse.enable = true;
${pkgs.coreutils}/bin/chown -v -R tvb:nas /nas # To avoid needing an active user session, run a single system instance
${pkgs.findutils}/bin/find /nas -type d -exec ${pkgs.coreutils}/bin/chmod -v 750 {} \; systemWide = true;
${pkgs.findutils}/bin/find /nas -type f -exec ${pkgs.coreutils}/bin/chmod -v 640 {} \;
'';
in [
"0 20 * * 1 root ${reassertPerms}"
"0 0 * * 1 tvb . /etc/profile; /home/tvb/gitea-backup"
];
}; };
services.openssh = { services.openssh.settings.PasswordAuthentication = true;
enable = true;
passwordAuthentication = true;
};
services.ntp = {
enable = true;
servers = ["time.nist.gov"];
};
services.rsyncd.enable = true; services.rsyncd.enable = true;
/*services.samba = services.nginx = {
let
sambaShare = path: validUsers: {
path = path;
comment = "Samba share for ${path}";
browseable = "yes";
"read only" = "no";
"guest okay" = "no";
"create mask" = "0640";
"force create mode" = "0640";
"directory mask" = "0750";
"force directory mode" = "0750";
"valid users" = validUsers;
"force group" = ''nas'';
};
sambaShareRO = path: validUsers: {
path = path;
comment = "Read-only Samba share for ${path}";
browseable = "yes";
"read only" = "yes";
"guest okay" = "no";
"valid users" = validUsers;
"force group" = ''nas'';
};
in
{
enable = true;
securityType = "user";
extraConfig = ''
workgroup = beatific
server string = Catacomb Nix SMB
netbios name = catacomb
deadtime = 300
local master = yes
domain master = yes
preferred master = yes
guest account = nobody
map to guest = bad user
case sensitive = yes
veto files = /^.DS_Store$/^.Trash-1000$/
load printers = no
printcap name = /dev/null
printing = bsd
log file = /var/log/samba/client-%m.log
log level = 2
max log size = 64
hide dot files = no
hosts allow = 10.7.3.
map archive = no
unix extensions = yes
ntlm auth = yes
'';
shares = {
audioRO = sambaShareRO "/nas/audio" ''@nas'';
docRO = sambaShareRO "/nas/doc/" ''@nas'';
gameRO = sambaShareRO "/nas/game/" ''@nas'';
imageRO = sambaShareRO "/nas/image" ''@nas'';
videoRO = sambaShareRO "/nas/video" ''@nas'';
#audio = sambaShare "/nas/audio" ''@nas'';
#doc = sambaShare "/nas/doc/" ''@nas'';
#game = sambaShare "/nas/game/" ''@nas'';
#image = sambaShare "/nas/image" ''@nas'';
#video = sambaShare "/nas/video" ''@nas'';
};
};*/
services.nebula.networks.beatific = {
enable = true; enable = true;
recommendedProxySettings = true;
# Network certificate and host credentials virtualHosts = {
ca = "/etc/nebula/beatific/beatific.crt"; default = {
cert = "/etc/nebula/beatific/catacomb.crt"; default = true;
key = "/etc/nebula/beatific/catacomb.key"; locations."/".return = "444";
};
listen.port = 4242; "mopidy.home.ktvb.site" = {
listen = [
# Connect to the lighthouse at empyrean { addr = "10.22.20.2"; }
# Note that this is a VPN address, not a public address { addr = "catacomb.lan"; }
lighthouses = [ "10.22.20.1" ]; ];
locations."/" = {
# Map the lighthouse address to its public address proxyWebsockets = true;
staticHostMap = { "10.22.20.1" = [ "vpn.alogoulogoi.com:4242" ]; }; proxyPass = "https://localhost:6680";
};
# Don't filter anything at the VPN level };
firewall.outbound = [ { port = "any"; proto = "any"; host = "any"; } ];
firewall.inbound = [ { port = "any"; proto = "any"; host = "any"; } ];
settings = {
# Enable UDP holepunching both ways, which allows nodes to establish more direct connections with each other
punchy = { punch = true; response = true; };
}; };
}; };
services.zfs = {
autoScrub = {
enable = true;
pools = ["catapool"];
interval = "monthly";
};
};
users.groups = {
nas = { gid = 1600; };
};
users.users.tvb = { users.users.tvb = {
isNormalUser = true;
uid = 1001; uid = 1001;
password = "badpassword"; extraGroups = [
extraGroups = ["wheel" "nas"]; "pipewire"
openssh.authorizedKeys.keyFiles = [ ];
../../keys/tvb.palamas.pub packages = [
../../keys/tvb.stagirite.pub (pkgs.writeShellScriptBin "yt-dlp" ''
../../keys/tvb.vagrant.pub exec $HOME/.env/bin/yt-dlp "$@"
../../keys/monitor.isidore.pub '')
../../keys/inquisitor.conduit.pub
]; ];
}; };
#./keys/tvb.empyrean.pub
users.users.katydid = {
isNormalUser = true;
uid = 1002;
};
nix.settings.cores = 4; nix.settings.cores = 4;
nix.extraOptions = "experimental-features = nix-command flakes";
} }

View File

@ -1,157 +0,0 @@
# nas indexer server module
{ pkgs, ... }:
let
# Build the catacomb server package
catacombServerSource = builtins.fetchGit {
url = "https://git.alogoulogoi.com/Jaculabilis/catacomb-server.git";
ref = "develop-nix";
rev = "63574bb39cc777deb56a76548f08789d238fcfec";
};
catacombServer = pkgs.callPackage catacombServerSource {};
catacombUser = "tvb";
# Define the service directory, which pretty much only stores tokens
catacombServerDir = "/var/lib/nas-indexer/";
# The address to bind to
bindAddr = "10.22.20.2";
# Create a setup script to ensure the token directory exists
catacombSetup = pkgs.writeShellScriptBin "catacomb-setup.sh" ''
${pkgs.coreutils}/bin/mkdir -p ${catacombServerDir}tokens
chown -R ${catacombUser} ${catacombServerDir}
'';
# Host-mode server run script
hostRun = pkgs.writeShellScriptBin "catacomb-run-host.sh" ''
cd ${catacombServerDir}
${catacombServer}/bin/gunicorn \
--bind=localhost:5000 \
--workers=3 \
--log-level=debug \
--env CATACOMB_ROOT=/nas \
--env CATACOMB_TOKENS=${catacombServerDir}tokens \
--env CATACOMB_MODE=host \
--env CATACOMB_GUEST_HOST=catacomb.alogoulogoi.com \
"catacomb.server:wsgi()"
'';
# Guest-mode server run script
guestRun = pkgs.writeShellScriptBin "catacomb-run-guest.sh" ''
cd ${catacombServerDir}
${catacombServer}/bin/gunicorn \
--bind=localhost:5001 \
--workers=3 \
--log-level=debug \
--env CATACOMB_ROOT=/nas \
--env CATACOMB_TOKENS=${catacombServerDir}tokens \
--env CATACOMB_MODE=guest \
"catacomb.server:wsgi()"
'';
# Guest-mode auth server for direct nginx file serving
accessRun = pkgs.writeShellScriptBin "catacomb-run-access.sh" ''
cd ${catacombServerDir}
${catacombServer}/bin/gunicorn \
--bind=localhost:5002 \
--workers=3 \
--log-level=debug \
--env CATACOMB_TOKENS=${catacombServerDir}tokens \
"catacomb.access.nginx:wsgi()"
'';
in
{
# Run the setup script on activation
system.activationScripts.catacombSetup = "${catacombSetup}/bin/catacomb-setup.sh";
# Set up the host mode service
systemd.services."catacomb-host" = {
enable = true;
description = "catapool host-mode index server";
script = "${hostRun}/bin/catacomb-run-host.sh";
serviceConfig = {
Type = "simple";
WorkingDirectory = "${catacombServerDir}";
};
requires = [ "zfs.target" ];
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
};
# Set up the guest mode service
systemd.services."catacomb-guest" = {
enable = true;
description = "catapool guest-mode index server";
script = "${guestRun}/bin/catacomb-run-guest.sh";
serviceConfig = {
Type = "simple";
User = "${catacombUser}";
WorkingDirectory = "${catacombServerDir}";
};
requires = [ "zfs.target" ];
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
};
# Set up the access server service
systemd.services."catacomb-access" = {
enable = true;
description = "catapool access token authenticator";
script = "${accessRun}/bin/catacomb-run-access.sh";
serviceConfig = {
Type = "simple";
User = "${catacombUser}";
WorkingDirectory = "${catacombServerDir}";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
};
networking.firewall.allowedTCPPorts = [ 80 7470 7471 7472 ];
# Set up nginx to reverse proxy to these services
services.nginx = {
enable = true;
# Serve the host server over the internal ip at the default port
virtualHosts."catacomb-host-server" = {
listen = [ { addr = bindAddr; } ];
root = "/nas";
locations."/".tryFiles = "\$uri @indexer";
locations."@indexer".proxyPass = "http://localhost:5000";
};
# Serve the guest server over the internal ip at a custom port
virtualHosts."catacomb-guest-server" = {
listen = [ { addr = bindAddr; port = 7472; } ];
extraConfig = ''
access_log /var/log/nginx/access.guest-server.log;
'';
locations."/".proxyPass = "http://localhost:5001";
};
# Serve the auth server at a custom port internally
virtualHosts."catacomb-auth" = {
listen = [ { addr = bindAddr; port = 7471; } ];
extraConfig = ''
access_log /var/log/nginx/access.guest-auth.log;
'';
locations."/".proxyPass = "http://localhost:5002";
};
# Serve files at a custom port internally
virtualHosts."catacomb-guest-files" = {
listen = [ { addr = bindAddr; port = 7470; } ];
extraConfig = ''
access_log /var/log/nginx/access.guest-files.log;
'';
locations."/".root = "/nas";
};
};
# Allow nginx to read catapool files
users.users.nginx.extraGroups = ["nas"];
}

View File

@ -18,14 +18,13 @@
fsType = "ext4"; fsType = "ext4";
}; };
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking # 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 # (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 # 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`. # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eth0.useDHCP = lib.mkDefault true; # networking.interfaces.eth0.useDHCP = lib.mkDefault true;
# networking.interfaces.nebula.beatific.useDHCP = lib.mkDefault true;
# networking.interfaces.wlan0.useDHCP = lib.mkDefault true; # networking.interfaces.wlan0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";

View File

@ -0,0 +1,39 @@
{ pkgs, ... }:
{
users.users.tvb.extraGroups = [
"mopidy"
];
users.groups.mopidy = {}; # rw group for media directory
users.users.mopidy.extraGroups = [
"mopidy"
"pipewire" # necessary to allow the system service to play sound
];
services.mopidy = let
mopidyPackages' = pkgs.mopidyPackages.overrideScope (prev: final: { extraPkgs = pkgs: [ pkgs.yt-dlp ]; });
in {
enable = true;
extensionPackages = with mopidyPackages'; [
mopidy-bandcamp
mopidy-jellyfin
mopidy-musicbox-webclient
mopidy-youtube
];
configuration = ''
[file]
media_dirs =
/media/music|Music
[jellyfin]
hostname = jellyfin.home.ktvb.site
username = mopidy
password = mopidy
libraries = Music,Weird Song Halftime
album_format = {Name} ({ProductionYear})
[youtube]
youtube_dl_package = yt_dlp
'';
};
}

View File

@ -0,0 +1,40 @@
{ pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
boot.loader.grub = {
efiSupport = true;
efiInstallAsRemovable = true;
device = "nodev";
};
beatific.hostName = "centroid";
beatific.defaults = {
tvbSync = false;
};
networking.networkmanager.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# To avoid needing an active user session, run a single system instance
systemWide = true;
};
environment.systemPackages = with pkgs; [
mpv # cli media player
];
users.users.tvb.extraGroups = [
"networkmanager"
"pipewire"
];
system.stateVersion = "23.11";
}

View File

@ -0,0 +1,40 @@
# 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.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/a08e9b3c-8ac7-433e-bf2c-6da234a2fb4a";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/5D60-DD0E";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/6dce2950-f8dd-49eb-b4d3-fdcf06cf920b"; }
];
# 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.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp0s20f0u1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -12,18 +12,18 @@
''; '';
locations = { locations = {
# Forwards to the index server # Forwards to the index server
"/browse/".proxyPass = "http://10.7.3.16:7472/browse/"; "/browse/".proxyPass = "http://10.22.20.2:7472/browse/";
# Forwards to nginx via catacomb auth server # Forwards to nginx via catacomb auth server
"/".extraConfig = '' "/".extraConfig = ''
auth_request /auth; auth_request /auth;
proxy_buffering off; proxy_buffering off;
proxy_pass http://10.7.3.16:7470/; proxy_pass http://10.22.20.2:7470/;
''; '';
"= /auth".extraConfig = '' "= /auth".extraConfig = ''
internal; internal;
proxy_buffering off; proxy_buffering off;
proxy_pass_request_body off; proxy_pass_request_body off;
proxy_pass http://10.7.3.16:7471/; proxy_pass http://10.22.20.2:7471/;
proxy_set_header Content-Length ""; proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Original-URI $request_uri;
''; '';

View File

@ -0,0 +1,133 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
#./amanuensis.nix
./catacomb.nix
./gitea.nix
./sync-pipeline.nix
];
beatific.hostName = "empyrean";
beatific.isLighthouse = true;
beatific.defaults.tvbSync = true;
# Use the GRUB 2 boot loader.
boot.loader.grub = {
enable = true;
device = "/dev/xvda";
extraConfig = "serial --unit=0 --speed=115200 ; terminal_input serial console ; terminal_output serial console";
};
boot.kernelParams = ["console=ttyS0"];
nix = {
package = pkgs.nixFlakes;
settings.max-jobs = 2;
};
swapDevices = [ { device = "/swap"; size = 1024; } ];
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true;
environment.systemPackages = with pkgs; [
tinc_pre
gitea
];
services.nginx = let
static-site = srv-dir: {
enableACME = true;
forceSSL = true;
root = "/srv/${srv-dir}/";
extraConfig = ''
access_log /var/log/nginx/access_${srv-dir}.log;
index index.html;
'';
};
service-stub = {
rejectSSL = true;
locations."/".return = "403";
};
in {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
# Static pages
"home.ktvb.site" = static-site "home.ktvb.site";
"wedding.ktvb.site" = static-site "wedding.ktvb.site";
"www.ktvb.site" = static-site "www.ktvb.site";
"www.alogoulogoi.com" = static-site "www.alogoulogoi.com";
"ecumene.alogoulogoi.com" = static-site "ecumene.alogoulogoi.com";
# Home service stub domains
"mopidy.home.ktvb.site" = service-stub;
"jellyfin.home.ktvb.site" = service-stub;
# mirror revproxy
"mirror.alogoulogoi.com" = {
enableACME = true;
forceSSL = true;
extraConfig = ''
access_log /var/log/nginx/access_mirror.alogoulogoi.com.log;
'';
locations."/".proxyPass = "http://mirror.backyard.home:7474/";
};
# Deny all other subdomains
"alogoulogoi.com" = {
default = true;
rejectSSL = true;
locations."/".return = "444";
};
};
};
security.acme = {
defaults.email = "tim.vanbaak+alogoulogoi@gmail.com";
acceptTerms = true;
};
services.openssh = {
settings.PasswordAuthentication = false;
settings.PermitRootLogin = "prohibit-password";
};
services.tinc.networks.beatific = {
listenAddress = "0.0.0.0";
chroot = false;
};
services.intake = {
listen = { addr = "10.22.20.1"; };
users.tvb.enable = true;
users.tvb.extraPackages = [ pkgs.intakeSources pkgs.openssh ];
};
networking.firewall = {
enable = true;
allowedTCPPorts = [
80 # http
443 # https
655 # tinc
];
allowedUDPPorts = [
655 # tinc
];
};
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.05"; # Did you read the comment?
}

View File

@ -5,26 +5,26 @@
{ {
# Gitea configuration # Gitea configuration
services.gitea = { services.gitea = {
# Enable Gitea and configure for reverse proxy
enable = true; enable = true;
httpAddress = "127.0.0.1";
httpPort = 3300;
domain = "git.alogoulogoi.com";
rootUrl = "https://git.alogoulogoi.com/";
# Private server
disableRegistration = true;
#useWizard = true; # Needed for first-time building #useWizard = true; # Needed for first-time building
# Settings # Settings
appName = "Horse Codes"; appName = "Horse Codes";
lfs.enable = true; lfs.enable = true;
# Disabled until I figure out how to make this not take up multiple gigabytes
dump = { dump = {
enable = true; enable = false;
interval = "weekly"; interval = "weekly";
}; };
log.level = "Info";
settings = { settings = {
"server" = {
# Configuration for reverse proxy
ROOT_URL = "https://git.alogoulogoi.com/";
HTTP_ADDR = "127.0.0.1";
HTTP_PORT = 3300;
DOMAIN = "git.alogoulogoi.com";
};
"repository" = { "repository" = {
DEFAULT_PRIVATE = true; DEFAULT_PRIVATE = true;
}; };
@ -40,11 +40,19 @@
"security" = { "security" = {
INSTALL_LOCK = true; INSTALL_LOCK = true;
}; };
"session" = {
SESSION_LIFE_TIME = 86400 * 7; # 1 week
};
"picture" = { "picture" = {
DISABLE_GRAVATAR = true; DISABLE_GRAVATAR = true;
}; };
"cron.archive_cleanup".ENABLED = false; #"cron.archive_cleanup".ENABLED = false; # TODO: figure out why this was enabled
"cron.sync_external_users".ENABLED = false; "cron.sync_external_users".ENABLED = false;
log.LEVEL = "Info";
# Private server
service.DISABLE_REGISTRATION = true;
# Disable package manager functionality
packages.ENABLED = false;
}; };
}; };
@ -64,5 +72,8 @@
proxy_pass http://localhost:3300/; proxy_pass http://localhost:3300/;
''; '';
}; };
# Give tvb group access to gitea config
users.users.tvb.extraGroups = [ "gitea" ];
} }

View File

@ -18,5 +18,5 @@
swapDevices = [ ]; swapDevices = [ ];
nix.maxJobs = lib.mkDefault 1; nix.settings.max-jobs = lib.mkDefault 1;
} }

View File

@ -0,0 +1,75 @@
{ pkgs, ... }:
# exiftool config and script based on that of @numinit
let
# An exiftool config that adds the OriginTimestamp property containing the best guess for file creation time
exiftool-config = pkgs.writeText "exiftool.config" ''
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
OriginTimestamp => {
Desire => {
0 => 'CreateDate',
1 => 'DateTimeOriginal',
2 => 'FileModifyDate'
},
ValueConv => '$val[0] || $val[1] || $val[2] || undef',
PrintConv => '$self->ConvertDateTime($val)',
PrintConvInv => '$self->InverseDateTime($val)'
}
}
)
'';
# A tool to use `find` and `exiftool` to sort images into YMD folders
sibd = pkgs.writeShellScriptBin "sort-images-by-date" ''
set -euo pipefail
if [ $# -lt 3 ]; then
echo "Usage: $0 [prefix] [src] [dest] [exiftool args...]" >&2
exit 1
fi
prefix="$1"
src="$2"
dest="$3"
# Remove $1, $2, $3 from $@ so the remainder can be passed to exiftool
shift; shift; shift
# This find expression matches .jpg/.png modified 14+ days ago.
# The -not (-name -prune) expressions exclude directories from the results by name.
# The exiftool command will move matched files to $dest/$prefix/year/month/day/filename.ext.
# -config loads the config defined above, which adds the OriginTimestamp composite property
# -filename tells exiftool to move each file to a new filename, $OriginTimestamp
# -d defines how the timestamp will be converted to a string, which ends up handling the pathing
${pkgs.findutils}/bin/find $src \
-not \( -name FalseKnees -prune \) \
-not \( -name Background -prune \) \
-type f \
-mtime +14 \
\( -name "*.jpg" -or -name "*.png" \) \
-exec ${pkgs.exiftool}/bin/exiftool \
-config ${exiftool-config} \
-api largefilesupport=1 \
-progress \
-filename'<OriginTimestamp' \
-d "''${dest}/''${prefix}/%Y-%m-%d/%%f%%-c.%%le" \
"$@" \
{} +
'';
# Script for cron jobs that sends output to journalctl -t sync-pipeline
sibd-cron = prefix: src: dest: pkgs.writeShellScript "sibd-cron" ''
${pkgs.systemd}/bin/systemd-cat -t sync-pipeline ${sibd}/bin/sort-images-by-date ${prefix} ${src} ${dest}
'';
in {
environment.systemPackages = [ sibd ];
services.cron = {
enable = true;
systemCronJobs = [
"0 0 * * 1 tvb ${sibd-cron "nokia" "/home/tvb/phone-sync/DCIM" "/home/tvb/phone-sync/staging"}"
"0 0 * * 1 tvb ${sibd-cron "nokia" "/home/tvb/phone-sync/Pictures" "/home/tvb/phone-sync/staging"}"
];
};
}

View File

@ -0,0 +1,97 @@
{ config, pkgs, ... }:
{
imports =
[
./hardware-configuration.nix
];
beatific.hostName = "imperium";
boot.loader.grub = {
enable = true;
device = "/dev/sda";
};
fileSystems."/home/tvb/backyard" = {
device = "//backyard.home/tvb";
fsType = "cifs";
options = [
"x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s,credentials=/home/tvb/.local/state/smb/backyard,uid=1000,gid=988"
];
};
networking.networkmanager.enable = true;
time.timeZone = "America/Los_Angeles";
services.xserver = {
enable = true;
displayManager.gdm.enable = true;
desktopManager.gnome.enable = true;
# keyboard
xkb.layout = "us";
xkb.variant = "";
};
# Enable sound with pipewire.
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
# This seems to be sufficient to autodetect the printing functionality of HP OfficeJet 6950
services.printing.enable = true;
services.printing.drivers = [ pkgs.hplip ];
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
users.users.tvb = {
extraGroups = [ "networkmanager" "docker" ];
packages = [
(pkgs.writeShellScriptBin "yt-dlp" ''exec $HOME/.yt-dlp/bin/yt-dlp "$@"'')
];
};
# Configs needed to run TF2 on integrated graphics
programs.steam.enable = true;
nixpkgs.config.allowUnfree = true;
services.xserver.videoDrivers = [ "i915" ];
hardware.opengl.enable = true;
hardware.opengl.driSupport32Bit = true;
beatific.extraPrograms = true;
environment.systemPackages = with pkgs; [
audacity
bitwarden
bitwarden-cli
comic-mono
firefox
gnome.gnome-terminal
gthumb
libreoffice
mpv
obsidian
unzip
];
programs.nix-ld.enable = true;
networking.firewall = {
enable = false;
};
# This value governs how some stateful data, like databases, are handled
# across different versions of NixOS. This should not be changed to a new
# release unless the sysadmin has determined that no services would be
# adversely affected by changing this.
system.stateVersion = "23.11";
}

View File

@ -0,0 +1,35 @@
# 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.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/798089ca-f249-431d-aa08-65909b85a184";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/5d55f9b7-cde3-403d-9c91-61c4b68c71f9"; }
];
# 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.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.nebula.beatific.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -0,0 +1,118 @@
{ config, pkgs, lib, ... }:
{
imports =
[
./hardware-configuration.nix
];
beatific.hostName = "unfolder";
beatific.extraPrograms = true;
# Bootloader.
boot.loader.grub = {
enable = true;
device = "/dev/sda";
};
networking.networkmanager.enable = true;
fileSystems."/mnt/backyard" = {
device = "//backyard.home/tvb";
fsType = "cifs";
options = [
"x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s,credentials=/home/tvb/.local/state/smb/backyard"
];
};
# Override time zone to PST
time.timeZone = "America/Los_Angeles";
# Enable Gnome because it has a virtual keyboard for tablet mode
services.xserver = {
enable = true;
displayManager.gdm.enable = true;
desktopManager.gnome.enable = true;
# keymap configuration
xkb.layout = "us";
xkb.variant = "";
};
# Enable sound with pipewire.
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
systemd.user.services.yoga-rotate = {
enable = false; # TODO
description = "ThinkPad Yoga display rotation";
#wantedBy = ["multi-user.target"];
wantedBy = [ "graphical-session.target" ];
#requires = ["display-manager.service"];
partOf = [ "graphical-session.target" ];
#after = ["display-manager.service"];
path = [ pkgs.gnome-randr ];
serviceConfig = {
#Type = "simple";
ExecStart = "${pkgs.python3}/bin/python /home/tvb/rotate.py";
#KillMode = "process";
#User = "tvb";
Restart = "on-failure";
RestartSec = 5;
};
#environment = {
# DISPLAY = ":0";
# XAUTHORITY = "/home/tvb/.Xauthority";
#};
};
users.users.tvb = {
extraGroups = [ "networkmanager" "docker" ];
packages = with pkgs; [
gnome-randr
python3
(writeShellScriptBin "single-file" ''
exec ${single-file-cli}/bin/single-file --browser-executable-path ${chromium}/bin/chromium "$@"
'')
];
};
nixpkgs.config.allowUnfree = true;
environment.systemPackages = with pkgs; [
bitwarden-cli
bitwarden-desktop
comic-mono
firefox
gnome.gnome-terminal
libreoffice
obsidian
mpv
qutebrowser
];
networking.firewall = {
enable = true;
};
# This seems to be sufficient to autodetect the printing functionality of HP OfficeJet 6950
services.printing.enable = true;
services.printing.drivers = [ pkgs.hplip ];
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
# This value governs how some stateful data, like databases, are handled
# across different versions of NixOS. This should not be changed to a new
# release unless the sysadmin has determined that no services would be
# adversely affected by changing this.
system.stateVersion = "22.11";
}

View File

@ -0,0 +1,34 @@
# 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.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/3a4363d6-c437-45ab-9f35-6831eb4a2cd8";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/4a083b38-322e-4d35-9877-a8dc1cda21d5"; }
];
# 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.wlp4s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

64
modules/ascii.nix Normal file
View File

@ -0,0 +1,64 @@
{
beatific = ''
____ ______ _______ _____ ______ _____ ______ ./|,,/|
| _ \| ____| /\ |__ __|_ _| ____|_ _|/ ____/ < o o|
| |_) | |__ / \ | | | | | |__ | | | | <\ ( |
| _ <| __| / /\ \ | | | | | __| | | | | <\\ |\ |
| |_) | |____/ ____ \ | | _| |_| | _| |_| |___<\\\ |(__)
|____/|_____/_/ \_\|_| |_____|_| |_____|\_____|\\ |
'';
backyard = ''
____ ______ _ ____ __ _____ _____ ./|,,/|
| _ \ /\ / ____/| | / /\ \ / / /\ | __ \| __ \ < o o|
| |_) | / \ | | | |/ / \ \ / / / \ | |__) | | | |</ ( |
| _ < / /\ \| | | < \ V / / /\ \ | _ /| | | |// |\ |
| |_) / ____ | |____ | |\ \ | | / ____ \| | \ \| |__| |// |(__)
|____/_/ \_\_____\|_| \_\ |_|/_/ \_|_| \_|_____//// |
'';
catacomb = ''
______ _______ ______ ____ __ __ ____ ./|,,/|
/ ____/ /\ |__ __| /\ / ____// __ \| \ / | _ \ < o o|
| | / \ | | / \ | | | | | | . \/ . | |_) |\ ( |
| | / /\ \ | | / /\ \| | | | | | |\ /| | _ <\\ |\ |
| |____ / ____ \ | | / ____ | |__ _| |__| | | \/ | | |_) |\ |(__)
\_____/_/ \_\|_|/_/ \_\_____\\____/|_| |_|____/\\ |
'';
centroid = ''
______ _____ _ _ _______ _____ ____ _____ _____ ./|,,/|
/ ____/| ___| \ | |__ __| __ \ / __ \|_ _| __ \ < o o|
| | | |__ | \| | | | | |__) | | | | | | | | | |\ ( |
| | | __|| . ' | | | | _ /| | | | | | | | | |\ |\ |
| |____ | |___| |\ | | | | | \ \| |__| |_| |_| |__| |\ |(__)
\_____\|_____|_| \_| |_| |_| \_\\____/|_____|_____/\\ |
'';
empyrean = ''
______ __ __ _______ _______ ______ _ _ ./|,,/|
| ____| \ / | __ \ \ / | __ \| ____| /\ | \ | | < o o|
| |__ | . \/ . | |__) \ \ / /| |__) | |__ / \ | \| |</ ( |
| __| | |\ /| | ___/ \ V / | _ /| __| / /\ \ | . ' |// |\ |
| |____| | \/ | | | | | | | \ \| |____ / ____ \| |\ |// |(__)
|______|_| |_|_| |_| |_| \_|______/_/ \_|_| \_|// |
'';
imperium = ''
_____ __ __ ____ _____ _____ _____ _ _ __ __ ./|,,/|
|_ _| \ / | __ \| ___| __ \|_ _| | | | \ / |< o o|
| | | . \/ . | |__) | |__ | |__) | | | | | | | . \/ . |\ ( |
| | | |\ /| | ___/| __|| _ / | | | | | | |\ /| |\ |\ |
_| |_| | \/ | | | | |___| | \ \ _| |_| |__| | | \/ | |\ |(__)
|_____|_| |_|_| |_____|_| \_|_____|\____/|_| <|_|\ |
'';
unfolder = ''
_ _ _ _ ______ ____ _ _____ ______ _____ ./|,,/|
| | | | \ | | ____|/ __ \| | | __ \| ____| __ \ < o o|
| | | | \| | |__ | | | | | | | | | |__ | |__) |\ ( |
| | | | . ' | __| | | | | | | | | | __| | _ /\\ |\ |
| |__| | |\ | | | |__| | |___| |__| | |____| | \ \\\ |(__)
\____/|_| \_|_| \____/|_____|_____/|______|_| <\_\\ |
'';
}

37
modules/bashrc Normal file
View File

@ -0,0 +1,37 @@
# Set the title bar to user@host: pwd
_TITLE_BAR="\u@\h: \w"
_SET_TITLE_BAR="\[\e]0;$_TITLE_BAR\a\]"
# Shorten $HOME to ~ in PWD and shorten other path dir names to one letter
_pwd() {
if [[ "$PWD" =~ ^"$HOME"($) ]]; then
printf "~"
elif [[ "$PWD" = "/" ]]; then
printf "/"
else
if [[ "$PWD" =~ ^"$HOME"/ ]]; then
printf "~"
DIR="${PWD#$HOME}"
else
DIR="$PWD"
fi
for path_elem in $(dirname "$DIR" | tr / '\n' | grep . | cut -c-1); do
printf '/%s' $path_elem
done
printf "/$(basename "$DIR")"
fi
}
_DIR='$(_pwd)'
# Color codes
_GREEN="\[\033[32;1m\]"
_DIM="\[\e[32;2m\]"
_OLIVE="\[\e[33;2m\]"
_RESET="\[\e[0m\]"
_HOST=$(if [ -z "$SSH_CLIENT" ]; then echo $_DIM; else echo $_OLIVE; fi)
# Nested shell level
_SHLVL=$(printf '\$%.0s' $(seq 1 $SHLVL))
# SSH detection
_SSH='$([ ! -z "$SSH_CLIENT" ] && echo "=>")'
# Build prompt
export PS1="$_SET_TITLE_BAR$_DIM[\A \u@$_RESET$_HOST\h$_DIM:$_RESET$_GREEN$_DIR$_RESET$_DIM]$_SHLVL$_RESET "
export HISTCONTROL=ignoreboth

271
modules/beatific.nix Normal file
View File

@ -0,0 +1,271 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkDefault mkIf mkMerge mkOption mkOverride types;
cfg = config.beatific;
mkFlag = description: mkOption {
type = types.bool;
inherit description;
default = true;
};
in {
options = {
beatific = {
# The host name is reused for beatific-specific configuration.
# The bulk of common config is handled in beatific.defaults below, but
# having one option without a default ensures that the module cannot be
# imported accidentally.
hostName = mkOption {
type = types.str;
description = "Hostname";
};
isLighthouse = mkOption {
type = types.bool;
description = "Whether this host is a Nebula lighthouse";
default = false;
};
extraPrograms = mkOption {
type = types.bool;
description = "Additional default programs";
default = false;
};
# Groups of related defaults can be disabled by flipping off the switches here:
# beatific.defaults.${category} = false;
# They default to true because the point is to do these things by default.
defaults = {
time = mkFlag "Default time zone and NTP";
i18n = mkFlag "Default locale settings";
programs = mkFlag "Default installed programs";
ssh = mkFlag "Default sshd settings";
nebula = mkFlag "Default beatific nebula settings";
tvb = mkFlag "Default tvb account";
tvbSync = mkFlag "Configure system syncthing for tvb";
hosts = mkFlag "Default 10.22.20.* DNS host entries";
};
};
};
config = mkMerge [
{
# Options to always set
networking.hostName = cfg.hostName;
nix.extraOptions = "experimental-features = nix-command flakes";
# Link /etc/nixos to the flake source
environment.etc.nixos.source = ./..;
environment.etc."bashrc.local".source = ./bashrc;
environment.shellAliases = {
# Shortcut for nixos-rebuild
nr = "sudo nixos-rebuild --fast --flake $HOME/nixos-configs";
# Always preserve mode, ownership, ts with copy
cp = "cp -rp";
xo = "xdg-open";
smv = "rsync -v --remove-source-files";
ffprobe = "ffprobe -hide_banner";
ffmpeg = "ffmpeg -hide_banner";
".." = "cd ..";
"..." = "cd ../..";
"...." = "cd ../../..";
"....." = "cd ../../../..";
};
security.sudo.extraRules = [{
users = [ "tvb" ];
commands = [ { command = "/run/current-system/sw/bin/nixos-rebuild"; options = [ "NOPASSWD" ]; } ];
}];
}
(mkIf cfg.defaults.time {
# mkDefault time zone to make it easy to configure it to non-UTC
time.timeZone = mkDefault "UTC";
services.ntp.enable = true;
services.ntp.servers = [ "time.nist.gov" ];
})
(mkIf cfg.defaults.i18n {
# en_US.UTF-8
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
LC_IDENTIFICATION = "en_US.UTF-8";
LC_MEASUREMENT = "en_US.UTF-8";
LC_MONETARY = "en_US.UTF-8";
LC_NAME = "en_US.UTF-8";
LC_NUMERIC = "en_US.UTF-8";
LC_PAPER = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
})
(mkIf cfg.defaults.programs {
environment.systemPackages = with pkgs; [
bat # colorized and numbered `less`
bc # Terminal calculator
curl # omnipotent URL tool
duf # disk-free checker
exiftool # media tag tool
ffmpeg # omnipotent media tool
file # file type inspector
htmlq # jq for html
jq # jq for json
nebula # vpn
poppler_utils # provides pdfto* utils, allows lesspipe to read pdfs
psmisc # provides killall
python3 # second-best language for everything
ripgrep # fast file searcher
rsync # incremental remote copy
sqlite # omnipotent database
tree # directory tree view
unzip # .zip archive tool
vim # terminal editor
viu # terminal image "viewer"
wget # web fetcher
zip # .zip archive tool
(writeShellScriptBin "clip" ''
${xclip}/bin/xclip -sel c < "$1"
'')
];
programs = {
git = {
enable = true;
config = {
init.defaultBranch = "master";
merge.conflictstyle = "diff3";
alias = {
amend = "commit --amend";
fixup = "commit --amend --no-edit";
pick = "cherry-pick";
};
};
};
htop.enable = true;
};
# The nixpkgs default is "nano", so we go one priority higher
environment.variables.EDITOR = mkOverride 999 "vim";
})
(mkIf cfg.extraPrograms {
environment.systemPackages = with pkgs; [
(pkgs.writeShellScriptBin "ebook-convert" ''
exec ${pkgs.calibre}/bin/ebook-convert "$@"
'')
imagemagick # image convertion cli
puddletag # mp3 tag editor
tesseract # OCR engine
];
})
(mkIf cfg.defaults.ssh {
services.openssh.enable = true;
services.openssh.settings.PrintMotd = true;
environment.etc."motd".text = let
ascii = import ./ascii.nix;
in ascii.${cfg.hostName} or ascii.beatific;
networking.firewall.allowPing = true;
networking.firewall.allowedTCPPorts = [ 22 ];
})
(mkIf cfg.defaults.nebula {
services.nebula.networks.beatific = let
empyreanExternalDns = "vpn.alogoulogoi.com";
empyreanInternalIp = "10.22.20.1";
nebulaPort = 4242;
in {
enable = true;
# The lighthouse only listens on the designated subdomain
listen.host = if cfg.isLighthouse then empyreanExternalDns else "0.0.0.0";
listen.port = nebulaPort;
# Standard certificate paths
ca = "/etc/nebula/beatific/beatific.crt";
cert = "/etc/nebula/beatific/${cfg.hostName}.crt";
key = "/etc/nebula/beatific/${cfg.hostName}.key";
isLighthouse = cfg.isLighthouse;
# Non-lighthouses connect to the lighthouse at empyrean
# This should be a VPN address in the static host map
lighthouses = mkIf (! cfg.isLighthouse) [ empyreanInternalIp ];
# Currently there is no VPN-level traffic filtering
firewall.outbound = [ { port = "any"; proto = "any"; host = "any"; } ];
firewall.inbound = [ { port = "any"; proto = "any"; host = "any"; } ];
# Map the lighthouse address to its public address
staticHostMap = { ${empyreanInternalIp} = [ "${empyreanExternalDns}:${toString nebulaPort}" ]; };
settings = {
# Enable UDP holepunching both ways, which allows nodes to establish more direct connections with each other
punchy = { punch = true; response = true; };
};
};
})
(mkIf cfg.defaults.tvb {
users.groups.tvb = {};
users.users.tvb = {
isNormalUser = true;
group = "tvb";
extraGroups = [ "wheel" ];
initialPassword = "password";
openssh.authorizedKeys.keyFiles = (import ../keys).tvb;
};
})
(mkIf cfg.defaults.tvbSync {
# I haven't gotten user services to work correctly yet,
# so for now, tvb monopolizes the system syncthing instance.
# Adding users in the future should probably involve multiple
# system services so as not to require login to sync.
services.syncthing = {
enable = true;
configDir = "/home/tvb/.config/syncthing";
# this doesn't prevent syncthing from putting sync points in other locations, it's just a default
# normally it would make sense to put it at ~ but see https://github.com/NixOS/nixpkgs/pull/273693
dataDir = "/home/tvb/.config/syncthing";
openDefaultPorts = true;
user = "tvb";
group = "tvb";
};
})
(mkIf cfg.defaults.hosts {
# Create *.home host entries for all the beatific members
networking.hosts = {
"10.22.20.1" = [
"empyrean.home"
];
"10.22.20.2" = [
"catacomb.home"
"mopidy.home.ktvb.site"
];
"10.22.20.3" = [
"palamas.home"
];
"10.22.20.4" = [
"stagirite.home"
];
"10.22.20.5" = [
"vagrant.home"
];
"10.22.20.6" = [
"unfolder.home"
];
"10.22.20.7" = [
"centroid.home"
];
"10.22.20.8" = [
"backyard.home"
"pool.backyard.home"
"mirror.backyard.home"
"jellyfin.home.ktvb.site"
];
"10.22.20.9" = [
"imperium.home"
];
};
})
];
}

722
modules/syncthings.nix Normal file
View File

@ -0,0 +1,722 @@
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.syncthing;
opt = options.services.syncthing;
defaultUser = "syncthing";
defaultGroup = defaultUser;
settingsFormat = pkgs.formats.json { };
cleanedConfig = converge (filterAttrsRecursive (_: v: v != null && v != {})) cfg.settings;
isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";
# Syncthing supports serving the GUI over Unix sockets. If that happens, the
# API is served over the Unix socket as well. This function returns the correct
# curl arguments for the address portion of the curl command for both network
# and Unix socket addresses.
curlAddressArgs = path: if isUnixGui
# if cfg.guiAddress is a unix socket, tell curl explicitly about it
# note that the dot in front of `${path}` is the hostname, which is
# required.
then "--unix-socket ${cfg.guiAddress} http://.${path}"
# no adjustements are needed if cfg.guiAddress is a network address
else "${cfg.guiAddress}${path}"
;
devices = mapAttrsToList (_: device: device // {
deviceID = device.id;
}) cfg.settings.devices;
folders = mapAttrsToList (_: folder: folder //
throwIf (folder?rescanInterval || folder?watch || folder?watchDelay) ''
The options services.syncthing.settings.folders.<name>.{rescanInterval,watch,watchDelay}
were removed. Please use, respectively, {rescanIntervalS,fsWatcherEnabled,fsWatcherDelayS} instead.
'' {
devices = map (device:
if builtins.isString device then
{ deviceId = cfg.settings.devices.${device}.id; }
else
device
) folder.devices;
}) (filterAttrs (_: folder:
folder.enable
) cfg.settings.folders);
jq = "${pkgs.jq}/bin/jq";
updateConfig = pkgs.writers.writeBash "merge-syncthing-config" (''
set -efu
# be careful not to leak secrets in the filesystem or in process listings
umask 0077
curl() {
# get the api key by parsing the config.xml
while
! ${pkgs.libxml2}/bin/xmllint \
--xpath 'string(configuration/gui/apikey)' \
${cfg.configDir}/config.xml \
>"$RUNTIME_DIRECTORY/api_key"
do sleep 1; done
(printf "X-API-Key: "; cat "$RUNTIME_DIRECTORY/api_key") >"$RUNTIME_DIRECTORY/headers"
${pkgs.curl}/bin/curl -sSLk -H "@$RUNTIME_DIRECTORY/headers" \
--retry 1000 --retry-delay 1 --retry-all-errors \
"$@"
}
'' +
/* Syncthing's rest API for the folders and devices is almost identical.
Hence we iterate them using lib.pipe and generate shell commands for both at
the sime time. */
(lib.pipe {
# The attributes below are the only ones that are different for devices /
# folders.
devs = {
new_conf_IDs = map (v: v.id) devices;
GET_IdAttrName = "deviceID";
override = cfg.overrideDevices;
conf = devices;
baseAddress = curlAddressArgs "/rest/config/devices";
};
dirs = {
new_conf_IDs = map (v: v.id) folders;
GET_IdAttrName = "id";
override = cfg.overrideFolders;
conf = folders;
baseAddress = curlAddressArgs "/rest/config/folders";
};
} [
# Now for each of these attributes, write the curl commands that are
# identical to both folders and devices.
(mapAttrs (conf_type: s:
# We iterate the `conf` list now, and run a curl -X POST command for each, that
# should update that device/folder only.
lib.pipe s.conf [
# Quoting https://docs.syncthing.net/rest/config.html:
#
# > PUT takes an array and POST a single object. In both cases if a
# given folder/device already exists, its replaced, otherwise a new
# one is added.
#
# What's not documented, is that using PUT will remove objects that
# don't exist in the array given. That's why we use here `POST`, and
# only if s.override == true then we DELETE the relevant folders
# afterwards.
(map (new_cfg: ''
curl -d ${lib.escapeShellArg (builtins.toJSON new_cfg)} -X POST ${s.baseAddress}
''))
(lib.concatStringsSep "\n")
]
/* If we need to override devices/folders, we iterate all currently configured
IDs, via another `curl -X GET`, and we delete all IDs that are not part of
the Nix configured list of IDs
*/
+ lib.optionalString s.override ''
stale_${conf_type}_ids="$(curl -X GET ${s.baseAddress} | ${jq} \
--argjson new_ids ${lib.escapeShellArg (builtins.toJSON s.new_conf_IDs)} \
--raw-output \
'[.[].${s.GET_IdAttrName}] - $new_ids | .[]'
)"
for id in ''${stale_${conf_type}_ids}; do
curl -X DELETE ${s.baseAddress}/$id
done
''
))
builtins.attrValues
(lib.concatStringsSep "\n")
]) +
/* Now we update the other settings defined in cleanedConfig which are not
"folders" or "devices". */
(lib.pipe cleanedConfig [
builtins.attrNames
(lib.subtractLists ["folders" "devices"])
(map (subOption: ''
curl -X PUT -d ${lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})} ${curlAddressArgs "/rest/config/${subOption}"}
''))
(lib.concatStringsSep "\n")
]) + ''
# restart Syncthing if required
if curl ${curlAddressArgs "/rest/config/restart-required"} |
${jq} -e .requiresRestart > /dev/null; then
curl -X POST ${curlAddressArgs "/rest/system/restart"}
fi
'');
in {
###### interface
options = {
services.syncthing = {
enable = mkEnableOption
(lib.mdDoc "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync");
cert = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Path to the `cert.pem` file, which will be copied into Syncthing's
[configDir](#opt-services.syncthing.configDir).
'';
};
key = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Path to the `key.pem` file, which will be copied into Syncthing's
[configDir](#opt-services.syncthing.configDir).
'';
};
overrideDevices = mkOption {
type = types.bool;
default = true;
description = mdDoc ''
Whether to delete the devices which are not configured via the
[devices](#opt-services.syncthing.settings.devices) option.
If set to `false`, devices added via the web
interface will persist and will have to be deleted manually.
'';
};
overrideFolders = mkOption {
type = types.bool;
default = true;
description = mdDoc ''
Whether to delete the folders which are not configured via the
[folders](#opt-services.syncthing.settings.folders) option.
If set to `false`, folders added via the web
interface will persist and will have to be deleted manually.
'';
};
settings = mkOption {
type = types.submodule {
freeformType = settingsFormat.type;
options = {
# global options
options = mkOption {
default = {};
description = mdDoc ''
The options element contains all other global configuration options
'';
type = types.submodule ({ name, ... }: {
freeformType = settingsFormat.type;
options = {
localAnnounceEnabled = mkOption {
type = types.nullOr types.bool;
default = null;
description = lib.mdDoc ''
Whether to send announcements to the local LAN, also use such announcements to find other devices.
'';
};
localAnnouncePort = mkOption {
type = types.nullOr types.int;
default = null;
description = lib.mdDoc ''
The port on which to listen and send IPv4 broadcast announcements to.
'';
};
relaysEnabled = mkOption {
type = types.nullOr types.bool;
default = null;
description = lib.mdDoc ''
When true, relays will be connected to and potentially used for device to device connections.
'';
};
urAccepted = mkOption {
type = types.nullOr types.int;
default = null;
description = lib.mdDoc ''
Whether the user has accepted to submit anonymous usage data.
The default, 0, mean the user has not made a choice, and Syncthing will ask at some point in the future.
"-1" means no, a number above zero means that that version of usage reporting has been accepted.
'';
};
limitBandwidthInLan = mkOption {
type = types.nullOr types.bool;
default = null;
description = lib.mdDoc ''
Whether to apply bandwidth limits to devices in the same broadcast domain as the local device.
'';
};
maxFolderConcurrency = mkOption {
type = types.nullOr types.int;
default = null;
description = lib.mdDoc ''
This option controls how many folders may concurrently be in I/O-intensive operations such as syncing or scanning.
The mechanism is described in detail in a [separate chapter](https://docs.syncthing.net/advanced/option-max-concurrency.html).
'';
};
};
});
};
# device settings
devices = mkOption {
default = {};
description = mdDoc ''
Peers/devices which Syncthing should communicate with.
Note that you can still add devices manually, but those changes
will be reverted on restart if [overrideDevices](#opt-services.syncthing.overrideDevices)
is enabled.
'';
example = {
bigbox = {
id = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
addresses = [ "tcp://192.168.0.10:51820" ];
};
};
type = types.attrsOf (types.submodule ({ name, ... }: {
freeformType = settingsFormat.type;
options = {
name = mkOption {
type = types.str;
default = name;
description = lib.mdDoc ''
The name of the device.
'';
};
id = mkOption {
type = types.str;
description = mdDoc ''
The device ID. See <https://docs.syncthing.net/dev/device-ids.html>.
'';
};
autoAcceptFolders = mkOption {
type = types.bool;
default = false;
description = mdDoc ''
Automatically create or share folders that this device advertises at the default path.
See <https://docs.syncthing.net/users/config.html?highlight=autoaccept#config-file-format>.
'';
};
};
}));
};
# folder settings
folders = mkOption {
default = {};
description = mdDoc ''
Folders which should be shared by Syncthing.
Note that you can still add folders manually, but those changes
will be reverted on restart if [overrideFolders](#opt-services.syncthing.overrideFolders)
is enabled.
'';
example = literalExpression ''
{
"/home/user/sync" = {
id = "syncme";
devices = [ "bigbox" ];
};
}
'';
type = types.attrsOf (types.submodule ({ name, ... }: {
freeformType = settingsFormat.type;
options = {
enable = mkOption {
type = types.bool;
default = true;
description = lib.mdDoc ''
Whether to share this folder.
This option is useful when you want to define all folders
in one place, but not every machine should share all folders.
'';
};
path = mkOption {
# TODO for release 23.05: allow relative paths again and set
# working directory to cfg.dataDir
type = types.str // {
check = x: types.str.check x && (substring 0 1 x == "/" || substring 0 2 x == "~/");
description = types.str.description + " starting with / or ~/";
};
default = name;
description = lib.mdDoc ''
The path to the folder which should be shared.
Only absolute paths (starting with `/`) and paths relative to
the [user](#opt-services.syncthing.user)'s home directory
(starting with `~/`) are allowed.
'';
};
id = mkOption {
type = types.str;
default = name;
description = lib.mdDoc ''
The ID of the folder. Must be the same on all devices.
'';
};
label = mkOption {
type = types.str;
default = name;
description = lib.mdDoc ''
The label of the folder.
'';
};
devices = mkOption {
type = types.listOf types.str;
default = [];
description = mdDoc ''
The devices this folder should be shared with. Each device must
be defined in the [devices](#opt-services.syncthing.settings.devices) option.
'';
};
versioning = mkOption {
default = null;
description = mdDoc ''
How to keep changed/deleted files with Syncthing.
There are 4 different types of versioning with different parameters.
See <https://docs.syncthing.net/users/versioning.html>.
'';
example = literalExpression ''
[
{
versioning = {
type = "simple";
params.keep = "10";
};
}
{
versioning = {
type = "trashcan";
params.cleanoutDays = "1000";
};
}
{
versioning = {
type = "staggered";
fsPath = "/syncthing/backup";
params = {
cleanInterval = "3600";
maxAge = "31536000";
};
};
}
{
versioning = {
type = "external";
params.versionsPath = pkgs.writers.writeBash "backup" '''
folderpath="$1"
filepath="$2"
rm -rf "$folderpath/$filepath"
''';
};
}
]
'';
type = with types; nullOr (submodule {
freeformType = settingsFormat.type;
options = {
type = mkOption {
type = enum [ "external" "simple" "staggered" "trashcan" ];
description = mdDoc ''
The type of versioning.
See <https://docs.syncthing.net/users/versioning.html>.
'';
};
};
});
};
copyOwnershipFromParent = mkOption {
type = types.bool;
default = false;
description = mdDoc ''
On Unix systems, tries to copy file/folder ownership from the parent directory (the directory its located in).
Requires running Syncthing as a privileged user, or granting it additional capabilities (e.g. CAP_CHOWN on Linux).
'';
};
};
}));
};
};
};
default = {};
description = mdDoc ''
Extra configuration options for Syncthing.
See <https://docs.syncthing.net/users/config.html>.
Note that this attribute set does not exactly match the documented
xml format. Instead, this is the format of the json rest api. There
are slight differences. For example, this xml:
```xml
<options>
<listenAddress>default</listenAddress>
<minHomeDiskFree unit="%">1</minHomeDiskFree>
</options>
```
corresponds to the json:
```json
{
options: {
listenAddresses = [
"default"
];
minHomeDiskFree = {
unit = "%";
value = 1;
};
};
}
```
'';
example = {
options.localAnnounceEnabled = false;
gui.theme = "black";
};
};
guiAddress = mkOption {
type = types.str;
default = "127.0.0.1:8384";
description = lib.mdDoc ''
The address to serve the web interface at.
'';
};
systemService = mkOption {
type = types.bool;
default = true;
description = lib.mdDoc ''
Whether to auto-launch Syncthing as a system service.
'';
};
user = mkOption {
type = types.str;
default = defaultUser;
example = "yourUser";
description = mdDoc ''
The user to run Syncthing as.
By default, a user named `${defaultUser}` will be created whose home
directory is [dataDir](#opt-services.syncthing.dataDir).
'';
};
group = mkOption {
type = types.str;
default = defaultGroup;
example = "yourGroup";
description = mdDoc ''
The group to run Syncthing under.
By default, a group named `${defaultGroup}` will be created.
'';
};
all_proxy = mkOption {
type = with types; nullOr str;
default = null;
example = "socks5://address.com:1234";
description = mdDoc ''
Overwrites the all_proxy environment variable for the Syncthing process to
the given value. This is normally used to let Syncthing connect
through a SOCKS5 proxy server.
See <https://docs.syncthing.net/users/proxying.html>.
'';
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/syncthing";
example = "/home/yourUser";
description = lib.mdDoc ''
The path where synchronised directories will exist.
'';
};
configDir = let
cond = versionAtLeast config.system.stateVersion "19.03";
in mkOption {
type = types.path;
description = lib.mdDoc ''
The path where the settings and keys will exist.
'';
default = cfg.dataDir + optionalString cond "/.config/syncthing";
defaultText = literalMD ''
* if `stateVersion >= 19.03`:
config.${opt.dataDir} + "/.config/syncthing"
* otherwise:
config.${opt.dataDir}
'';
};
databaseDir = mkOption {
type = types.path;
description = lib.mdDoc ''
The directory containing the database and logs.
'';
default = cfg.configDir;
defaultText = literalExpression "config.${opt.configDir}";
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--reset-deltas" ];
description = lib.mdDoc ''
Extra flags passed to the syncthing command in the service definition.
'';
};
openDefaultPorts = mkOption {
type = types.bool;
default = false;
example = true;
description = lib.mdDoc ''
Whether to open the default ports in the firewall: TCP/UDP 22000 for transfers
and UDP 21027 for discovery.
If multiple users are running Syncthing on this machine, you will need
to manually open a set of ports for each instance and leave this disabled.
Alternatively, if you are running only a single instance on this machine
using the default ports, enable this.
'';
};
package = mkOption {
type = types.package;
default = pkgs.syncthing;
defaultText = literalExpression "pkgs.syncthing";
description = lib.mdDoc ''
The Syncthing package to use.
'';
};
};
};
imports = [
(mkRemovedOptionModule [ "services" "syncthing" "useInotify" ] ''
This option was removed because Syncthing now has the inotify functionality included under the name "fswatcher".
It can be enabled on a per-folder basis through the web interface.
'')
(mkRenamedOptionModule [ "services" "syncthing" "extraOptions" ] [ "services" "syncthing" "settings" ])
(mkRenamedOptionModule [ "services" "syncthing" "folders" ] [ "services" "syncthing" "settings" "folders" ])
(mkRenamedOptionModule [ "services" "syncthing" "devices" ] [ "services" "syncthing" "settings" "devices" ])
(mkRenamedOptionModule [ "services" "syncthing" "options" ] [ "services" "syncthing" "settings" "options" ])
] ++ map (o:
mkRenamedOptionModule [ "services" "syncthing" "declarative" o ] [ "services" "syncthing" o ]
) [ "cert" "key" "devices" "folders" "overrideDevices" "overrideFolders" "extraOptions"];
###### implementation
config = mkIf cfg.enable {
networking.firewall = mkIf cfg.openDefaultPorts {
allowedTCPPorts = [ 22000 ];
allowedUDPPorts = [ 21027 22000 ];
};
systemd.packages = [ pkgs.syncthing ];
users.users = mkIf (cfg.systemService && cfg.user == defaultUser) {
${defaultUser} =
{ group = cfg.group;
home = cfg.dataDir;
createHome = true;
uid = config.ids.uids.syncthing;
description = "Syncthing daemon user";
};
};
users.groups = mkIf (cfg.systemService && cfg.group == defaultGroup) {
${defaultGroup}.gid =
config.ids.gids.syncthing;
};
systemd.services = {
# upstream reference:
# https://github.com/syncthing/syncthing/blob/main/etc/linux-systemd/system/syncthing%40.service
syncthing = mkIf cfg.systemService {
description = "Syncthing service";
after = [ "network.target" ];
environment = {
STNORESTART = "yes";
STNOUPGRADE = "yes";
inherit (cfg) all_proxy;
} // config.networking.proxy.envVars;
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Restart = "on-failure";
SuccessExitStatus = "3 4";
RestartForceExitStatus="3 4";
User = cfg.user;
Group = cfg.group;
ExecStartPre = mkIf (cfg.cert != null || cfg.key != null)
"+${pkgs.writers.writeBash "syncthing-copy-keys" ''
install -dm700 -o ${cfg.user} -g ${cfg.group} ${cfg.configDir}
${optionalString (cfg.cert != null) ''
install -Dm400 -o ${cfg.user} -g ${cfg.group} ${toString cfg.cert} ${cfg.configDir}/cert.pem
''}
${optionalString (cfg.key != null) ''
install -Dm400 -o ${cfg.user} -g ${cfg.group} ${toString cfg.key} ${cfg.configDir}/key.pem
''}
''}"
;
ExecStart = ''
${cfg.package}/bin/syncthing \
-no-browser \
-gui-address=${if isUnixGui then "unix://" else ""}${cfg.guiAddress} \
-config=${cfg.configDir} \
-data=${cfg.databaseDir} \
${escapeShellArgs cfg.extraFlags}
'';
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
CapabilityBoundingSet = [
"~CAP_SYS_PTRACE" "~CAP_SYS_ADMIN"
"~CAP_SETGID" "~CAP_SETUID" "~CAP_SETPCAP"
"~CAP_SYS_TIME" "~CAP_KILL"
];
};
};
syncthing-init = mkIf (cleanedConfig != {}) {
description = "Syncthing configuration updater";
requisite = [ "syncthing.service" ];
after = [ "syncthing.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = cfg.user;
RemainAfterExit = true;
RuntimeDirectory = "syncthing-init";
Type = "oneshot";
ExecStart = updateConfig;
};
};
syncthing-resume = {
wantedBy = [ "suspend.target" ];
};
};
};
}

View File

@ -1,120 +0,0 @@
# redstring server module
{ pkgs, ... }:
let
# Import package
redstringSource = builtins.fetchGit {
url = "https://git.alogoulogoi.com/Jaculabilis/redstring.git";
ref = "master";
rev = "91dd353ad1d48118452a949b15e100b3035bf297";
};
redstring = pkgs.callPackage redstringSource {};
# Define the data directory
redstringDir = "/var/lib/redstring/";
redstringData = "${redstringDir}docs/";
# Define the service user
redstringUser = {
name = "redstring";
description = "redstring service user";
group = "redstring";
isSystemUser = true;
};
# Create the public server config file in the nix store
publicConfigAttrs = {
root = redstringData;
edit = false;
};
publicConfig = pkgs.writeTextFile { name = "redstring-config-external.json"; text = (builtins.toJSON publicConfigAttrs); };
# Create the private server config file in the nix store
privateConfig = pkgs.writeTextFile {
name = "redstring-config-internal.json";
text = (builtins.toJSON {
root = redstringData;
edit = true;
});
};
# Create a setup script to ensure the data directory exists
redstringSetup = pkgs.writeShellScriptBin "redstring-setup.sh" ''
# Ensure the service directory
${pkgs.coreutils}/bin/mkdir -p ${redstringData}
# Ensure ownership
chown -R ${redstringUser.name} ${redstringDir}
chmod 700 ${redstringDir}
'';
# Create a run script for the public server
publicRun = pkgs.writeShellScriptBin "redstring-run-external.sh" ''
cd ${redstringDir}
${redstring}/bin/gunicorn \
--bind=localhost:24144 \
--workers=3 \
--log-level debug \
--env REDSTRING_CONFIG=${publicConfig} \
"redstring.server:wsgi()"
'';
# Create a run script for the private server
privateRun = pkgs.writeShellScriptBin "redstring-run-internal.sh" ''
cd ${redstringDir};
${redstring}/bin/gunicorn \
--bind=10.7.3.1:24145 \
--workers=3 \
--log-level debug \
--env REDSTRING_CONFIG=${privateConfig} \
"redstring.server:wsgi()"
'';
in
{
users.users.redstring = redstringUser;
users.groups.redstring = {};
# Run the setup script on activation
system.activationScripts.redstringSetup = "${redstringSetup}/bin/redstring-setup.sh";
# Set up the public redstring service
systemd.services."redstring-public" =
{
description = "redstring public read-only server";
script = "${publicRun}/bin/redstring-run-external.sh";
serviceConfig = {
User = "${redstringUser.name}";
Type = "simple";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
enable = true;
};
# Set up the private redstring service
systemd.services."redstring-private" =
{
description = "redstring private editable server";
script = "${privateRun}/bin/redstring-run-internal.sh";
serviceConfig = {
User = redstringUser.name;
Type = "simple";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
enable = true;
};
# Configure nginx to forward to the public server at the docs subdomain
services.nginx.virtualHosts."docs.alogoulogoi.com" = {
enableACME = true;
forceSSL = true;
extraConfig = ''
access_log /var/log/nginx/access.docs.log;
'';
locations."/".proxyPass = "http://localhost:24144";
};
# Open the firewall to the private server's port
networking.firewall.allowedTCPPorts = [ 24145 ];
}