1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 name = "roon-server";
7 cfg = config.services.roon-server;
8in {
9 options = {
10 services.roon-server = {
11 enable = mkEnableOption "Roon Server";
12 package = lib.mkPackageOption pkgs "roon-server" { };
13 openFirewall = mkOption {
14 type = types.bool;
15 default = false;
16 description = ''
17 Open ports in the firewall for the server.
18 '';
19 };
20 user = mkOption {
21 type = types.str;
22 default = "roon-server";
23 description = ''
24 User to run the Roon Server as.
25 '';
26 };
27 group = mkOption {
28 type = types.str;
29 default = "roon-server";
30 description = ''
31 Group to run the Roon Server as.
32 '';
33 };
34 };
35 };
36
37 config = mkIf cfg.enable {
38 systemd.services.roon-server = {
39 after = [ "network.target" ];
40 description = "Roon Server";
41 wantedBy = [ "multi-user.target" ];
42
43 environment.ROON_DATAROOT = "/var/lib/${name}";
44 environment.ROON_ID_DIR = "/var/lib/${name}";
45
46 serviceConfig = {
47 ExecStart = "${lib.getExe cfg.package}";
48 LimitNOFILE = 8192;
49 User = cfg.user;
50 Group = cfg.group;
51 StateDirectory = name;
52 };
53 };
54
55 networking.firewall = mkIf cfg.openFirewall {
56 allowedTCPPortRanges = [
57 { from = 9100; to = 9200; }
58 { from = 9330; to = 9339; }
59 { from = 30000; to = 30010; }
60 ];
61 allowedUDPPorts = [ 9003 ];
62 extraCommands = optionalString (!config.networking.nftables.enable) ''
63 ## IGMP / Broadcast ##
64 iptables -A INPUT -s 224.0.0.0/4 -j ACCEPT
65 iptables -A INPUT -d 224.0.0.0/4 -j ACCEPT
66 iptables -A INPUT -s 240.0.0.0/5 -j ACCEPT
67 iptables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT
68 iptables -A INPUT -m pkttype --pkt-type broadcast -j ACCEPT
69 '';
70 extraInputRules = optionalString config.networking.nftables.enable ''
71 ip saddr { 224.0.0.0/4, 240.0.0.0/5 } accept
72 ip daddr 224.0.0.0/4 accept
73 pkttype { multicast, broadcast } accept
74 '';
75 };
76
77
78 users.groups.${cfg.group} = {};
79 users.users.${cfg.user} =
80 optionalAttrs (cfg.user == "roon-server") {
81 isSystemUser = true;
82 description = "Roon Server user";
83 group = cfg.group;
84 extraGroups = [ "audio" ];
85 };
86 };
87}