at 23.05-pre 2.5 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.libreddit; 7 8 args = concatStringsSep " " ([ 9 "--port ${toString cfg.port}" 10 "--address ${cfg.address}" 11 ]); 12in 13{ 14 options = { 15 services.libreddit = { 16 enable = mkEnableOption (lib.mdDoc "Private front-end for Reddit"); 17 18 address = mkOption { 19 default = "0.0.0.0"; 20 example = "127.0.0.1"; 21 type = types.str; 22 description = lib.mdDoc "The address to listen on"; 23 }; 24 25 port = mkOption { 26 default = 8080; 27 example = 8000; 28 type = types.port; 29 description = lib.mdDoc "The port to listen on"; 30 }; 31 32 openFirewall = mkOption { 33 type = types.bool; 34 default = false; 35 description = lib.mdDoc "Open ports in the firewall for the libreddit web interface"; 36 }; 37 38 }; 39 }; 40 41 config = mkIf cfg.enable { 42 systemd.services.libreddit = { 43 description = "Private front-end for Reddit"; 44 wantedBy = [ "multi-user.target" ]; 45 after = [ "network.target" ]; 46 serviceConfig = { 47 DynamicUser = true; 48 ExecStart = "${pkgs.libreddit}/bin/libreddit ${args}"; 49 AmbientCapabilities = lib.mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ]; 50 Restart = "on-failure"; 51 RestartSec = "2s"; 52 # Hardening 53 CapabilityBoundingSet = if (cfg.port < 1024) then [ "CAP_NET_BIND_SERVICE" ] else [ "" ]; 54 DeviceAllow = [ "" ]; 55 LockPersonality = true; 56 MemoryDenyWriteExecute = true; 57 PrivateDevices = true; 58 # A private user cannot have process capabilities on the host's user 59 # namespace and thus CAP_NET_BIND_SERVICE has no effect. 60 PrivateUsers = (cfg.port >= 1024); 61 ProcSubset = "pid"; 62 ProtectClock = true; 63 ProtectControlGroups = true; 64 ProtectHome = true; 65 ProtectHostname = true; 66 ProtectKernelLogs = true; 67 ProtectKernelModules = true; 68 ProtectKernelTunables = true; 69 ProtectProc = "invisible"; 70 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; 71 RestrictNamespaces = true; 72 RestrictRealtime = true; 73 RestrictSUIDSGID = true; 74 SystemCallArchitectures = "native"; 75 SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ]; 76 UMask = "0077"; 77 }; 78 }; 79 80 networking.firewall = mkIf cfg.openFirewall { 81 allowedTCPPorts = [ cfg.port ]; 82 }; 83 }; 84}