diff --git a/modules/homelab/services/jellyfin/default.nix b/modules/homelab/services/jellyfin/default.nix new file mode 100644 index 0000000..b816f17 --- /dev/null +++ b/modules/homelab/services/jellyfin/default.nix @@ -0,0 +1,108 @@ +{ pkgs, config, lib, ... }: + +let + service = ""; + cfg = config.modules.services.${service}; + sec = config.sops.secrets; + homelab = config.modules.homelab; +in +{ + options.modules.services.${service} = { + enable = lib.mkEnableOption "enables ${service}"; + + # set port options + port = lib.mkOption { + type = lib.types.int; + default = ; + description = "set port for ${service} (default: ${toString cfg.port}"; + }; + url = lib.mkOption { + type = lib.types.str; + default = "${service}.${homelab.base_domain}"; + description = "set domain for ${service}"; + }; + data_dir = lib.mkOption { + type = lib.types.str; + default = "/var/lib/${service}"; + description = "set data directory for ${service}"; + }; + ids = lib.mkOption { + type = lib.types.int; + default = cfg.port; + description = "set uid and pid of ${service} user (matches port by default)"; + }; + backup = lib.mkOption { + type = lib.types.bool; + default = true; + description = "enable backups for ${service}"; + }; + }; + + config = lib.mkIf cfg.enable { + + # declare ${service} group + users.groups.${service} = { gid = lib.mkForce cfg.ids; }; + + # declare ${service} user + users.users.${service} = { + description = "${service} server user"; + uid = lib.mkForce cfg.ids; + isSystemUser = true; + home = cfg.data_dir; + createHome = true; + group = "${service}"; + extraGroups = [ "media" ]; + }; + + # enable the ${service} service + services.${service} = { + enable = true; + openFirewall = true; + user = "${service}"; + group = "${service}"; + dataDir = cfg.data_dir; + settings = { + server.port = cfg.port; + }; + }; + + # override umask to make permissions work out + systemd.services.${service}.serviceConfig = { + UMask = lib.mkForce "0007"; +# User = "${service}"; +# Group = "${service}"; + }; + +# # open firewall +# networking.firewall.allowedTCPPorts = [ cfg.port ]; + + # internal reverse proxy entry + services.nginx.virtualHosts."${cfg.url}" = { + forceSSL = true; + sslCertificate = sec."ssl_blakedheld_crt".path; + sslCertificateKey = sec."ssl_blakedheld_key".path; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString cfg.port}"; + }; + }; +# # external reverse proxy entry +# services.nginx.virtualHosts."${service}.blakedheld.xyz" = { +# forceSSL = true; +# sslCertificate = sec."ssl_blakedheld_crt".path; +# sslCertificateKey = sec."ssl_blakedheld_key".path; +# locations."/" = { +# proxyPass = "http://127.0.0.1:${toString cfg.port}"; +# }; +# }; +# +# sops.secrets = { +# "${service}_" = { +# owner = "${service}"; +# group = "${service}"; +# }; +# }; + + # add to backups + modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ]; + }; +} diff --git a/modules/homelab/services/qbittorrent/default.nix b/modules/homelab/services/qbittorrent/default.nix new file mode 100644 index 0000000..9344c14 --- /dev/null +++ b/modules/homelab/services/qbittorrent/default.nix @@ -0,0 +1,124 @@ +{ pkgs, config, lib, ... }: + +let + service = "qbittorrent"; + cfg = config.modules.services.${service}; + sec = config.sops.secrets; + homelab = config.modules.homelab; +in +{ + options.modules.services.${service} = { + enable = lib.mkEnableOption "enables ${service}"; + + # set port options + port = lib.mkOption { + type = lib.types.int; + default = ; + description = "set port for ${service} (default: ${toString cfg.port}"; + }; +# torrenting_port = lib.mkOption { +# type = lib.types.int; +# default = ; +# description = "set port for ${service} (default: ${toString cfg.port}"; +# }; + url = lib.mkOption { + type = lib.types.str; + default = "qbit.${homelab.base_domain}"; + description = "set domain for ${service}"; + }; + data_dir = lib.mkOption { + type = lib.types.str; + default = "/var/lib/${service}"; + description = "set data directory for ${service}"; + }; + ids = lib.mkOption { + type = lib.types.int; + default = cfg.port; + description = "set uid and pid of ${service} user (matches port by default)"; + }; + vpn_inf = lib.mkOption { + type = lib.types.str; + default = "enp89s0.69"; + description = "set the interface qbittorrent will be bound to (used to route through vpn)"; + }; + backup = lib.mkOption { + type = lib.types.bool; + default = true; + description = "enable backups for ${service}"; + }; + }; + + config = lib.mkIf cfg.enable { + + # declare ${service} group + users.groups.${service} = { gid = lib.mkForce cfg.ids; }; + + # declare ${service} user + users.users.${service} = { + description = "${service} server user"; + uid = lib.mkForce cfg.ids; + isSystemUser = true; + home = cfg.data_dir; + createHome = true; + group = "${service}"; + extraGroups = [ "media" ]; + }; + + # enable the qbittorrent service + services.${service} = { + enable = true; + openFirewall = true; + user = "${service}"; + group = "${service}"; + profileDir = cfg.data_dir; + webuiPort = cfg.port; +# torrentingPort = cfg.torrenting_port; + }; + + # override umask to make permissions work out + systemd.services.${service} = { + serviceConfig = { + UMask = lib.mkForce "0007"; + }; + }; + + # bind to network interface but allow local access to webui + networking.firewall.extraCommands = '' + iptables -F QBIT + iptables -X QBIT + iptables -N QBIT + iptables -A OUTPUT -m owner --uid-owner ${toString cfg.ids} -j QBIT + iptables -A QBIT -o ${cfg.vpn_inf} -j ACCEPT + iptables -A QBIT -p udp --dport 53 -o ${cfg.vpn_inf} -j ACCEPT + iptables -A QBIT -p tcp --dport 53 -o ${cfg.vpn_inf} -j ACCEPT + iptables -A QBIT -p tcp -d 127.0.0.1 --dport ${toString cfg.port} -j ACCEPT + iptables -A QBIT -p tcp -o enp89s0 -d 10.0.0.0/8 --dport ${toString cfg.port} -j ACCEPT + iptables -A QBIT -j DROP + ''; + +# boilerplate for if you ever want to try to get this working again +# ------------------------------------------------------------------------------ +# # add systemd service to VPN network namespace +# vpnConfinement = { +# enable = true; +# vpnNamespace = "wgmex"; +# }; +# ------------------------------------------------------------------------------ + +# # open firewall +# networking.firewall.allowedTCPPorts = [ cfg.port ]; + + # internal reverse proxy entry + services.nginx.virtualHosts."${cfg.url}" = { + forceSSL = true; + sslCertificate = sec."ssl_blakedheld_crt".path; + sslCertificateKey = sec."ssl_blakedheld_key".path; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString cfg.port}"; + }; + }; + + # add to backups + modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ]; + }; +}