diff --git a/flake.lock b/flake.lock index bcac3bb..a7ae76e 100755 --- a/flake.lock +++ b/flake.lock @@ -4,7 +4,7 @@ "inputs": { "devshell": "devshell", "nix-fetcher-data": "nix-fetcher-data", - "nixpkgs": "nixpkgs_6" + "nixpkgs": "nixpkgs_7" }, "locked": { "lastModified": 1732920288, @@ -20,6 +20,25 @@ "type": "github" } }, + "copyparty": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1740346641, + "narHash": "sha256-0djPRTfFhRo2FTYVNGkw9zFh8SbH0e0lyIwsrvwA1OY=", + "owner": "9001", + "repo": "copyparty", + "rev": "598a29a7339f0824bc042f35c31697e239475095", + "type": "github" + }, + "original": { + "owner": "9001", + "repo": "copyparty", + "type": "github" + } + }, "devshell": { "inputs": { "nixpkgs": [ @@ -44,7 +63,7 @@ }, "disko": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_2" }, "locked": { "lastModified": 1738148035, @@ -79,6 +98,21 @@ } }, "flake-utils": { + "locked": { + "lastModified": 1678901627, + "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { "inputs": { "systems": "systems" }, @@ -98,7 +132,7 @@ }, "home-manager": { "inputs": { - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs_3" }, "locked": { "lastModified": 1736441698, @@ -134,7 +168,7 @@ "inputs": { "niri-stable": "niri-stable", "niri-unstable": "niri-unstable", - "nixpkgs": "nixpkgs_3", + "nixpkgs": "nixpkgs_4", "nixpkgs-stable": "nixpkgs-stable", "xwayland-satellite-stable": "xwayland-satellite-stable", "xwayland-satellite-unstable": "xwayland-satellite-unstable" @@ -211,18 +245,17 @@ }, "nixpkgs": { "locked": { - "lastModified": 1737879851, - "narHash": "sha256-H+FXIKj//kmFHTTW4DFeOjR7F1z2/3eb2iwN6Me4YZk=", + "lastModified": 1680334310, + "narHash": "sha256-ISWz16oGxBhF7wqAxefMPwFag6SlsA9up8muV79V9ck=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5d3221fd57cc442a1a522a15eb5f58230f45a304", + "rev": "884e3b68be02ff9d61a042bc9bd9dd2a358f95da", "type": "github" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" + "id": "nixpkgs", + "ref": "nixos-22.11", + "type": "indirect" } }, "nixpkgs-lib": { @@ -254,6 +287,22 @@ } }, "nixpkgs_2": { + "locked": { + "lastModified": 1737879851, + "narHash": "sha256-H+FXIKj//kmFHTTW4DFeOjR7F1z2/3eb2iwN6Me4YZk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5d3221fd57cc442a1a522a15eb5f58230f45a304", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { "locked": { "lastModified": 1736012469, "narHash": "sha256-/qlNWm/IEVVH7GfgAIyP6EsVZI6zjAx1cV5zNyrs+rI=", @@ -269,7 +318,7 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_4": { "locked": { "lastModified": 1738410390, "narHash": "sha256-xvTo0Aw0+veek7hvEVLzErmJyQkEcRk6PSR4zsRQFEc=", @@ -285,7 +334,7 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_5": { "locked": { "lastModified": 1738517419, "narHash": "sha256-tttEXgKimgbtPvxFl+Avos4P4lssIqxHhxpLbbvNekk=", @@ -301,7 +350,7 @@ "type": "github" } }, - "nixpkgs_5": { + "nixpkgs_6": { "locked": { "lastModified": 1731763621, "narHash": "sha256-ddcX4lQL0X05AYkrkV2LMFgGdRvgap7Ho8kgon3iWZk=", @@ -317,7 +366,7 @@ "type": "github" } }, - "nixpkgs_6": { + "nixpkgs_7": { "locked": { "lastModified": 1728492678, "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=", @@ -333,7 +382,7 @@ "type": "github" } }, - "nixpkgs_7": { + "nixpkgs_8": { "locked": { "lastModified": 1737632463, "narHash": "sha256-38J9QfeGSej341ouwzqf77WIHAScihAKCt8PQJ+NH28=", @@ -351,18 +400,19 @@ }, "root": { "inputs": { + "copyparty": "copyparty", "disko": "disko", "home-manager": "home-manager", "impermanence": "impermanence", "niri": "niri", - "nixpkgs": "nixpkgs_4", + "nixpkgs": "nixpkgs_5", "sops-nix": "sops-nix", "sydnix-cli": "sydnix-cli" } }, "sops-nix": { "inputs": { - "nixpkgs": "nixpkgs_5" + "nixpkgs": "nixpkgs_6" }, "locked": { "lastModified": 1738291974, @@ -381,8 +431,8 @@ "sydnix-cli": { "inputs": { "clj-nix": "clj-nix", - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs_7" + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs_8" }, "locked": { "lastModified": 1737870551, diff --git a/flake.nix b/flake.nix index 98a4c64..628b133 100755 --- a/flake.nix +++ b/flake.nix @@ -3,20 +3,15 @@ inputs = { disko.url = "github:nix-community/disko"; - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - impermanence.url = "github:nix-community/impermanence"; - # We're using my branch until #6259 is merged. home-manager.url = "github:msyds/home-manager/service-mpdscribble"; # home-manager.url = "path:///persist/dots/DELETE-ME/home-manager"; - niri.url = "github:sodiboo/niri-flake"; - sops-nix.url = "github:Mic92/sops-nix"; - sydnix-cli.url = "path:///persist/dots/scripts/sydnix-cli"; + copyparty.url = "github:9001/copyparty"; }; outputs = { nixpkgs, ... }@inputs: @@ -30,9 +25,7 @@ collectModules = path: let modules = list-nix-directory path; in { pkgs, lib, ... }: { - imports = - lib.debug.traceVal - (builtins.map (m: ./${path}/${m}) modules); + imports = builtins.map (m: ./${path}/${m}) modules; }; in { # REVIEW: Why don't we put each module under nixosModules.? diff --git a/hosts/deertopia/configuration.nix b/hosts/deertopia/configuration.nix index 75bf261..bc6e791 100755 --- a/hosts/deertopia/configuration.nix +++ b/hosts/deertopia/configuration.nix @@ -99,6 +99,7 @@ nginx.enable = true; slskd.enable = true; webdav.enable = true; + copyparty.enable = true; # A simple default webpage. This should probably live somewhere else. nginx.vhosts."www" = { diff --git a/modules/nixos/deertopia/authelia.nix b/modules/nixos/deertopia/authelia.nix index 95d7ad4..770f2c5 100644 --- a/modules/nixos/deertopia/authelia.nix +++ b/modules/nixos/deertopia/authelia.nix @@ -132,18 +132,21 @@ in { }; }; - sydnix.deertopia.nginx.vhosts."auth".vhost = { - forceSSL = true; - enableACME = true; - extraConfig = '' - set $upstream http://127.0.0.1:${builtins.toString cfg.httpPort}; - ''; - locations."/".extraConfig = '' - include ${./authelia/proxy.conf}; - proxy_pass $upstream; - ''; - locations."/api/verify".proxyPass = "$upstream"; - locations."/api/authz".proxyPass = "$upstream"; + sydnix.deertopia.nginx.vhosts."auth" = { + directory = null; + vhost = { + forceSSL = true; + enableACME = true; + extraConfig = '' + set $upstream http://127.0.0.1:${builtins.toString cfg.httpPort}; + ''; + locations."/".extraConfig = '' + include ${./authelia/proxy.conf}; + proxy_pass $upstream; + ''; + locations."/api/verify".proxyPass = "$upstream"; + locations."/api/authz".proxyPass = "$upstream"; + }; }; # TODO: Remove this. It's only used for a quick demo for myself. The diff --git a/modules/nixos/deertopia/copyparty.nix b/modules/nixos/deertopia/copyparty.nix new file mode 100644 index 0000000..2816bac --- /dev/null +++ b/modules/nixos/deertopia/copyparty.nix @@ -0,0 +1,66 @@ +{ config, lib, pkgs, ... }@inputs: + +let cfg = config.sydnix.deertopia.copyparty; +in { + options.sydnix.deertopia.copyparty = { + enable = lib.mkEnableOption "Copyparty"; + port = lib.mkOption { + type = lib.types.port; + description = '' + Port on which Copyparty is to listen. + ''; + default = 3923; + }; + }; + + config = lib.mkIf cfg.enable { + sydnix.impermanence.directories = [ + ]; + + nixpkgs.overlays = [ inputs.copyparty.overlays.default ]; + + # HACK: Ad-hoc permissions, as typical. + users.users.copyparty.extraGroups = [ "jellyfin" ]; + + # HACK: Make files created by copypaste.service initialise with the mode + # 775. + systemd.services.copyparty.serviceConfig.UMask = lib.mkForce "002"; + + services.copyparty = { + enable = true; + settings = { + # These three options are necessary for SSO integration. No idea what + # they do. }:) + xff-src = "lan"; + idp-h-usr = "remote-user"; + idp-h-grp = "remote-groups"; + }; + volumes = { + "/Jellyfin" = { + path = "/persist/vault/jellyfin"; + # View and upload, but no deleting. + access.rw = "*"; + access.rwmd = "@jellyfin-admin"; + }; + }; + }; + + sydnix.deertopia.nginx.vhosts."files" = { + directory = null; + vhost = { + forceSSL = true; + enableACME = true; + extraConfig = '' + include ${./authelia/authelia-location.conf}; + # Increase limit of upload sizes. + client_max_body_size 20G; + ''; + locations."/".extraConfig = '' + include ${./authelia/authelia-authrequest.conf}; + include ${./authelia/proxy.conf}; + proxy_pass http://localhost:${builtins.toString cfg.port}; + ''; + }; + }; + }; +} diff --git a/modules/nixos/deertopia/jellyfin.nix b/modules/nixos/deertopia/jellyfin.nix index a001e0f..de54772 100644 --- a/modules/nixos/deertopia/jellyfin.nix +++ b/modules/nixos/deertopia/jellyfin.nix @@ -28,6 +28,9 @@ in { openFirewall = true; }; + # HACK: Force the mode 664 upon Jellyfin-created files. + systemd.services.jellyfin.serviceConfig.UMask = lib.mkForce "002"; + sydnix.deertopia.nginx.vhosts."watch".vhost = # Currently no (convenient) way to specify Jellyfin's port from Nix. let port = builtins.toString 8096; diff --git a/modules/nixos/deertopia/nginx.nix b/modules/nixos/deertopia/nginx.nix index 5de5e6e..808fa12 100644 --- a/modules/nixos/deertopia/nginx.nix +++ b/modules/nixos/deertopia/nginx.nix @@ -71,7 +71,7 @@ in services.nginx.enable = true; networking.firewall.allowedTCPPorts = [ - 80 # HTTP + 80 # HTTP 443 # HTTPS ]; @@ -85,6 +85,11 @@ in defaults.email = "lomiskiam@gmail.com"; }; + sydnix.impermanence.directories = [ + # Don't regenerate certs on reboot. + "/var/lib/acme" + ]; + services.nginx.virtualHosts = builtins.listToAttrs (builtins.map diff --git a/modules/nixos/deertopia/slskd.nix b/modules/nixos/deertopia/slskd.nix index 5a36b08..189623b 100644 --- a/modules/nixos/deertopia/slskd.nix +++ b/modules/nixos/deertopia/slskd.nix @@ -55,6 +55,18 @@ in { include ${./authelia/proxy.conf}; proxy_pass $upstream; ''; + locations."/hub".extraConfig = '' + proxy_pass $upstream; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + ''; }; }; }; diff --git a/modules/nixos/syncthing.nix b/modules/nixos/syncthing.nix index 8d2b8a8..4fe2d98 100644 --- a/modules/nixos/syncthing.nix +++ b/modules/nixos/syncthing.nix @@ -26,6 +26,10 @@ in { "nginx" ]; + sydnix.impermanence.directories = [ + "/var/lib/syncthing" + ]; + sydnix.deertopia.nginx.vhosts."syncthing".vhost = { forceSSL = true; enableACME = true; diff --git a/outputs/nixosConfigurations.nix b/outputs/nixosConfigurations.nix index efcde08..69f143b 100755 --- a/outputs/nixosConfigurations.nix +++ b/outputs/nixosConfigurations.nix @@ -21,6 +21,7 @@ let mkHost = hostName: let system = import ../hosts/${hostName}/system.nix; in nixpkgs.lib.nixosSystem { + # Pass `inputs` to all modules as a 'special arg,' like `config` or `lib`. specialArgs = inputs; inherit system; modules = [ @@ -28,9 +29,11 @@ let inputs.self.nixosModules.default + # TODO: Move imports to their own respective modules. inputs.disko.nixosModules.disko inputs.sops-nix.nixosModules.sops inputs.impermanence.nixosModules.impermanence + inputs.copyparty.nixosModules.default # Directory name should always match host name. ({ ... }: { networking.hostName = hostName; }) diff --git a/users/lain/default.nix b/users/lain/default.nix index 6b48a35..668b921 100755 --- a/users/lain/default.nix +++ b/users/lain/default.nix @@ -14,6 +14,8 @@ "annex" # Can modify Deertopia's Jellyfin libraries. "jellyfin" + # Can access slskd's downloads + "slskd" ]; initialHashedPassword = "$y$j9T$aEFDDwdTZbAc6VQRXrkBJ0$K8wxTGTWDihyX1wxJ.ZMH//wmQFfrGGUkLkxIU0Lyq8";