1 { pkgs, lib, config, machines, ... }:
4 inherit (config) networking;
5 inherit (config.security) gnupg;
6 inherit (config.users) users groups;
7 inherit (config.networking) domain;
8 inherit (config.services) upnpc;
11 options.services.upnpc = {
12 redirections = lib.mkOption {
14 type = types.listOf (types.submodule ({config, ...}: {
19 externalPort = lib.mkOption {
21 default = config.port;
23 protocol = lib.mkOption {
24 type = with types; enum ["TCP" "UDP"];
27 duration = lib.mkOption {
36 systemd.services.upnpc = {
37 after = [ "network-online.target" ];
38 wantedBy = [ "multi-user.target" ];
42 ExecStart = "${pkgs.miniupnpc}/bin/upnpc -r" + lib.concatMapStrings
43 (r: " ${toString r.port} ${toString r.externalPort} ${r.protocol}")
45 Restart = "on-failure";
48 User = users."upnpc".name;
51 users.users."upnpc".isSystemUser = true;
52 networking.nftables.ruleset = ''
53 #add set filter ssdp_out {type inet_service \; timeout 5s \;}
54 # Create a rule for accepting any SSDP packets going to a remembered port.
55 add rule inet filter net2fw udp dport @ssdp_out \
56 counter accept comment "SSDP answer"
57 add rule inet filter fw2net \
58 skuid ${users.upnpc.name} \
59 ip daddr 239.255.255.250 udp dport 1900 \
60 set add udp sport @ssdp_out \
61 comment "SSDP automatic opening"
62 add rule inet filter fw2net \
63 skuid ${users.upnpc.name} \
64 ip daddr 239.255.255.250 udp dport 1900 \
65 counter accept comment "SSDP"
66 '' + lib.optionalString networking.enableIPv6 ''
67 add rule inet filter fw2net \
68 skuid ${users.upnpc.name} \
69 ip6 daddr {FF02::C, FF05::C, FF08::C, FF0E::C} udp dport 1900 \
70 set add udp sport @ssdp_out comment "SSDP automatic opening"
71 add rule inet filter fw2net \
72 skuid ${users.upnpc.name} \
73 ip6 daddr {FF02::C, FF05::C, FF08::C, FF0E::C} udp dport 1900 \
74 counter accept comment "SSDP"