summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvin <vin@vineetk.net>2025-09-20 17:31:10 -0400
committervin <vin@vineetk.net>2025-09-20 17:59:06 -0400
commitbd18f4a8f3d5d3d360216bbb01ae83514c28d00c (patch)
tree020d9404a8b4825f9bd4ab3f4f0146012e75183d
parent1718f4f19bc947c3e1179a278e816310a3c8cec6 (diff)
prepare repo for switching back to nixos
-rw-r--r--home.nix727
-rw-r--r--hosts/demiurge/default.nix509
-rw-r--r--hosts/hastur/default.nix297
-rw-r--r--secrets/secrets.nix9
-rw-r--r--secrets/tailscale_demiurge.age10
-rw-r--r--secrets/tailscale_hastur.agebin371 -> 0 bytes
-rw-r--r--secrets/tailscale_saklas.age11
-rw-r--r--secrets/wg0_demiurge.age7
-rw-r--r--secrets/wg0_hastur.age8
-rw-r--r--secrets/wg1_demiurge.age7
-rw-r--r--secrets/wg1_hastur.age7
-rw-r--r--secrets/wpa_supplicant.agebin0 -> 1095 bytes
12 files changed, 552 insertions, 1040 deletions
diff --git a/home.nix b/home.nix
index 6497147..a56ea21 100644
--- a/home.nix
+++ b/home.nix
@@ -37,6 +37,28 @@ let
37 }; 37 };
38 extraPkgs = pkgs: [ pkgs.icu ]; 38 extraPkgs = pkgs: [ pkgs.icu ];
39 }; 39 };
40
41 my-texlive = with pkgs; texlive.withPackages (texlivePackages: with texlivePackages; [
42 # A minimal base scheme and a common build tool
43 scheme-small
44 latexmk
45
46 # Packages from your research paper's preamble
47 amsmath
48 graphicx
49 siunitx
50 booktabs
51 algorithm2e
52 caption
53 pslatex
54 ec
55 microtype
56 cite
57 url
58 xcolor
59 hyperref
60 ]);
61
40in 62in
41{ 63{
42 home = { 64 home = {
@@ -45,68 +67,50 @@ in
45 stateVersion = "24.05"; 67 stateVersion = "24.05";
46 68
47 packages = with pkgs; [ 69 packages = with pkgs; [
48 # normal utils
49 neofetch
50 rclone
51 wcalc
52
53 # programming
54 python3
55
56 # CAD software
57 kicad
58 openscad
59
60 # document writing and viewing 70 # document writing and viewing
61 mupdf # needed for emacs docview 71 mupdf # needed for emacs docview
62 texlive.combined.scheme-full 72 my-texlive
63 zathura
64 73
65 # messaging 74 # messaging
66 profanity 75 profanity
67 vesktop 76 vesktop
68 77
69 # email 78 # email
70 notmuch 79 muchsync
71 oauth2ms 80 oauth2ms
72 81
73 # hardware 82 # hardware
74 acpi
75 acpilight
76 amdgpu_top 83 amdgpu_top
77 84
78 # encryption 85 # encryption
79 age 86 age
80 age-plugin-yubikey 87 oath-toolkit
81 oathToolkit 88 # TODO actually use my yubikey?
82 yubikey-agent 89 #age-plugin-yubikey
83 yubikey-manager 90 #yubikey-agent
91 #yubikey-manager
84 92
85 # system utils 93 # system utils
86 dmenu
87 file 94 file
88 htop 95 htop
89 mlocate 96 mlocate
90 ncdu 97 ncdu
91 tree 98 #tree
92 unzip 99 #unzip
93 p7zip 100 #p7zip
94 page
95 fd
96 ripgrep 101 ripgrep
97 102
98 # X and desktop-related 103 # X and desktop-related
99 scrot 104 scrot
100 sxiv 105 sxiv
101 xclip 106 xclip
102 xdotool
103 xwallpaper 107 xwallpaper
104 108
105 # wayland and desktop-related 109 # desktop-related
106 grim 110 dmenu
107 slurp 111 scrot
108 wl-clipboard 112 xclip
109 wmenu 113 xsel
110 114
111 # 3d printing 115 # 3d printing
112 prusa-slicer 116 prusa-slicer
@@ -210,9 +214,9 @@ in
210 214
211 accounts = { 215 accounts = {
212 university = { 216 university = {
213 address = "***REDACTED_EMAIL***"; 217 address = "vsureshkumar3892@floridapoly.edu";
214 realName = "Vineet Kumar"; 218 realName = "Vineet Kumar";
215 userName = "***REDACTED_EMAIL***"; 219 userName = "vsureshkumar3892@floridapoly.edu";
216 passwordCommand = "oauth2ms"; 220 passwordCommand = "oauth2ms";
217 221
218 imap.host = "outlook.office365.com"; 222 imap.host = "outlook.office365.com";
@@ -386,6 +390,20 @@ in
386 390
387 mpv = { 391 mpv = {
388 enable = true; 392 enable = true;
393 package = pkgs.mpv.override {
394 archiveSupport = false;
395 bluraySupport = false;
396 bs2bSupport = false;
397 cacaSupport = false;
398 cmsSupport = false;
399 dvdnavSupport = false;
400 javascriptSupport = false;
401 pipewireSupport = true;
402 pulseSupport = false;
403 rubberbandSupport = false;
404 waylandSupport = false;
405 zimgSupport = false;
406 };
389 407
390 bindings = { 408 bindings = {
391 # I wish there was a more elegant way of setting Anime4K 409 # I wish there was a more elegant way of setting Anime4K
@@ -414,197 +432,23 @@ in
414 }; 432 };
415 }; 433 };
416 434
417 neovim = {
418 enable = true;
419
420 extraLuaConfig = ''
421 -- my better defaults
422 vim.opt.autoindent = true
423 vim.opt.autoread = true
424 vim.opt.backup = false
425 vim.opt.hlsearch = false
426 vim.opt.relativenumber = true
427 vim.opt.ignorecase = true
428
429 -- colors
430 vim.opt.bg = "dark"
431 vim.opt.colorcolumn = "80"
432 vim.cmd("colorscheme everblush")
433
434 -- mappings
435 vim.g.mapleader = " "
436 vim.keymap.set('n', '<Leader>g', '<cmd>Neogit cwd=%:p:h<cr>')
437 vim.keymap.set('n', '<Leader>l', '<cmd>ls<cr>')
438 vim.keymap.set('n', '<Leader>tt', '<cmd>Telescope<cr>')
439 vim.keymap.set('n', '<Leader>tb', '<cmd>Telescope buffers<cr>')
440 vim.keymap.set('n', '<Leader>tf', '<cmd>Telescope frecency<cr>')
441 '';
442
443 plugins = with pkgs.vimPlugins; [
444 {
445 plugin = (
446 pkgs.vimUtils.buildVimPlugin {
447 name = "everblush-nvim";
448 src = pkgs.fetchFromGitHub {
449 owner = "everblush";
450 repo = "nvim";
451 rev = "9a0e695fdd57b340d3ba2b72406e3ca519029f25";
452 hash = "sha256-O6Erp+Tzk5TV5gpgVs73cO6v9vgeUVYpunrtf/7Ppic=";
453 };
454 }
455 );
456 config = ''
457 lua << END
458 require "everblush".setup {
459 transparent_background = true,
460
461 override = {
462 LineNr = { fg = "#b3b9b8" },
463 },
464 }
465 END
466 '';
467 }
468
469 # languages
470 vim-nix
471
472 # qol plugins
473 {
474 plugin = which-key-nvim;
475 config = ''
476 lua << END
477 require "which-key".setup {
478 delay = 300
479 }
480 END
481 '';
482 }
483 neogit
484 gitsigns-nvim
485
486 # telescope stuff
487 {
488 plugin = telescope-nvim;
489 config = ''
490 lua << END
491 require "telescope".setup {
492 defaults = vim.tbl_extend(
493 "force",
494 require "telescope.themes".get_ivy(),
495 {
496 layout_config = { height = 10 },
497 }
498 )
499 }
500 END
501 '';
502 }
503 {
504 plugin = telescope-zf-native-nvim;
505 config = ''
506 lua << END
507 require "telescope".load_extension("zf-native")
508 END
509 '';
510 }
511 {
512 plugin = telescope-frecency-nvim;
513 config = ''
514 lua << END
515 require "telescope".load_extension("frecency")
516 END
517 '';
518 }
519
520 # tree-sitter stuff, mainly for better syntax highlighting
521 nvim-treesitter
522 nvim-treesitter-textobjects
523 ] ++ (with pkgs.vimPlugins.nvim-treesitter-parsers; [
524 arduino
525 asm
526 awk
527 bash
528 bibtex
529 c
530 cmake
531 commonlisp
532 cpp
533 css
534 csv
535 diff
536 disassembly
537 dockerfile
538 forth
539 git_config
540 git_rebase
541 gitattributes
542 gitcommit
543 gitignore
544 go
545 gomod
546 gosum
547 haskell
548 html
549 ini
550 json
551 kconfig
552 latex
553 lua
554 luadoc
555 luap
556 luau
557 make
558 markdown
559 markdown_inline
560 meson
561 muttrc
562 nasm
563 ninja
564 nix
565 ocaml
566 ocaml_interface
567 ocamllex
568 printf
569 python
570 r
571 regex
572 rust
573 scheme
574 scss
575 slang
576 sql
577 sway
578 tcl
579 toml
580 udev
581 xml
582 yaml
583 zig
584 ]);
585
586 viAlias = true;
587 vimAlias = true;
588 withNodeJs = false;
589 withPython3 = false;
590 withRuby = false;
591 };
592
593 notmuch = { 435 notmuch = {
594 enable = true; 436 enable = true;
595 extraConfig.user = { 437 extraConfig.user = {
596 name = "Vineet Kumar"; 438 name = "Vineet Kumar";
597 primary_email = "me@vineetk.net"; 439 primary_email = "me@vineetk.net";
598 other_email = "vineet@vineetk.net;***REDACTED_EMAIL***;kar@13f0.net"; 440 other_email = "vineet@vineetk.net;vsureshkumar3892@floridapoly.edu;kar@13f0.net";
599 }; 441 };
600 hooks = { 442 hooks = {
601 postNew = '' 443 postNew = ''
602 notmuch tag +13f0 -- tag:unread and to:"*@13f0.net" 444 notmuch tag +13f0 -- tag:unread and to:"*@13f0.net"
603 notmuch tag +vineetk -- tag:unread and to:"*@vineetk.net" 445 notmuch tag +vineetk -- tag:unread and to:"*@vineetk.net"
604 notmuch tag +university -- tag:unread and to:***REDACTED_EMAIL*** 446 notmuch tag +university -- tag:unread and to:"*@floridapoly.edu"
605 notmuch tag +openbsd_announce -inbox -- tag:unread and to:announce@openbsd.org 447 notmuch tag +openbsd_announce -inbox -- tag:unread and to:announce@openbsd.org
606 notmuch tag +openbsd_arm -inbox -- tag:unread and to:arm@openbsd.org 448 notmuch tag +openbsd_arm -inbox -- tag:unread and to:arm@openbsd.org
607 notmuch tag +openbsd_misc -inbox -- tag:unread and to:misc@openbsd.org 449 notmuch tag +openbsd_misc -inbox -- tag:unread and to:misc@openbsd.org
450 notmuch tag +openbsd_ports -inbox -- tag:unread and to:ports@openbsd.org
451 notmuch tag +openbsd_tech -inbox -- tag:unread and to:tech@openbsd.org
608 notmuch tag +opensmtpd_misc -inbox -- tag:unread and to:misc@opensmtpd.org 452 notmuch tag +opensmtpd_misc -inbox -- tag:unread and to:misc@opensmtpd.org
609 notmuch tag +oss_security -inbox -- tag:unread and to:oss-security@lists.openwall.com 453 notmuch tag +oss_security -inbox -- tag:unread and to:oss-security@lists.openwall.com
610 notmuch tag +tuhs -inbox -- tag:unread and to:tuhs@tuhs.org 454 notmuch tag +tuhs -inbox -- tag:unread and to:tuhs@tuhs.org
@@ -619,7 +463,6 @@ in
619 quickmarks = { 463 quickmarks = {
620 canvas = "https://floridapolytechnic.instructure.com"; 464 canvas = "https://floridapolytechnic.instructure.com";
621 cams = "https://cams.floridapoly.org/student/login.asp"; 465 cams = "https://cams.floridapoly.org/student/login.asp";
622 weather = "https://forecast.weather.gov/MapClick.php***REMOVED***";
623 entertrained = "https://entertrained.app/"; 466 entertrained = "https://entertrained.app/";
624 burst = "https://www.burst-type.pro/"; 467 burst = "https://www.burst-type.pro/";
625 colemakcamp = "https://colemakcamp.github.io/"; 468 colemakcamp = "https://colemakcamp.github.io/";
@@ -779,7 +622,6 @@ in
779 # glance? 622 # glance?
780 # gpg-agent with ssh? 623 # gpg-agent with ssh?
781 # mpd and ncmpcpp? 624 # mpd and ncmpcpp?
782 # nextcloud-client?
783 # pass-secret-service? 625 # pass-secret-service?
784 # plan9port for plumbing? 626 # plan9port for plumbing?
785 # recoll? 627 # recoll?
@@ -787,232 +629,6 @@ in
787 # screen-locker 629 # screen-locker
788 # sxhkd if using bspwm and not i3 630 # sxhkd if using bspwm and not i3
789 # unison 631 # unison
790 # vdirsyncer
791
792 # parametric equalizer (and other stuff I don't use) in pipewire
793 easyeffects = {
794 enable = true;
795 preset = "he5xx_oratory1990";
796 extraPresets.he5xx_oratory1990 = {
797 output = {
798 blocklist = [ ];
799 "equalizer#0" = {
800 balance = 0;
801 bypass = false;
802 input-gain = -10.8;
803 left = {
804 band0 = {
805 frequency = 25;
806 gain = 5.3;
807 mode = "APO (DR)";
808 mute = false;
809 q = 1;
810 slope = "x1";
811 solo = false;
812 type = "Bell";
813 width = 4;
814 };
815 band1 = {
816 frequency = 105;
817 gain = 5.5;
818 mode = "APO (DR)";
819 mute = false;
820 q = 0.666667;
821 slope = "x1";
822 solo = false;
823 type = "Lo-shelf";
824 width = 4;
825 };
826 band2 = {
827 frequency = 470;
828 gain = -1;
829 mode = "APO (DR)";
830 mute = false;
831 q = 4;
832 slope = "x1";
833 solo = false;
834 type = "Bell";
835 width = 4;
836 };
837 band3 = {
838 frequency = 530;
839 gain = 1.8;
840 mode = "APO (DR)";
841 mute = false;
842 q = 1.2;
843 slope = "x1";
844 solo = false;
845 type = "Bell";
846 width = 4;
847 };
848 band4 = {
849 frequency = 800;
850 gain = 5;
851 mode = "APO (DR)";
852 mute = false;
853 q = 0.666667;
854 slope = "x1";
855 solo = false;
856 type = "Hi-shelf";
857 width = 4;
858 };
859 band5 = {
860 frequency = 910;
861 gain = -3.4;
862 mode = "APO (DR)";
863 mute = false;
864 q = 3;
865 slope = "x1";
866 solo = false;
867 type = "Bell";
868 width = 4;
869 };
870 band6 = {
871 frequency = 1300;
872 gain = -3.3;
873 mode = "APO (DR)";
874 mute = false;
875 q = 3;
876 slope = "x1";
877 solo = false;
878 type = "Bell";
879 width = 4;
880 };
881 band7 = {
882 frequency = 5400;
883 gain = -4.8;
884 mode = "APO (DR)";
885 mute = false;
886 q = 4.5;
887 slope = "x1";
888 solo = false;
889 type = "Bell";
890 width = 4;
891 };
892 band8 = {
893 frequency = 11000;
894 gain = -7;
895 mode = "APO (DR)";
896 mute = false;
897 q = 0.666667;
898 slope = "x1";
899 solo = false;
900 type = "Hi-shelf";
901 width = 4;
902 };
903 };
904 mode = "IIR";
905 num-bands = 9;
906 output-gain = 0;
907 pitch-left = 0;
908 pitch-right = 0;
909 right = {
910 band0 = {
911 frequency = 25;
912 gain = 5.3;
913 mode = "APO (DR)";
914 mute = false;
915 q = 1;
916 slope = "x1";
917 solo = false;
918 type = "Bell";
919 width = 4;
920 };
921 band1 = {
922 frequency = 105;
923 gain = 5.5;
924 mode = "APO (DR)";
925 mute = false;
926 q = 0.666667;
927 slope = "x1";
928 solo = false;
929 type = "Lo-shelf";
930 width = 4;
931 };
932 band2 = {
933 frequency = 470;
934 gain = -1;
935 mode = "APO (DR)";
936 mute = false;
937 q = 4;
938 slope = "x1";
939 solo = false;
940 type = "Bell";
941 width = 4;
942 };
943 band3 = {
944 frequency = 530;
945 gain = 1.8;
946 mode = "APO (DR)";
947 mute = false;
948 q = 1.2;
949 slope = "x1";
950 solo = false;
951 type = "Bell";
952 width = 4;
953 };
954 band4 = {
955 frequency = 800;
956 gain = 5;
957 mode = "APO (DR)";
958 mute = false;
959 q = 0.666667;
960 slope = "x1";
961 solo = false;
962 type = "Hi-shelf";
963 width = 4;
964 };
965 band5 = {
966 frequency = 910;
967 gain = -3.4;
968 mode = "APO (DR)";
969 mute = false;
970 q = 3;
971 slope = "x1";
972 solo = false;
973 type = "Bell";
974 width = 4;
975 };
976 band6 = {
977 frequency = 1300;
978 gain = -3.3;
979 mode = "APO (DR)";
980 mute = false;
981 q = 3;
982 slope = "x1";
983 solo = false;
984 type = "Bell";
985 width = 4;
986 };
987 band7 = {
988 frequency = 5400;
989 gain = -4.8;
990 mode = "APO (DR)";
991 mute = false;
992 q = 4.5;
993 slope = "x1";
994 solo = false;
995 type = "Bell";
996 width = 4;
997 };
998 band8 = {
999 frequency = 11000;
1000 gain = -7;
1001 mode = "APO (DR)";
1002 mute = false;
1003 q = 0.666667;
1004 slope = "x1";
1005 solo = false;
1006 type = "Hi-shelf";
1007 width = 4;
1008 };
1009 };
1010 split-channels = false;
1011 };
1012 plugins_order = [ "equalizer#0" ];
1013 };
1014 };
1015 };
1016 632
1017 poweralertd.enable = true; 633 poweralertd.enable = true;
1018 634
@@ -1118,18 +734,6 @@ in
1118 xdg = { 734 xdg = {
1119 enable = true; 735 enable = true;
1120 736
1121 portal = {
1122 enable = true;
1123 extraPortals = [ pkgs.xdg-desktop-portal-luminous ];
1124 config.sway = {
1125 default = [ "luminous" ];
1126 "org.freedesktop.impl.portal.Screenshot" = [ "luminous" ];
1127 "org.freedesktop.impl.portal.ScreenCast" = [ "luminous" ];
1128 "org.freedesktop.impl.portal.Settings" = [ "luminous" ];
1129 "org.freedesktop.impl.portal.RemoteDesktop" = [ "luminous" ];
1130 };
1131 };
1132
1133 configFile = { 737 configFile = {
1134 "qutebrowser/theme.py".text = '' 738 "qutebrowser/theme.py".text = ''
1135 # Colors. 739 # Colors.
@@ -1343,221 +947,4 @@ in
1343 videos = "$HOME/"; 947 videos = "$HOME/";
1344 }; 948 };
1345 }; 949 };
1346
1347 wayland.windowManager.sway = {
1348 enable = true;
1349 package = pkgs.swayfx;
1350
1351 # https://github.com/nix-community/home-manager/issues/5379#issuecomment-2096066969
1352 checkConfig = false;
1353
1354 config = {
1355 input."type:pointer".accel_profile = "flat";
1356 output."*".background = "~/pics/wp/elite_milky_way_below2.png fill";
1357
1358 bars = [
1359 {
1360 colors = {
1361 # background = colors.current.primary.background;
1362 background = "#000000";
1363 statusline = colors.current.primary.foreground;
1364 focusedWorkspace = {
1365 background = colors.current.normal.black;
1366 border = colors.current.normal.black;
1367 text = colors.current.normal.green;
1368 };
1369 activeWorkspace = {
1370 background = colors.current.normal.black;
1371 border = colors.current.normal.black;
1372 text = colors.current.primary.foreground;
1373 };
1374 inactiveWorkspace = {
1375 background = colors.current.primary.background;
1376 border = colors.current.primary.background;
1377 text = colors.current.normal.white;
1378 };
1379 };
1380 command = "${pkgs.sway}/bin/swaybar";
1381 position = "top";
1382 statusCommand = "while date +'%Y-%m-%d %X'; do sleep 1; done";
1383 }
1384 ];
1385
1386 colors = {
1387 focused = {
1388 background = colors.current.primary.background;
1389 border = colors.current.primary.background;
1390 childBorder = colors.current.primary.background;
1391 indicator = colors.current.normal.black;
1392 text = colors.current.normal.green;
1393 };
1394 focusedInactive = {
1395 background = colors.current.primary.background;
1396 border = colors.current.primary.background;
1397 childBorder = colors.current.primary.background;
1398 indicator = colors.current.normal.black;
1399 text = colors.current.primary.foreground;
1400 };
1401 unfocused = {
1402 background = colors.current.normal.black;
1403 border = colors.current.normal.black;
1404 childBorder = colors.current.normal.black;
1405 indicator = colors.current.primary.background;
1406 text = colors.current.normal.white;
1407 };
1408 };
1409
1410 focus = {
1411 mouseWarping = true;
1412 wrapping = "yes";
1413 };
1414
1415 fonts = {
1416 names = [ "monospace" ];
1417 size = 11.0;
1418 };
1419
1420 gaps = {
1421 inner = 15;
1422 smartGaps = true;
1423 };
1424
1425 keybindings =
1426 let
1427 left = "n";
1428 down = "e";
1429 up = "o";
1430 right = "i";
1431 modifier = config.wayland.windowManager.sway.config.modifier;
1432 menu = config.wayland.windowManager.sway.config.menu;
1433 terminal = config.wayland.windowManager.sway.config.terminal;
1434 in
1435 lib.mkOptionDefault {
1436 "${modifier}+Return" = "exec ${terminal}";
1437 "${modifier}+p" = "exec ${menu}";
1438 "${modifier}+b" = "exec bm t";
1439 "${modifier}+Shift+b" = "exec kasimenu";
1440 "${modifier}+u" = "exec kasimenu user";
1441 "${modifier}+Shift+u" = "exec kasimenu email";
1442 "${modifier}+Shift+t" = "exec kasimenu_totp";
1443
1444 "${modifier}+Shift+q" = "kill";
1445 "${modifier}+Shift+c" = "reload";
1446 "Mod1+Mod4+Ctrl+Shift+e" = "exit";
1447
1448 "${modifier}+${left}" = "focus left;";
1449 "${modifier}+${down}" = "focus down;";
1450 "${modifier}+${up}" = "focus up;";
1451 "${modifier}+${right}" = "focus right;";
1452 "${modifier}+Shift+${left}" = "move left";
1453 "${modifier}+Shift+${down}" = "move down";
1454 "${modifier}+Shift+${up}" = "move up";
1455 "${modifier}+Shift+${right}" = "move right";
1456
1457 # TODO do this programatically
1458 "${modifier}+1" = "workspace number 1";
1459 "${modifier}+2" = "workspace number 2";
1460 "${modifier}+3" = "workspace number 3";
1461 "${modifier}+4" = "workspace number 4";
1462 "${modifier}+5" = "workspace number 5";
1463 "${modifier}+6" = "workspace number 6";
1464 "${modifier}+7" = "workspace number 7";
1465 "${modifier}+8" = "workspace number 8";
1466 "${modifier}+9" = "workspace number 9";
1467 "${modifier}+0" = "workspace number 10";
1468 "${modifier}+Shift+1" = "move container to workspace number 1";
1469 "${modifier}+Shift+2" = "move container to workspace number 2";
1470 "${modifier}+Shift+3" = "move container to workspace number 3";
1471 "${modifier}+Shift+4" = "move container to workspace number 4";
1472 "${modifier}+Shift+5" = "move container to workspace number 5";
1473 "${modifier}+Shift+6" = "move container to workspace number 6";
1474 "${modifier}+Shift+7" = "move container to workspace number 7";
1475 "${modifier}+Shift+8" = "move container to workspace number 8";
1476 "${modifier}+Shift+9" = "move container to workspace number 9";
1477 "${modifier}+Shift+0" = "move container to workspace number 10";
1478
1479 "${modifier}+Ctrl+Shift+b" = "splith";
1480 "${modifier}+Ctrl+Shift+v" = "splitv";
1481 "${modifier}+s" = "layout stacking";
1482 "${modifier}+t" = "layout tabbed";
1483 "${modifier}+Ctrl+Shift+t" = "layout toggle split";
1484 "${modifier}+Shift+f" = "fullscreen";
1485 "${modifier}+Shift+space" = "floating toggle";
1486 "${modifier}+space" = "focus mode_toggle";
1487 "${modifier}+a" = "focus parent";
1488
1489 "${modifier}+r" = "mode resize";
1490 };
1491
1492 menu = "${pkgs.wmenu}/bin/wmenu-run";
1493
1494 modes.resize =
1495 let
1496 left = "n";
1497 down = "e";
1498 up = "o";
1499 right = "i";
1500 in
1501 lib.mkOptionDefault {
1502 ${left} = "resize shrink width 10px";
1503 ${down} = "resize grow height 10px";
1504 ${up} = "resize shrink width 10px";
1505 ${right} = "resize grow width 10px";
1506 Escape = "mode default";
1507 };
1508
1509 modifier = "Mod4";
1510
1511 terminal = "foot";
1512
1513 window = {
1514 border = 0;
1515 titlebar = false;
1516 };
1517
1518 defaultWorkspace = "workspace number 1";
1519 workspaceAutoBackAndForth = true;
1520 };
1521
1522 extraConfig = ''
1523 # I hate xdg-desktop-portal
1524 exec systemctl --user set-environment XDG_CURRENT_DESKTOP=sway
1525 exec systemctl --user import-environment DISPLAY \
1526 SWAYSOCK \
1527 WAYLAND_DISPLAY \
1528 XDG_CURRENT_DESKTOP
1529 exec hash dbus-update-activation-environment 2>/dev/null && \
1530 dbus-update-activation-environment --systemd DISPLAY \
1531 SWAYSOCK \
1532 XDG_CURRENT_DESKTOP=sway \
1533 WAYLAND_DISPLAY
1534
1535 mouse_warping container
1536
1537 blur enable
1538 blur_xray disable
1539 blur_radius 3
1540 blur_passes 5
1541
1542 corner_radius 10
1543
1544 shadows enable
1545 shadow_blur_radius 10
1546
1547 for_window [class="Emacs"] opacity 0.9
1548 for_window [app_id="qutebrowser"] opacity 0.9
1549 for_window [app_id="vesktop"] opacity 0.9
1550
1551 for_window [title="profanity"] move container to workspace 9
1552 for_window [app_id="vesktop"] move container to workspace 10
1553
1554 exec ${pkgs.qutebrowser}/bin/qutebrowser
1555 exec ${pkgs.vesktop}/bin/vesktop --use-vulkan --ozone-platform=wayland --enable-features=UseOzonePlatform,Vulkan
1556 exec ${config.wayland.windowManager.sway.config.terminal} -T profanity -e ${pkgs.profanity}/bin/profanity
1557
1558 # for elite va
1559 bindsym --whole-window BTN_SIDE echo press >/tmp/elite_va.fifo
1560 bindsym --whole-window --release BTN_SIDE echo release >/tmp/elite_va.fifo
1561 '';
1562 };
1563} 950}
diff --git a/hosts/demiurge/default.nix b/hosts/demiurge/default.nix
index ab36f02..c53c3eb 100644
--- a/hosts/demiurge/default.nix
+++ b/hosts/demiurge/default.nix
@@ -21,14 +21,6 @@
21 allowUnfreePredicate = 21 allowUnfreePredicate =
22 pkg: 22 pkg:
23 builtins.elem (lib.getName pkg) [ 23 builtins.elem (lib.getName pkg) [
24 /*
25 "cuda_cccl"
26 "cuda_cudart"
27 "cuda_nvcc"
28 "cudnn"
29 "libcublas"
30 "libcufile"
31 */
32 "steam" 24 "steam"
33 "steam-unwrapped" 25 "steam-unwrapped"
34 ]; 26 ];
@@ -44,30 +36,6 @@
44 36
45 overlays = [ 37 overlays = [
46 (self: super: { 38 (self: super: {
47 invidious = super.invidious.overrideAttrs (old: {
48 # try removing shorts by ignoring any videos shorter than 65 seconds
49 postPatch =
50 old.postPatch
51 + ''
52 sed -i '/GROUP BY channel/a\ AND length_seconds > 65' src/invidious/database/channels.cr
53 sed -i 's/\({view_name}\) \(ORDER BY published\)/\1 WHERE length_seconds > 65 \2/' src/invidious/users.cr
54 sed -i 's/\({values})\) \(ORDER BY published\)/\1 AND length_seconds > 65 \2/' src/invidious/users.cr
55 '';
56 });
57 })
58 (self: super: {
59 inv-sig-helper = super.inv-sig-helper.overrideAttrs (old: {
60 version = "0-unstable-2025-04-23";
61
62 src = super.fetchFromGitHub {
63 owner = "iv-org";
64 repo = "inv_sig_helper";
65 rev = "5d3c7a4574fafe0bc5fbed9e7e33483889832fd4";
66 hash = "sha256-WGh62tjKGe9OD19aq+lP9GfYs5PrGqkeT6VvmtNottQ=";
67 };
68 });
69 })
70 (self: super: {
71 alvr = super.alvr.overrideAttrs (old: { 39 alvr = super.alvr.overrideAttrs (old: {
72 buildInputs = old.buildInputs ++ [ 40 buildInputs = old.buildInputs ++ [
73 super.android-tools 41 super.android-tools
@@ -91,11 +59,8 @@
91 59
92 # decrypt agenix secrets 60 # decrypt agenix secrets
93 age.secrets = { 61 age.secrets = {
94 tailscale_demiurge = { 62 wg0_demiurge.file = ../../secrets/wg0_demiurge.age;
95 file = ../../secrets/tailscale_demiurge.age; 63 wg1_demiurge.file = ../../secrets/wg0_demiurge.age;
96 owner = "root";
97 group = "root";
98 };
99 }; 64 };
100 65
101 # boot options 66 # boot options
@@ -114,7 +79,7 @@
114 79
115 zfs.extraPools = [ 80 zfs.extraPools = [
116 "data_wd" 81 "data_wd"
117 "nvme_warm" 82 "data"
118 ]; 83 ];
119 }; 84 };
120 85
@@ -134,34 +99,101 @@
134 allowedUDPPorts = [ 51413 ]; 99 allowedUDPPorts = [ 51413 ];
135 }; 100 };
136 101
137 # mullvad to miami 102 wg-quick.interfaces = {
138 wg-quick.interfaces.us-mia-wg-002 = { 103 # mullvad
139 address = [ 104 wg0 = {
140 "10.135.221.102/32" 105 address = [
141 "fc00:bbbb:bbbb:bb01:d:0:7:dd66/128" 106 "10.68.117.111/32"
142 ]; 107 "fc00:bbbb:bbbb:bb01::5:756e/128"
143 privateKey = "***REDACTED_WG_KEY***="; 108 ];
109 privateKeyFile = config.age.secrets.wg0_demiurge.path;
144 110
145 # supposed to be done by tailscale instead \_(:/)_/ 111 postUp = "ip route add 45.134.142.206 dev eth0";
146 postUp = '' 112 postDown = "ip route del 45.134.142.206 dev eth0";
147 ip route add 100.64.0.0/24 dev tailscale0
148 ip route add 100.100.100.100/32 dev tailscale0
149 '';
150 postDown = ''
151 ip route del 100.64.0.0/24 dev tailscale0
152 ip route del 100.100.100.100/32 dev tailscale0
153 '';
154 113
155 peers = [ 114 peers = [{
156 { 115 allowedIPs = [
157 allowedIPs = [ 116 "0.0.0.0/0"
158 "0.0.0.0/0" 117 "::0/0"
159 "::0/0" 118 ];
160 ]; 119 endpoint = "45.134.142.206:51820";
161 endpoint = "45.134.142.206:51820"; 120 publicKey = "H5t7PsMDnUAHrR8D2Jt3Mh6N6w43WmCzrOHShlEU+zw=";
162 publicKey = "H5t7PsMDnUAHrR8D2Jt3Mh6N6w43WmCzrOHShlEU+zw="; 121 }];
163 } 122 };
164 ]; 123
124 # epistemia
125 wg1 = {
126 address = [
127 "10.0.13.2/24"
128 "fd00:b0ba:cafe:babe::2/64"
129 ];
130 privateKeyFile = config.age.secrets.wg1_demiurge.path;
131 listenPort = 51820;
132 fwMark = 51821;
133 MTU = 1420;
134
135 table = false;
136 postUp = ''
137PostUp = ip rule add from 10.0.13.0/24 lookup main pref 31000
138PostUp = ip rule add from all fwmark 51821 lookup 51821 pref 32000
139PostUp = ip route add default via 192.168.1.1 dev eth0 table 51821
140
141# NAT iphonebob and allow traffic between peers (when routing through demiurge)
142PostUp = iptables -F FORWARD
143PostUp = iptables -t nat -I POSTROUTING 1 -s 10.0.13.4/32 -o wg0 -j MASQUERADE
144PostUp = iptables -A FORWARD -i wg1 -o wg1 -j ACCEPT
145PostUp = iptables -A FORWARD -i wg1 -o wg0 -j ACCEPT
146PostUp = iptables -A FORWARD -i wg0 -o wg1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
147 '';
148 preDown = ''
149PreDown = ip rule del from all fwmark 51821 lookup 51821 pref 32000
150PreDown = ip rule del from 10.0.13.0/24 lookup main pref 31000
151PreDown = ip route flush table 51821
152
153PreDown = iptables -t nat -D POSTROUTING -s 10.0.13.4/32 -o wg0 -j MASQUERADE
154PreDown = iptables -F FORWARD
155 '';
156
157 peers = [
158 # saklas
159 {
160 allowedIPs = [
161 "10.0.13.1/32"
162 "fd00:b0ba:cafe:babe::1/128"
163 ];
164 endpoint = "157.180.125.215:51820";
165 persistentKeepalive = 25;
166 publicKey = "XvRailvccuc7LJIF4aaYM/MLkU4upiprwFlCfBllhl0=";
167 }
168 # hastur
169 {
170 allowedIPs = [
171 "10.0.13.3/32"
172 "fd00:b0ba:cafe:babe::3/128"
173 ];
174 persistentKeepalive = 25;
175 publicKey = "MOmRjVbRuWEuK0oHQ+C0jTaceCUPd2fpzDbh8ue6bDc=";
176 }
177 # iphonebob
178 {
179 allowedIPs = [
180 "10.0.13.4/32"
181 "fd00:b0ba:cafe:babe::4/128"
182 ];
183 persistentKeepalive = 25;
184 publicKey = "Xn0EmeRZdpMejBgzr98mYtb/2f5O58GAzQLNZV/SS30=";
185 }
186 # lab
187 {
188 allowedIPs = [
189 "10.0.13.5/32"
190 "fd00:b0ba:cafe:babe::5/128"
191 ];
192 persistentKeepalive = 25;
193 publicKey = "iMDEwvXjPAlQH8ZCmP63FM5ICYIFIX5XIyGxjnXoNVE=";
194 }
195 ];
196 };
165 }; 197 };
166 }; 198 };
167 199
@@ -186,24 +218,19 @@
186 isNormalUser = true; 218 isNormalUser = true;
187 219
188 extraGroups = [ 220 extraGroups = [
189 "input"
190 "kvm"
191 "libvirtd"
192 "transmission" 221 "transmission"
193 "video"
194 "wheel" 222 "wheel"
195 ]; 223 ];
196 224
197 shell = pkgs.zsh; 225 shell = pkgs.zsh;
198 226
199 openssh.authorizedKeys.keys = [ 227 openssh.authorizedKeys.keys = [
200 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvM0xCLziR+ZT/SYE1aZM6dklbw4fEC17TWqbADIZRH kou@demiurge" 228 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvM0xCLziR+ZT/SYE1aZM6dklbw4fEC17TWqbADIZRH vin@demiurge"
201 ]; 229 ];
202 230
203 packages = with pkgs; [ 231 packages = with pkgs; [
204 alvr 232 alvr
205 bs-manager 233 bs-manager
206 distrobox
207 (llama-cpp.packages.x86_64-linux.rocm.override { useVulkan = true; }) 234 (llama-cpp.packages.x86_64-linux.rocm.override { useVulkan = true; })
208 #(vllm.override { cudaSupport = false; rocmSupport = true; gpuTargets = [ "gfx906" "gfx1100" ]; }) 235 #(vllm.override { cudaSupport = false; rocmSupport = true; gpuTargets = [ "gfx906" "gfx1100" ]; })
209 ]; 236 ];
@@ -249,9 +276,6 @@
249 # steam, proprietary. I sometimes like playing nonfree games too. 276 # steam, proprietary. I sometimes like playing nonfree games too.
250 steam.enable = true; 277 steam.enable = true;
251 278
252 # virtualization
253 virt-manager.enable = true;
254
255 # configuration in home-manager 279 # configuration in home-manager
256 zsh.enable = true; 280 zsh.enable = true;
257 zsh.promptInit = "PS1='$ '"; 281 zsh.promptInit = "PS1='$ '";
@@ -270,53 +294,57 @@
270 ]; 294 ];
271 }; 295 };
272 296
273 pki.certificates = [
274 ''
275 -----BEGIN CERTIFICATE-----
276 MIIDMDCCAhigAwIBAgIUcSUafnojcFKod3f436VELfEKoFkwDQYJKoZIhvcNAQEL
277 BQAwHTEbMBkGA1UEAwwSZGVtaXVyZ2UuZXBpc3RlbWlhMB4XDTI1MDMwMzEwMjQw
278 OVoXDTI2MDMwMzEwMjQwOVowHTEbMBkGA1UEAwwSZGVtaXVyZ2UuZXBpc3RlbWlh
279 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwiRlreCXc7f+yWclxR2M
280 639g0+Lr/c9HrX7EM2/olavPAtZgCzqqvJsDmXq4AURlwd82wZUZxXjWFwlRji/+
281 WViXQBTWwnXVjc9MJlxTq2X2zfU2GIxYsrA1ZQuj0wVHlA+R/66oL0Padc/qQZfv
282 sshQnrqnutvGobBWEGJXcCIDiwUGgHlIoelwY9G0GLE/rkVujNjAonyMhVGJHVUv
283 lXyc3RNslQHymr4Wl6+lL6V6XfuB1taECJYSLXPx66TvJqod2Io+b7T7cWp+9g9U
284 B2jQu1YnPRpwjdPvbOCPjPbOP6UcbyHdbHAidSM0FSL5riVUmugwDwbQKXFFX2gH
285 hwIDAQABo2gwZjAfBgNVHREEGDAWghQqLmRlbWl1cmdlLmVwaXN0ZW1pYTATBgNV
286 HSUEDDAKBggrBgEFBQcDATAPBgNVHRMECDAGAQH/AgEAMB0GA1UdDgQWBBTjMVhw
287 zmkE6P5jFHkLVQE2gNB2ejANBgkqhkiG9w0BAQsFAAOCAQEAWvnwB83vXzQFpObF
288 vn/nfZ9wYpNaBsE15ab3Fwd2nDc55KDkDWgBi5Xl8fwN3OhFOU2XXBCYqbCU6asx
289 OnSx9glbhJioORO7B5ENbEYrpB97SaWASNXrBQ2KiQT5aC+9xb52K53kkk0tTn2l
290 nBb+jyLItzWX99H6EavOq69a4T2BObZaSPQAfpM8FIrKl+UZC3152+bi8wKfG4K4
291 FQsOJMjIvhTm2IiOS8xIaZz7EJORxFjtOkLEIGGZBNK6QcnD714/nYbHSrQx4eNM
292 /ek8Rmf6DTLaFBx+raWyDTgMY23lvWTKDTT1+dZnRNcg72bFpIdqHsDrIg/IBjZ0
293 3eGfkQ==
294 -----END CERTIFICATE-----
295 ''
296 ];
297
298 sudo.enable = false; 297 sudo.enable = false;
299 }; 298 };
300 299
301 services = { 300 services = {
302 # control unicorn barf
303 hardware.openrgb.enable = true;
304
305 # dns 301 # dns
306 dnsmasq = { 302 unbound = {
307 enable = true; 303 enable = true;
308 settings = { 304 settings = {
309 server = [ 305 server = {
310 "192.168.1.1" 306 interface = [ "127.0.0.1" "10.0.13.2" "fd00:b0ba:cafe:babe::2" "::1" ];
311 "/epistemia/100.100.100.100" 307 access-control = [ "0.0.0.0/0 allow" "::0/0 allow" ];
312 ]; 308
309 hide-identity = yes;
310 hide-version = yes;
311
312 # Synthesize NXDOMAINs from DNSSEC NSEC chains.
313 # https://tools.ietf.org/html/rfc8198
314 aggressive-nsec = no;
315
316 local-zone = "saklas.epistemia." redirect;
317 local-data = "saklas.epistemia. 86400 IN A 10.0.13.1";
318 local-data = "saklas.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::1";
319 local-zone = "demiurge.epistemia." redirect;
320 local-data = "demiurge.epistemia. 86400 IN A 10.0.13.2";
321 local-data = "demiurge.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::2";
322 local-zone = "hastur.epistemia." redirect;
323 local-data = "hastur.epistemia. 86400 IN A 10.0.13.3";
324 local-data = "hastur.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::3";
325 local-zone = "iphonebob.epistemia." redirect;
326 local-data = "iphonebob.epistemia. 86400 IN A 10.0.13.4";
327 local-data = "iphonebob.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::4";
328 local-zone = "lab.epistemia." redirect;
329 local-data = "lab.epistemia. 86400 IN A 10.0.13.5";
330 local-data = "lab.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::5";
331 local-zone = "paraclete.epistemia." redirect;
332 local-data = "paraclete.epistemia. 86400 IN A 10.0.13.6";
333 local-data = "paraclete.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::6";
334 };
313 335
314 interface = "lo"; 336 # hagezi for dns-based adblocking (in addition to others)
315 listen-address = "127.0.0.1"; 337 rpz = {
316 bind-interfaces = true; 338 name = "hagezi.ultimate";
317 no-resolv = true; 339 zonefile = "hagezi.ultimate";
340 url = "https://raw.githubusercontent.com/hagezi/dns-blocklists/main/rpz/ultimate.txt";
341 };
318 342
319 conf-file = "/data/src/clones/networking/hagezi_dns-blocklists/dnsmasq/ultimate.txt"; 343 # go through mullvad for regular dns queries
344 forward-zone = {
345 name = ".";
346 forward-addr = [ "100.64.0.3" ];
347 };
320 }; 348 };
321 }; 349 };
322 350
@@ -361,39 +389,6 @@
361 }; 389 };
362 }; 390 };
363 391
364 # invidious
365 invidious = {
366 enable = true;
367
368 http3-ytproxy.enable = true;
369 nginx.enable = true;
370 sig-helper.enable = true;
371
372 domain = "invidious.demiurge.epistemia";
373 extraSettingsFile = "/run/invidious_settings";
374 settings = {
375 admins = [ "vin" ];
376 captcha_enabled = false;
377 registration_enabled = false;
378 hmac_key = "zCYyRa7vD0qt";
379 default_user_preferences = {
380 captions = [ "English" ];
381 dark_mode = "dark";
382 feed_menu = [
383 "Popular"
384 "Subscriptions"
385 "Playlists"
386 ];
387 max_results = 100;
388 quality = "dash";
389 save_player_pos = true;
390 unseen_only = true;
391 local = true;
392 extend_desc = true;
393 };
394 };
395 };
396
397 # graphical input 392 # graphical input
398 libinput = { 393 libinput = {
399 enable = true; 394 enable = true;
@@ -420,7 +415,7 @@
420 nginx = { 415 nginx = {
421 enable = true; 416 enable = true;
422 417
423 defaultListenAddresses = [ "100.64.0.2" ]; 418 defaultListenAddresses = [ "10.0.13.2" "fd00:b0ba:cafe:babe::2" ];
424 419
425 recommendedGzipSettings = true; 420 recommendedGzipSettings = true;
426 recommendedOptimisation = true; 421 recommendedOptimisation = true;
@@ -460,22 +455,14 @@
460 }; 455 };
461 456
462 "sdui.demiurge.epistemia" = { 457 "sdui.demiurge.epistemia" = {
463 # addSSL = true; 458 addSSL = true;
464 # sslCertificate = "/var/demiurge.epistemia.crt"; 459 sslCertificate = "/var/demiurge.epistemia.crt";
465 # sslCertificateKey = "/var/demiurge.epistemia.key"; 460 sslCertificateKey = "/var/demiurge.epistemia.key";
466 locations."/" = { 461 locations."/" = {
467 proxyPass = "http://127.0.0.1:7860"; 462 proxyPass = "http://127.0.0.1:7860";
468 proxyWebsockets = true; 463 proxyWebsockets = true;
469 }; 464 };
470 }; 465 };
471
472 "invidious.demiurge.epistemia" = {
473 addSSL = true;
474 enableACME = false;
475 forceSSL = false;
476 sslCertificate = "/var/demiurge.epistemia.crt";
477 sslCertificateKey = "/var/demiurge.epistemia.key";
478 };
479 }; 466 };
480 }; 467 };
481 468
@@ -508,7 +495,127 @@
508 # using pulseaudio and home-manager, so had to disable pulseaudio. 495 # using pulseaudio and home-manager, so had to disable pulseaudio.
509 pipewire = { 496 pipewire = {
510 enable = true; 497 enable = true;
498 alsa.enable = true;
499 audio.enable = true;
511 pulse.enable = true; 500 pulse.enable = true;
501
502 extraConfig.pipewire = {
503 "99-filter-he5xx.conf" = {
504 "context.modules" = [
505 {
506 name = "libpipewire-module-filter-chain";
507 args = {
508 node.name = "peq-he5xx-sink";
509 node.description = "PEQ HE5XX (auto)";
510 # playback.props is the virtual sink/device properties
511 playback.props = {
512 media.class = "Audio/Sink";
513 "filter.smart" = true;
514 "filter.smart.name" = "peq-he5xx";
515 # tell WirePlumber what target properties this filter is intended for
516 # (we leave this unset here; smart target matching will be done by wireplumber)
517 };
518 # filter graph: single builtin param_eq node that loads the param file
519 filter.graph = [
520 {
521 type = "builtin";
522 name = "param_eq";
523 label = "param_eq_he5xx";
524 config.filename = "/etc/pipewire/parametric/he5xx.txt";
525 }
526 ];
527 };
528 };
529 ];
530 };
531
532 "99-filter-airpods.conf" = {
533 "context.modules" = [
534 {
535 name = "libpipewire-module-filter-chain";
536 args = {
537 node.name = "peq-airpods-pro-2-sink";
538 node.description = "PEQ AirPods Pro 2 (auto)";
539 playback.props = {
540 media.class = "Audio/Sink";
541 "filter.smart" = true;
542 "filter.smart.name" = "peq-airpods-pro-2";
543 };
544 filter.graph = [
545 {
546 type = "builtin";
547 name = "param_eq";
548 label = "param_eq_airpods";
549 config.filename = "/etc/pipewire/parametric/airpods-pro-2.txt";
550 }
551 ];
552 };
553 }
554 ];
555 };
556 };
557
558 # TODO run nixfmt to fix indenting of below (can't right now because on gentoo without nixfmt)
559 wireplumber = {
560 enable = true;
561 extraConfig."50-smartfilters-airpods.conf".text = ''
562 {
563 "monitor.bluez.rules" : [
564 # When a BlueZ device is detected we set an identifying property that the smart filter will match.
565 # (This fragment adds nothing by default; we're using a policy to match target.node later.)
566 ],
567
568 "policy.rules" : [
569 # The core smart filter matching is done by matching the target.node properties
570 # WirePlumber's smart filters will look for filter.smart.target (set below).
571 ],
572
573 "policy" : {
574 "smart_filters" : {
575 "rules" : [
576 {
577 "matches" : [
578 { "device.props" : { "bluez5.device.name" : "AirPods Pro 2" } }
579 ],
580 "actions" : {
581 # If target device matches, set the 'target.node' metadata for smart filters to use
582 "update-metadata" : {
583 "target.node" : { "name" : "bluez_output.*AirPods.*" }
584 }
585 }
586 }
587 ]
588 }
589 },
590
591 "endpoint.rules" : [
592 {
593 "matches" : [
594 { "node.name" : "peq-airpods-pro-2-sink" }
595 ],
596 "actions" : {
597 "update-props" : {
598 # Mark this WF sink as intended for a specific target device.
599 # WirePlumber will use filter.smart.target to identify which device to chain to.
600 "filter.smart.target" : { "bluez5.device.name" : "AirPods Pro 2" }
601 }
602 }
603 },
604 {
605 "matches" : [
606 { "node.name" : "peq-he5xx-sink" }
607 ],
608 "actions" : {
609 "update-props" : {
610 # He5xx is a generic filter (no specific bluez target) — it could be matched by other rules.
611 "filter.smart.target" : {}
612 }
613 }
614 }
615 ]
616 }
617 '';
618 };
512 }; 619 };
513 620
514 # reddit 621 # reddit
@@ -555,11 +662,11 @@
555 # Disable autoplay videos by default 662 # Disable autoplay videos by default
556 REDLIB_DEFAULT_AUTOPLAY_VIDEOS = false; 663 REDLIB_DEFAULT_AUTOPLAY_VIDEOS = false;
557 # Define a default list of subreddit subscriptions (format: sub1+sub2+sub3) 664 # Define a default list of subreddit subscriptions (format: sub1+sub2+sub3)
558 REDLIB_DEFAULT_SUBSCRIPTIONS = "ergomechkeyboards+localllama+factorio+warframe+elitedangerous+unixporn+usabilityporn"; 665 REDLIB_DEFAULT_SUBSCRIPTIONS = "ergomechkeyboards+localllama+elitedangerous";
559 # Define a default list of subreddit filters (format: sub1+sub2+sub3) 666 # Define a default list of subreddit filters (format: sub1+sub2+sub3)
560 REDLIB_DEFAULT_FILTERS = "popular+all+funny+memes"; 667 REDLIB_DEFAULT_FILTERS = "popular+all+funny+memes";
561 # Hide awards by default 668 # Hide awards by default
562 REDLIB_DEFAULT_HIDE_AWARDS = false; 669 REDLIB_DEFAULT_HIDE_AWARDS = true;
563 # Hide sidebar and summary 670 # Hide sidebar and summary
564 REDLIB_DEFAULT_HIDE_SIDEBAR_AND_SUMMARY = false; 671 REDLIB_DEFAULT_HIDE_SIDEBAR_AND_SUMMARY = false;
565 # Disable the confirmation before visiting Reddit 672 # Disable the confirmation before visiting Reddit
@@ -604,8 +711,8 @@
604 711
605 hostnames = { 712 hostnames = {
606 replace = { 713 replace = {
607 "(.*\.)?youtube\.com$" = "invidious.demiurge.epistemia"; 714 "(.*\.)?youtube\.com$" = "yewtu.be";
608 "(.*\.)?youtu\.be$" = "invidious.demiurge.epistemia"; 715 "(.*\.)?youtu\.be$" = "yewtu.be";
609 "(.*\.)?reddit\.com$" = "redlib.demiurge.epistemia"; 716 "(.*\.)?reddit\.com$" = "redlib.demiurge.epistemia";
610 "(.*\.)?redd\.it$" = "redlib.demiurge.epistemia"; 717 "(.*\.)?redd\.it$" = "redlib.demiurge.epistemia";
611 }; 718 };
@@ -967,7 +1074,6 @@
967 doi_resolvers = { 1074 doi_resolvers = {
968 "oadoi.org" = "https://oadoi.org/"; 1075 "oadoi.org" = "https://oadoi.org/";
969 "doi.org" = "https://doi.org/"; 1076 "doi.org" = "https://doi.org/";
970 "doai.io" = "https://dissem.in/";
971 "sci-hub.se" = "https://sci-hub.se/"; 1077 "sci-hub.se" = "https://sci-hub.se/";
972 "sci-hub.st" = "https://sci-hub.st/"; 1078 "sci-hub.st" = "https://sci-hub.st/";
973 "sci-hub.ru" = "https://sci-hub.ru/"; 1079 "sci-hub.ru" = "https://sci-hub.ru/";
@@ -977,25 +1083,10 @@
977 }; 1083 };
978 }; 1084 };
979 1085
980 # vpn
981 tailscale = {
982 enable = true;
983 authKeyFile = config.age.secrets.tailscale_demiurge.path;
984 extraDaemonFlags = [ "--no-logs-no-support" ];
985 extraUpFlags = [
986 "--login-server=https://headscale.13f0.net"
987 "--advertise-exit-node"
988 ];
989 openFirewall = true;
990 };
991
992 # udev rules 1086 # udev rules
993 udev = { 1087 udev = {
994 enable = true; 1088 enable = true;
995 extraRules = '' 1089 extraRules = ''
996 # ST-Link v2.1
997 SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", MODE:="0666"
998
999 # Oculus Quest 2 1090 # Oculus Quest 2
1000 SUBSYSTEM=="usb", ATTR{idVendor}=="2833", ATTR{idProduct}=="0186", MODE="0660", 1091 SUBSYSTEM=="usb", ATTR{idVendor}=="2833", ATTR{idProduct}=="0186", MODE="0660",
1001 GROUP="input", SYMLINK+="ocuquest%n" 1092 GROUP="input", SYMLINK+="ocuquest%n"
@@ -1015,53 +1106,10 @@
1015 }; 1106 };
1016 1107
1017 # extra systemd stuff 1108 # extra systemd stuff
1018 systemd = { 1109 systemd.services.nginx = {
1019 services = { 1110 after = [ "wg-quick@wg1.service" ];
1020 invidious_token = { 1111 requires = [ "wg-quick@wg1.service" ];
1021 script = '' 1112 serviceConfig.Type = lib.mkForce "idle";
1022 set -euo pipefail
1023
1024 a="$(${pkgs.podman}/bin/podman run quay.io/invidious/youtube-trusted-session-generator | sed -n 4,5p)"
1025 visitor_data=$(echo "$a" | sed -n 1p | cut -d' ' -f2)
1026 po_token=$(echo "$a" | sed -n 2p | cut -d' ' -f2)
1027 day=$(date +%e | tr -d ' ')
1028
1029 printf '{"visitor_data": "%s",\n"po_token": "%s",\n' \
1030 "$visitor_data" "$po_token" \
1031 >/run/invidious_settings
1032
1033 if [ $((day % 2)) -eq 0 ]; then
1034 printf '"force_resolve": "ipv6"}\n' >>/run/invidious_settings
1035 else
1036 printf '"force_resolve": "ipv4"}\n' >>/run/invidious_settings
1037 fi
1038
1039 ${pkgs.systemd}/bin/systemctl restart invidious-sig-helper
1040 ${pkgs.systemd}/bin/systemctl restart invidious
1041 '';
1042 serviceConfig = {
1043 Type = "oneshot";
1044 User = "root";
1045 };
1046 };
1047
1048 nginx = {
1049 after = [ "tailscaled.service" ];
1050 requires = [ "tailscaled.service" ];
1051 serviceConfig.Type = lib.mkForce "idle";
1052 };
1053
1054 postgresql.serviceConfig.Type = lib.mkForce "idle";
1055 tailscaled.serviceConfig.Type = lib.mkForce "idle";
1056 };
1057
1058 timers.invidious_token = {
1059 timerConfig = {
1060 OnCalendar = "hourly";
1061 Persistent = true;
1062 };
1063 wantedBy = [ "timers.target" ];
1064 };
1065 }; 1113 };
1066 1114
1067 # create caches and use mandoc 1115 # create caches and use mandoc
@@ -1072,20 +1120,5 @@
1072 mandoc.enable = true; 1120 mandoc.enable = true;
1073 }; 1121 };
1074 1122
1075 # virtualization stuff
1076 virtualisation = {
1077 libvirtd.enable = true;
1078
1079 podman = {
1080 enable = true;
1081 dockerCompat = true;
1082 };
1083 };
1084
1085 xdg.portal = {
1086 config.common.default = [ "wlr" ];
1087 wlr.enable = true;
1088 };
1089
1090 system.stateVersion = "24.05"; 1123 system.stateVersion = "24.05";
1091} 1124}
diff --git a/hosts/hastur/default.nix b/hosts/hastur/default.nix
index 5127533..d9507c4 100644
--- a/hosts/hastur/default.nix
+++ b/hosts/hastur/default.nix
@@ -19,11 +19,9 @@
19 19
20 # decrypt agenix secrets 20 # decrypt agenix secrets
21 age.secrets = { 21 age.secrets = {
22 tailscale_hastur = { 22 wg0_hastur.file = ../../secrets/wg0_hastur.age;
23 file = ../../secrets/tailscale_hastur.age; 23 wg1_hastur.file = ../../secrets/wg1_hastur.age;
24 owner = "root"; 24 wpa_supplicant.file = ../../secrets/wpa_supplicant.age;
25 group = "root";
26 };
27 }; 25 };
28 26
29 # boot options 27 # boot options
@@ -40,34 +38,14 @@
40 ]; 38 ];
41 }; 39 };
42 40
43 # disable wifi and open some ports
44 networking = { 41 networking = {
45 hostName = "hastur"; 42 hostName = "hastur";
46 hostId = "deadcafe"; 43 hostId = "deadcafe";
47 44
48 wireless = { 45 wireless = {
49 enable = true; 46 enable = true;
50 47 userControlled = true;
51 networks = { 48 allowAuxiliaryImperativeNetworks = true;
52 OpenDyna.pskRaw = "***REDACTED_PSK***";
53
54 FloridaPoly = {
55 authProtocols = [ "WPA-EAP" ];
56 auth = ''
57 eap=PEAP
58 phase2="auth=MSCHAPv2"
59 identity="***REDACTED_EMAIL***"
60 password="***REDACTED_PASSWORD***"
61 '';
62 };
63
64 USF-Guest = { };
65
66 iphonebob.pskRaw = "***REDACTED_PSK***";
67 Retreat_86WiFi.pskRaw = "***REDACTED_PSK***";
68 Orbi-1.pskRaw = "***REDACTED_PSK***";
69 SETUP-E55E.pskRaw = "***REDACTED_PSK***";
70 };
71 }; 49 };
72 50
73 firewall = { 51 firewall = {
@@ -75,34 +53,58 @@
75 # allowedUDPPorts = [ ]; 53 # allowedUDPPorts = [ ];
76 }; 54 };
77 55
78 # mullvad to miami 56 wg-quick.interfaces = {
79 wg-quick.interfaces.us-mia-wg-001 = { 57 # mullvad
80 address = [ 58 wg0 = {
81 "10.70.235.16/32" 59 address = [
82 "fc00:bbbb:bbbb:bb01::7:eb0f/128" 60 "10.75.226.117/32"
83 ]; 61 "fc00:bbbb:bbbb:bb01::c:e274/128"
84 privateKey = "***REDACTED_WG_KEY***="; 62 ];
85 63 privateKeyFile = config.age.secrets.wg0_hastur.path;
86 # supposed to be done by tailscale instead \_(:/)_/ 64
87 postUp = '' 65 peers = [{
88 ip route add 100.64.0.0/24 dev tailscale0 66 allowedIPs = [
89 ip route add 100.100.100.100/32 dev tailscale0 67 "0.0.0.0/0"
90 ''; 68 "::0/0"
91 postDown = '' 69 ];
92 ip route del 100.64.0.0/24 dev tailscale0 70 endpoint = "45.134.142.206:51820";
93 ip route del 100.100.100.100/32 dev tailscale0 71 publicKey = "H5t7PsMDnUAHrR8D2Jt3Mh6N6w43WmCzrOHShlEU+zw=";
94 ''; 72 }];
73 };
95 74
96 peers = [ 75 # epistemia
97 { 76 wg1 = {
98 allowedIPs = [ 77 address = [
99 "0.0.0.0/0" 78 "10.0.13.3/24"
100 "::0/0" 79 "fd00:b0ba:cafe:babe::3/64"
101 ]; 80 ];
102 endpoint = "45.134.142.219:51820"; 81 privateKeyFile = config.age.secrets.wg1_hastur.path;
103 publicKey = "FVEKAMJqaJU2AwWn5Mg9TK9IAfJc4XDUmSzEeC/VXGs="; 82
104 } 83 peers = [
105 ]; 84 # saklas
85 {
86 allowedIPs = [
87 "10.0.13.1/32"
88 "fd00:b0ba:cafe:babe::1/128"
89 ];
90 endpoint = "vineetk.net:51820";
91 persistentKeepalive = 25;
92 publicKey = "XvRailvccuc7LJIF4aaYM/MLkU4upiprwFlCfBllhl0=";
93 }
94 # demiurge (and lab through it)
95 {
96 allowedIPs = [
97 "10.0.13.2/32"
98 "10.0.13.5/32"
99 "fd00:b0ba:cafe:babe::2/128"
100 "fd00:b0ba:cafe:babe::5/128"
101 ];
102 endpoint = "carcosa.13f0.net:51820";
103 persistentKeepalive = 25;
104 publicKey = "FMLvbSxY6vA8CRV4S1vl4+pMeCr/kR9n0G5w9buNqh4=";
105 }
106 ];
107 };
106 }; 108 };
107 }; 109 };
108 110
@@ -126,8 +128,6 @@
126 isNormalUser = true; 128 isNormalUser = true;
127 129
128 extraGroups = [ 130 extraGroups = [
129 "kvm"
130 "libvirtd"
131 "transmission" 131 "transmission"
132 "wheel" 132 "wheel"
133 ]; 133 ];
@@ -135,7 +135,12 @@
135 shell = pkgs.zsh; 135 shell = pkgs.zsh;
136 136
137 openssh.authorizedKeys.keys = [ 137 openssh.authorizedKeys.keys = [
138 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvM0xCLziR+ZT/SYE1aZM6dklbw4fEC17TWqbADIZRH kou@demiurge" 138 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvM0xCLziR+ZT/SYE1aZM6dklbw4fEC17TWqbADIZRH vin@hastur"
139 ];
140
141 packages = with pkgs; [
142 acpi
143 acpilight
139 ]; 144 ];
140 }; 145 };
141 146
@@ -149,6 +154,8 @@
149 ]; 154 ];
150 155
151 pathsToLink = [ "/share/zsh" ]; 156 pathsToLink = [ "/share/zsh" ];
157
158 etc."wpa_supplicant.conf".source = config.age.secrets.wpa_supplicant.path;
152 }; 159 };
153 160
154 # enable bluetooth and add some udev rules 161 # enable bluetooth and add some udev rules
@@ -190,39 +197,57 @@
190 ]; 197 ];
191 }; 198 };
192 199
193 pki.certificates = [
194 ''
195 -----BEGIN CERTIFICATE-----
196 MIIBoDCCAUagAwIBAgIRANI8aOT3LE+pzmsQWjcDOIgwCgYIKoZIzj0EAwIwLjER
197 MA8GA1UEChMIZGVtaXVyZ2UxGTAXBgNVBAMTEGRlbWl1cmdlIFJvb3QgQ0EwHhcN
198 MjUwMjE4MDUzNTA5WhcNMzUwMjE2MDUzNTA5WjAuMREwDwYDVQQKEwhkZW1pdXJn
199 ZTEZMBcGA1UEAxMQZGVtaXVyZ2UgUm9vdCBDQTBZMBMGByqGSM49AgEGCCqGSM49
200 AwEHA0IABMv8weeXJSDLygVlBxxAHLCvQCdf2COCk0QffNeDaVlIU/NFo3IyPSqG
201 E3YtWEWamU/icgsJS999z3BZ5O+cTP6jRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNV
202 HRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBRM51S3OgTxXwNhdSSHw6llz0APFzAK
203 BggqhkjOPQQDAgNIADBFAiA9alHJ1XHLlKNRUGRL4tdFC3RZYHtoN8BmBHEfDa1S
204 LQIhANgsvYmyCp/Nur2RKaV25CDg3kMYVBXED2HVDy8qa+3i
205 -----END CERTIFICATE-----
206 ''
207 ];
208
209 sudo.enable = false; 200 sudo.enable = false;
210 }; 201 };
211 202
212 services = { 203 services = {
213 # dns 204 # dns
214 dnsmasq = { 205 unbound = {
215 enable = true; 206 enable = true;
216 settings = { 207 settings = {
217 server = [ 208 server = {
218 "/epistemia/100.100.100.100" 209 interface = [ "127.0.0.1" "10.0.13.2" "fd00:b0ba:cafe:babe::2" "::1" ];
219 "9.9.9.9" 210 access-control = [ "0.0.0.0/0 allow" "::0/0 allow" ];
220 ]; 211
212 hide-identity = yes;
213 hide-version = yes;
214
215 # Synthesize NXDOMAINs from DNSSEC NSEC chains.
216 # https://tools.ietf.org/html/rfc8198
217 aggressive-nsec = no;
218
219 local-zone = "saklas.epistemia." redirect;
220 local-data = "saklas.epistemia. 86400 IN A 10.0.13.1";
221 local-data = "saklas.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::1";
222 local-zone = "demiurge.epistemia." redirect;
223 local-data = "demiurge.epistemia. 86400 IN A 10.0.13.2";
224 local-data = "demiurge.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::2";
225 local-zone = "hastur.epistemia." redirect;
226 local-data = "hastur.epistemia. 86400 IN A 10.0.13.3";
227 local-data = "hastur.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::3";
228 local-zone = "iphonebob.epistemia." redirect;
229 local-data = "iphonebob.epistemia. 86400 IN A 10.0.13.4";
230 local-data = "iphonebob.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::4";
231 local-zone = "lab.epistemia." redirect;
232 local-data = "lab.epistemia. 86400 IN A 10.0.13.5";
233 local-data = "lab.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::5";
234 local-zone = "paraclete.epistemia." redirect;
235 local-data = "paraclete.epistemia. 86400 IN A 10.0.13.6";
236 local-data = "paraclete.epistemia. 86400 IN AAAA fd00:b0ba:cafe:babe::6";
237 };
238
239 # hagezi for dns-based adblocking (in addition to others)
240 rpz = {
241 name = "hagezi.ultimate";
242 zonefile = "hagezi.ultimate";
243 url = "https://raw.githubusercontent.com/hagezi/dns-blocklists/main/rpz/ultimate.txt";
244 };
221 245
222 interface = "lo"; 246 # go through mullvad for regular dns queries
223 listen-address = "127.0.0.1"; 247 forward-zone = {
224 bind-interfaces = true; 248 name = ".";
225 no-resolv = true; 249 forward-addr = [ "100.64.0.3" ];
250 };
226 }; 251 };
227 }; 252 };
228 253
@@ -258,33 +283,90 @@
258 # using pulseaudio and home-manager, so had to disable pulseaudio. 283 # using pulseaudio and home-manager, so had to disable pulseaudio.
259 pipewire = { 284 pipewire = {
260 enable = true; 285 enable = true;
286 alsa.enable = true;
287 audio.enable = true;
261 pulse.enable = true; 288 pulse.enable = true;
262 };
263 289
264 # vpn 290 extraConfig.pipewire = {
265 tailscale = { 291 "99-filter-airpods.conf" = {
266 enable = true; 292 "context.modules" = [
267 authKeyFile = config.age.secrets.tailscale_hastur.path; 293 {
268 extraDaemonFlags = [ "--no-logs-no-support" ]; 294 name = "libpipewire-module-filter-chain";
269 extraUpFlags = [ 295 args = {
270 "--login-server=https://headscale.13f0.net" 296 node.name = "peq-airpods-pro-2-sink";
271 "--advertise-exit-node" 297 node.description = "PEQ AirPods Pro 2 (auto)";
272 ]; 298 playback.props = {
273 openFirewall = true; 299 media.class = "Audio/Sink";
300 "filter.smart" = true;
301 "filter.smart.name" = "peq-airpods-pro-2";
302 };
303 filter.graph = [
304 {
305 type = "builtin";
306 name = "param_eq";
307 label = "param_eq_airpods";
308 config.filename = "/etc/pipewire/parametric/airpods-pro-2.txt";
309 }
310 ];
311 };
312 }
313 ];
314 };
315 };
316
317 # TODO run nixfmt to fix indenting of below (can't right now because on gentoo without nixfmt)
318 wireplumber = {
319 enable = true;
320 extraConfig."50-smartfilters-airpods.conf".text = ''
321 {
322 "monitor.bluez.rules" : [
323 # When a BlueZ device is detected we set an identifying property that the smart filter will match.
324 # (This fragment adds nothing by default; we're using a policy to match target.node later.)
325 ],
326
327 "policy.rules" : [
328 # The core smart filter matching is done by matching the target.node properties
329 # WirePlumber's smart filters will look for filter.smart.target (set below).
330 ],
331
332 "policy" : {
333 "smart_filters" : {
334 "rules" : [
335 {
336 "matches" : [
337 { "device.props" : { "bluez5.device.name" : "AirPods Pro 2" } }
338 ],
339 "actions" : {
340 # If target device matches, set the 'target.node' metadata for smart filters to use
341 "update-metadata" : {
342 "target.node" : { "name" : "bluez_output.*AirPods.*" }
343 }
344 }
345 }
346 ]
347 }
348 },
349
350 "endpoint.rules" : [
351 {
352 "matches" : [
353 { "node.name" : "peq-airpods-pro-2-sink" }
354 ],
355 "actions" : {
356 "update-props" : {
357 "filter.smart.target" : { "bluez5.device.name" : "AirPods Pro 2" }
358 }
359 }
360 }
361 ]
362 }
363 '';
364 };
274 }; 365 };
275 366
276 # enable better power management 367 # enable better power management
277 tlp.enable = true; 368 tlp.enable = true;
278 369
279 # udev rules
280 udev = {
281 enable = true;
282 extraRules = ''
283 # ST-Link v2.1
284 SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", MODE:="0666"
285 '';
286 };
287
288 # to get startx and use amdgpu driver 370 # to get startx and use amdgpu driver
289 # WM in home-manager 371 # WM in home-manager
290 xserver = { 372 xserver = {
@@ -295,6 +377,11 @@
295 }; 377 };
296 }; 378 };
297 379
380 systemd.services."wg-quick@wg1" = {
381 after = [ "wg-quick@wg0.service" ];
382 requires = [ "wg-quick@wg0.service" ];
383 };
384
298 # create caches and use mandoc 385 # create caches and use mandoc
299 documentation.man = { 386 documentation.man = {
300 enable = true; 387 enable = true;
@@ -303,11 +390,5 @@
303 mandoc.enable = true; 390 mandoc.enable = true;
304 }; 391 };
305 392
306 # virtualization stuff
307 virtualisation.podman = {
308 enable = true;
309 dockerCompat = true;
310 };
311
312 system.stateVersion = "24.05"; 393 system.stateVersion = "24.05";
313} 394}
diff --git a/secrets/secrets.nix b/secrets/secrets.nix
index ca794fd..c1c6978 100644
--- a/secrets/secrets.nix
+++ b/secrets/secrets.nix
@@ -18,7 +18,10 @@ in
18 "hetzner_dns.age".publicKeys = users ++ [ saklas ]; 18 "hetzner_dns.age".publicKeys = users ++ [ saklas ];
19 "radicale_users.age".publicKeys = users ++ [ saklas ]; 19 "radicale_users.age".publicKeys = users ++ [ saklas ];
20 20
21 "tailscale_demiurge.age".publicKeys = users ++ [ demiurge ]; 21 "wg0_demiurge.age".publicKeys = users ++ [ demiurge ];
22 "tailscale_hastur.age".publicKeys = users ++ [ hastur ]; 22 "wg0_hastur.age".publicKeys = users ++ [ hastur ];
23 "tailscale_saklas.age".publicKeys = users ++ [ saklas ]; 23 "wg1_demiurge.age".publicKeys = users ++ [ demiurge ];
24 "wg1_hastur.age".publicKeys = users ++ [ hastur ];
25
26 "wpa_supplicant.age".publicKeys = users ++ [ hastur ];
24} 27}
diff --git a/secrets/tailscale_demiurge.age b/secrets/tailscale_demiurge.age
deleted file mode 100644
index 2dfd303..0000000
--- a/secrets/tailscale_demiurge.age
+++ /dev/null
@@ -1,10 +0,0 @@
1age-encryption.org/v1
2-> ssh-ed25519 AaF/mQ Tgl9rg4GuKxgZMuHcwCw7ykOoZqRX3t4UN/E9qcMZSI
3LdVTcOS8pGeKwh/18QYtaGFuSRTKawDTtYyvurev0NE
4-> ssh-ed25519 F30WWA G0HHHxSzX7RznR8CLhlDOqev4a8eA5odn6IyJnEZaRA
5j9ivd4Jg3uAO13ffuouTlGyJDsTppBlHGFftzSncuKM
6-> ssh-ed25519 hc2ELA iCpXfQ7xRoQNkN0meAy3weOJkWOLY9dLNm9chmMGmlE
76E7ZRjh7C+HrjyzGCVAf5Menk4UGXyIRrqOAb4nyOvI
8--- QgTpqSI1sMG0nNYu1jtZAKJ9pcvCVgivW7UW24+F9nw
9к!J%ngNheG /
10ej~TBEm`k⍾pIpR 5~96?+8> \ No newline at end of file
diff --git a/secrets/tailscale_hastur.age b/secrets/tailscale_hastur.age
deleted file mode 100644
index 167826a..0000000
--- a/secrets/tailscale_hastur.age
+++ /dev/null
Binary files differ
diff --git a/secrets/tailscale_saklas.age b/secrets/tailscale_saklas.age
deleted file mode 100644
index ae7369a..0000000
--- a/secrets/tailscale_saklas.age
+++ /dev/null
@@ -1,11 +0,0 @@
1age-encryption.org/v1
2-> ssh-ed25519 AaF/mQ eUu7OoAObwNKVNHnf4gqC1tJ7xlmjkhW01G+HdcqAxc
3SwYGhawZISYmqHSyA7fqKs05IzVlVu+3+7zDgvBBbkQ
4-> ssh-ed25519 F30WWA A8NddnDcg3IlQ8wJhuLoj1oS9rvRaIzLWFR+zp5qjAA
5Rezb8NRw32cQSytyegAGW5s/knHQUseHoSTeHpmlJGs
6-> ssh-ed25519 hc2ELA za1uRZpbO1VkGdIVnNqYJkrJpCji/JEBq3lPolodhxU
7u/FlNi8t03cwOvdqmUGOMPhAbVmLnWHAbScYCAbTvxw
8--- BaEwzkb52piuKrSglC0P8xCr/HlD97B3WgklyyuBEbA
9C`
10fqAO4̛4/{W᫇Tƫ)j_dnDkACi3
118(L^'I҆$bgp \ No newline at end of file
diff --git a/secrets/wg0_demiurge.age b/secrets/wg0_demiurge.age
new file mode 100644
index 0000000..11f2561
--- /dev/null
+++ b/secrets/wg0_demiurge.age
@@ -0,0 +1,7 @@
1age-encryption.org/v1
2-> ssh-ed25519 AaF/mQ yqsS5z6keZjZRc2WECiDtrIQ81uy9dPNuC+4JL4QGgQ
3PZfc4aEh3zIexIpLjcJjtPmXN7nFNFPzUcsjwNj1GtI
4-> ssh-ed25519 F30WWA lK3glF0i1Z8i16YF+Pc7AlJjEk3zETFt6HYBrzHntFk
5hsh9wGSi08ZFGUzF8nl3aT3EqMmciGTDjvfxW9FXNKA
6--- 5SHG64tPuD9a4EfWVs8RteQTpBcNR9ZiLKvuUukraZI
7k] !ax^OLOb^93@h)Vx˲-"!AR \ No newline at end of file
diff --git a/secrets/wg0_hastur.age b/secrets/wg0_hastur.age
new file mode 100644
index 0000000..83079cf
--- /dev/null
+++ b/secrets/wg0_hastur.age
@@ -0,0 +1,8 @@
1age-encryption.org/v1
2-> ssh-ed25519 AaF/mQ 56BWU8ca94VnN9a2XS9MyMECcA2NnUvclaIgzsAasGw
34ym2vDPFta3Jjp1ZEmGg+4QjtfqCv98crJmFFJxK4Wk
4-> ssh-ed25519 CQpZUw 8T0BdKSFpFj9j8wfe2h9s1uvweGDlJYmLaBaF1h+31A
5JV2ckgV8Hg6EYx44Uh0XF3FvZf6T5bnRULT+5pCueLw
6--- jB4Nfx/RnFtL0sOSc0mfZ3a98IsDl03dAj0SqqqZoz0
7oR-ɨKlЍlg a!RĝX)_Tě
8nclyV2!Yqkpjois| \ No newline at end of file
diff --git a/secrets/wg1_demiurge.age b/secrets/wg1_demiurge.age
new file mode 100644
index 0000000..b9bbbff
--- /dev/null
+++ b/secrets/wg1_demiurge.age
@@ -0,0 +1,7 @@
1age-encryption.org/v1
2-> ssh-ed25519 AaF/mQ MX+cICKRHIB8NaZ6+Kdz6wmhGQHgzNthVe4BiFp3V2c
3pZa2tCwE4YRTS/4kTdlu5DrHNFePU8BiDNXZI0Uaeg0
4-> ssh-ed25519 F30WWA UfyQtZSmrl9pw9FVNCxGOo0ICIglS9Q4sDRTg/1PXTw
5Sd6q4jECTtdRfGbgeAf/AniX5gw64ZZ/PrESAlst5tg
6--- YkDaRa81QgMNVefXmDCPv2OdDI1BtMO4AhixPoKx2Os
78ח/-p>т^?A$<>|!0M u-Azm/g!;tᙌǙ!ݎ \ No newline at end of file
diff --git a/secrets/wg1_hastur.age b/secrets/wg1_hastur.age
new file mode 100644
index 0000000..62841ca
--- /dev/null
+++ b/secrets/wg1_hastur.age
@@ -0,0 +1,7 @@
1age-encryption.org/v1
2-> ssh-ed25519 AaF/mQ Bb1FBNNOPSZ5hJeoRIfnjBU4kQVbXOK/0Eems+055Xo
3l1O6Jab0xAzeV1VgnzltinixgeC3xT+60vMrW49CtYQ
4-> ssh-ed25519 CQpZUw gTPSRzQQ25H7oimwatm0F1pgKdXGHGyuaww6dhPaqCE
5VxK1cjss0z6Vw5hCM4Soao9E5VdQw1FoXUNTLQ2744M
6--- h1Cg8XMs8MEPnjDtsebMzWsjvoJ2oyi+YthMaSxAhvA
7i_3KfH=j<PUf ; wU#3a ax琞_:8g(6|Uw> \ No newline at end of file
diff --git a/secrets/wpa_supplicant.age b/secrets/wpa_supplicant.age
new file mode 100644
index 0000000..f7a08ec
--- /dev/null
+++ b/secrets/wpa_supplicant.age
Binary files differ