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