nixos-config

NixOS configs for my systems
Log | Files | Refs

default.nix (10239B)


      1 # Edit this configuration file to define what should be installed on
      2 # your system. Help is available in the configuration.nix(5) man page, on
      3 # https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
      4 
      5 {
      6   config,
      7   home-manager,
      8   lib,
      9   pkgs,
     10   inputs,
     11   ...
     12 }:
     13 
     14 {
     15   imports = [
     16     ./hardware.nix
     17     home-manager.nixosModules.default
     18   ];
     19 
     20   # decrypt agenix secrets
     21   age.secrets = {
     22     wg0_hastur.file = ../../secrets/wg0_hastur.age;
     23     wg1_hastur.file = ../../secrets/wg1_hastur.age;
     24     wpa_supplicant.file = ../../secrets/wpa_supplicant.age;
     25   };
     26 
     27   # boot options
     28   boot.loader.grub = {
     29     enable = true;
     30     zfsSupport = true;
     31     efiSupport = true;
     32     efiInstallAsRemovable = true;
     33     mirroredBoots = [
     34       {
     35         devices = [ "nodev" ];
     36         path = "/boot";
     37       }
     38     ];
     39   };
     40 
     41   networking = {
     42     hostName = "hastur";
     43     hostId = "deadcafe";
     44 
     45     wireless = {
     46       enable = true;
     47       userControlled = true;
     48       allowAuxiliaryImperativeNetworks = true;
     49     };
     50 
     51     firewall = {
     52       #      allowedTCPPorts = [ ];
     53       #      allowedUDPPorts = [ ];
     54     };
     55 
     56     wg-quick.interfaces = {
     57       # mullvad
     58       wg0 = {
     59         address = [
     60           "10.75.226.117/32"
     61           "fc00:bbbb:bbbb:bb01::c:e274/128"
     62         ];
     63         privateKeyFile = config.age.secrets.wg0_hastur.path;
     64 
     65         peers = [{
     66             allowedIPs = [
     67               "0.0.0.0/0"
     68               "::0/0"
     69             ];
     70             endpoint = "45.134.142.206:51820";
     71             publicKey = "H5t7PsMDnUAHrR8D2Jt3Mh6N6w43WmCzrOHShlEU+zw=";
     72         }];
     73       };
     74 
     75       # epistemia
     76       wg1 = {
     77         address = [
     78           "10.0.13.3/24"
     79           "fd00:b0ba:cafe:babe::3/64"
     80         ];
     81         privateKeyFile = config.age.secrets.wg1_hastur.path;
     82 
     83         peers = [
     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       };
    108     };
    109   };
    110 
    111   # Set your time zone.
    112   time.timeZone = "America/Toronto";
    113 
    114   # Select internationalisation properties.
    115   i18n.defaultLocale = "en_US.UTF-8";
    116   console = {
    117     font = "Lat2-Terminus16";
    118   };
    119 
    120   # enable flakes and nix cli
    121   nix.settings.experimental-features = [
    122     "nix-command"
    123     "flakes"
    124   ];
    125 
    126   # Define a user account.
    127   users.users.vin = {
    128     isNormalUser = true;
    129 
    130     extraGroups = [
    131       "transmission"
    132       "wheel"
    133     ];
    134 
    135     shell = pkgs.zsh;
    136 
    137     openssh.authorizedKeys.keys = [
    138       "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvM0xCLziR+ZT/SYE1aZM6dklbw4fEC17TWqbADIZRH vin@hastur"
    139     ];
    140 
    141     packages = with pkgs; [
    142       acpi
    143       acpilight
    144     ];
    145   };
    146 
    147   # default packages for both me and root
    148   environment = {
    149     systemPackages = with pkgs; [
    150       distrobox
    151       doas-sudo-shim
    152       git
    153       wget
    154     ];
    155 
    156     pathsToLink = [ "/share/zsh" ];
    157 
    158     etc."wpa_supplicant.conf".source = config.age.secrets.wpa_supplicant.path;
    159   };
    160 
    161   # enable bluetooth and add some udev rules
    162   hardware = {
    163     bluetooth.enable = true;
    164     flipperzero.enable = true;
    165     keyboard.qmk.enable = true;
    166   };
    167 
    168   programs = {
    169     # for gtk in home-manager
    170     dconf.enable = true;
    171 
    172     # gpg
    173     gnupg.agent = {
    174       enable = true;
    175       enableSSHSupport = false;
    176       pinentryPackage = pkgs.pinentry-rofi;
    177       settings.default-cache-ttl = 600;
    178     };
    179 
    180     # disable nano. I don't like nano.
    181     nano.enable = false;
    182 
    183     # configuration in home-manager
    184     zsh.enable = true;
    185   };
    186 
    187   security = {
    188     # I prefer doas over sudo for simplicity
    189     doas = {
    190       enable = true;
    191       extraRules = [
    192         {
    193           users = [ "vin" ];
    194           keepEnv = true;
    195           persist = true;
    196         }
    197       ];
    198     };
    199 
    200     sudo.enable = false;
    201   };
    202 
    203   services = {
    204     # dns
    205     unbound = {
    206       enable = true;
    207       settings = {
    208 	      server = {
    209 	        interface = [ "127.0.0.1" "10.0.13.2" "fd00:b0ba:cafe:babe::2" "::1" ];
    210           access-control = [ "0.0.0.0/0 allow" "::0/0 allow" ];
    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         };
    245 
    246         # go through mullvad for regular dns queries
    247 	      forward-zone = {
    248 	        name = ".";
    249 	        forward-addr = [ "100.64.0.3" ];
    250         };
    251       };
    252     };
    253 
    254     # graphical input
    255     libinput = {
    256       enable = true;
    257 
    258       mouse.accelProfile = "flat";
    259 
    260       touchpad = {
    261         accelProfile = "flat";
    262         tapping = true;
    263         tappingButtonMap = "lrm";
    264       };
    265     };
    266 
    267     # ssh
    268     openssh = {
    269       enable = true;
    270 
    271       settings = {
    272         KbdInteractiveAuthentication = false;
    273         PasswordAuthentication = false;
    274         PermitRootLogin = "no";
    275         X11Forwarding = true;
    276       };
    277     };
    278 
    279     # for yubikey
    280     pcscd.enable = true;
    281 
    282     # sound. for some reason, pipewire enabled itself when I tried
    283     # using pulseaudio and home-manager, so had to disable pulseaudio.
    284     pipewire = {
    285       enable = true;
    286       alsa.enable = true;
    287       audio.enable = true;
    288       pulse.enable = true;
    289 
    290       extraConfig.pipewire = {
    291         "99-filter-airpods.conf" = {
    292           "context.modules" = [
    293             {
    294               name = "libpipewire-module-filter-chain";
    295               args = {
    296                 node.name = "peq-airpods-pro-2-sink";
    297                 node.description = "PEQ AirPods Pro 2 (auto)";
    298                 playback.props = {
    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       };
    365     };
    366 
    367     # enable better power management
    368     tlp.enable = true;
    369 
    370     # to get startx and use amdgpu driver
    371     # WM in home-manager
    372     xserver = {
    373       enable = true;
    374       autorun = false;
    375       displayManager.startx.enable = true;
    376       videoDrivers = [ "modesetting" ];
    377     };
    378   };
    379 
    380   systemd.services."wg-quick@wg1" = {
    381     after = [ "wg-quick@wg0.service" ];
    382     requires = [ "wg-quick@wg0.service" ];
    383   };
    384 
    385   # create caches and use mandoc
    386   documentation.man = {
    387     enable = true;
    388     generateCaches = true;
    389     man-db.enable = false;
    390     mandoc.enable = true;
    391   };
    392 
    393   system.stateVersion = "24.05";
    394 }