Configuration for my NixOS based systems and Home Manager
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add misaki

+1032 -85
+6 -7
configuration.nix
··· 21 21 randomizedDelaySec = "45min"; 22 22 }; 23 23 24 - # This value determines the NixOS release from which the default 25 - # settings for stateful data, like file locations and database versions 26 - # on your system were taken. It's perfectly fine and recommended to leave 27 - # this value at the release version of the first install of this system. 28 - # Before changing this value read the documentation for this option 29 - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 30 - #system.stateVersion = "23.11"; # Did you read the comment? 24 + # Automatic Garbage Collection 25 + nix.gc.automatic = true; 26 + nix.gc.options = "--delete-older-than 8d"; 27 + 28 + # I don't care that much about free vs unfree 29 + nixpkgs.config.allowUnfree = true; 31 30 }
+3 -3
flake.lock
··· 397 397 }, 398 398 "nixpkgs_4": { 399 399 "locked": { 400 - "lastModified": 1766885793, 401 - "narHash": "sha256-P6RVkrM9JLCW6xBjSwHfgTOQ1JwBUma5xe5LI8xAPC0=", 400 + "lastModified": 1767047869, 401 + "narHash": "sha256-tzYsEzXEVa7op1LTnrLSiPGrcCY6948iD0EcNLWcmzo=", 402 402 "owner": "nixos", 403 403 "repo": "nixpkgs", 404 - "rev": "9ef261221d1e72399f2036786498d78c38185c46", 404 + "rev": "89dbf01df72eb5ebe3b24a86334b12c27d68016a", 405 405 "type": "github" 406 406 }, 407 407 "original": {
+35 -19
flake.nix
··· 43 43 system ? "x86_64-linux", 44 44 modules ? [ ], 45 45 unstable ? false, 46 + extraGroups ? [ ], 46 47 ... 47 48 }: 48 49 inputs.nixpkgs.lib.nixosSystem { 49 50 inherit system; 50 - specialArgs = 51 - { 52 - inherit inputs; 53 - } 54 - // nixpkgs.lib.optionalAttrs unstable { 55 - unstable = nixpkgs-unstable.legacyPackages.${system}; 51 + specialArgs = { 52 + inherit inputs extraGroups; 53 + } 54 + // nixpkgs.lib.optionalAttrs unstable { 55 + unstable = import nixpkgs-unstable { 56 + inherit system; 57 + config.allowUnfree = true; 56 58 }; 59 + }; 57 60 modules = [ 58 61 determinite.nixosModules.default 59 62 ./configuration.nix 60 - ./users.nix 61 - ./services.nix 63 + ./users.nix 64 + ./services.nix 62 65 agenix.nixosModules.default 63 66 home-manager.nixosModules.home-manager 64 67 { 65 68 home-manager.useGlobalPkgs = true; 66 69 home-manager.useUserPackages = true; 67 70 home-manager.users.noah = ./home.nix; 68 - home-manager.extraSpecialArgs = 69 - { 70 - inherit inputs; 71 - } 72 - // nixpkgs.lib.optionalAttrs unstable { 73 - unstable = nixpkgs-unstable.legacyPackages.${system}; 74 - }; 71 + home-manager.extraSpecialArgs = { 72 + inherit inputs; 73 + } 74 + // nixpkgs.lib.optionalAttrs unstable { 75 + unstable = nixpkgs-unstable.legacyPackages.${system}; 76 + }; 75 77 } 76 - ] ++ modules; 78 + ] 79 + ++ modules; 77 80 }; 78 81 in 79 82 { ··· 81 84 nixosConfigurations.odin = basicSystem { 82 85 unstable = true; 83 86 }; 87 + nixosConfigurations.misaki = basicSystem { 88 + unstable = true; 89 + extraGroups = [ 90 + "render" 91 + "nats" 92 + "litterbox" 93 + "httpd" 94 + ]; 95 + modules = [ 96 + ./host-specific/misaki/configuration.nix 97 + ]; 98 + }; 84 99 nixosConfigurations.touma-wsl = basicSystem { 85 100 unstable = true; 86 101 modules = [ ··· 91 106 nixosConfigurations.edge = basicSystem { 92 107 unstable = true; 93 108 modules = [ 94 - ./host-specific/edge/configuration.nix 95 - ]; 109 + ./host-specific/edge/configuration.nix 110 + ]; 96 111 }; 97 112 checks = forAllSystems (system: { 98 113 pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run { ··· 111 126 inherit (self.checks.${system}.pre-commit-check) shellHook; 112 127 buildInputs = [ 113 128 nixpkgs.legacyPackages.${system}.nixfmt-rfc-style 114 - ] ++ self.checks.${system}.pre-commit-check.enabledPackages; 129 + ] 130 + ++ self.checks.${system}.pre-commit-check.enabledPackages; 115 131 }; 116 132 }); 117 133 formatter = forAllSystems (system: inputs.nixpkgs.legacyPackages.${system}.nixfmt-rfc-style);
+13
host-specific/misaki/boot.nix
··· 1 + { ... }: 2 + { 3 + # Use the systemd-boot EFI boot loader. 4 + boot.loader.systemd-boot.enable = true; 5 + boot.loader.efi.canTouchEfiVariables = true; 6 + 7 + boot.supportedFilesystems = [ "zfs" ]; 8 + boot.zfs.forceImportRoot = false; 9 + boot.zfs.extraPools = [ 10 + "shokuhou" 11 + "mentalout" 12 + ]; 13 + }
+12
host-specific/misaki/configuration.nix
··· 1 + { ... }: 2 + { 3 + imports = [ 4 + ./boot.nix 5 + ./users.nix 6 + ./hardware-configuration.nix 7 + ./networking.nix 8 + ./packages.nix 9 + ./services.nix 10 + ]; 11 + system.stateVersion = "23.11"; # Did you read the comment? 12 + }
+1
host-specific/misaki/coredns/localhost.hosts
··· 1 + 127.0.0.1 *.localhost
+9
host-specific/misaki/coredns/ngp.computer.hosts
··· 1 + 192.168.1.3 img.ngp.computer 2 + 192.168.1.3 photos.ngp.computer 3 + 192.168.1.3 misaki.ngp.computer 4 + 192.168.1.3 files.ngp.computer 5 + 6 + fe80::9ab7:85ff:fe1e:dfe8 img.ngp.computer 7 + fe80::9ab7:85ff:fe1e:dfe8 photos.ngp.computer 8 + fe80::9ab7:85ff:fe1e:dfe8 misaki.ngp.computer 9 + fe80::9ab7:85ff:fe1e:dfe8 files.ngp.computer
+17
host-specific/misaki/coredns/packetlost.dev.hosts
··· 1 + # Services 2 + 192.168.1.3 git.packetlost.dev 3 + 192.168.1.3 plex.packetlost.dev 4 + 192.168.1.3 jellyfin.packetlost.dev 5 + 192.168.1.3 nats.packetlost.dev 6 + 7 + # LAN Hosts 8 + 192.168.1.3 misaki.packetlost.dev misaki 9 + 192.168.1.3 cache.packetlost.dev cache 10 + 192.168.1.5 komoe.packetlost.dev komoe 11 + 192.168.1.6 rainbow.packetlost.dev rainbow 12 + 192.168.1.10 ichika.packetlost.dev ichika 13 + 192.168.1.11 futaba.packetlost.dev futaba 14 + 192.168.1.12 mitsumi.packetlost.dev mitsumi 15 + 192.168.1.13 orangepi5.packetlost.dev orangepi5 16 + 192.168.1.30 touma.packetlost.dev touma 17 + 192.168.1.33 kamijou.packetlost.dev kamijou
+91
host-specific/misaki/hardware-configuration.nix
··· 1 + # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 + # and may be overwritten by future invocations. Please make changes 3 + # to /etc/nixos/configuration.nix instead. 4 + { 5 + config, 6 + lib, 7 + pkgs, 8 + modulesPath, 9 + ... 10 + }: 11 + 12 + { 13 + imports = [ 14 + (modulesPath + "/installer/scan/not-detected.nix") 15 + ]; 16 + 17 + boot.kernelPackages = pkgs.linuxPackages; 18 + boot.initrd.availableKernelModules = [ 19 + "nvme" 20 + "xhci_pci" 21 + "ahci" 22 + "usbhid" 23 + "usb_storage" 24 + "sd_mod" 25 + "dm-raid" 26 + "raid1" 27 + ]; 28 + boot.initrd.kernelModules = [ 29 + "dm-snapshot" 30 + "dm-raid" 31 + "raid1" 32 + ]; 33 + boot.kernelModules = [ 34 + "kvm-amd" 35 + "zfs" 36 + ]; 37 + boot.kernelParams = [ "i915.enable_guc=3" ]; 38 + boot.extraModulePackages = [ ]; 39 + 40 + fileSystems."/" = { 41 + device = "/dev/disk/by-uuid/1988fa0d-ff4a-44aa-a93e-7f0bf3cea5cf"; 42 + fsType = "ext4"; 43 + }; 44 + 45 + fileSystems."/boot" = { 46 + device = "/dev/disk/by-uuid/81D4-01CD"; 47 + fsType = "vfat"; 48 + }; 49 + 50 + swapDevices = [ ]; 51 + 52 + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 53 + # (the default) this is the recommended approach. When using systemd-networkd it's 54 + # still possible to use this option, but it's recommended to use it in conjunction 55 + # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`. 56 + networking.useDHCP = lib.mkDefault true; 57 + # networking.interfaces.enp4s0f0.useDHCP = lib.mkDefault true; 58 + # networking.interfaces.enp4s0f1.useDHCP = lib.mkDefault true; 59 + # networking.interfaces.enp6s0.useDHCP = lib.mkDefault true; 60 + 61 + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 62 + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 63 + 64 + #nixpkgs.config.packageOverrides = pkgs: { 65 + # vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; }; 66 + #}; 67 + hardware.graphics = { 68 + enable = true; 69 + extraPackages = with pkgs; [ 70 + intel-media-driver 71 + #vaapiVdpau 72 + #libvdpau-va-gl # unmaintained, very old 73 + intel-compute-runtime 74 + vpl-gpu-rt 75 + ]; 76 + #extraPackages32 = with pkgs; [ 77 + # intel-media-driver 78 + # vaapiVdpau 79 + # #libvdpau-va-gl 80 + # intel-compute-runtime 81 + # vpl-gpu-rt 82 + #]; 83 + }; 84 + environment.variables = { 85 + VDPAU_DRIVER = "va_gl"; 86 + LIBVA_DRIVER_NAME = "iHD"; 87 + LIBVA_DRIVERS_PATH = "/run/opengl-driver/lib/dri"; 88 + GST_VAAPI_ALL_DRIVERS = "1"; 89 + }; 90 + #services.xserver.videoDrivers = [ "intel" ]; 91 + }
+113
host-specific/misaki/networking.nix
··· 1 + { config, ... }: 2 + { 3 + # networking.hostName = "nixos"; # Define your hostname. 4 + # Pick only one of the below networking options. 5 + # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. 6 + # networking.networkmanager.enable = true; # Easiest to use and most distros use this by default. 7 + networking.hostName = "misaki"; 8 + # I like systemd-networkd 9 + systemd.network.enable = true; 10 + systemd.network.networks."50-wlp2s0" = { 11 + matchConfig.name = "wlp2s0"; 12 + networkConfig.DHCP = "yes"; 13 + linkConfig.RequiredForOnline = "no"; 14 + }; 15 + 16 + networking.tempAddresses = "disabled"; 17 + 18 + networking.interfaces = { 19 + enp4s0f1 = { 20 + ipv4.addresses = [ 21 + { 22 + address = "192.168.1.3"; 23 + prefixLength = 24; 24 + } 25 + ]; 26 + }; 27 + }; 28 + networking.defaultGateway = { 29 + address = "192.168.1.1"; 30 + interface = "enp4s0f1"; 31 + }; 32 + 33 + networking.defaultGateway6 = { 34 + address = "fe80::2870:4eff:fe84:d884"; 35 + interface = "enp4s0f1"; 36 + }; 37 + 38 + networking.nameservers = [ 39 + "192.168.1.3" 40 + "45.90.28.93" 41 + "45.90.30.93" 42 + ]; 43 + 44 + # This is necessary for ZFS 45 + networking.hostId = "5beebabe"; 46 + 47 + networking.useNetworkd = true; 48 + # TODO: static IP @ 192.168.1.2 49 + 50 + # Configure network proxy if necessary 51 + # networking.proxy.default = "http://user:password@proxy:port/"; 52 + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; 53 + # Open ports in the firewall. 54 + # networking.firewall.allowedTCPPorts = [ ... ]; 55 + # networking.firewall.allowedUDPPorts = [ ... ]; 56 + # Or disable the firewall altogether. 57 + # TODO: allow some ports 58 + networking.firewall = { 59 + enable = true; 60 + allowPing = true; 61 + trustedInterfaces = [ 62 + "tailscale0" 63 + ]; 64 + allowedUDPPorts = [ 65 + # DNS 66 + 53 67 + config.services.tailscale.port 68 + ]; 69 + allowedTCPPorts = [ 70 + # DNS over TCP 71 + 53 72 + # NFSv4 73 + 2049 74 + # HTTP(s) 75 + 443 76 + 80 77 + # iperf3 78 + 5201 79 + 5301 80 + 5401 81 + # NATS 82 + 4222 83 + # Prometheus 84 + 9001 85 + # Minio 86 + 9003 87 + # Minio web 88 + 9004 89 + # AFP via Netatalk 90 + 548 91 + #9p 92 + 564 93 + # Misc development 94 + 3000 95 + ]; 96 + }; 97 + 98 + services.avahi = { 99 + enable = true; 100 + nssmdns4 = true; 101 + nssmdns6 = true; 102 + ipv6 = true; 103 + openFirewall = true; 104 + publish = { 105 + enable = true; 106 + addresses = true; 107 + workstation = true; 108 + userServices = true; 109 + domain = true; 110 + }; 111 + }; 112 + 113 + }
+67
host-specific/misaki/packages.nix
··· 1 + { 2 + pkgs, 3 + lib, 4 + inputs, 5 + ... 6 + }: 7 + { 8 + 9 + # List packages installed in system profile. To search, run: 10 + # $ nix search wget 11 + environment.systemPackages = with pkgs; [ 12 + neovim 13 + appimage-run 14 + wget 15 + kitty 16 + w3m 17 + fishPlugins.fzf-fish 18 + fzf 19 + qemu 20 + OVMF 21 + metastore 22 + # 9p 23 + diod 24 + plan9port 25 + vis 26 + rc 27 + ncdu 28 + inputs.agenix.packages."${system}".agenix 29 + 30 + # ZFS / filesystem stuff 31 + zfs 32 + 33 + # GPU stuff 34 + intel-gpu-tools 35 + #(ffmpeg-full.override { 36 + # withUnfree = true; 37 + # withMfx = false; 38 + # withSmallBuild = false; 39 + # withTensorflow = false; 40 + #}) 41 + libva 42 + libva-utils 43 + nvtopPackages.intel 44 + ]; 45 + 46 + # Fix dynamically linked libraries for unpackaged binaries 47 + programs.nix-ld = { 48 + enable = true; 49 + libraries = with pkgs; [ 50 + # Add missing dynamic libraries for unpackaged programs HERE 51 + # NOT in environment.systemPackages 52 + zlib 53 + ]; 54 + }; 55 + 56 + programs.fuse.userAllowOther = true; 57 + 58 + # Whitelist some unfree packages 59 + #nixpkgs.config.allowUnfreePredicate = 60 + # pkg: 61 + # builtins.elem (lib.getName pkg) [ 62 + # "tailscale" 63 + # "plexmediaserver" 64 + # "teamspeak-server" 65 + # "ffmpeg-full" 66 + # ]; 67 + }
+3
host-specific/misaki/scripts/fix-jpeg-raw-duplicates-immich.rcsh
··· 1 + #!/usr/bin/env rc 2 + 3 + nix run 'github:nixos/nixpkgs?ref=nixos-unstable-small#immich-go' -- stack -k `{pa show immich-api} -s 'https://photos.ngp.computer' --manage-raw-jpeg StackCoverJPG
+13
host-specific/misaki/scripts/nr
··· 1 + #!/usr/bin/env rc 2 + 3 + flag x + 4 + 5 + if(~ $1 -x) { 6 + flake e + 7 + shift 8 + } 9 + 10 + pkg=$1 11 + shift 12 + 13 + exec nix run --impure 'nixpkgs#'^$pkg -- $*
+8
host-specific/misaki/scripts/oclip
··· 1 + #!/usr/bin/env rc 2 + flag e + 3 + 4 + if (~ $1 -x) { 5 + flag x + 6 + } 7 + data=`{base64 <[0=0]} 8 + printf '\033]52;c;%s\007' $"data
+14
host-specific/misaki/scripts/update-src
··· 1 + #!/usr/bin/env rc 2 + 3 + background=() 4 + for(repo in `{cat downstream}) { 5 + echo Updating $repo 6 + git -C $repo fetch --all --tags --prune --force & 7 + background=($apid $background) 8 + } 9 + 10 + for (i in $background) { 11 + wait $i 12 + } 13 + 14 + echo Done!
+1
host-specific/misaki/secrets/cache-pub-key.pem
··· 1 + misaki.packetlost.dev:y5Z/utaVBozpL0UAbUQDWLjpm2sVMOoKzyG76n/167A=
+7
host-specific/misaki/secrets/nix-serve-secret-key.age
··· 1 + age-encryption.org/v1 2 + -> ssh-ed25519 e6zq8g l39Xz9AifFdYzu1lY0X6+lRSf9YCSwVvKpkY2yIltDY 3 + vnYucN1xNAb+KmrT5zJQlq8cz8GV+ZL915g0fZeIai4 4 + -> ssh-ed25519 QBbeMw cXXePretHJG85V9IXnwmEII5eGS//QsGdYpZvWzPvHo 5 + e/B9cP88ehm+R4hOhlrzuqIdg5BMGUD19U9ieD/H2Z8 6 + --- YlswbYIQdog/Qep02v7L35jN2cZZ1IVCK1jOYAvF7hc 7 + �A�[�(���W�聠�{����+��)�Y�f���b�8cn��%�ۀBx�)���z 5�|�� Կ]���2| �"���j 7 A�t^��z �G�� �K$B��!Xu}@"� R�Y�Ym���NY}JP�O|��
+6
host-specific/misaki/secrets/porkbun-api-key.age
··· 1 + age-encryption.org/v1 2 + -> ssh-ed25519 e6zq8g CdLTZ6uXiJB+xaD+I5NVHD5OxLSH+yAz99j04GiKukU 3 + kQTUR4yK23wHV9QGMlmTmIlMh63nP49g1NrS+sJKfBY 4 + --- H6/xHryPPKmAWW/bDXUN4YBXMKrsFpUAveKxWsT0SH0 5 + �E����,�ήS��P)A.������9O\�����2n��U�!���X�a��� l�Z�4*(G�[��>�Zl� 6 + :QՅ���������o����$=��& ڍ�w�t^�<<E�0p�8��:���� G�̉����J#�QR�����p�򘐞�kA,�=!��5�KK��0o��nQ��)�\\�ĘN�����wQ�҉
+15
host-specific/misaki/secrets/secrets.nix
··· 1 + let 2 + noah = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDQFlX3hhXxsqAUYLvF+IX1YWQ+k22OHlqMOjgyNBe9e noah@misaki"; 3 + misaki = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO+Rcf4Lr+JPWGKQol6eAml6SMgERkGJWgN7y1qYUUvX root@nixos"; 4 + #users = [noah]; 5 + in 6 + { 7 + "porkbun-api-key.age".publicKeys = [ 8 + noah 9 + misaki 10 + ]; 11 + "nix-serve-secret-key.age".publicKeys = [ 12 + misaki 13 + noah 14 + ]; 15 + }
+583
host-specific/misaki/services.nix
··· 1 + { 2 + config, 3 + pkgs, 4 + unstable, 5 + ... 6 + }: 7 + { 8 + 9 + services.zfs = { 10 + autoScrub.enable = true; 11 + }; 12 + services.nfs.server.enable = true; 13 + # Some programs need SUID wrappers, can be configured further or are 14 + # started in user sessions. 15 + # programs.mtr.enable = true; 16 + programs.gnupg.agent = { 17 + enable = true; 18 + enableSSHSupport = false; 19 + }; 20 + 21 + # Fish shell, the best 22 + programs.fish.enable = true; 23 + 24 + # MOSH, SSH over flakey connections 25 + programs.mosh.enable = true; 26 + 27 + # List services that you want to enable: 28 + 29 + # Enable the OpenSSH daemon. 30 + services.openssh = { 31 + enable = true; 32 + openFirewall = true; 33 + settings.PasswordAuthentication = false; 34 + }; 35 + 36 + # This option is for enabling the bolt daemon for managing Thunderbolt/USB4 Devices. 37 + services.hardware.bolt.enable = true; 38 + 39 + # Tailscale 40 + services.tailscale = { 41 + enable = true; 42 + useRoutingFeatures = "client"; 43 + }; 44 + 45 + # Containers and VMs 46 + virtualisation = { 47 + podman = { 48 + enable = true; 49 + dockerCompat = true; 50 + defaultNetwork.settings.dns_enabled = true; 51 + }; 52 + }; 53 + 54 + # Samba, for shares 55 + # TODO 56 + services.samba = { 57 + enable = true; 58 + openFirewall = true; 59 + nmbd.enable = true; 60 + winbindd.enable = true; 61 + settings = { 62 + global = { 63 + workgroup = "WORKGROUP"; 64 + "server string" = "misaki"; 65 + security = "user"; 66 + "use sendfile" = "yes"; 67 + "hosts allow" = "192.168.1. 127.0.0.1 localhost"; 68 + "hosts deny" = "0.0.0.0/0"; 69 + "guest account" = "nobody"; 70 + "map to guest" = "bad user"; 71 + deadtime = 30; 72 + }; 73 + shokuhou = { 74 + path = "/srv/shokuhou"; 75 + browseable = "yes"; 76 + "read only" = "no"; 77 + "guest ok" = "no"; 78 + "create mask" = "0644"; 79 + "directory mask" = "0755"; 80 + "force user" = "noah"; 81 + "force group" = "nas"; 82 + }; 83 + mentalout = { 84 + path = "/srv/mentalout"; 85 + browseable = "yes"; 86 + "read only" = "no"; 87 + "guest ok" = "no"; 88 + "create mask" = "0644"; 89 + "directory mask" = "0755"; 90 + "force user" = "noah"; 91 + "force group" = "nas"; 92 + }; 93 + }; 94 + }; 95 + services.samba-wsdd = { 96 + enable = true; 97 + openFirewall = true; 98 + }; 99 + 100 + services.coredns = { 101 + enable = true; 102 + config = '' 103 + packetlost.dev { 104 + hosts ${./coredns/packetlost.dev.hosts} packetlost.dev { 105 + fallthrough 106 + } 107 + bind enp4s0f1 108 + } 109 + ngp.computer { 110 + hosts ${./coredns/ngp.computer.hosts} ngp.computer { 111 + fallthrough 112 + } 113 + bind enp4s0f1 114 + } 115 + localhost { 116 + hosts ${./coredns/localhost.hosts} localhost { 117 + fallthrough 118 + } 119 + bind enp4s0f1 120 + } 121 + . { 122 + # NextDNS 123 + forward . tls://2a07:a8c0::dd:2feb:853 tls://2a07:a8c1::dd:2feb:853 tls://45.90.28.93:853 tls://45.90.30.93:853 { 124 + tls_servername dd2feb.dns.nextdns.io 125 + health_check 5s 126 + } 127 + bind enp4s0f1 128 + cache 129 + errors 130 + log 131 + } 132 + ''; 133 + }; 134 + 135 + services.nats = { 136 + enable = true; 137 + jetstream = true; 138 + user = "nats"; 139 + group = "nats"; 140 + serverName = "misaki"; 141 + dataDir = "/srv/shokuhou/applications/nats"; 142 + validateConfig = false; 143 + settings = { 144 + authorization = { 145 + users = [ 146 + { 147 + user = "seedbox@packetlost.dev"; 148 + permissions = { 149 + publish = [ 150 + "torrents" 151 + "torrents.>" 152 + "$JS.API.INFO" 153 + #"$JS.API.STREAM.INFO.>" 154 + "$KV.torrents.>" 155 + #"$JS.API.STREAM.*.*.OBJ_torrents" 156 + "$JS.API.*.*.OBJ_torrents" 157 + "$JS.API.STREAM.MSG.GET.OBJ_torrents" 158 + "$JS.API.*.*.OBJ_torrents.>" 159 + "$O.torrents.>" 160 + ]; 161 + subscribe = [ 162 + "torrents.>" 163 + "_INBOX.>" 164 + ]; 165 + allow_responses = false; 166 + }; 167 + } 168 + { user = "odin@packetlost.dev"; } 169 + { user = "misaki@packetlost.dev"; } 170 + { user = "noah@packetlost.dev"; } 171 + { user = "touma-nixos@packetlost.dev"; } 172 + ]; 173 + }; 174 + tls = { 175 + cert_file = "/srv/nats/nats.packetlost.dev/cert.pem"; 176 + key_file = "/srv/nats/nats.packetlost.dev/key.pem"; 177 + ca_file = "/srv/nats/minica.pem"; 178 + verify_and_map = true; 179 + }; 180 + jetstream = { 181 + # 50GB 182 + max_file_store = 53687091200; 183 + max_mem = 8589934592; 184 + }; 185 + }; 186 + }; 187 + 188 + # Minio's object storage has been mostly replaced with NATS. If I specifically need a 189 + # S3-like API, this will be revived. 190 + services.minio = { 191 + enable = false; 192 + listenAddress = ":9003"; 193 + consoleAddress = ":9004"; 194 + dataDir = [ 195 + /srv/shokuhou/applications/minio 196 + ]; 197 + }; 198 + 199 + services.netatalk = { 200 + enable = true; 201 + settings = { 202 + time-machine = { 203 + path = "/srv/shokuhou/backup/timemachine"; 204 + "valid users" = "noah"; 205 + "time machine" = true; 206 + }; 207 + }; 208 + }; 209 + 210 + services.webdav.enable = false; 211 + services.sftpgo = { 212 + enable = false; 213 + dataDir = /srv/shokuhou/documents/sftpgo; 214 + group = "nas"; 215 + }; 216 + services.syncthing = { 217 + enable = false; 218 + openDefaultPorts = true; 219 + # disable the sync folder creation 220 + extraFlags = [ "--no-default-folder" ]; 221 + settings = { 222 + folders = { 223 + "Sync" = { 224 + path = "/srv/shokuhou/documents/sync"; 225 + }; 226 + }; 227 + }; 228 + }; 229 + 230 + services.grafana = { 231 + enable = false; 232 + settings.server.http_port = 2342; 233 + settings.server.domain = "grafana.packetlost.dev"; 234 + settings.server.http_addr = "127.0.0.1"; 235 + }; 236 + 237 + services.prometheus = { 238 + enable = false; 239 + port = 9001; 240 + exporters = { 241 + node = { 242 + enable = true; 243 + enabledCollectors = [ "systemd" ]; 244 + port = 9002; 245 + }; 246 + }; 247 + 248 + scrapeConfigs = [ 249 + { 250 + job_name = "chrysalis"; 251 + static_configs = [ 252 + { targets = [ "127.0.0.1:${builtins.toString config.services.prometheus.exporters.node.port}" ]; } 253 + ]; 254 + } 255 + ]; 256 + }; 257 + 258 + # TODO: figure out how to appropriately configure this 259 + services.step-ca = { 260 + enable = false; 261 + openFirewall = true; 262 + port = 8443; 263 + address = "0.0.0.0"; 264 + intermediatePasswordFile = /etc/nixos/step-ca-intermediate-ca-password; 265 + settings = builtins.fromJSON (builtins.readFile /home/noah/.step/config/ca.json); 266 + }; 267 + 268 + age.secrets.acme = { 269 + file = ./secrets/porkbun-api-key.age; 270 + owner = "root"; 271 + group = "acme"; 272 + }; 273 + 274 + # TODO: re-enable this once Agenix is set up 275 + security.acme = { 276 + acceptTerms = true; 277 + defaults.email = "noah@packetlost.dev"; 278 + certs."plex.packetlost.dev" = { 279 + dnsProvider = "porkbun"; 280 + group = "httpd"; 281 + environmentFile = config.age.secrets.acme.path; 282 + }; 283 + certs."img.ngp.computer" = { 284 + group = "httpd"; 285 + dnsProvider = "porkbun"; 286 + environmentFile = config.age.secrets.acme.path; 287 + }; 288 + certs."files.ngp.computer" = { 289 + group = "httpd"; 290 + dnsProvider = "porkbun"; 291 + environmentFile = config.age.secrets.acme.path; 292 + }; 293 + certs."photos.ngp.computer" = { 294 + group = "httpd"; 295 + dnsProvider = "porkbun"; 296 + environmentFile = config.age.secrets.acme.path; 297 + }; 298 + certs."jellyfin.packetlost.dev" = { 299 + group = "httpd"; 300 + dnsProvider = "porkbun"; 301 + environmentFile = config.age.secrets.acme.path; 302 + }; 303 + }; 304 + 305 + # A test email server that only works on LAN 306 + services.maddy = { 307 + enable = true; 308 + openFirewall = true; 309 + primaryDomain = "misaki.local"; 310 + ensureAccounts = [ 311 + "noah@misaki.local" 312 + "postmaster@misaki.local" 313 + "test@misaki.local" 314 + ]; 315 + ensureCredentials = { 316 + "noah@misaki.local".passwordFile = "${pkgs.writeText "noah" "Password123"}"; 317 + "postmaster@misaki.local".passwordFile = "${pkgs.writeText "noah" "Password123"}"; 318 + "test@misaki.local".passwordFile = "${pkgs.writeText "test" "Password123"}"; 319 + }; 320 + }; 321 + 322 + age.secrets.nix-serve = { 323 + file = ./secrets/nix-serve-secret-key.age; 324 + owner = "root"; 325 + group = "root"; 326 + }; 327 + services.nix-serve = { 328 + enable = true; 329 + package = unstable.nix-serve-ng; 330 + secretKeyFile = config.age.secrets.nix-serve.path; 331 + openFirewall = true; 332 + }; 333 + 334 + services.plex = { 335 + enable = true; 336 + openFirewall = false; # we proxy this with nginx 337 + group = "nas"; 338 + user = "noah"; 339 + package = unstable.plex; 340 + }; 341 + 342 + services.jellyfin = { 343 + enable = true; 344 + openFirewall = true; 345 + user = "noah"; 346 + group = "nas"; 347 + logDir = "/srv/shokuhou/applications/jellyfin/log"; 348 + cacheDir = "/srv/shokuhou/applications/jellyfin/cache"; 349 + dataDir = "/srv/shokuhou/applications/jellyfin/data"; 350 + configDir = "/srv/shokuhou/applications/jellyfin/config"; 351 + }; 352 + 353 + # services.gitea = { 354 + # enable = true; 355 + # user = "git"; 356 + # domain = "git.packetlost.dev"; 357 + # }; 358 + 359 + # Litterbox, collect my IRC logs 360 + systemd = { 361 + services = { 362 + "litterbox@" = { 363 + path = [ pkgs.litterbox ]; 364 + serviceConfig = { 365 + StartLimitIntervalSec = 5; 366 + StartLimitBurst = 10; 367 + Restart = "on-failure"; 368 + RestartSec = "10s"; 369 + Type = "simple"; 370 + ExecStart = "${pkgs.litterbox}/bin/litterbox /srv/litterbox/%i.conf"; 371 + ExecReload = "kill -USR1 $MAINPID"; 372 + User = "noah"; 373 + Group = "litterbox"; 374 + }; 375 + }; 376 + 377 + #"litterbox@libera.irc.packetlost.dev" = { 378 + # overrideStrategy = "asDropin"; 379 + # wantedBy = [ "multi-user.target" ]; 380 + #}; 381 + "update-downstream-src" = { 382 + path = with pkgs; [ 383 + rc 384 + coreutils 385 + git 386 + openssh 387 + ]; 388 + script = "exec ${./scripts/update-src}"; 389 + serviceConfig = { 390 + Type = "oneshot"; 391 + User = "noah"; 392 + WorkingDirectory = "/srv/src"; 393 + }; 394 + }; 395 + }; 396 + timers = { 397 + "update-downstream-src" = { 398 + wantedBy = [ "timers.target" ]; 399 + timerConfig = { 400 + OnCalendar = "daily"; 401 + Persistent = true; 402 + }; 403 + }; 404 + }; 405 + }; 406 + 407 + services.teamspeak3 = { 408 + enable = true; 409 + openFirewall = true; 410 + }; 411 + 412 + services.immich = { 413 + enable = true; 414 + package = unstable.immich; 415 + accelerationDevices = [ "/dev/dri/renderD128" ]; 416 + mediaLocation = "/srv/shokuhou/pictures/immich"; 417 + }; 418 + users.users.immich.extraGroups = [ 419 + "video" 420 + "render" 421 + "nas" 422 + ]; 423 + 424 + # Nginx Reverse SSL Proxy 425 + services.nginx = { 426 + enable = true; 427 + group = "nas"; 428 + user = "noah"; 429 + 430 + # This is disabled for now 431 + #virtualHosts."${config.services.grafana.settings.server.domain}" = { 432 + # locations."/" = { 433 + # proxyPass = "http://127.0.0.1:${builtins.toString config.services.grafana.settings.server.http_port}"; 434 + # proxyWebsockets = true; 435 + # }; 436 + #}; 437 + 438 + virtualHosts."cache.packetlost.dev" = { 439 + locations."/".proxyPass = 440 + "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; 441 + }; 442 + virtualHosts."photos.ngp.computer" = { 443 + enableACME = false; 444 + useACMEHost = "photos.ngp.computer"; 445 + acmeRoot = null; 446 + forceSSL = true; 447 + locations."/" = { 448 + proxyPass = "http://[::1]:${toString config.services.immich.port}"; 449 + proxyWebsockets = true; 450 + recommendedProxySettings = true; 451 + extraConfig = '' 452 + client_max_body_size 50000M; 453 + proxy_read_timeout 600s; 454 + proxy_send_timeout 600s; 455 + send_timeout 600s; 456 + ''; 457 + }; 458 + }; 459 + virtualHosts."img.ngp.computer" = { 460 + forceSSL = true; 461 + enableACME = false; 462 + useACMEHost = "img.ngp.computer"; 463 + acmeRoot = null; 464 + root = "/srv/shokuhou/pictures/public"; 465 + extraConfig = '' 466 + sendfile on; 467 + autoindex_exact_size on; 468 + tcp_nopush on; 469 + ''; 470 + locations."/" = { 471 + extraConfig = '' 472 + autoindex on; 473 + autoindex_exact_size on; 474 + alias /srv/shokuhou/pictures/public/$1; 475 + ''; 476 + }; 477 + }; 478 + virtualHosts."files.ngp.computer" = { 479 + forceSSL = true; 480 + enableACME = false; 481 + useACMEHost = "files.ngp.computer"; 482 + acmeRoot = null; 483 + root = null; 484 + extraConfig = '' 485 + sendfile on; 486 + tcp_nopush on; 487 + ''; 488 + locations."/books/" = { 489 + extraConfig = '' 490 + autoindex on; 491 + autoindex_exact_size on; 492 + alias /srv/shokuhou/books/sync/$1; 493 + ''; 494 + }; 495 + }; 496 + virtualHosts."jellyfin.packetlost.dev" = { 497 + forceSSL = true; 498 + enableACME = false; 499 + useACMEHost = "jellyfin.packetlost.dev"; 500 + acmeRoot = null; 501 + http2 = true; 502 + locations."/" = { 503 + proxyPass = "http://localhost:8096/"; 504 + }; 505 + }; 506 + 507 + # give a name to the virtual host. It also becomes the server name. 508 + virtualHosts."plex.packetlost.dev" = { 509 + # Since we want a secure connection, we force SSL 510 + forceSSL = true; 511 + enableACME = false; 512 + useACMEHost = "plex.packetlost.dev"; 513 + acmeRoot = null; 514 + 515 + # http2 can more performant for streaming: https://blog.cloudflare.com/introducing-http2/ 516 + http2 = true; 517 + 518 + # Provide the ssl cert and key for the vhost 519 + # These are filled in automatically with ACME 520 + extraConfig = '' 521 + 522 + #Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause 523 + send_timeout 100m; 524 + 525 + # Why this is important: https://blog.cloudflare.com/ocsp-stapling-how-cloudflare-just-made-ssl-30/ 526 + ssl_stapling on; 527 + ssl_stapling_verify on; 528 + 529 + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 530 + ssl_prefer_server_ciphers on; 531 + #Intentionally not hardened for security for player support and encryption video streams has a lot of overhead with something like AES-256-GCM-SHA384. 532 + ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; 533 + 534 + # Forward real ip and host to Plex 535 + proxy_set_header X-Real-IP $remote_addr; 536 + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 537 + proxy_set_header X-Forwarded-Proto $scheme; 538 + proxy_set_header Host $server_addr; 539 + proxy_set_header Referer $server_addr; 540 + proxy_set_header Origin $server_addr; 541 + 542 + # Plex has A LOT of javascript, xml and html. This helps a lot, but if it causes playback issues with devices turn it off. 543 + gzip on; 544 + gzip_vary on; 545 + gzip_min_length 1000; 546 + gzip_proxied any; 547 + gzip_types text/plain text/css text/xml application/xml text/javascript application/x-javascript image/svg+xml; 548 + gzip_disable "MSIE [1-6]\."; 549 + 550 + # Nginx default client_max_body_size is 1MB, which breaks Camera Upload feature from the phones. 551 + # Increasing the limit fixes the issue. Anyhow, if 4K videos are expected to be uploaded, the size might need to be increased even more 552 + client_max_body_size 100M; 553 + 554 + # Plex headers 555 + proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; 556 + proxy_set_header X-Plex-Device $http_x_plex_device; 557 + proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; 558 + proxy_set_header X-Plex-Platform $http_x_plex_platform; 559 + proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; 560 + proxy_set_header X-Plex-Product $http_x_plex_product; 561 + proxy_set_header X-Plex-Token $http_x_plex_token; 562 + proxy_set_header X-Plex-Version $http_x_plex_version; 563 + proxy_set_header X-Plex-Nocache $http_x_plex_nocache; 564 + proxy_set_header X-Plex-Provides $http_x_plex_provides; 565 + proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; 566 + proxy_set_header X-Plex-Model $http_x_plex_model; 567 + 568 + # Websockets 569 + proxy_http_version 1.1; 570 + proxy_set_header Upgrade $http_upgrade; 571 + proxy_set_header Connection "upgrade"; 572 + 573 + # Buffering off send to the client as soon as the data is received from Plex. 574 + proxy_redirect off; 575 + proxy_buffering off; 576 + ''; 577 + 578 + locations."/" = { 579 + proxyPass = "http://localhost:32400/"; 580 + }; 581 + }; 582 + }; 583 + }
+6
host-specific/misaki/users.nix
··· 1 + { ... }: 2 + { 3 + users.groups.nas.gid = 1001; 4 + users.groups.httpd.gid = 1002; 5 + users.groups.litterbox.gid = 1003; 6 + }
-43
packages.nix
··· 1 - { pkgs, lib, ... }: 2 - { 3 - # List packages installed in system profile. To search, run: 4 - # $ nix search wget 5 - environment.systemPackages = with pkgs; [ 6 - neovim 7 - appimage-run 8 - wget 9 - kitty 10 - w3m 11 - fishPlugins.fzf-fish 12 - fzf 13 - qemu 14 - OVMF 15 - gitFull 16 - # plan9 17 - diod 18 - plan9port 19 - vis 20 - rc 21 - 22 - xdg-utils 23 - ]; 24 - 25 - # Fix dynamically linked libraries for unpackaged binaries 26 - programs.nix-ld = { 27 - enable = true; 28 - libraries = with pkgs; 29 - [ 30 - # Add missing dynamic libraries for unpackaged programs HERE 31 - # NOT in environment.systemPackages 32 - zlib 33 - fuse3 34 - ]; 35 - }; 36 - 37 - # Logseq uses an ancient version of Electron, so we enable that 38 - #nixpkgs.config.permittedInsecurePackages = [ "electron-25.9.0" ]; 39 - 40 - # Whitelist some unfree packages 41 - nixpkgs.config.allowUnfreePredicate = pkg: 42 - builtins.elem (lib.getName pkg) [ ]; 43 - }
-11
services.nix
··· 7 7 8 8 # Fish shell, the best 9 9 programs.fish.enable = true; 10 - 11 - # List services that you want to enable: 12 - 13 - # Containers and VMs 14 - virtualisation = { 15 - podman = { 16 - enable = false; 17 - dockerCompat = true; 18 - defaultNetwork.settings.dns_enabled = true; 19 - }; 20 - }; 21 10 }
+9 -2
users.nix
··· 1 - { pkgs, lib, config, ... }: 1 + { 2 + pkgs, 3 + lib, 4 + config, 5 + extraGroups ? [ ], 6 + ... 7 + }: 2 8 { 3 9 4 10 # Declarative only optoins. ··· 20 26 "wheel" 21 27 "video" 22 28 "nas" 23 - ]; # Enable ‘sudo’ for the user. 29 + ] 30 + ++ extraGroups; # Enable ‘sudo’ for the user. 24 31 hashedPasswordFile = config.age.secrets.noah-password.path; 25 32 openssh.authorizedKeys.keys = lib.strings.splitString "\n" ( 26 33 builtins.readFile (