at 22.05-pre 3.1 kB view raw
1{ config, pkgs, lib, ... }: 2 3with lib; 4 5let 6 cfg = config.services.jellyfin; 7in 8{ 9 options = { 10 services.jellyfin = { 11 enable = mkEnableOption "Jellyfin Media Server"; 12 13 user = mkOption { 14 type = types.str; 15 default = "jellyfin"; 16 description = "User account under which Jellyfin runs."; 17 }; 18 19 package = mkOption { 20 type = types.package; 21 default = pkgs.jellyfin; 22 defaultText = literalExpression "pkgs.jellyfin"; 23 description = '' 24 Jellyfin package to use. 25 ''; 26 }; 27 28 group = mkOption { 29 type = types.str; 30 default = "jellyfin"; 31 description = "Group under which jellyfin runs."; 32 }; 33 34 openFirewall = mkOption { 35 type = types.bool; 36 default = false; 37 description = '' 38 Open the default ports in the firewall for the media server. The 39 HTTP/HTTPS ports can be changed in the Web UI, so this option should 40 only be used if they are unchanged. 41 ''; 42 }; 43 }; 44 }; 45 46 config = mkIf cfg.enable { 47 systemd.services.jellyfin = { 48 description = "Jellyfin Media Server"; 49 after = [ "network.target" ]; 50 wantedBy = [ "multi-user.target" ]; 51 52 serviceConfig = rec { 53 User = cfg.user; 54 Group = cfg.group; 55 StateDirectory = "jellyfin"; 56 CacheDirectory = "jellyfin"; 57 ExecStart = "${cfg.package}/bin/jellyfin --datadir '/var/lib/${StateDirectory}' --cachedir '/var/cache/${CacheDirectory}'"; 58 Restart = "on-failure"; 59 60 # Security options: 61 62 NoNewPrivileges = true; 63 64 AmbientCapabilities = ""; 65 CapabilityBoundingSet = ""; 66 67 # ProtectClock= adds DeviceAllow=char-rtc r 68 DeviceAllow = ""; 69 70 LockPersonality = true; 71 72 PrivateTmp = true; 73 PrivateDevices = true; 74 PrivateUsers = true; 75 76 ProtectClock = true; 77 ProtectControlGroups = true; 78 ProtectHostname = true; 79 ProtectKernelLogs = true; 80 ProtectKernelModules = true; 81 ProtectKernelTunables = true; 82 83 RemoveIPC = true; 84 85 RestrictNamespaces = true; 86 # AF_NETLINK needed because Jellyfin monitors the network connection 87 RestrictAddressFamilies = [ "AF_NETLINK" "AF_INET" "AF_INET6" ]; 88 RestrictRealtime = true; 89 RestrictSUIDSGID = true; 90 91 SystemCallArchitectures = "native"; 92 SystemCallErrorNumber = "EPERM"; 93 SystemCallFilter = [ 94 "@system-service" 95 "~@cpu-emulation" "~@debug" "~@keyring" "~@memlock" "~@obsolete" "~@privileged" "~@setuid" 96 ]; 97 }; 98 }; 99 100 users.users = mkIf (cfg.user == "jellyfin") { 101 jellyfin = { 102 group = cfg.group; 103 isSystemUser = true; 104 }; 105 }; 106 107 users.groups = mkIf (cfg.group == "jellyfin") { 108 jellyfin = {}; 109 }; 110 111 networking.firewall = mkIf cfg.openFirewall { 112 # from https://jellyfin.org/docs/general/networking/index.html 113 allowedTCPPorts = [ 8096 8920 ]; 114 allowedUDPPorts = [ 1900 7359 ]; 115 }; 116 117 }; 118 119 meta.maintainers = with lib.maintainers; [ minijackson ]; 120}