Compare commits

...

264 Commits

Author SHA1 Message Date
1f4494d333 fix postfix hopefully 2026-01-28 15:09:47 -06:00
85255adb2c fix postfix hopefully 2026-01-28 14:10:10 -06:00
f251a6f5c7 fix postfix hopefully 2026-01-28 13:48:37 -06:00
1f84cf19c7 fix postfix hopefully 2026-01-28 12:28:14 -06:00
0e49c1b9ee add japanese fonts and input 2026-01-09 23:10:42 -06:00
3ff5251b15 add yveltal back to device list 2026-01-09 20:23:13 -06:00
007c66c007 device list on syncthing 2026-01-09 20:17:00 -06:00
d37a0ce652 updates for mew setup 2026-01-09 20:00:08 -06:00
5ab6c9e4c8 add anki 2026-01-09 19:46:02 -06:00
fccec4d504 add anki 2026-01-09 19:45:49 -06:00
8feda54866 updates for mew setup 2026-01-09 19:18:15 -06:00
7179e6f047 mew added 2026-01-09 18:50:18 -06:00
1da9d994de add new host 2026-01-09 18:02:44 -06:00
e213c64481 add key for ipad 2026-01-09 00:02:43 -06:00
49ac3c2bf5 add ipad to syncthing client 2026-01-08 16:32:21 -06:00
8acebb13cc add ipad to syncthing fixed 2026-01-08 16:28:56 -06:00
ff08538bae add ipad to syncthing 2026-01-08 16:26:40 -06:00
494ac6cf57 switch back to listen address 2025-12-30 13:53:50 -06:00
4cfddd2c7e updates 2025-12-30 13:30:18 -06:00
60509f93f0 fix proxys 2025-12-27 21:02:34 -06:00
96d8fd1129 bind dns to interfact rather then ip 2025-12-13 13:20:55 -06:00
39264279e0 add cobblemon to motd 2025-12-04 20:59:21 -06:00
07c9533255 fix ssh message 2025-12-04 20:32:30 -06:00
015f416169 finish cobblemon, add to glance 2025-12-04 20:30:00 -06:00
35d8c83423 fix postfix 2025-12-04 20:13:38 -06:00
b488af297a fixin cobblemon, and new version warning finally GOD 2025-12-04 20:10:35 -06:00
dbb5560793 fixin cobblemon 2025-12-04 20:01:52 -06:00
7bcfef3ccf enable cobblemon and modded mc in general 2025-12-04 19:57:06 -06:00
a1fd3b3af2 fix postfix 2025-12-04 19:44:13 -06:00
a45d9014dd 25.11 2025-12-04 19:39:07 -06:00
80451e9430 added cobblemon 2025-12-04 19:37:52 -06:00
df1a77f73e added cobblemon 2025-12-04 19:37:40 -06:00
6f51671dbb updates 2025-11-25 19:28:49 -06:00
a238d2b61c updates 2025-11-20 16:56:11 -06:00
62dd3f5d7c darwin updates 2025-11-17 15:43:55 -06:00
8b8dc8cde8 show casing shit 2025-11-17 15:37:38 -06:00
3047ff97b4 add wallpapers 2025-11-12 22:11:01 -06:00
1c963f5563 fin udiskie 2025-11-12 21:48:02 -06:00
c02f2853c1 add icons, didnt do anything lmao 2025-11-12 21:47:12 -06:00
d73a561b9d add udiskie for automount 2025-11-12 21:11:10 -06:00
7d97acfdfb add udiskie for automount 2025-11-12 21:10:22 -06:00
cfb55f980d fix zdot till stable update 2025-11-12 00:36:23 -06:00
1a67b02d7c make gpg work with yubi smartcard 2025-11-12 00:19:07 -06:00
0196b1d8b2 a whole lotta shit 2025-11-12 00:14:50 -06:00
d7a6a85841 add folder for new device 2025-11-11 22:04:48 -06:00
cc7aca0fce fix gitea 2025-11-11 20:17:13 -06:00
6b393c7e4f add default branch 2025-11-11 20:15:35 -06:00
c9bcda6043 fix relative path in dotdir 2025-11-11 19:29:37 -06:00
7ce43bf8e7 add cifs client side mounts 2025-11-11 19:28:22 -06:00
5a451bcaa1 add cifs client side mounts 2025-11-11 19:08:56 -06:00
b4bba876ae ssh temp fix for stable rn 2025-11-11 17:36:06 -06:00
005d0451f5 testing ssh 2025-11-11 17:33:52 -06:00
d20a1787c2 testing ssh 2025-11-11 17:25:42 -06:00
6bb1a13741 test id file 2025-11-11 17:15:27 -06:00
b21060e78d fix snowbelle specific home man config 2025-11-11 17:10:51 -06:00
8caa3b6fe7 ssh changes 2025-11-11 17:04:24 -06:00
6fb6dc7abb add blake ssh key 2025-11-11 16:50:42 -06:00
4a6eb5059c add blake ssh key 2025-11-11 16:49:10 -06:00
d92a192a7f random shit 2025-11-11 16:34:13 -06:00
51c3ae6d1e fin secureboot support 2025-11-11 16:29:31 -06:00
2ea0b96230 add secure boot support 2025-11-11 15:55:18 -06:00
f7ece5059d add secure boot support 2025-11-11 15:51:22 -06:00
b84a2d7628 change wallpaper back 2025-11-11 15:35:29 -06:00
b78a43d40a add fastfetch 2025-11-08 12:15:03 -06:00
f5ff1a6639 attempt to fix flatpaks not appearing in tofi 2025-11-07 20:54:57 -06:00
0534a04108 mime shit 2025-11-07 18:55:05 -06:00
4af26da42f add flatpaks with nix-flatpak, but like right this time 2025-11-07 18:38:37 -06:00
d014733441 add flatpaks with nix-flatpak 2025-11-07 18:22:05 -06:00
38c0191ad2 clean up gitea config from testing 2025-11-07 17:22:35 -06:00
2bbbd49a07 fix ssh config 2025-11-07 17:21:00 -06:00
38a22b5255 update ssh config 2025-11-07 17:17:01 -06:00
a787a7dfc5 fin gitea testing 2025-11-07 17:10:37 -06:00
4349ccb132 fix ssh, back to built in 2025-11-07 17:09:29 -06:00
96920b6b3d attempt to use systemssh 2025-11-07 16:35:13 -06:00
b97d7e4cb1 just add a second entry for local access 2025-11-07 16:23:01 -06:00
59927a4e3d testing local access 2025-11-07 16:21:06 -06:00
076653fd15 remove local url 2025-11-07 16:19:49 -06:00
63dcc450b6 change reverseproxy for gitea 2025-11-07 16:19:32 -06:00
c15704eb22 add local root url 2025-11-07 16:19:32 -06:00
85f7a2889c restructure slippi into gaming subdir 2025-11-07 15:35:58 -06:00
6bfea61ffe restructure slippi into gaming subdir 2025-11-07 15:35:45 -06:00
4e0cc2a322 hope this is the right binary lmao 2025-11-07 15:06:54 -06:00
7ef99c8dd1 add userspace tools and passwdless sudo 2025-11-07 15:05:42 -06:00
1655c0a867 add nh, a nix cli helper tool 2025-11-07 14:54:33 -06:00
724c63f9ff add shortcut to goto ~/.nix 2025-11-07 04:21:22 -06:00
5813db8160 rearrange common nix config, add optimising and garbage collecting 2025-11-07 04:18:09 -06:00
cdf8403991 restructure programs (yes again okay like shut up), reorg standard packages, add obs : ) 2025-11-07 03:54:32 -06:00
10488b90c9 adjust default packages 2025-11-07 03:38:03 -06:00
bcb1b88861 add motd alias 2025-11-07 03:13:49 -06:00
e27be65861 explain gcc import 2025-11-07 03:10:34 -06:00
0e0e58b909 slippi sucess! 2025-11-07 02:59:34 -06:00
4e3a31cf87 more config shullfing, browsers moved, slippi added WOOO 2025-11-07 02:17:58 -06:00
58e68a003a cleaning up my mess so hopefully this shit builds 2025-11-07 01:41:48 -06:00
82d61d54eb add even more programs 2025-11-07 01:34:30 -06:00
fa981032d4 add even more programs 2025-11-07 01:34:26 -06:00
5090fa9cd4 add even more programs 2025-11-07 01:34:06 -06:00
125d639f9f add even more programs 2025-11-07 01:33:20 -06:00
9ad80827ee add a whole shit ton of programs 2025-11-07 01:14:38 -06:00
f0fa2540b5 remove icon for non urgent messages 2025-11-07 00:35:21 -06:00
0bfe74abb7 fix icon paths 2025-11-07 00:33:56 -06:00
766e20ffc4 update icon paths 2025-11-07 00:29:47 -06:00
178fba9c84 remove unused scripts, renamed the rest, updated zsh conf to reflect this 2025-11-07 00:22:42 -06:00
eef41bbca8 fucking with tofi 2025-11-06 23:53:44 -06:00
a0c728f147 tofi adjustments 2025-11-06 23:48:15 -06:00
35645a3e9c fixed launch option comment 2025-11-06 23:29:40 -06:00
67002a94dd finally figured out the cursors, needed to use the setcursor commadn in hyprctl 2025-11-06 23:11:37 -06:00
6beb28477f add hypr specific? 2025-11-06 22:42:07 -06:00
dc03836ac0 with the right name this time 2025-11-06 22:40:12 -06:00
646ba6d63f try w/o pointer cursor just vars 2025-11-06 22:39:19 -06:00
e34b5161d4 this is the one, add the links 2025-11-06 22:38:15 -06:00
81c59857e5 this is the one I swear the env vars will work 2025-11-06 22:36:24 -06:00
7576364d43 happy middle ground 2025-11-06 22:30:22 -06:00
f31eefe6eb fuck this custom cursor shit 2025-11-06 22:26:01 -06:00
788155194f finished troubleshooting a ghost 2025-11-06 22:15:37 -06:00
777c4f3192 fix paths... again 2025-11-06 22:10:49 -06:00
e7ed3e584d fix paths 2025-11-06 22:07:53 -06:00
af9d2553d5 try and add cursors 2025-11-06 22:04:43 -06:00
14c67a8bb3 test failed, large sad 2025-11-06 00:26:41 -06:00
97d2610240 fprintd test 2025-11-06 00:22:37 -06:00
2e36efa1c3 cleanup 2025-11-06 00:11:13 -06:00
8a781d6b2a fix bb alias 2025-11-06 00:06:25 -06:00
c8a036edc2 all hardcoded paths in home man 2025-11-06 00:05:12 -06:00
f0a8d8f0fb remove more hard coded paths 2025-11-05 23:58:04 -06:00
303c759bb4 remove hard coded paths 2025-11-05 23:51:05 -06:00
c243c4393f adjust popup settings 2025-11-05 23:45:06 -06:00
de4822bc68 make dunst declaritive 2025-11-05 23:30:42 -06:00
ed3046e18a wrap up suspend-then-hibernate 2025-11-05 23:14:26 -06:00
e3546caeb5 i think i finally figured out hibernate then sleep 2025-11-05 22:53:27 -06:00
cc083128a3 testing timeout 2025-11-05 22:23:24 -06:00
9faad0e16c add proper target 2025-11-05 22:21:05 -06:00
e50f503270 wait its something else 2025-11-05 22:18:46 -06:00
8a502bdf15 didnt work lmao 2025-11-05 22:17:53 -06:00
32d737f011 attempt to use suspend then hibrnate again 2025-11-05 22:16:51 -06:00
7f84ae360c add theming for qt 2025-11-05 22:15:46 -06:00
bce6234c10 add qalculate-qt 2025-11-05 22:13:38 -06:00
7572b52d6f please? 2025-11-05 21:56:42 -06:00
68ca7ff5f8 i swear this time 2025-11-05 21:54:50 -06:00
51d9300990 fix clipboard once and for all 2025-11-05 21:51:59 -06:00
183eb27980 fix controller 2025-11-05 21:38:12 -06:00
3f689d46f4 all renames 2025-11-05 21:34:52 -06:00
2a576d8d39 did it, add all sinks 2025-11-05 21:30:34 -06:00
e92206ae43 this is the one 2025-11-05 21:25:15 -06:00
733145692f maybe? 2025-11-05 21:12:19 -06:00
ad8b20fd0c actually install the fucking wl-clipboard idiot 2025-11-05 21:00:23 -06:00
d9c20efa16 make nvf use wl-copy 2025-11-05 20:52:31 -06:00
3bbe306485 add clipboard 2025-11-05 20:48:56 -06:00
f9ac7944b3 add explicit pipewire config 2025-11-05 19:33:15 -06:00
eff39f2218 add explicit pipewire config 2025-11-05 19:33:07 -06:00
cdbb5f913d add gaming 2025-11-05 19:09:55 -06:00
e329c17546 add gaming 2025-11-05 19:05:56 -06:00
85c8b9ec1c restructure desktop with option config wrappers 2025-11-05 18:41:33 -06:00
96fd9d96c1 restructure desktop with option config wrappers 2025-11-05 18:41:07 -06:00
090889dff2 restructure desktop with option config wrappers 2025-11-05 18:40:34 -06:00
8c4a82a73f restructure desktop with option config wrappers 2025-11-05 18:40:25 -06:00
f448ce43ec add userspace tools for intel 2025-11-05 18:31:13 -06:00
2fb0dc4c50 fix refs to graphics 2025-11-05 18:28:15 -06:00
2ed9add88e more stupid shit 2025-11-05 18:27:20 -06:00
881d4dd78a punc error lmao 2025-11-05 18:26:48 -06:00
ad487e6715 update nvidia module to graphics and add support for amd and intel 2025-11-05 18:25:55 -06:00
f107cf19c7 update nvidia module to graphics and add support for amd and intel 2025-11-05 18:24:30 -06:00
f5bc0400ae change cert to one for blakedheld.xyz 2025-11-04 23:52:17 -06:00
96ca6c6ea0 hopeing 2025-11-04 23:43:29 -06:00
610513edb7 change extraUpFlags to extraSetFlags across the board 2025-11-04 23:18:56 -06:00
f49978d587 add extraSetFlags to tailscale config 2025-11-04 23:15:39 -06:00
cb4234630b ts test 2025-11-04 23:13:05 -06:00
992616c1ca testing ts 2025-11-04 23:12:19 -06:00
7b39e418c9 add advertisement to snowbelle itself 2025-11-04 23:08:21 -06:00
adf9d1ee4a could fix it all 2025-11-04 22:58:38 -06:00
0c4aed6591 add some packages 2025-11-04 22:54:41 -06:00
1f8fe59423 put it back? 2025-11-04 22:53:18 -06:00
0fc620e7da fix tm 2025-11-04 22:53:18 -06:00
245f06fd3a remove timemachine 2025-11-04 22:53:18 -06:00
d39fb7af39 add sudo insults 2025-11-04 00:53:55 -06:00
6ddebc86d7 add config wrapper for stylix wallpaper 2025-11-04 00:48:03 -06:00
e2047cba7b final test of mixed stable and unstable 2025-11-04 00:03:35 -06:00
d7ae540ebf make this dumb unstable and stable shit work 2025-11-04 00:02:26 -06:00
0fae0e72d3 hardware config removal test 2025-11-03 22:48:41 -06:00
3304d04d9d dear lord PLEASE 2025-11-03 22:35:46 -06:00
e54f91bcd9 fix tofi-drun 2025-11-03 21:34:29 -06:00
4d38c79dfa updates! 2025-11-03 21:33:52 -06:00
946413ada0 big home manager dotfile restructure 2025-11-03 21:13:26 -06:00
4c9b1651bf big home manager dotfile restructure 2025-11-03 21:13:05 -06:00
0fc3f1f501 big home manager dotfile restructure 2025-11-03 21:12:34 -06:00
9b758fdd96 add ignore patterns to syncthing 2025-11-03 20:35:18 -06:00
225d102cea fix lf 2025-11-03 20:21:27 -06:00
38b298fcd6 break core out to own config 2025-11-03 20:13:15 -06:00
a9579a7bf9 break core out to own config 2025-11-03 20:06:14 -06:00
1192cef3ed break core out to own config 2025-11-03 20:03:21 -06:00
8eae778b23 break core out to own config 2025-11-03 20:03:00 -06:00
61fb81abef update wallpaper to yveltal, me likes 2025-11-03 19:59:53 -06:00
03c0b51343 change wallpaper again lmao 2025-11-03 19:37:04 -06:00
647c94bd6e cleanup enables, change wallpaper 2025-11-03 19:23:29 -06:00
e21db6c245 configure btop with stylix 2025-11-02 12:42:29 -06:00
97b66bbb33 configure stylix and allow default to remain, autoenable is now on 2025-11-02 12:42:18 -06:00
edafa28c3e configure stylix 2025-11-02 12:27:08 -06:00
400ac5212f add firefox 2025-11-02 10:20:11 -06:00
c1182d8521 fix stylix imports 2025-11-02 09:59:10 -06:00
b0bcc1040e break tailscale into 2 configs for server and client 2025-11-02 09:58:23 -06:00
b08cb2ea82 break tailscale into 2 configs for server and client 2025-11-02 09:58:21 -06:00
021c4a9172 add dig to nixos common packages 2025-11-02 09:48:41 -06:00
dcf958c0a8 add howdy to tuigreet 2025-11-02 09:48:13 -06:00
037a9b08e3 change greetd to tty2 to supress console output in passwd box 2025-11-01 21:51:56 -05:00
11f247bac8 change greetd to tty2 to supress console output in passwd box 2025-11-01 21:41:22 -05:00
dd34c532d0 add dunst 2025-11-01 21:39:12 -05:00
8b2dd3829a add dunst 2025-11-01 21:37:45 -05:00
0b6e0b7577 syncthing fin 2025-11-01 21:31:26 -05:00
0038a61fff git nonsense 2025-11-01 21:30:49 -05:00
5c1e292f60 testing git ssh with yubi 2025-11-01 21:07:07 -05:00
fc0f270c34 test 2025-11-01 21:06:23 -05:00
9f22aef6af test 2025-11-01 21:06:11 -05:00
f04911def2 add declatrive cert and pem to secrets 2025-11-01 21:05:39 -05:00
329f156f87 syncthing adjustments, adding yveltal 2025-11-01 21:03:20 -05:00
f43f3b1749 add yveltal to syncthing on holocron 2025-11-01 21:01:53 -05:00
d4bcd95d52 add syncthing 2025-11-01 21:00:46 -05:00
f1e9914ea1 add syncthing 2025-11-01 20:33:29 -05:00
419d86342d add tofi 2025-11-01 19:13:08 -05:00
b5b9633c3c add tofi 2025-11-01 19:09:58 -05:00
93e1150a56 add tofi 2025-11-01 19:09:24 -05:00
ba40661f5e add host specific home manager config for snowbelle 2025-11-01 17:56:01 -05:00
a6d2c0030d remove sshDefaultConfig till 25.11 drops 2025-11-01 17:51:59 -05:00
458090e795 add power switch handling to host specific config 2025-11-01 17:51:03 -05:00
4078ed0d21 add config wrappers to everything in home manager 2025-11-01 17:49:49 -05:00
4a995d51c3 add config wrappers to everything in home manager 2025-11-01 17:47:19 -05:00
84b7477cff a little restructuring of home manager to focus on host specific configs 2025-11-01 12:33:27 -05:00
ba2bcba53b add yubikey signin 2025-10-31 00:29:20 -05:00
ec252348fd didnt need 2025-10-30 23:36:10 -05:00
5a20416be1 rename tuigreet to new package name 2025-10-30 22:55:36 -05:00
83bdbd296f add pikacig 2025-10-30 22:52:32 -05:00
b48bd36fd7 actually start waybar lmao 2025-10-30 22:49:00 -05:00
728425868c restructure to actually import waybar with home man 2025-10-30 22:47:08 -05:00
69d748c3ff add waybar and librewolf 2025-10-30 22:40:47 -05:00
4e59f2d8ca add waybar and librewolf 2025-10-30 22:36:04 -05:00
817f2b29a3 add hyprcursor settings 2025-10-29 22:41:51 -05:00
c1ae4d7060 dunno 2025-10-28 22:35:10 -05:00
fd4119a579 add greetd 2025-10-28 22:34:06 -05:00
fb64e3406b add greetd 2025-10-28 22:33:54 -05:00
1268291250 add userspace yubi tools 2025-10-28 22:18:25 -05:00
5e3155b465 fix perms 2025-10-25 14:39:45 -05:00
de0117edff yveltal init 2025-10-25 14:36:52 -05:00
700943ab97 laied out the groundwork for hyprland 2025-10-25 12:14:34 -05:00
6fa11eea8f add hypr stuff and remove current_system var fromflake 2025-10-25 10:55:00 -05:00
2d1d85ddc6 laying ground work for hyprland and yveltal 2025-10-24 21:40:13 -05:00
7a371f3b1e fuck it nah its only 30 min 2025-10-23 22:40:30 -05:00
bf8c4d050d make smart tests less frequent 2025-10-23 22:36:47 -05:00
1832c5ac83 clean up and finish syncthing to holocron 2025-10-23 22:33:11 -05:00
6f1c74d243 add syncthing to proxy and glance 2025-10-23 22:16:25 -05:00
d1dde74c4f add holocron folder ID 2025-10-23 22:02:02 -05:00
05607c2b48 add syncthing to holocron 2025-10-23 21:57:50 -05:00
eea735134d add syncthing to holocron 2025-10-23 21:55:44 -05:00
d9f06234fd add syncthing to holocron 2025-10-23 21:55:18 -05:00
f4b505d1d1 update 2025-10-23 19:30:03 -05:00
24ac2aca51 disable ensure perms 2025-10-22 22:20:20 -05:00
4881ac5808 fix zfs 2025-10-22 22:12:54 -05:00
b7fb67f939 add ffmpeg to sonarr and radarr 2025-10-22 21:50:35 -05:00
32f37c7c2e add automatic smart testing 2025-10-19 15:06:10 -05:00
0a31b25d83 test email 2025-10-19 14:49:15 -05:00
acc28d9278 add email notifs to zfs and smart 2025-10-19 14:44:35 -05:00
ae04500e63 postfix with gmail 2025-10-19 14:33:36 -05:00
f463b76253 try with apple 2025-10-19 14:13:23 -05:00
5298430415 try with apple email 2025-10-19 14:11:47 -05:00
14f790e67a update options to support new syntax 2025-10-19 14:06:42 -05:00
6ca265e97b add postfix 2025-10-19 13:59:06 -05:00
7b11dbdcfa give copyparty access to archives 2025-10-19 13:32:31 -05:00
652f005769 restructure homemanager to support multiplatforms 2025-10-19 03:40:04 -05:00
2728 changed files with 8808 additions and 1194 deletions

View File

@@ -1,203 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# --- SUDO CHECK ---
if [ "$EUID" -ne 0 ]; then
echo "This script requires root privileges. Re-running with sudo..."
exec sudo "$0" "$@"
fi
# --- HANDLE OPTIONS ---
BORG_PASSPHRASE=""
SHOW_FOLDERS_ONLY=false
SHOW_FILES=false # Default to showing files and directories
while getopts "k:fp" opt; do
case "$opt" in
k)
BORG_PASSPHRASE=$(<"$OPTARG")
if [ -z "$BORG_PASSPHRASE" ]; then
echo "Error: The key file is empty."
exit 1
fi
echo "Using passphrase from key file: $OPTARG"
;;
f)
SHOW_FOLDERS_ONLY=true
echo "Only directories will be shown in fzf by default."
SHOW_FILES=false
;;
p)
SHOW_FILES=true
echo "Both files and directories will be shown in fzf."
;;
*)
echo "Usage: $0 [-k passphrase_file] [-f] [-p] <repo>"
exit 1
;;
esac
done
shift $((OPTIND - 1))
# --- FALLBACK TO /run/secrets/borg_passwd IF NO KEY FILE ---
if [ -z "$BORG_PASSPHRASE" ]; then
if [ $# -eq 0 ]; then
BORG_PASSPHRASE=$(<"/run/secrets/borg_passwd")
echo "Using passphrase from /run/secrets/borg_passwd"
else
# Prompt user for passphrase if neither -k nor /run/secrets/borg_passwd is available
read -s -p "Enter Borg repository passphrase: " BORG_PASSPHRASE
echo
fi
fi
export BORG_PASSPHRASE
# --- DEFAULT REPO ---
REPO="${1:-/holocron/archives/servers/snowbelle}"
# --- CHECK REQUIRED COMMANDS ---
for cmd in borg fzf find tree cp mkdir; do
command -v "$cmd" >/dev/null || { echo "Error: '$cmd' is required but not installed."; exit 1; }
done
# --- LIST ARCHIVES (sorted, newest last) ---
mapfile -t archives < <(borg list --format="{archive}{NL}" "$REPO" | sort -r)
if [ ${#archives[@]} -eq 0 ]; then
echo "No archives found in $REPO"
exit 1
fi
# --- FZF ARCHIVE SELECT ---
selected=$(printf '%s\n' "${archives[@]}" | fzf --prompt="Select archive: " --height=40% --border)
if [ -z "$selected" ]; then
echo "No archive selected."
exit 1
fi
echo "Selected archive: $selected"
# --- GENERATE A UNIQUE, SHORTER MOUNT POINT ---
MOUNT_POINT="/tmp/$(uuidgen | sha256sum | head -c 2)-restore-${selected}"
mkdir -p "$MOUNT_POINT"
# --- MOUNT ARCHIVE ---
echo "Mounting '$selected' to $MOUNT_POINT..."
borg mount "$REPO::$selected" "$MOUNT_POINT"
if [ ! -d "$MOUNT_POINT" ]; then
echo "Error: mount failed."
exit 1
fi
# --- LIST FILES AND DIRECTORIES ---
echo "Scanning files and directories..."
if command -v fd >/dev/null 2>&1; then
# List both files and directories with fd
if [ "$SHOW_FILES" = true ]; then
files=$(fd . "$MOUNT_POINT" | sort) # Show both files and directories
else
files=$(fd --type d . "$MOUNT_POINT" | sort) # Only directories
fi
else
# Fall back to find if fd is not available
if [ "$SHOW_FILES" = true ]; then
files=$(find "$MOUNT_POINT" | sort) # Show both files and directories
else
files=$(find "$MOUNT_POINT" -type d | sort) # Only directories
fi
fi
if [ -z "$files" ]; then
echo "No files or directories found in archive."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 1
fi
# --- FZF FILE/DIRECTORY SELECTION ---
if [ "$SHOW_FILES" = true ]; then
# If showing files and directories, we pass everything to fzf
selected_items=$(printf '%s\n' "$files" | sed "s|$MOUNT_POINT/||" | tac | fzf \
--multi \
--height=50% \
--border \
--prompt="Select files or directories to restore: " \
--preview "tree -C -L 5 $MOUNT_POINT/$(dirname {})" \
--preview-window=right:50% \
--delimiter='/' \
--with-nth=1..)
else
# If only showing directories, pass directories to fzf
selected_items=$(printf '%s\n' "$files" | sed "s|$MOUNT_POINT/||" | tac | fzf \
--multi \
--height=50% \
--border \
--prompt="Select directories to restore: " \
--preview "tree -C -d -L 3 $MOUNT_POINT/$(dirname {})" \
--preview-window=right:50% \
--delimiter='/' \
--with-nth=1..)
fi
if [ -z "$selected_items" ]; then
echo "No items selected. Exiting."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 0
fi
# --- SUMMARY OF SELECTED ITEMS ---
echo "Selected items:"
for item in $selected_items; do
echo " $item"
done
# --- OPTIONS MENU (concise) ---
# Default to option 1 if no input is given
echo "Select restore destination: 1) Restore to ./${selected}_restore 2) Restore to original dirs 3) Quit"
read -p "Enter your choice (1/2/3) [default: 1]: " choice
# Default to option 1 if user presses Enter without providing input
choice="${choice:-1}"
# --- SET RESTORE DESTINATION BASED ON USER CHOICE ---
case "$choice" in
1)
DEST="./${selected}_restore"
;;
2)
DEST="$MOUNT_POINT"
;;
3)
echo "Quitting. No items restored."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 0
;;
*)
echo "Invalid choice. Exiting."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 1
;;
esac
mkdir -p "$DEST"
# --- RESTORE SELECTED ITEMS (FILES OR DIRECTORIES) ---
echo "Restoring selected items..."
while IFS= read -r item; do
dest_path="$DEST/$item"
mkdir -p "$(dirname "$dest_path")"
if [ -d "$MOUNT_POINT/$item" ]; then
cp -r "$MOUNT_POINT/$item" "$dest_path"
else
cp -a "$MOUNT_POINT/$item" "$dest_path"
fi
echo "Restored: $item"
done <<< "$selected_items"
# --- CLEANUP ---
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
echo "Restore complete."

View File

@@ -1,99 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# --- SUDO CHECK ---
if [ "$EUID" -ne 0 ]; then
echo "This script requires root privileges. Re-running with sudo..."
exec sudo "$0" "$@"
fi
# --- HANDLE OPTIONS ---
BORG_PASSPHRASE=""
SHOW_FOLDERS_ONLY=false
SHOW_FILES=false # Default to showing files and directories
while getopts "k:fp" opt; do
case "$opt" in
k)
BORG_PASSPHRASE=$(<"$OPTARG")
if [ -z "$BORG_PASSPHRASE" ]; then
echo "Error: The key file is empty."
exit 1
fi
echo "Using passphrase from key file: $OPTARG"
;;
f)
SHOW_FOLDERS_ONLY=true
echo "Only directories will be shown in fzf by default."
SHOW_FILES=false
;;
p)
SHOW_FILES=true
echo "Both files and directories will be shown in fzf."
;;
*)
echo "Usage: $0 [-k passphrase_file] [-f] [-p] <repo>"
exit 1
;;
esac
done
shift $((OPTIND - 1))
# --- FALLBACK TO /run/secrets/borg_passwd IF NO KEY FILE ---
if [ -z "$BORG_PASSPHRASE" ]; then
if [ $# -eq 0 ]; then
BORG_PASSPHRASE=$(<"/run/secrets/borg_passwd")
echo "Using passphrase from /run/secrets/borg_passwd"
else
# Prompt user for passphrase if neither -k nor /run/secrets/borg_passwd is available
read -s -p "Enter Borg repository passphrase: " BORG_PASSPHRASE
echo
fi
fi
export BORG_PASSPHRASE
# --- DEFAULT REPO ---
REPO="${1:-/holocron/archives/servers/snowbelle}"
# --- CHECK REQUIRED COMMANDS ---
for cmd in borg fzf find tree cp mkdir; do
command -v "$cmd" >/dev/null || { echo "Error: '$cmd' is required but not installed."; exit 1; }
done
# --- LIST ARCHIVES (sorted, newest last) ---
mapfile -t archives < <(borg list --format="{archive}{NL}" "$REPO" | sort -r)
if [ ${#archives[@]} -eq 0 ]; then
echo "No archives found in $REPO"
exit 1
fi
# --- FZF ARCHIVE SELECT ---
selected=$(printf '%s\n' "${archives[@]}" | fzf --prompt="Select archive: " --height=40% --border)
if [ -z "$selected" ]; then
echo "No archive selected."
exit 1
fi
echo "Selected archive: $selected"
# --- GENERATE A UNIQUE, SHORTER MOUNT POINT ---
MOUNT_POINT="/tmp/$(uuidgen | sha256sum | head -c 2)-restore-${selected}"
mkdir -p "$MOUNT_POINT"
# --- MOUNT ARCHIVE ---
echo "Mounting '$selected' to $MOUNT_POINT..."
borg mount "$REPO::$selected" "$MOUNT_POINT"
cleanup() {
echo "Unmounting archive..."
borg umount "$MOUNT_POINT" >/dev/null 2>&1 || true
rmdir "$MOUNT_POINT" >/dev/null 2>&1 || true
}
trap cleanup EXIT INT TERM
if [ ! -d "$MOUNT_POINT" ]; then
echo "Error: mount failed."
exit 1
fi
lf $MOUNT_POINT

View File

@@ -26,6 +26,8 @@ echo "files:"
git status --short git status --short
read -rp "commit message: " commit_msg read -rp "commit message: " commit_msg
echo "rebuilding nixos with flake.nix..." echo "rebuilding nixos with flake.nix..."
#if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then
#if ! nh os switch 2>&1 | tee "$logfile"; then
if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then
echo "rebuild failed; exited with no commit" echo "rebuild failed; exited with no commit"
exit 1 exit 1

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
pushd ~/.nix
# nvim flake.nix
# alejandra . &>/dev/null
# git diff -U0 *.nix
# add generation comment to flake.nix
gen=$(nixos-rebuild list-generations | grep current)
if sed -n '3p' flake.nix | grep -q '^# generation:'; then
# replace the comment on line 3
sed -i "3s/^# generation:.*/# generation: $gen/" flake.nix
else
# insert comment on line 3
sed -i "3i# generation: $gen" flake.nix
fi
git diff -U0 $(find . -name '*.nix')
echo "nixos rebuilding..."
#sudo nixos-rebuild switch --flake ~/.nix#snowbelle &>.nixos-switch-log || (
# cat .nixos-switch-log | grep --color error && false)
sudo nixos-rebuild switch --flake ~/.nix#snowbelle 2>&1 | tee .nixos-switch-log | grep --color=always -E "error|$" && true
git commit -am "$gen"
popd

1049
flake.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,21 +4,38 @@
{ {
description = "blakes nix config"; description = "blakes nix config";
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-25.05"; nixpkgs.url = "nixpkgs/nixos-25.11";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
nix-darwin = { nix-darwin = {
url = "github:LnL7/nix-darwin"; url = "github:nix-darwin/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
home-manager = {
url = "github:nix-community/home-manager/release-25.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
home-manager-unstable = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
nix-homebrew.url = "github:zhaofengli/nix-homebrew"; nix-homebrew.url = "github:zhaofengli/nix-homebrew";
home-manager = { nix-flatpak.url = "github:gmodena/nix-flatpak/?ref=latest";
url = "github:nix-community/home-manager/release-25.05";
inputs.nixpkgs.follows = "nixpkgs";
};
sops-nix = { sops-nix = {
url = "github:Mic92/sops-nix"; url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
disko = {
url = "github:nix-community/disko/latest";
inputs.nixpkgs.follows = "nixpkgs";
};
lanzaboote = {
url = "github:nix-community/lanzaboote/v0.4.3";
inputs.nixpkgs.follows = "nixpkgs";
};
watershot = {
url = "github:Kirottu/watershot";
inputs.nixpkgs.follows = "nixpkgs";
};
vpn-confinement = { vpn-confinement = {
url = "github:Maroka-chan/VPN-Confinement"; url = "github:Maroka-chan/VPN-Confinement";
}; };
@@ -27,14 +44,18 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
autoaspm = { autoaspm = {
url = "github:notthebee/AutoASPM"; url = "git+https://git.notthebe.ee/notthebee/AutoASPM.git";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
stylix = { stylix = {
url = "github:nix-community/stylix"; url = "github:nix-community/stylix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs-unstable";
}; };
copyparty.url = "github:9001/copyparty"; copyparty.url = "github:9001/copyparty";
slippi = {
url = "github:lytedev/slippi-nix";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
}; };
outputs = { outputs = {
self, self,
@@ -61,6 +82,26 @@
inputs.home-manager.nixosModules.default inputs.home-manager.nixosModules.default
]; ];
}; };
yveltal = nixpkgs-unstable.lib.nixosSystem {
system = systems.x86_64;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
./hosts/nixos/yveltal/configuration.nix
./hosts/nixos/yveltal/disko.nix
inputs.home-manager-unstable.nixosModules.default
inputs.disko.nixosModules.disko
];
};
mew = nixpkgs-unstable.lib.nixosSystem {
system = systems.x86_64;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
./hosts/nixos/mew/configuration.nix
./hosts/nixos/mew/disko.nix
inputs.home-manager-unstable.nixosModules.default
inputs.disko.nixosModules.disko
];
};
vaniville = nixpkgs.lib.nixosSystem { vaniville = nixpkgs.lib.nixosSystem {
system = systems.x86_64; system = systems.x86_64;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;}; specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
@@ -75,14 +116,15 @@
system = systems.darwin; system = systems.darwin;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs nix-homebrew;}; specialArgs = {inherit inputs stable_pkgs unstable_pkgs nix-homebrew;};
modules = [ modules = [
./hosts/darwin/cen-it-07/configuration.nix #./hosts/darwin/cen-it-07/configuration.nix
inputs.home-manager.darwinModules.default inputs.home-manager.darwinModules.default
nix-homebrew.darwinModules.nix-homebrew nix-homebrew.darwinModules.nix-homebrew
{ {
nix-homebrew = { nix-homebrew = {
enable = true; # install homebrew enable = true; # install homebrew
enableRosetta = true; # install homebrew for rosetta as well enableRosetta = true; # install homebrew for rosetta as well
user = "blake"; # user owning homebrew prefix autoMigrate = true;
user = "bhelderman"; # user owning homebrew prefix
}; };
} }
]; ];

View File

@@ -5,45 +5,80 @@
inputs, inputs,
... ...
}: { }: {
imports = [ imports = [
inputs.autoaspm.nixosModules.default inputs.autoaspm.nixosModules.default
]; ];
# base system package install list
environment.systemPackages = with pkgs; [
wget
curl
rsync
git
age
fzf
neofetch
usbutils
pciutils
python3
vim
lf
btop
powertop
];
# set timezone # set timezone
time.timeZone = "America/Chicago"; time.timeZone = "America/Chicago";
nix = {
# garbage collect & remove builds older then 14 days
gc = {
automatic = true;
dates = "daily";
options = "--delete-older-than 14d";
persistent = true;
};
# optimise nix store, dedupe and such
optimise = {
automatic = true;
dates = [ "daily" ];
};
# the goats
settings = {
substituters = [
"https://cache.nixos.org"
];
trusted-public-keys = [
];
experimental-features = lib.mkDefault [
"nix-command"
"flakes"
];
};
};
# allow proprietary packages # allow proprietary packages
nixpkgs.config.allowUnfree = true; nixpkgs = {
config = {
allowUnfree = true;
allowUnfreePredicate = _: true;
};
};
# power management # power management
services.autoaspm.enable = true; services.autoaspm.enable = true;
powerManagement.powertop.enable = true; powerManagement.powertop.enable = true;
# enable flakes # things are better this way
nix.settings.experimental-features = ["nix-command" "flakes"];
users.defaultUserShell = pkgs.zsh; users.defaultUserShell = pkgs.zsh;
# passwordless rebuild # base system package install list
security.sudo.extraRules = [ environment.systemPackages = with pkgs; [
wget
curl
dig
nmap
rsync
iperf3
jq
git
age
vim
ncdu
btop
powertop
iotop
cifs-utils
usbutils
pciutils
lm_sensors
];
# nice to have passwordless sudo
security.sudo = {
extraRules = [
{ {
users = ["blake"]; users = ["blake"];
commands = [ commands = [
@@ -63,7 +98,23 @@
command = "/run/current-system/sw/bin/tailscale"; command = "/run/current-system/sw/bin/tailscale";
options = ["NOPASSWD"]; options = ["NOPASSWD"];
} }
]; {
command = "/etc/profiles/per-user/blake/bin/nom";
options = ["NOPASSWD"];
}
{
command = "/etc/profiles/per-user/blake/bin/nom-build";
options = ["NOPASSWD"];
}
{
command = "/etc/profiles/per-user/blake/bin/nom-shell";
options = ["NOPASSWD"];
} }
]; ];
} }
];
extraConfig = ''
Defaults insults
'';
};
}

View File

@@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = ""; # disk id here
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
#keyFile = "/tmp/secret.key";
};
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}

View File

@@ -0,0 +1,113 @@
{
pkgs,
config,
lib,
modulesPath,
inputs,
stable_pkgs,
unstable_pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
(modulesPath + "/installer/scan/not-detected.nix")
#./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/desktop
../../../modules/system
];
# home grown nixos modules
system = {
secure_boot.enable = false;
cifs_mounts.enable = true;
udiskie.enable = true;
ssh.enable = true;
sops.enable = true;
japanese.enable = true;
yubikey.enable = true;
yubikey.lock_on_remove = false;
tailscale.enable = true;
syncthing.enable = true;
flatpak.enable = true;
graphics = {
enable = true;
vendor = "amd";
};
};
desktop = {
pipewire.enable = true;
hypr.enable = true;
greetd.enable = true;
};
gaming = {
steam.enable = true;
lutris.enable = true;
proton_ge.enable = true;
gamemode.enable = true;
mangohud.enable = true;
};
# import home grown host specific home-manager modules
home-manager.users.blake.imports = [
../../../users/blake/hosts/yveltal.nix
];
# fix power buttons
# move this to a laptops file at some point
services.logind.settings.Login = {
HandlePowerKey = "suspend-then-hibernate";
HandleLidSwitch = "suspend-then-hibernate";
};
# sets the delay before hibernation for ^
systemd.sleep.extraConfig = ''
HibernateDelaySec=1800
'';
# boot (systemd is growing on me)
boot = {
kernelModules = [ "kvm-amd" ];
extraModulePackages = [];
loader = {
systemd-boot.enable = true; # systemd your pretty cool ya know
efi.canTouchEfiVariables = true;
};
initrd = {
systemd.enable = true; # better logging
availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod" "ahci"];
kernelModules = [];
};
};
# setup hostname and networking stack
networking = {
hostName = "mew"; # hostname
useDHCP = lib.mkDefault true;
interfaces = {
wlp7s0.useDHCP = lib.mkDefault true;
};
firewall = {
enable = true;
allowedTCPPorts = [22];
allowedUDPPorts = [51820]; # wireguard
};
networkmanager = {
enable = true; # the goat
dns = "systemd-resolved"; # the backup dancer!
};
};
services.resolved = {
enable = true;
fallbackDns = ["1.1.1.1" "9.9.9.9"];
dnsovertls = "opportunistic";
};
hardware.bluetooth.enable = true;
system.stateVersion = "25.05"; # stays here : )
# hardware shit
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

70
hosts/nixos/mew/disko.nix Normal file
View File

@@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/nvme-MTFDHBA512TDV-1AZ1AABHA_UJUND0170FW7O0"; # disk id here
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
#keyFile = "/tmp/secret.key";
};
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}

View File

@@ -1,4 +1,4 @@
{ config, lib, stable_pkgs, unstable_pkgs, ... }: { config, lib, inputs, stable_pkgs, unstable_pkgs, ... }:
let let
pkgs = stable_pkgs.x86_64; pkgs = stable_pkgs.x86_64;
@@ -14,6 +14,11 @@ in
../../../modules/holocron ../../../modules/holocron
../../../modules/homelab ../../../modules/homelab
../../../modules/gameservers/minecraft_recpro ../../../modules/gameservers/minecraft_recpro
../../../modules/gameservers/minecraft_modded
];
home-manager.users.blake.imports = [
../../../users/blake/hosts/snowbelle.nix
]; ];
system = { system = {
@@ -21,21 +26,26 @@ in
sops.enable = true; sops.enable = true;
podman.enable = true; podman.enable = true;
yubikey.enable = true; yubikey.enable = true;
syncthing.enable = true; graphics = {
tailscale.enable = true; enable = true;
nvidia.enable = true; vendor = "nvidia";
};
}; };
holocron = { holocron = {
copyparty.enable = true; syncthing.enable = true;
ensure_perms.enable = true; copyparty.enable = false;
ensure_perms.enable = false;
zfs.enable = true; zfs.enable = true;
smb.enable = true; smb.enable = true;
nfs.enable = true; nfs.enable = true;
}; };
homelab = { homelab = {
enable = true; enable = true;
tailscale.enable = true;
dnsmasq.enable = true;
backups.enable = true; backups.enable = true;
motd.enable = true; motd.enable = true;
postfix.enable = true;
gitea.enable = true; gitea.enable = true;
glance.enable = true; glance.enable = true;
immich.enable = true; immich.enable = true;
@@ -57,6 +67,7 @@ in
}; };
gameservers = { gameservers = {
minecraft_recpro.enable = true; minecraft_recpro.enable = true;
minecraft_modded.enable = true;
}; };
# boot (systemd is going on me) # boot (systemd is going on me)
@@ -138,7 +149,7 @@ in
# Or disable the firewall altogether. # Or disable the firewall altogether.
networking.firewall.enable = true; networking.firewall.enable = true;
system.stateVersion = "25.05"; # Did you read the comment? system.stateVersion = "25.05"; # stays here : )
} }

View File

@@ -0,0 +1,112 @@
{
pkgs,
config,
lib,
modulesPath,
inputs,
stable_pkgs,
unstable_pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
(modulesPath + "/installer/scan/not-detected.nix")
#./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/desktop
../../../modules/system
];
# home grown nixos modules
system = {
secure_boot.enable = true;
cifs_mounts.enable = true;
udiskie.enable = true;
ssh.enable = true;
sops.enable = true;
yubikey.enable = true;
yubikey.lock_on_remove = true;
tailscale.enable = true;
syncthing.enable = true;
flatpak.enable = true;
graphics = {
enable = true;
vendor = "intel";
};
};
desktop = {
pipewire.enable = true;
hypr.enable = true;
greetd.enable = true;
};
gaming = {
steam.enable = true;
lutris.enable = true;
proton_ge.enable = true;
gamemode.enable = true;
mangohud.enable = true;
};
# import home grown host specific home-manager modules
home-manager.users.blake.imports = [
../../../users/blake/hosts/yveltal.nix
];
# fix power buttons
# move this to a laptops file at some point
services.logind.settings.Login = {
HandlePowerKey = "suspend-then-hibernate";
HandleLidSwitch = "suspend-then-hibernate";
};
# sets the delay before hibernation for ^
systemd.sleep.extraConfig = ''
HibernateDelaySec=1800
'';
# boot (systemd is growing on me)
boot = {
kernelModules = ["kvm-intel"];
extraModulePackages = [];
loader = {
systemd-boot.enable = true; # systemd your pretty cool ya know
efi.canTouchEfiVariables = true;
};
initrd = {
systemd.enable = true; # better logging
availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod"];
kernelModules = [];
};
};
# setup hostname and networking stack
networking = {
hostName = "yveltal"; # hostname
useDHCP = lib.mkDefault true;
interfaces = {
wlp0s20f3.useDHCP = lib.mkDefault true;
};
firewall = {
enable = true;
allowedTCPPorts = [22];
allowedUDPPorts = [51820]; # wireguard
};
networkmanager = {
enable = true; # the goat
dns = "systemd-resolved"; # the backup dancer!
};
};
services.resolved = {
enable = true;
fallbackDns = ["1.1.1.1" "9.9.9.9"];
dnsovertls = "opportunistic";
};
hardware.bluetooth.enable = true;
system.stateVersion = "25.05"; # stays here : )
# hardware shit
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/nvme-PC_SN530_NVMe_WDC_512GB_210513807733"; # disk id here
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
#keyFile = "/tmp/secret.key";
};
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}

View File

@@ -0,0 +1,13 @@
{
pkgs,
config,
lib,
...
}: {
imports = [
./pipewire
./hypr
./greetd
./gaming
];
}

View File

@@ -0,0 +1,16 @@
{
pkgs,
config,
inputs,
lib,
...
}: {
imports = [
inputs.slippi.nixosModules.default # gcc drivers
./steam
./lutris
./proton_ge
./gamemode
./mangohud
];
}

View File

@@ -0,0 +1,20 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.gamemode;
in {
options.gaming.gamemode = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
# enable gamemode for game optimizations
# requires setting launch option `gamemoderun %command%`
programs.gamemode.enable = true;
};
}

View File

@@ -0,0 +1,19 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.lutris;
in {
options.gaming.lutris = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
lutris
wine
];
};
}

View File

@@ -0,0 +1,20 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.mangohud;
in {
options.gaming.mangohud = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
# preformance overlay
# requires setting launch option `mangohud %command%`
environment.systemPackages = with pkgs; [
mangohud
];
};
}

View File

@@ -0,0 +1,24 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.proton_ge;
in {
options.gaming.proton_ge = {
enable = lib.mkEnableOption "enable proton ge";
};
# this is an imperitive install after rebuild run `protonup`
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
protonup-ng
];
# tells `protonup` what path to use
environment.sessionVariables = {
STEAM_EXTRA_COMPACT_TOOLS_PATHS = "/home/blake/.steam/root/compatibilitytools.d";
};
};
}

View File

@@ -0,0 +1,22 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.steam;
in {
options.gaming.steam = {
enable = lib.mkEnableOption "enable steam";
};
config = lib.mkIf cfg.enable {
programs.steam = {
enable = true;
gamescopeSession.enable = true; # requires setting launch option `gamescope <options> -- %command%`
remotePlay.openFirewall = true; # open ports for remote play
#dedicatedServer.openFirewall = true; # open ports for source dedicated server
protontricks.enable = true;
};
};
}

View File

@@ -0,0 +1,34 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.desktop.greetd;
in {
options.desktop.greetd = {
enable = lib.mkEnableOption "enable greetd with tuigreet";
};
config = lib.mkIf cfg.enable {
services.greetd = {
enable = true;
# tuigreet command to run
settings = {
default_session = {
user = "greeter";
command = "${pkgs.tuigreet}/bin/tuigreet -c Hyprland -t --greeting \"howdy o/\" --user-menu --remember --remember-user-session --power-shutdown \"systemctl poweroff\" --power-reboot \"systemctl reboot\"";
};
};
};
# allow yubikey signin with u2f
security.pam.services.greetd.u2fAuth = true;
# ensure the user exists
users.users.greeter = {
isSystemUser = true;
description = "user for greetd";
};
};
}

View File

@@ -0,0 +1,22 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.desktop.hypr;
in {
options.desktop.hypr = {
enable = lib.mkEnableOption "enable hypr on nixos side";
};
config = lib.mkIf cfg.enable {
# enable hyprland
programs.hyprland.enable = true;
# give hyprlock perms to unlock
security.pam.services.hyprlock = {
enable = true;
};
};
}

View File

@@ -0,0 +1,136 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.desktop.pipewire;
in {
options.desktop.pipewire = {
enable = lib.mkEnableOption "enable pipewire for sound!";
};
config = lib.mkIf cfg.enable {
security.rtkit.enable = true;
environment.systemPackages = with pkgs; [
qpwgraph # patching software
pavucontrol # volume mixer
pulsemixer
];
services.pipewire = {
enable = true;
alsa = {
enable = true;
support32Bit = true;
};
pulse.enable = true;
jack.enable = true;
wireplumber = {
enable = true;
extraConfig = {
"90-yveltal-renames" = {
"monitor.alsa.rules" = [
# audio sinks
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink";
}
];
actions = {
"update-props" = {
"node.description" = "Speakers / 3.5mm";
"node.nick" = "Speakers / 3.5mm";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI1__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 1";
"node.nick" = "HDMI / DP 1";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI2__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 2";
"node.nick" = "HDMI / DP 2";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI3__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 3";
"node.nick" = "HDMI / DP 3";
};
};
}
# audio sources
{
matches = [
{
"node.name" = "alsa_input.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Headset__source";
}
];
actions = {
"update-props" = {
"node.description" = "3.5mm Mic";
"node.nick" = "3.5mm Mic";
};
};
}
{
matches = [
{
"node.name" = "alsa_input.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Mic1__source";
}
];
actions = {
"update-props" = {
"node.description" = "Laptop Mic";
"node.nick" = "Laptop Mic";
};
};
}
# audio controllers
{
matches = [
{
"device.name" = "alsa_card.pci-0000_00_1f.3-platform-skl_hda_dsp_generic";
}
];
actions = {
"update-props" = {
"node.description" = "Laptop Controller";
"node.nick" = "Laptop Controller";
};
};
}
];
};
};
};
};
};
}

View File

@@ -0,0 +1,156 @@
{
pkgs,
config,
lib,
...
}: let
service = "minecraft_modded";
cfg = config.gameservers.${service};
sec = config.sops.secrets;
servers = {
cobblemon = {
data_dir = "/var/lib/gameservers/minecraft_modded/cobblemon";
start_file = "start.sh";
};
};
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "enables ${service}";
url = lib.mkOption {
type = lib.types.str;
default = "mc.recoil.pro";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = 25565;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = false;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "velocity";
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/gameservers/minecraft/modded";
description = "path to take hourly backups to with borg!";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} user
users.users.minecraft = lib.mkDefault {
description = "minecraft server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
shell = pkgs.bash;
group = "minecraft";
extraGroups = [];
};
systemd.tmpfiles.rules =
lib.attrsets.mapAttrsToList (
name: cfg: "d ${cfg.data_dir} 0770 minecraft minecraft -"
)
servers;
# Create a systemd service per server running in tmux
systemd.services =
lib.attrsets.mapAttrs (name: srv: {
description = "minecraft_recpro: ${name}";
after = ["network.target"];
wants = ["network.target"];
serviceConfig = {
User = "minecraft";
Group = "minecraft";
WorkingDirectory = srv.data_dir;
UMask = "0007";
ExecStart = "${pkgs.openjdk21}/bin/java -Xms4G -Xmx12G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true @libraries/net/neoforged/neoforge/21.1.211/unix_args.txt";
#ExecStart = "${srv.data_dir}/${srv.start_file}";
Restart = "on-failure";
KillMode = "process";
};
wantedBy = ["multi-user.target"];
})
servers;
environment.systemPackages = with pkgs; [openjdk21 mcrcon];
# services.mysql = {
# enable = true;
# package = pkgs.mariadb;
# ensureDatabases = ["minecraft_recpro_db"];
# ensureUsers = [
# {
# name = "minecraft";
# ensurePermissions = {"minecraft_recpro_db.*" = "ALL PRIVILEGES";};
# }
# ];
# initialScript = pkgs.writeText "minecraft_recpro-init.sql" ''
# CREATE USER IF NOT EXISTS 'minecraft_recpro'@'localhost' IDENTIFIED BY 'IKNOWTHISISBADIJUSTNEEDTHISTOWORKRNPLS';
# GRANT ALL PRIVILEGES ON minecraft_recpro_db.* TO 'minecraft_recpro'@'localhost';
# FLUSH PRIVILEGES;
# '';
# };
# open firewall
networking.firewall.allowedTCPPorts = [25778];
# sops.secrets = {
# "velocity_forwarding" = {
# owner = "minecraft";
# group = "minecraft";
# path = "/var/lib/gameservers/minecraft_recpro/velocity/forwarding.secret";
# mode = "0400";
# };
# "minecraft_recpro_db_passwd" = {
# owner = "mysql";
# group = "mysql";
# };
# };
# backups minecraft_recpro with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = lib.flatten (
lib.attrValues (
lib.mapAttrs (_: srv:
[srv.data_dir]
++ (
if builtins.hasAttr "db_dump" srv
then [srv.db_dump]
else []
))
servers
)
);
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
};
}

View File

@@ -58,7 +58,7 @@ in {
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" "blake" ]; extraGroups = [ "media" "blake" "archives" ];
}; };
# enable the ${service} service # enable the ${service} service
@@ -102,7 +102,7 @@ in {
flags = { flags = {
chmod_f = 660; chmod_f = 660;
chmod_d = 770; chmod_d = 770;
gid = 700; gid = "700";
}; };
}; };
"/users/blake" = { "/users/blake" = {
@@ -113,7 +113,7 @@ in {
flags = { flags = {
chmod_f = 660; chmod_f = 660;
chmod_d = 770; chmod_d = 770;
gid = 1000; gid = "1000";
}; };
}; };
}; };

View File

@@ -10,6 +10,7 @@
./nfs ./nfs
./smb ./smb
./zfs ./zfs
./syncthing
./copyparty ./copyparty
./perms ./perms
]; ];

View File

@@ -0,0 +1,87 @@
{
pkgs,
config,
lib,
...
}: let
service = "syncthing";
cfg = config.holocron.${service};
sec = config.sops.secrets;
url = "syncthing.snowbelle.lan";
homelab = config.homelab;
in {
options.holocron.${service} = {
enable = lib.mkEnableOption "enables syncthing";
};
config = lib.mkIf cfg.enable {
services.syncthing = {
enable = true;
user = "blake";
group = "blake";
dataDir = "/var/lib/syncthing";
guiAddress = "0.0.0.0:2222";
openDefaultPorts = true;
#extraFlags = ["--no-default-folder"];
key = sec."${service}/snowbelle/key".path;
cert = sec."${service}/snowbelle/cert".path;
settings = {
devices = {
"lugia" = {id = "BKKSFPH-YEOVVAB-DTT7KK3-UDKAEJ2-PC6ECG7-Y76ZIVP-JRYMMXS-RTZYVQ3";};
"zygarde" = {id = "UYLTF52-VVKUR7F-JN33HQZ-RFNWGL3-JER52LA-GZD2LPJ-QIFEE7K-MNMZRQ5";};
"yveltal" = {id = "ZVSQ4WJ-7OICYOZ-3ECES4X-KH37IPB-TKHKUJG-BSEGXVM-AHYY5C3-VKG44AX";};
"CEN-IT-07" = {id = "DPYKA4Z-3PX7JB2-FBEOXXX-SC7TLT2-QC5P2IR-SXOPJGX-QO3DMII-5B7UCA4";};
"CEN-IT-00007" = {id = "XBPXGYU-DUJSLDH-6BDNF4D-CO2COC3-N3FM6W5-IHZOJBM-Z2N77RI-IVAV5AH";};
};
folders = {
"holocron" = {
path = "/holocron/users/blake/holocron";
devices = ["lugia" "zygarde" "CEN-IT-07" "CEN-IT-00007" "yveltal"];
id = "5voxg-c3he2";
versioning = {
type = "staggered";
fsPath = "/holocron/users/blake/holocron/.stversions";
params = {
cleanInterval = "3600";
maxAge = "0";
};
};
};
};
options = {
urAccepted = -1;
};
};
};
sops.secrets = {
"${service}/snowbelle/key" = {
owner = "blake";
group = "blake";
};
"${service}/snowbelle/cert" = {
owner = "blake";
group = "blake";
};
};
homelab.backups.baks = {
${service} = { paths = [ config.services.syncthing.dataDir ]; };
};
services.caddy.virtualHosts."${url}" = {
extraConfig = ''
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
reverse_proxy 127.0.0.1:2222
'';
};
# add to glance (local service)
homelab.glance.links.system = [{
title = service;
url = "https://${url}";
error-url = "http://${homelab.host_ip}:2222";
check-url = "http://${homelab.host_ip}:2222";
icon = "di:${service}"; }];
};
}

View File

@@ -18,17 +18,41 @@ in {
boot.kernelModules = ["zfs"]; boot.kernelModules = ["zfs"];
boot.supportedFilesystems = ["zfs"]; boot.supportedFilesystems = ["zfs"];
# arc cache size
boot.kernelParams = [ "zfs.zfs_arc_max=12884901888" ];
# pools to import
#boot.zfs.extraPools = [ "holocron" "holocron/archives" "/holocron/media" "/holocron/users" ];
#boot.zfs.extraPools = [ "holocron" ];
# enable smart monitoring # enable smart monitoring
services.smartd.enable = true; services.smartd = {
enable = true;
autodetect = true;
defaults.monitored = "-a -o on -s (S/../.././05|L/../01/./05)";
notifications.mail = {
enable = true;
sender = "zfs@snowbelle.lan";
};
};
# enable zfs # enable zfs
services.zfs = { services.zfs = {
autoScrub.enable = true; autoScrub.enable = true;
autoScrub.interval = "weekly"; autoScrub.interval = "weekly";
# email notifs
zed = {
enableMail = true;
settings = {
ZED_EMAIL_ADDR = ["root"];
# send notification if scrub succeeds
ZED_NOTIFY_VERBOSE = true;
};
};
}; };
# install userspace tools for acl's # install userspace tools for acl's
environment.systemPackages = with pkgs; [ nfs-utils ]; environment.systemPackages = with pkgs; [smartmontools];
fileSystems."/holocron" = { fileSystems."/holocron" = {
device = "holocron"; device = "holocron";

View File

@@ -3,16 +3,13 @@
config, config,
lib, lib,
... ...
}: }: let
let
service = ""; service = "";
cfg = config.modules.services.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{ options.homelab.${service} = {
options.modules.services.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
# set port options # set port options
@@ -44,7 +41,6 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { users.groups.${service} = {
gid = lib.mkForce cfg.ids; gid = lib.mkForce cfg.ids;
@@ -118,7 +114,7 @@ in
# }; # };
# add to backups # add to backups
system.backups.baks = { homelab.backups.baks = {
${service} = { ${service} = {
paths = [cfg.data_dir]; paths = [cfg.data_dir];
}; };

View File

@@ -78,7 +78,7 @@ in
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };

View File

@@ -74,7 +74,7 @@ in
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };

View File

@@ -80,7 +80,7 @@ in
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };

View File

@@ -44,6 +44,9 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# required
environment.systemPackages = with pkgs; [ffmpeg_6-headless];
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = { gid = lib.mkForce cfg.ids; };
@@ -83,7 +86,7 @@ in
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };

View File

@@ -44,6 +44,9 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# required
environment.systemPackages = with pkgs; [ffmpeg_6-headless];
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = { gid = lib.mkForce cfg.ids; };
@@ -80,8 +83,9 @@ in
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
# tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };

View File

@@ -42,8 +42,10 @@ in
# the order determines the order in glance :3 # the order determines the order in glance :3
imports = [ imports = [
./motd ./motd
./dnsmasq
./backups ./backups
./glance ./glance
./postfix
./caddy ./caddy
./home/zigbee2mqtt ./home/zigbee2mqtt
./vaultwarden ./vaultwarden
@@ -61,6 +63,7 @@ in
./arr/flaresolverr ./arr/flaresolverr
./home/mosquitto ./home/mosquitto
./uptime-kuma ./uptime-kuma
./tailscale
]; ];
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {

View File

@@ -0,0 +1,42 @@
{
pkgs,
config,
lib,
...
}: let
service = "dnsmasq";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
port = lib.mkOption {
type = lib.types.int;
default = 53;
description = "set port for ${service} (default: ${toString cfg.port}";
};
};
config = lib.mkIf cfg.enable {
# enable the ${service} service
services.${service} = {
enable = true;
settings = {
listen-address = "10.10.0.10"; # your LAN IP
#interface = "enp89s0";
bind-interfaces = true;
address = "/snowbelle.lan/10.10.0.10";
server = [ # upstream dns
"9.9.9.9"
"1.1.1.1"
];
};
};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
networking.firewall.allowedUDPPorts = [ cfg.port ];
};
}

View File

@@ -1,4 +1,4 @@
{ pkgs, config, lib, ... }: { pkgs, nixpkgs-unstable, config, lib, ... }:
let let
service = "gitea"; service = "gitea";
@@ -62,6 +62,10 @@ in
createHome = true; createHome = true;
group = service; group = service;
extraGroups = []; extraGroups = [];
# if you wanna attempt system ssh again
#openssh.authorizedKeys.keyFiles = [
# "${cfg.data_dir}/.ssh/authorized_keys"
#];
}; };
# declare the gitea service # declare the gitea service
@@ -73,16 +77,26 @@ in
appName = "gitea"; appName = "gitea";
settings = { settings = {
server = { server = {
# http config
ROOT_URL = "https://git.blakedheld.xyz"; ROOT_URL = "https://git.blakedheld.xyz";
DOMAIN = "git.blakedheld.xyz"; DOMAIN = "git.blakedheld.xyz";
HTTP_PORT = cfg.port; HTTP_PORT = cfg.port;
SSH_PORT = cfg.ssh_port; # local network config
START_SSH_SERVER = true; #LOCAL_ROOT_URL = "https://git.snowbelle.lan";
ENABLE_PUSH_CREATE_USER = true;
ALLOW_LOCALNETWORKS = true; ALLOW_LOCALNETWORKS = true;
ALLOWED_DOMAINS = "10.10.0.10"; ALLOWED_DOMAINS = "10.10.0.10";
SKIP_TLS_VERIFY = true; SKIP_TLS_VERIFY = true;
# configure for system ssh (trying to use the systms on nix sucks)
SSH_PORT = cfg.ssh_port;
START_SSH_SERVER = true;
# SSH_PORT = 22;
# START_SSH_SERVER = false;
# SSH_ROOT_PATH = "${cfg.data_dir}/.ssh";
# SSH_CREATE_AUTHORIZED_KEYS_FILE = true;
# actual git config
DEFAULT_BRANCH = "trunk";
ENABLE_PUSH_CREATE_USER = true;
DEFAULT_PUSH_CREATE_PRIVATE = true;
}; };
}; };
database = { database = {
@@ -99,8 +113,13 @@ in
networking.firewall.allowedTCPPorts = [ cfg.port cfg.ssh_port ]; networking.firewall.allowedTCPPorts = [ cfg.port cfg.ssh_port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."git.${homelab.public_domain}" = {
extraConfig = ''
reverse_proxy localhost:${toString cfg.port} {
}
'';
};
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "git.${homelab.public_domain}" ];
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy localhost:${toString cfg.port} { reverse_proxy localhost:${toString cfg.port} {
@@ -108,6 +127,7 @@ in
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.services = [{ homelab.glance.links.services = [{
title = service; title = service;

View File

@@ -242,6 +242,13 @@ in
cache = "5s"; cache = "5s";
template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>"; template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>";
} }
{
type = "custom-api";
title = "cobblemon";
url = "https://api.mcstatus.io/v2/status/java/cobblemon.recoil.pro";
cache = "5s";
template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>";
}
]; ];
} }
{ {

View File

@@ -78,7 +78,7 @@ in {
# --- gameservers --- # --- gameservers ---
echo -e "''${headings}gameservers:''${reset}" echo -e "''${headings}gameservers:''${reset}"
for service in velocity smp superflat bento; do for service in velocity smp superflat bento cobblemon; do
status=$(systemctl is-active $service 2>/dev/null) status=$(systemctl is-active $service 2>/dev/null)
if [ "$status" = "active" ]; then if [ "$status" = "active" ]; then
printf "%-32s%s\n" " ''${active}[$service]''${reset}" "running" printf "%-32s%s\n" " ''${active}[$service]''${reset}" "running"

View File

@@ -0,0 +1,99 @@
{
pkgs,
config,
lib,
...
}: let
service = "postfix";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 587;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
# users.groups.${service} = {
# gid = lib.mkForce cfg.ids;
# };
#
# # declare ${service} user
# users.users.${service} = {
# description = "${service} server user";
# uid = lib.mkForce cfg.ids;
# isSystemUser = true;
# home = cfg.data_dir;
# createHome = true;
# group = service;
# extraGroups = [];
# };
# enable the ${service} service
services.postfix = {
enable = true;
settings.main = {
relayhost = ["smtp.gmail.com:${toString cfg.port}"];
smtp_tls_security_level = "may";
smtp_sasl_auth_enable = "yes";
smtp_sasl_security_options = "noanonymous";
smtp_sasl_password_maps = "texthash:${config.sops.secrets."postfix_passwd".path}";
# optional: Forward mails to root (e.g. from cron jobs, smartd)
# to me privately and to my work email:
virtual_alias_maps = "inline:{ {root=me@blakedheld.xyz, throwedspam@gmail.com} }";
};
};
# override umask to make permissions work out
# systemd.services.${service}.serviceConfig = {
# UMask = lib.mkForce "0007";
# User = service;
# Group = service;
#};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
sops.secrets = {
"${service}_passwd" = {
owner = config.services.postfix.user;
group = config.services.postfix.group;
};
};
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir];
};
};
};
}

View File

@@ -0,0 +1,100 @@
{
pkgs,
config,
lib,
...
}: let
service = "postfix";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 587;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
# users.groups.${service} = {
# gid = lib.mkForce cfg.ids;
# };
#
# # declare ${service} user
# users.users.${service} = {
# description = "${service} server user";
# uid = lib.mkForce cfg.ids;
# isSystemUser = true;
# home = cfg.data_dir;
# createHome = true;
# group = service;
# extraGroups = [];
# };
# enable the ${service} service
services.postfix = {
enable = true;
relayHost = "smtp.mail.me.com";
relayPort = cfg.port;
config = {
smtp_tls_security_level = "may";
smtp_sasl_auth_enable = "yes";
smtp_sasl_security_options = "";
smtp_sasl_password_maps = "texthash:${config.sops.secrets."postfix_passwd".path}";
# optional: Forward mails to root (e.g. from cron jobs, smartd)
# to me privately and to my work email:
virtual_alias_maps = "inline:{ {root=me@blakedheld.xyz} }";
};
};
# override umask to make permissions work out
# systemd.services.${service}.serviceConfig = {
# UMask = lib.mkForce "0007";
# User = service;
# Group = service;
#};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
sops.secrets = {
"${service}_passwd" = {
owner = config.services.postfix.user;
group = config.services.postfix.group;
};
};
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir];
};
};
};
}

View File

@@ -117,7 +117,7 @@ in
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };

View File

@@ -0,0 +1,40 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.homelab.tailscale;
authkey_file = config.sops.secrets."tailscale_authkey".path;
in {
options.homelab.tailscale = {
enable = lib.mkEnableOption "enables tailscale";
};
config = lib.mkIf cfg.enable {
services.tailscale = {
enable = true;
openFirewall = true;
useRoutingFeatures = "both";
authKeyFile = authkey_file;
extraSetFlags = [
"--advertise-routes=10.10.0.10/32" # advertise self
"--accept-routes=false" # true is equilivant to useRoutingFeatures = "client" (breaks shit)
"--accept-dns=true" # explicitly allow resolved
];
extraUpFlags = [
];
};
# network config
networking.firewall.trustedInterfaces = ["tailscale0"];
networking.firewall.allowedUDPPorts = [config.services.tailscale.port];
# declare authkey secrets
sops.secrets = {
"tailscale_authkey" = {
owner = "root";
};
};
};
}

View File

@@ -0,0 +1,72 @@
{
pkgs,
inputs,
config,
lib,
...
}: let
cfg = config.system.cifs_mounts;
sec = config.sops.secrets;
in {
options.system.cifs_mounts = {
enable = lib.mkEnableOption "enables mounting holocron fileshare on the client side";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
cifs-utils
];
fileSystems."/media/holocron/blake" = {
device = "//10.10.0.10/users/blake";
fsType = "cifs";
options = [
"x-systemd.automount"
"noauto"
"_netdev"
"credentials=${sec."holocron_creds".path}"
"uid=1000"
"gid=1000"
"file_mode=0664"
"dir_mode=0775"
];
};
fileSystems."/media/holocron/archives" = {
device = "//10.10.0.10/archives";
fsType = "cifs";
options = [
"x-systemd.automount"
"noauto"
"_netdev"
"credentials=${sec."holocron_creds".path}"
"uid=1000"
"gid=1000"
"file_mode=0664"
"dir_mode=0775"
];
};
fileSystems."/media/holocron/media" = {
device = "//10.10.0.10/media";
fsType = "cifs";
options = [
"x-systemd.automount"
"noauto"
"_netdev"
"credentials=${sec."holocron_creds".path}"
"uid=1000"
"gid=1000"
"file_mode=0664"
"dir_mode=0775"
];
};
# manage secrets with sops
sops.secrets = {
"holocron_creds" = {
owner = "blake";
group = "blake";
};
};
};
}

View File

@@ -11,18 +11,17 @@
./podman ./podman
./yubikey ./yubikey
./tailscale ./tailscale
./japanese
./vpns ./vpns
./vpn-confinement ./vpn-confinement
./syncthing ./syncthing
./nvidia ./graphics
./flatpak
./secure_boot
./cifs_mounts
./udiskie
]; ];
system.ssh.enable = lib.mkDefault true; system.ssh.enable = lib.mkDefault true;
system.sops.enable = lib.mkDefault true; system.sops.enable = lib.mkDefault true;
system.docker.enable = lib.mkDefault false;
system.tailscale.enable = lib.mkDefault true;
system.vpns.enable = lib.mkDefault false;
system.vpn-confinement.enable = lib.mkDefault false;
system.syncthing.enable = lib.mkDefault false;
system.nvidia.enable = lib.mkDefault false;
} }

View File

@@ -9,8 +9,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
virtualisation.docker = { virtualisation.docker = {
enable = true; enable = true;
daemon.settings.features.cdi = true;
rootless.daemon.settings.features.cdi = true;
daemon.settings = { daemon.settings = {
experimental = true; experimental = true;
}; };

View File

@@ -0,0 +1,19 @@
{
pkgs,
inputs,
config,
lib,
...
}: let
cfg = config.system.flatpak;
in {
options.system.flatpak = {
enable = lib.mkEnableOption "enables nix-flatpak on nixos side";
};
imports = [inputs.nix-flatpak.nixosModules.nix-flatpak];
config = lib.mkIf cfg.enable {
services.flatpak.enable = true;
};
}

View File

@@ -0,0 +1,89 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.system.graphics;
in {
options.system.graphics = {
enable = lib.mkEnableOption "enables nvidia";
vendor = lib.mkOption {
type = lib.types.enum ["intel" "amd" "nvidia"];
default = "intel";
description = ''
set the vendor of your graphics device
supported options are "intel" "amd" "nvidia"
'';
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
hardware.graphics.enable = true;
hardware.graphics.enable32Bit = true;
}
(lib.mkIf (cfg.vendor == "intel") {
services.xserver.videoDrivers = ["modesetting"];
# userspace tools
environment.systemPackages = with pkgs; [
intel-gpu-tools
];
hardware.graphics.extraPackages = with pkgs; [
# Required for modern Intel GPUs (Xe iGPU and ARC)
intel-media-driver # VA-API (iHD) userspace
vpl-gpu-rt # oneVPL (QSV) runtime
# Optional (compute / tooling):
intel-compute-runtime # OpenCL (NEO) + Level Zero for Arc/Xe
];
environment.sessionVariables = {
LIBVA_DRIVER_NAME = "iHD"; # Prefer the modern iHD backend
};
})
(lib.mkIf (cfg.vendor == "amd") {
boot.initrd.kernelModules = ["amdgpu"];
services.xserver.videoDrivers = ["amdgpu"];
# userspace tools
environment.systemPackages = with pkgs; [
radeontop
];
# enable amd vulkan (program will choose this or regular)
hardware.graphics.extraPackages = with pkgs; [
rocmPackages.clr.icd # enable open cl (compute framework like cuda)
];
# ^ but 32 bit
hardware.graphics.extraPackages32 = with pkgs; [
];
# make hip work (extension on cli.icd ^)
systemd.tmpfiles.rules = [
"L+ /opt/rocm/hip - - - - ${pkgs.rocmPackages.clr}"
];
})
(lib.mkIf (cfg.vendor == "nvidia") {
boot.kernelModules = ["nvidia" "nvidia_modeset" "nvidia_uvm" "nvidia_drm"];
services.xserver.videoDrivers = ["nvidia"];
# enable nvidia proprietary driver
hardware.nvidia = {
modesetting.enable = true; # required
open = false; # use proprietary driver
nvidiaSettings = true; # no shit
powerManagement.enable = false; # can cause sleep issues
package = config.boot.kernelPackages.nvidiaPackages.stable;
};
# enable docker gpu passthrough
hardware.nvidia-container-toolkit.enable = true;
})
]);
}

View File

@@ -0,0 +1,52 @@
{
pkgs,
inputs,
config,
lib,
...
}: let
cfg = config.system.japanese;
in {
options.system.japanese = {
enable = lib.mkEnableOption "enables japanese tools";
};
config = lib.mkIf cfg.enable {
# japanese input
i18n.inputMethod = {
enabled = "fcitx5";
fcitx5.addons = with pkgs; [
fcitx5-mozc
fcitx5-gtk
fcitx5-qt
];
};
environment.systemPackages = with pkgs; [
fcitx5
fcitx5-configtool
];
# fonts for japanese
fonts = {
enableDefaultPackages = true;
packages = with pkgs; [
noto-fonts
noto-fonts-cjk
noto-fonts-emoji
source-han-sans
source-han-serif
];
fontconfig = {
defaultFonts = {
serif = [ "Noto Serif CJK JP" ];
sansSerif = [ "Noto Sans CJK JP" ];
monospace = [ "Noto Sans Mono CJK JP" ];
};
};
};
};
}

View File

@@ -1,37 +0,0 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.system.nvidia;
in {
options.system.nvidia = {
enable = lib.mkEnableOption "enables nvidia";
};
config = lib.mkIf cfg.enable {
services.xserver.videoDrivers = ["nvidia"];
boot.kernelModules = ["nvidia" "nvidia_modeset" "nvidia_uvm" "nvidia_drm"];
# boot.kernelModules = [ "nvidia" ];
hardware.graphics = {
enable = true;
enable32Bit = true;
};
# enable nvidia proprietary driver
hardware.nvidia = {
modesetting.enable = true; # required
open = false; # use proprietary driver
nvidiaSettings = true; # no shit
powerManagement.enable = false; # can cause sleep issues
package = config.boot.kernelPackages.nvidiaPackages.stable;
};
# enable docker gpu passthrough
hardware.nvidia-container-toolkit.enable = true;
virtualisation.docker.daemon.settings.features.cdi = true;
virtualisation.docker.rootless.daemon.settings.features.cdi = true;
};
}

View File

@@ -0,0 +1,43 @@
{
pkgs,
inputs,
config,
lib,
...
}: let
cfg = config.system.secure_boot;
in {
options.system.secure_boot = {
enable = lib.mkEnableOption "enables secureboot with lanzaboote";
};
imports = [inputs.lanzaboote.nixosModules.lanzaboote];
config = lib.mkIf cfg.enable {
# install userspace secureboot tools
environment.systemPackages = with pkgs; [
sbctl
e2fsprogs
];
# force disable systemd-boot so lanzaboote can be used
boot.loader.systemd-boot.enable = lib.mkForce false;
/*
this uses the project lanzaboote for secureboot (extension on systemd)
setup guide can be found here: https://github.com/nix-community/lanzaboote/blob/master/docs/QUICK_START.md
tldr:
while currently using systemd-boot
generate keys with `nix-shell -p --run "sudo sbctl create-keys"`
rebuild with this module enabled then check `sudo sbctl verify`
reboot and enable secureboot setup mode in bios
check that setup mode is enabled with `sudo sbctl status`
enroll keys with `sudo sbctl enroll-keys` use the `--microsoft` flag to incude their keys for compatibality
reboot (disable secureboot setup mode if not done automatically) then check secure boot status with `sudo bootctl status`
*/
boot.lanzaboote = {
enable = true;
pkiBundle = "/var/lib/sbctl";
};
};
}

View File

@@ -13,7 +13,7 @@ in
services.openssh = { services.openssh = {
enable = true; enable = true;
settings = { settings = {
PasswordAuthentication = true; PasswordAuthentication = false;
PermitRootLogin = "no"; PermitRootLogin = "no";
X11Forwarding = false; X11Forwarding = false;
}; };

View File

@@ -1,21 +1,95 @@
{ pkgs, config, lib, ... }:
let
cfg = config.system.syncthing;
in
{ {
options.system.syncthing = { pkgs,
config,
lib,
...
}: let
service = "syncthing";
cfg = config.system.${service};
sec = config.sops.secrets;
in {
options.system.${service} = {
enable = lib.mkEnableOption "enables syncthing"; enable = lib.mkEnableOption "enables syncthing";
host = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = config.networking.hostName;
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.syncthing = { services.syncthing = {
enable = true; enable = true;
# user = "blake"; user = "blake";
# group = "blake"; group = "blake";
# dataDir = "/var/lib/syncthing";
guiAddress = "0.0.0.0:2222"; guiAddress = "0.0.0.0:2222";
# openDefaultPorts = true; openDefaultPorts = true;
dataDir = "/home/blake/.config/syncthing";
#extraFlags = ["--no-default-folder"];
overrideFolders = false;
overrideDevices = false;
key = sec."${service}/${cfg.host}/key".path;
cert = sec."${service}/${cfg.host}/cert".path;
settings = {
devices = {
"snowbelle" = {id = "6WQ6ATA-5AT4RUM-NW67PAL-N62CPNV-ALRFG3P-5BDRO22-HWFC2Q4-5S5BDA5";};
"lugia" = {id = "BKKSFPH-YEOVVAB-DTT7KK3-UDKAEJ2-PC6ECG7-Y76ZIVP-JRYMMXS-RTZYVQ3";};
"zygarde" = {id = "UYLTF52-VVKUR7F-JN33HQZ-RFNWGL3-JER52LA-GZD2LPJ-QIFEE7K-MNMZRQ5";};
"mew" = {id = "7ZC2NAS-QONQKAL-Z54NPMB-7TRXM6M-K7Z6PZD-FG4AI4H-V7SMFJN-JOYBHQO";};
"yveltal" = {id = "ZVSQ4WJ-7OICYOZ-3ECES4X-KH37IPB-TKHKUJG-BSEGXVM-AHYY5C3-VKG44AX";};
"CEN-IT-07" = {id = "DPYKA4Z-3PX7JB2-FBEOXXX-SC7TLT2-QC5P2IR-SXOPJGX-QO3DMII-5B7UCA4";};
"CEN-IT-00007" = {id = "XBPXGYU-DUJSLDH-6BDNF4D-CO2COC3-N3FM6W5-IHZOJBM-Z2N77RI-IVAV5AH";};
};
folders = {
"holocron" = {
path = "/home/blake/holocron";
devices = ["lugia" "zygarde" "mew" "yveltal" "CEN-IT-07" "CEN-IT-00007" "snowbelle"];
id = "5voxg-c3he2";
versioning = {
type = "staggered";
fsPath = "/home/blake/holocron/.stversions";
params = {
cleanInterval = "3600";
maxAge = "0";
};
};
ignorePerms = true;
ignorePatterns = [
"// syncthing"
"/.versions"
"/.versions/**"
"/.stversions"
"/.stversions/**"
"// macos system junk"
"(?d).DS_Store"
"(?d).AppleDouble"
"(?d).LSOverride"
"(?d)Icon?"
"(?d)._*"
"(?d).Spotlight-V100"
"(?d).Trashes"
"(?d).fseventsd"
"(?d).metadata_never_index"
"(?d).com.apple.timemachine.donotpresent"
"(?d).com.apple.*"
"(?d)~*.tmp"
];
};
};
options = {
urAccepted = -1;
};
};
};
sops.secrets = {
"${service}/${cfg.host}/key" = {
owner = "blake";
group = "blake";
};
"${service}/${cfg.host}/cert" = {
owner = "blake";
group = "blake";
};
}; };
}; };
} }

View File

@@ -15,12 +15,15 @@ in {
services.tailscale = { services.tailscale = {
enable = true; enable = true;
useRoutingFeatures = "both"; useRoutingFeatures = "both";
authKeyFile = authkey_file; #authKeyFile = authkey_file;
extraUpFlags = [ extraSetFlags = [
"--accept-routes=false" # true is equilivant to useRoutingFeatures = "client" (breaks shit) "--accept-routes=true" # true is equilivant to useRoutingFeatures = "client" (breaks shit)
"--accept-dns=true" # explicitly allow resolved "--accept-dns=true" # explicitly allow resolved
]; ];
}; };
systemd.services.tailscaled = {
after = [ "remote-fs.target" ]; # keep tailscale up until remote mounts are unmounted
};
# network config # network config
networking.firewall.trustedInterfaces = ["tailscale0"]; networking.firewall.trustedInterfaces = ["tailscale0"];

View File

@@ -0,0 +1,16 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.system.udiskie;
in {
options.system.udiskie = {
enable = lib.mkEnableOption "enable udiskie for automount on nixos side";
};
config = lib.mkIf cfg.enable {
services.udisks2.enable = true;
};
}

View File

@@ -5,7 +5,7 @@
... ...
}: }:
/* /*
# to enroll a yubikey (works like .ssh/known_hosts) # to enroll a yubikey with pam (works like .ssh/known_hosts)
nix-shell -p pam_u2f nix-shell -p pam_u2f
mkdir -p ~/.config/Yubico mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys pamu2fcfg > ~/.config/Yubico/u2f_keys
@@ -15,6 +15,9 @@ pamu2fcfg -n >> ~/.config/Yubico/u2f_keys (to add additional yubikeys)
nix-shell -p pamtester nix-shell -p pamtester
pamtester login <username> authenticate pamtester login <username> authenticate
pamtester sudo <username> authenticate pamtester sudo <username> authenticate
# to enroll yubikey with luks
`sudo systemd-cryptenroll --fido2-device=auto /dev/<disk>`
*/ */
let let
service = "yubikey"; service = "yubikey";
@@ -37,9 +40,24 @@ in {
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
yubikey-personalization
yubikey-manager
];
# enable smartcard
services.pcscd.enable = true;
# enables it for everything
security.pam.u2f = lib.mkIf (cfg.mode == "u2f") {
enable = true;
};
# selectivlt edit what u2f is enabled for
security.pam.services = lib.mkIf (cfg.mode == "u2f") { security.pam.services = lib.mkIf (cfg.mode == "u2f") {
login.u2fAuth = true; #login.u2fAuth = true;
sudo.u2fAuth = true; #sudo.u2fAuth = true;
}; };
security.pam.yubico = lib.mkIf (cfg.mode == "challenge-response") { security.pam.yubico = lib.mkIf (cfg.mode == "challenge-response") {

View File

@@ -6,10 +6,22 @@ klefki_auth_map: ENC[AES256_GCM,data:u8OBLtT/,iv:THW21BDyhyFIjcwixsAnaAODofxbuQZ
tailscale_authkey: ENC[AES256_GCM,data:SU0k3asrJd+WZ86VbC4w8TDJp+MqsbyagrzCfDcgTzO5yvBjpWAKbJ7A+VxgQvdu4+S2jMYbdrONPp3YbQ==,iv:VMYmGVk5GpUQApKKQYhdOw/cYCXrXxEZJJwHfQL4MjQ=,tag:7ruaoCDxuFQ7tE/JLJ37Xw==,type:str] tailscale_authkey: ENC[AES256_GCM,data:SU0k3asrJd+WZ86VbC4w8TDJp+MqsbyagrzCfDcgTzO5yvBjpWAKbJ7A+VxgQvdu4+S2jMYbdrONPp3YbQ==,iv:VMYmGVk5GpUQApKKQYhdOw/cYCXrXxEZJJwHfQL4MjQ=,tag:7ruaoCDxuFQ7tE/JLJ37Xw==,type:str]
#ENC[AES256_GCM,data:bEbCic+ZDAA5ieNedCbiVbJrse17,iv:UwRYlis6NPB/RUcv+YnPxrGdbIcF4hrNiZt19YvWZNQ=,tag:m6PVlzPNnahX7X7KzMUj7A==,type:comment] #ENC[AES256_GCM,data:bEbCic+ZDAA5ieNedCbiVbJrse17,iv:UwRYlis6NPB/RUcv+YnPxrGdbIcF4hrNiZt19YvWZNQ=,tag:m6PVlzPNnahX7X7KzMUj7A==,type:comment]
borg_passwd: ENC[AES256_GCM,data:XOMJtr+DRs7xn5Iclc49iTzK9cFJyc/fSXJjhdKa9jdN,iv:YB8z7zNYjh6NpSxQb1TfPxAYUdzThdVfNZIe6tO5grA=,tag:bO6kZ3cLJDL4IQoWmGvRdg==,type:str] borg_passwd: ENC[AES256_GCM,data:XOMJtr+DRs7xn5Iclc49iTzK9cFJyc/fSXJjhdKa9jdN,iv:YB8z7zNYjh6NpSxQb1TfPxAYUdzThdVfNZIe6tO5grA=,tag:bO6kZ3cLJDL4IQoWmGvRdg==,type:str]
#ENC[AES256_GCM,data:ztRwuY0mTMDmwV5HqVR7Dmc+dCWcrVRtWZGEL1abE/WUcA==,iv:mmaWfHRiENJUGNhyUBFo1z7PdzVPH1OUZrVhkce6KV0=,tag:GKEvT0qkzTtimQXDueKPdw==,type:comment]
holocron_creds: ENC[AES256_GCM,data:2QXtXrN5w0UFn70GZOsYFPdtPwjLcuUdtkEam5aZ83N6LEDqPWJi,iv:kUS9pq5CX19vqHumc6QjY+Xpd4N+Ge7oCcQYtMFh+WM=,tag:IUA1ZVThF91EdHrwmS624g==,type:str]
#ENC[AES256_GCM,data:VdbMrwGKUKNJHw==,iv:OLwBh6KQXR/H8eRgp/hH8k3QfIkK/ydL735kx/dpc8E=,tag:N+v+ym6RMbvW4IckbiLK8Q==,type:comment]
syncthing:
gui_passwd: ENC[AES256_GCM,data:CicGIe5dT8lJVchCcE4wg3E8va3RYR8d53MISkE=,iv:8ziDDyQvU8ABaKKwYlcHmvm8Qybk4G+q5F0Ghqluu9w=,tag:YlyNPE04KD3detL1QUTrgQ==,type:str]
snowbelle:
key: ENC[AES256_GCM,data:MrAc4RXi6h4WOboZgBRjggPNGUrQwM1Vu5N5aPYBxeBZPi2ut8OApWcA9apWzYZNQTFF5QCtCpG9W+1CLJRG701PRK1Wf01r5SDI8aIXkgc2MjXuzS/y/WIqWoPK1nmtjxTYqaDR68II2tc/P7hgtf2EwYPV2JP6v6cCihADOKvXW1pBxi9kMjZGcbY54IyUrOdNauDvaZRgCSP7xtg8aWf1FlmJbiQgMW2lK/f+8rc/3OGS+ieFt35h29Khl4rhuYGB6rgTwvDaWa9g60rPzVcg6tKw+Unef99pA+CQnhVJJIejKlC07pCdqdjCUc+w0oQ69cVoucWeHqlq3xA7IvYIGi9K+OFCLmsoqjMe/wUSC/r2s/nnqbXsgVx9j8j0,iv:2FoZwwzKUky02Z34KRVP/jPhOMXnLZh841+4lybsbCY=,tag:ZL5qh3OcFjiWgqtmTCUFkw==,type:str]
cert: ENC[AES256_GCM,data:tvJX88ounzIzKmKcvEe0UtHrq51DMAIHGVZE2StqfNkn2QP+Er/geEh0wwmP9Q8+XBBjDT6oSAlWLjq6Tc1yYWSKju6Ig8GEJNDHL2UMVniBFzroSlO9hqZzbbNe1896WiwhhypvBoves7STTE7tJ2+Hzyss1BCYjcI+evGliJslq2nqxroMxIwBXfuDtxcTAeJ+SiKonY7W29NA05P1zYm6o6Td09VUS0cYWx2VUoP/8PMpeWLNciaHz8TjUeZ2Qob3pcNielu/VDqbunLvbFapqdV0hkl8gxgho+MmkC3+DXp/JDnG+vRm603wxqDECh6CNYc0CEXvM0/8gSXt6AkjATv6tBV98VeLknZkqVjBahtxrZuwquMuQbh1jD53RgsvnwB39FyFHZw29DGcUD0A7hIGnqSYVc2TXW+sgRxzXVFYsVrt1sWrYa2DpZT5zaFbps0dd194/j0SHOdf3p/4HF0GncWfTWLT89F/oAyJLio4X7yjES/DljgvmsrX0LdHnAYYAKDCWhZml3wSHBJ7Uvj1KiH2asxXkdiTPf8wulmwT+01hhBoX3QCkVYkdJpDbVddjLkwpLNyJATHctyuqzOdEMR4w5usTv9vKcgkMtbmxfWajb4lhjCpuaavkDUoI5h6eB8veXbZqAuX24bCvsLBWOVkg4qt1GGRqHx7+lfFanzMGyYYC/ufAXWD6eOOVsCjHJbHJoI16zq0HkfNpr30w+gO8hOyKgBP64anElzT3NB1sDi2GWxhSUKTDZ3rLsagPhZb3l3/u5SMf6lLWsY6IyFgPcVgY1snSOtd+PO9z9ipfyQZn4kKCtkNPPof8T58Qi7CP4KmVvbJsF67BH26SFclQLaJv5RO7e936vNwLrVhbyaclM0Vz6Y8wJvG4vW1Z4qPt6kP80NEATdrfwAr9nvZkb5rHqRWdxqIWSD5as+HPFzM/Mv0sBZ+B+CnsSv1btdB/iLacd032PGKXfZLxqGGOL1HIjM+QjSjaBTqrYcMke3GvnVfIujfdtcn9tOqGK+QYPS1CTYxWznmHloL2/WYwBY=,iv:qlIfrPxz7NvjkIXSkumfKvN0O1qq1S0T5j+37L8aReU=,tag:Qg8CYcDY/MaLWwNY566wBQ==,type:str]
yveltal:
key: ENC[AES256_GCM,data:unUnEeDhCqHUZCJtGCbj5rmrLx+9GiUTl75K3HdkI94YfCLNYCBACYu2v/7FbNIEsjVoQEA5/gKEcUHzVq6LaHM2w9GSo6tjkegdzTUgbHBJf4ssJ38z5rQkMc7tbzsA0NUHBPklz1eyjkW96HQPD0REcwA3CIc=,iv:PZ7vfhIpwPpMz4P04bewNhRuahmpukasgYb8fL/EJBE=,tag:G1HDyPAVSdm/fwqTXTT3PQ==,type:str]
cert: ENC[AES256_GCM,data:yLq2dNjdMiRj4reyZWsSqZ+1rw4DTwKBZoQHzeKb8YBn63ub4TZPlnOjSTt2DwOQwrJDNhsaeGscZ6J7rLxF/rtH6YnR8XxQuOu/NNIcZ4m9EqhsXyznSx4Q+0gamUXujRgGRVH5FNrfiFoqP3VuNghoX+NLxfX0BcVruEjbmLUWVVzY0yS0ufzxegM8WFAxuKhcr1NlhBU65TxKUtbj4vcByzWHkfLGIb5ICnGeF/p9/FvpFSavw3nLdybDLJ6EKEeaxy6t984fkuotAvk54kLbF4yt0q5mjDxy0U6xtn1hg3x03IRAPjKDRdpDmzYf4XxykEb74JX9q2zjUhb2l1ORWcZu/uKvEiuZWDJRmJ4ypOiyZOCqTvY6s2iDhEjmMKxlNr2mhuz9Hn6b3KoQjePIEd1eS/VEmo09pEuUlhlAEziVcdnpeRyWlN2xpv4ps90gLxJ1Mj9nAZwRqFOQl0V4N5OBHEqMBE1nQv4afMpGX5QF2UotTpNfka+LdKwc1iHHtpHZYmG1/LVwz3jDv4XnVLdDWojFA/8eJIWVq1BsUTYSy+Q27bsoTX4iL0Y/OAHRzXZTqYc4aiAWJoaNTNgmagZ9C03SA6qePlGe/5azI3f54rC2m1/JDUtYW3IABHSFUaVnTdWnD4GDNSYRJIknyUwXR4sE3pRD979prmgtepOyETOAVgEeUVKz1leJZ2HyyhjFU41TL0IN/sl+YPD9bC3Nmw7OsxMFGPC4l5vn64DVp7HHRSKyJvZ5fG8s4nSzyZAKomkocOpKHEuQPyyerZpL1lne/m2B/y7/W2ouAGxcawZOSU6f74mn5wM=,iv:Ggag5SNUFkhMWS0u1kwkD5tGjiMv4i041bCESl5XOdc=,tag:pPISz0eBWzHcPHsC8dVG3g==,type:str]
mew:
key: ENC[AES256_GCM,data:8i2thp667lKEXR0cIaEOLHPXWlhFS38FvbtHgni3i0dTBx9DYtJbGogNaWMlA8r2HzBHkG3Jg0nJs7IOrJWugnGLNLbvhdsxBswEndOBaed4vq+SSN6ssxdjjyFd38wlIZNZsytjPFhyRgDLJ+0rftcIQXPjBhU=,iv:IZ3zWD/ZpalOzSAJQubo/y4LcEzHMEcl+C4GB3Q/nac=,tag:IKEwIkuvHE6qrUoCEqI2Ug==,type:str]
cert: ENC[AES256_GCM,data:uvNZYmQnexXTr/Sz7vLQIJK93MmsoiJfCAL8/rLVQH0D+1nVaM472lqR5pP0qhLKuYhFUESxhAotVtqLpOWK1MfAxuk2RHv8mvbtIJkheRmsIWw7dAAABIkmgnelI03P2Tk2129I95vMM1lybu4W6m9VslwJF8X/4rCxshdbuz9mcjwxBpUEDr1V76DO3bgQUuPwizx17ON8gNd+NtRqPPaXlGrfLCFv1Fib3YFd7+WRkERki9ZO7Q0quY75G4Jseb28QaiM2BT7jfECJo4x7rMePMV303sIrF9paaUKTuSiCUsamLsi5Hwr907y2lHB9Gocwio7tnSRSRhHHcWLI8dQktzW7Flqs8+MZGZ1oJBQO7kQDefF1q4mddADimoqD9F1NsOiOmqqZRRB37alLGmRjeYBIlA6q/FgN9BAj9h0cG3oN1MUXPRGzDfggg5TLjBM2FbG/N3xgncZ2AzTPOcLtrtc0I2PYk3FFxgzpHWnjS2t7CQo/JxqdXbdy9nTHIqbrnKIQ/FtS7/p+cgQcU815UMsJm3qP+hPLCyNuziYq3Vt/X7C3eTnrqemXjEeJ/SJxb+Oul5GS1OL14dNsJllFNuj33Zep/hyQvHnf/HW7kXAfDqIP9zn85EFriAZEuaKwbHB2pkvbWKFxrpXJFhjnPFDKxGOjAmsLmil4paFKdt5hK7rp0mmoIMN+mMFbYx333llik0qk27yYTQwOR3eeCGqHODUU+izUT8NuQBezyxsEmEYu/YBcpatcYylwKgIFcC058oltsxlbxRg5Rrdk5FOqj7Uui0qwFXvYesz6Tiq/rGmcOPlcE5xw14=,iv:LePpzWGDTV1ONwt1uHUptMW1dO1SwwUKrtCEerc/DEc=,tag:a5B/7hmIxvLXU90Stcq7zA==,type:str]
#ENC[AES256_GCM,data:A0ITyGOGMIoyVOcn5JOi1RAtqUM=,iv:+wWpmFbeLiX/Ae53pj0QmnYY3MEzOMib4cqbePUKtGI=,tag:JHXvrN4bOH+oD3Q70pUuew==,type:comment] #ENC[AES256_GCM,data:A0ITyGOGMIoyVOcn5JOi1RAtqUM=,iv:+wWpmFbeLiX/Ae53pj0QmnYY3MEzOMib4cqbePUKtGI=,tag:JHXvrN4bOH+oD3Q70pUuew==,type:comment]
pia_auth: ENC[AES256_GCM,data:rwAu4f5XVS4v4FCLj2zXAegIZeRPLIzUVv6TCrdfg9RGSDJYHgVAX0aFXCBQsDQju9RDycXmc9Id8IuyYN8=,iv:kEA4ADQyUI+zlQoZOKi81dw5BLE1oesqhVf6bfiLgB4=,tag:VHT2uPNW27F3KRM7ZhWdCw==,type:str] pia_auth: ENC[AES256_GCM,data:rwAu4f5XVS4v4FCLj2zXAegIZeRPLIzUVv6TCrdfg9RGSDJYHgVAX0aFXCBQsDQju9RDycXmc9Id8IuyYN8=,iv:kEA4ADQyUI+zlQoZOKi81dw5BLE1oesqhVf6bfiLgB4=,tag:VHT2uPNW27F3KRM7ZhWdCw==,type:str]
#ENC[AES256_GCM,data:7y1mtYNfbsagqtr66kOx2rinneEW3EZaCJIXzK0qjLX36g==,iv:8ozXuBYirLbKd8sCln2xv/WjhTojY85xU0cL5NVeMlQ=,tag:mclz0GfQ9j2EGWMiQ62QmA==,type:comment]
openvpn_pia_mexico_config: ENC[AES256_GCM,data:59HQ3OZ0QKq92jI=,iv:DZTNvfi6kLXG7dsNkPcXUmXhAG2UdPZBy/L9eWNmRdE=,tag:ndxDDQNL2z1fjxFfU2VRwQ==,type:str]
#ENC[AES256_GCM,data:mbIgMJBhL8nWJzl8q2dFL8XtO1Xa1Q==,iv:caYHYp1boK9wRgCcQe40HTWT/HxAIvYe+HyaruI53Vc=,tag:S6wowhAHObEcs7z8FimZ1g==,type:comment] #ENC[AES256_GCM,data:mbIgMJBhL8nWJzl8q2dFL8XtO1Xa1Q==,iv:caYHYp1boK9wRgCcQe40HTWT/HxAIvYe+HyaruI53Vc=,tag:S6wowhAHObEcs7z8FimZ1g==,type:comment]
wg_mex_key: ENC[AES256_GCM,data:vxDXixo6X6D33+p21L4hB0/yCH+TvMHZl991BkRsE/jdz7rzZuJF+zI7h+Q=,iv:8WR+feHXNUcat8DB2wY7wpos+P7TzgRF7rFD0fYosjY=,tag:p9b9ck0/VZjyLxtHut3n5Q==,type:str] wg_mex_key: ENC[AES256_GCM,data:vxDXixo6X6D33+p21L4hB0/yCH+TvMHZl991BkRsE/jdz7rzZuJF+zI7h+Q=,iv:8WR+feHXNUcat8DB2wY7wpos+P7TzgRF7rFD0fYosjY=,tag:p9b9ck0/VZjyLxtHut3n5Q==,type:str]
#ENC[AES256_GCM,data:CO5nrcDbgymnEmCvuTexOBEMncuNM5lQ,iv:6HrxqSN6e7ODuz09MIFgPbIqDCKQySRDaKk5Wdu4HoQ=,tag:JBRjZeEdOg+trohfanO6Mg==,type:comment] #ENC[AES256_GCM,data:CO5nrcDbgymnEmCvuTexOBEMncuNM5lQ,iv:6HrxqSN6e7ODuz09MIFgPbIqDCKQySRDaKk5Wdu4HoQ=,tag:JBRjZeEdOg+trohfanO6Mg==,type:comment]
@@ -22,6 +34,10 @@ minecraft_recpro_db_passwd: ENC[AES256_GCM,data:dPAkdEX0hBigo/lND2r3ShxnS4Jc5wTI
#ENC[AES256_GCM,data:nbB5Cd7i/KTMCjCzcX8o1sxREZQ/gLAG,iv:iyuO2erxdJM08WHJBjKuNIXYxVhH7rfyOLTcGCcGqNQ=,tag:UeDszimXv8kQUmDetLeFqg==,type:comment] #ENC[AES256_GCM,data:nbB5Cd7i/KTMCjCzcX8o1sxREZQ/gLAG,iv:iyuO2erxdJM08WHJBjKuNIXYxVhH7rfyOLTcGCcGqNQ=,tag:UeDszimXv8kQUmDetLeFqg==,type:comment]
mosquitto_hashed_passwd: ENC[AES256_GCM,data:k1Lnr8ZTDpzXMoRmRH61X41boX/D8Rm1KPh7x3/IHFo+XKIOUQns53iA+7e7Ohp8uWSthDlOk4SlRvTXdUNiEz7Zmw9LYwy7BHbwpNo2pFApAye1ORPrMrhMUkUfgBgc8oqPPyRXmmrOAFp6GBbRhg==,iv:D8wQL9iF0rqOte5X24kDTVjYUJXbZSLz0Ykbp0HqmYo=,tag:RUCgO1uKPIdumSo563cg1Q==,type:str] mosquitto_hashed_passwd: ENC[AES256_GCM,data:k1Lnr8ZTDpzXMoRmRH61X41boX/D8Rm1KPh7x3/IHFo+XKIOUQns53iA+7e7Ohp8uWSthDlOk4SlRvTXdUNiEz7Zmw9LYwy7BHbwpNo2pFApAye1ORPrMrhMUkUfgBgc8oqPPyRXmmrOAFp6GBbRhg==,iv:D8wQL9iF0rqOte5X24kDTVjYUJXbZSLz0Ykbp0HqmYo=,tag:RUCgO1uKPIdumSo563cg1Q==,type:str]
mosquitto_passwd.yaml: ENC[AES256_GCM,data:9xwHiUaQ6zG/4rkRemXtbRJ/KEV4yajqyYlcXRR1eAQ2XijYOzitPjt53h3FPqp5rxl6dJerXNH5CiZZK3t1l339NxNseJFGVmIHitWJxNmGJMlG3M8r8Q==,iv:C6WWZuVkYaasB2pol3uf4Mc3d/lDEgt2pKX+dHl/Cr4=,tag:jYTC6RKF2TzDSwSUh6D8zQ==,type:str] mosquitto_passwd.yaml: ENC[AES256_GCM,data:9xwHiUaQ6zG/4rkRemXtbRJ/KEV4yajqyYlcXRR1eAQ2XijYOzitPjt53h3FPqp5rxl6dJerXNH5CiZZK3t1l339NxNseJFGVmIHitWJxNmGJMlG3M8r8Q==,iv:C6WWZuVkYaasB2pol3uf4Mc3d/lDEgt2pKX+dHl/Cr4=,tag:jYTC6RKF2TzDSwSUh6D8zQ==,type:str]
#ENC[AES256_GCM,data:zmSByl0De3a39qLbS99oce7ORe2BBoPa+3I05/YYxL7iBeWCP3ZK,iv:6nUTBUFpNK7Mttckqu6Wk/QJ5cP4+iL+EH4ldaIuu9s=,tag:pc5UtjbNPsVOEMCdLKgGMA==,type:comment]
#ENC[AES256_GCM,data:ZWlAWAthigdTlfHrQl1x8eSj+gv4Gj1poZfPViu1mVz/ZmUJFZyCSkdIg0CPdNNF38TE0iabBk+o7aHkFmIFz18hjVYAk4M2E034qg==,iv:jU+2E+XAILgFNyMkGZ1CMJ83q7V/yyEJwHXWw05RlHo=,tag:n8w0/ktmum5P31vMWJVxgA==,type:comment]
postfix_passwd: ENC[AES256_GCM,data:3ndIsTGPyAQELM8lptBK241a3p77fNijXma4souFKnyrkLBpZ4OP6KWuldFlWySpSG7Yme0by5gOzg==,iv:nYuJKeY4H3OfQleLo7gvheT5JHgXW3hGQvjHeEEN260=,tag:q952E/0QLC49O5Rwua0RWQ==,type:str]
#ENC[AES256_GCM,data:UcpnHZj5xr8P64PzhWVKbFy8pvFM9GCz2mDoW/6iRVqgLTL0FSn6KXep/kfLEnYiqv5ZpsVZjjXsbI5VRJfBo7w4kzX661oDU8323DfQHDkbo2g=,iv:nEApgutl5kjfZkwi9WTOwatraM3+TQqFgk5gEMw0rwA=,tag:Q4gndL+6q7jHN02QCpJDjw==,type:comment]
#ENC[AES256_GCM,data:3oMbbBSrbjrqsdiON1ENB8JeKW0=,iv:+/eL/51OA+VHbkWWSNzQId5BlxnMm+5NBA0uKw010Tk=,tag:vBJpCYmvFivBYIKatDWgHw==,type:comment] #ENC[AES256_GCM,data:3oMbbBSrbjrqsdiON1ENB8JeKW0=,iv:+/eL/51OA+VHbkWWSNzQId5BlxnMm+5NBA0uKw010Tk=,tag:vBJpCYmvFivBYIKatDWgHw==,type:comment]
copyparty_passwd: ENC[AES256_GCM,data:I3UYy4nJ0B6RnIp661O0VVqEmxloxxcroBKmNFcgoQ==,iv:sWkPfKqomrNaYFZbn+BeQEugRMlaqi1qJhELqfsGCik=,tag:Sgz56ZW9EY49zfwFDN7whg==,type:str] copyparty_passwd: ENC[AES256_GCM,data:I3UYy4nJ0B6RnIp661O0VVqEmxloxxcroBKmNFcgoQ==,iv:sWkPfKqomrNaYFZbn+BeQEugRMlaqi1qJhELqfsGCik=,tag:Sgz56ZW9EY49zfwFDN7whg==,type:str]
#ENC[AES256_GCM,data:3ATkokBKeOp97uORzaePROrKKfG94ic=,iv:MNJRh6Vrso1heqNUJc0M4xGNcMLGwcF9IzoiQ5+SS+g=,tag:xj8Actwkirvq4GE+Ly1M9w==,type:comment] #ENC[AES256_GCM,data:3ATkokBKeOp97uORzaePROrKKfG94ic=,iv:MNJRh6Vrso1heqNUJc0M4xGNcMLGwcF9IzoiQ5+SS+g=,tag:xj8Actwkirvq4GE+Ly1M9w==,type:comment]
@@ -33,9 +49,12 @@ id_snowbelle: ENC[AES256_GCM,data:MAw5R2fqVIctN7fB/d3hfCU7W3sxvuy2O3w3n0vD8FxK1D
#ENC[AES256_GCM,data:ozhgyE+IyqR10KT8vI9x,iv:+ZOTucRlCZRQ9ZbxZgySPMOJ/qU4gXbhSyLAMgt4QMs=,tag:mQ3X+dqCet1Yk1gZ5pZ5gw==,type:comment] #ENC[AES256_GCM,data:ozhgyE+IyqR10KT8vI9x,iv:+ZOTucRlCZRQ9ZbxZgySPMOJ/qU4gXbhSyLAMgt4QMs=,tag:mQ3X+dqCet1Yk1gZ5pZ5gw==,type:comment]
id_snowbelle.pub: ENC[AES256_GCM,data:rQ32bqwknbVssJDN4TW72YrusMPQJRFTfpoH2M2ELsAf3DkXtchGwOSjEbeR9ezUgHkTD96rFm5JvjDFQukAOpBHfMP5aRVy6RjTtb8j7aAD+EGUEpBSAVspZKQAWAqyDQ==,iv:8bEgvJgWpu7QwsrWhkjUw3GtRI92Pn7TT0rXCQ/i2Js=,tag:EnUehKMncN5v4dZZ/es3Qw==,type:str] id_snowbelle.pub: ENC[AES256_GCM,data:rQ32bqwknbVssJDN4TW72YrusMPQJRFTfpoH2M2ELsAf3DkXtchGwOSjEbeR9ezUgHkTD96rFm5JvjDFQukAOpBHfMP5aRVy6RjTtb8j7aAD+EGUEpBSAVspZKQAWAqyDQ==,iv:8bEgvJgWpu7QwsrWhkjUw3GtRI92Pn7TT0rXCQ/i2Js=,tag:EnUehKMncN5v4dZZ/es3Qw==,type:str]
#ENC[AES256_GCM,data:lS++LQwlDVP0aYcdaaudBkKxNB3P3UBE,iv:UqGcXcX/Jvf60o409Cxj7VJCDh63uUxy45PuZbHK2l8=,tag:OXdMwuJwdN8DQaLXACpcRA==,type:comment] #ENC[AES256_GCM,data:lS++LQwlDVP0aYcdaaudBkKxNB3P3UBE,iv:UqGcXcX/Jvf60o409Cxj7VJCDh63uUxy45PuZbHK2l8=,tag:OXdMwuJwdN8DQaLXACpcRA==,type:comment]
ssl_blakedheld_crt: ENC[AES256_GCM,data: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,iv:VQIqXN3r7DOVREX4fP5/OR8xECXLjYKfhd6XP3ghMaY=,tag:eVdyxrw/w5zBGxV6Tai2Pg==,type:str] ssl_blakedheld_crt: ENC[AES256_GCM,data:OPrDCh56XdRLslAcx/vw9l7gvc42no+QzB9tVSLHtcHbWWqb+hefvAE6xnfMLlt5+BRuAJRvspA6kx/WfagjFuN7q3HAHPt/FcfZPCYZNT5wXZH59wtV8JkVtLKnCxqSUXrah9a/WrHkU7njzoWql53eoAXEt58mvxyxZihqZd/uwinZt/T4QsevmikIsB3LB7AQtUHfsHd13ZFAaGiA+Mnncdl6Nt5s3U4yTuUxhfmYwr2cuyL+Li5eNzdO2ZooXBySdp4Ym03rpBERuh0U8a7NNj5ZaoHW1f0AyFRRKQ7RIHHyhQNC6hL2eGqsv+hTkJCJKxOCYKW1cF9rDt6bueKAm7zk3RTw0Sk7eXaOoqulCf8vBcMf4ckfH5mFVUpSHuwc4lfIZExjggn2i7Bu7xGIOLqC1RL4S5cuhLGUxzgvCiKMcMmaZZcT+fZa5wiHzv2vaCzXuYRb1rNi0xoiAZcL65yIV0NGtP0mOFygdY2hI4R7itbcE0MGIbwdOuWkCRs19WVFchNgcV7GnZBUVKAbhFXq+GilWLufODJr4Zxc1NpxRjG4flWQl3A3jGc4+tW5Infa1n6XPmhHz6JjyPE2mVbLq4JORPHeMcN4Wbckrmio0ruJu5rV9J95HYceXJIF2dw7AgmaWEX67JCHJPbAg5n4zRrfraeMwKB7XHTMglTLbyQsw7zkqzGDpT6ztOn/uCtErEmU0LSlIcOzz8WdGnnWbReMLiUfrQwuKvJhwOpcr9t+FVAtDyjyZhL/PTDy4/qIjQNPwBiVMKzv1CV/eA1WHcYKb6oRvP2TAlh82mA5uIE1jqY9QXg1cfMl2ncnsHnv3d1iFHy3OxvmWwvve+1zzJ2jubh+1ZwKAjP/9UEq9eldyFqC86qYKYGXec5j4Q4QGrMN4AiObVI/yDnRdeWal8jM8p5cz56rgBesDX7/ljR5wjifdQ5s4Iao2exPrHAWtiJHWE1i4R1g4rB+h8piu4feZXiPh3chdxrUrxCaQK0N0nOkN6+F7y8rbd6egk9Q5xvjNlJGzJGiSQ9xhDYmnPZtUTWXL3KioIPwy2/yh+lpkG/JrUacgc+HaHO+DsXs2NhlObrcswo4zmZ1eEckwFSpl1iP5ABHTxNVY0V6pdj1+7YyB+wav8tlVfguyxLf8JV7dqVnADCV+R5D5rBikmoJdjgdZwNxO0QBaZFVLeaCSgoCVEfvSPFtL9cMnEhLhdtw+k3U53+JJYemRfdh48DAM01Na2b9q6Ey2R6YrqtONVIauMNAaKXOeaJCxJhYVBqB8yNiAOOhyJ/Wvzq/CUM1QsXHQvwbndAxmyeFc8XSo7HZZME9m11fNvcEdWfdm63BpwkrHKPzQc7sR6tKeMy7l48f1baPTNoevEd0vFeURHoOggrnyBeO4q8YdLCderFmsSOzyDP+KjDxwTE6u+4P2xMXfnjwTpxLZInV+sNPsgaMj/bBeOJr7m6IN8N3/jxgPiBTGMObiVCIzhXL/VP352xc7Vbh5ZjMvuXQIPWCodPjWV6kcK8EvanN/l0vbDh1MxMAFiqj6tRHUfB0Px0JiC263kR0vzEDI1K6qEfPmPjA8TiDo1tK,iv:qdtzMcF1iELnhrCs3SboRcAsnw/0WgcUpWWHzKHNEYc=,tag:TkUMk8Wp2OTQd8CRtS07Wg==,type:str]
#ENC[AES256_GCM,data:3G8XqUKua1QgUxv2YJkW0fDnQPX7+v8GDC9BHg==,iv:BkESkMmMalgesy9why9eaKkOOvwSsN2EhNCRRRmZNtA=,tag:x95zt2B2M19BkzeMpAlXIg==,type:comment] #ENC[AES256_GCM,data:3G8XqUKua1QgUxv2YJkW0fDnQPX7+v8GDC9BHg==,iv:BkESkMmMalgesy9why9eaKkOOvwSsN2EhNCRRRmZNtA=,tag:x95zt2B2M19BkzeMpAlXIg==,type:comment]
ssl_blakedheld_key: ENC[AES256_GCM,data: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,iv:T1sDL6oXItF2spTr4cbAjJ8WFdSHVN8cInElC5ZC2NM=,tag:OVJiimHRgHi4lJTELjx0iA==,type:str] ssl_blakedheld_key: ENC[AES256_GCM,data:JCjbKYU6p7CTMtnWotZWBvW7vmLQ9MAP3bejcOteLLFLDZfmNguqA5h/8s0wLbjGnbGiNnupkvyWPCkC4xhO+fVq9Jzl7+YPEZn3uKjG7vyLlbVhLsmv3BleR01jddEJv+2fn2QztP3CfbocPHm2QaQhCqgfxxvcSpy0SlN3IOKckQaQB1oDJB+nHndPLN5VGwABE+b4x1AoYltfoFvNiGam8xXu31ENOz0WPVzi0Xmw/noVoS627BK/P+ISC1KP/iGuyRiWVmF2P8dN2oAtUarC2JV63/HevmN225pszBIyEeDta2Wv2QCNBYzUsDr5NA==,iv:fPuepEZUNjGWekTCfROyMoPdsioissEqvR2gZu+2NAQ=,tag:fVPI22eUYXOSI2A/MSbsEQ==,type:str]
ssl_recpro_crt: ENC[AES256_GCM,data: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,iv:5KucKtHOeiviRb8AIhF54CuFx/RxxYifrQP2vvIr0zk=,tag:r5pvRK0BAO9nkgFPPUSMMw==,type:str]
#ENC[AES256_GCM,data:3G8XqUKua1QgUxv2YJkW0fDnQPX7+v8GDC9BHg==,iv:BkESkMmMalgesy9why9eaKkOOvwSsN2EhNCRRRmZNtA=,tag:x95zt2B2M19BkzeMpAlXIg==,type:comment]
ssl_recpro_key: ENC[AES256_GCM,data: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,iv:682Ok4M7ptRiWBytvbbiDyBCKBdZ51AIn7VWA62GdBk=,tag:UWsWZnDZ10dMF2vAB8V8tA==,type:str]
sops: sops:
age: age:
- recipient: age14gfh682a7m7jfp3qrulql03x5rs7yedwmxwksxrrmgjsunstyuksqx93pz - recipient: age14gfh682a7m7jfp3qrulql03x5rs7yedwmxwksxrrmgjsunstyuksqx93pz
@@ -47,7 +66,7 @@ sops:
U0tmdFBuZnJES3piOTZNV0VKQmQ0eVUKCWRQ/flLzmpC64WyLoipklZBmrkpYiUg U0tmdFBuZnJES3piOTZNV0VKQmQ0eVUKCWRQ/flLzmpC64WyLoipklZBmrkpYiUg
PRu+itNolpPTHm96pe+P93g2iP0wgekG0cX21wkiU2xaLF3dY2FEIA== PRu+itNolpPTHm96pe+P93g2iP0wgekG0cX21wkiU2xaLF3dY2FEIA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-10-17T08:24:51Z" lastmodified: "2026-01-28T21:02:05Z"
mac: ENC[AES256_GCM,data:kIlrr+U7+O1Ocdi8CffmQNOQYh46crnaaQHBOkeOwG4AuAErNb1UjhZiOUELYD6bTG4GnIw0QGAS6xu+C22aA/jKsg/Z0q/LjX3FPDLLmLyEXhjIDVB+DOsxUsUWupZqGOq+HoBWuVYt11kc2ylPqqC5JlxNwQpIXGa1YgsKaNQ=,iv:L813P4Zvse38E2+K1wv0kTrPYgaKQc0rAleGGfhJRyA=,tag:k0v2ApQincLnu1Pd3WOkGw==,type:str] mac: ENC[AES256_GCM,data:b9aX43ViObNX29DkVNHtwkQRm26PRe2rZYhDnL1ZYLLWyaO3OGP9+rM4vHT0lyuowQ6+Ur3IMPVpUSziXYLh3mtxr0hyYy5Y1miBuIxXYLBi3oLRTW1TgZdklzFDVL3c1GT4lXEh4q9KG3dP64r9/8dvjO2iRIosZ93/l0pIi3A=,iv:/gdNfVy8UiQsIRAHh2jiha5fL+wmfgp0srxt17Ry4Xs=,tag:YdVbvpBnQSaIarGIfiTzKQ==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.11.0 version: 3.11.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
forbidden

View File

@@ -0,0 +1 @@
wait

View File

@@ -0,0 +1 @@
background

View File

@@ -0,0 +1 @@
link

View File

@@ -0,0 +1 @@
move

Binary file not shown.

View File

@@ -0,0 +1 @@
default

View File

@@ -0,0 +1 @@
size_NeSw

View File

@@ -0,0 +1 @@
size_NeSw

View File

@@ -0,0 +1 @@
size_NwSe

View File

@@ -0,0 +1 @@
size_NS

View File

@@ -0,0 +1 @@
size_NS

View File

@@ -0,0 +1 @@
precise

View File

@@ -0,0 +1 @@
alt

View File

@@ -0,0 +1 @@
forbidden

View File

@@ -0,0 +1 @@
link

View File

@@ -0,0 +1 @@
size_EW

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