NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
16.42k stars 12.92k forks source link

firewall: support SSDP #161328

Open wmertens opened 2 years ago

wmertens commented 2 years ago

I want to control my Sonos system and it's hard to configure the firewall to allow this. I propose that we add a setting like allowSsdp to the firewall.

I currently have these rules to make it work:

{
  networking.firewall.allowedTCPPorts = [
    # Sonos
    1400
  ];

  # support SSDP https://serverfault.com/a/911286/9166
  networking.firewall.extraPackages = [ pkgs.ipset ];
  networking.firewall.extraCommands = ''
    if ! ipset --quiet list upnp; then
      ipset create upnp hash:ip,port timeout 3
    fi
    iptables -A OUTPUT -d 239.255.255.250/32 -p udp -m udp --dport 1900 -j SET --add-set upnp src,src --exist
    iptables -A nixos-fw -p udp -m set --match-set upnp dst,dst -j nixos-fw-accept
  '';
}

This creates a 3-second memory for multicast SSDP UDP traffic that was initiated from the system, to allow UDP answers back in.

There's no nixos-fw-output chain, how about adding that? Right now the OUTPUT rule gets inserted on every firewall start, because I'm not sure how to replace exactly that rule.

Is this something that could go in the firewall module, or is that too specific?

nixos-discourse commented 2 years ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/ssdp-firewall-support/17809/3

Alexnortung commented 1 year ago

While doing this, I would appreciate if we could also add an option to allow multicast. Multicast is used to discover devices such as chromecasts on your network.

I have tried and somewhat succeded, but after a couple of rebuilds it seems broken :/.'

This is what I tried

{
  networking.firewall.extraCommands = ''
    iptables -I INPUT -m pkttype --pkt-type multicast -j ACCEPT
    iptables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT
    iptables -I INPUT -p udp -m udp --match multiport --dports 1900,5353 -j ACCEPT
  '';
  networking.firewall.allowedTCPPorts = [
    8008 8009 8010
  ];
  networking.firewall.allowedUDPPorts = [
    1900 # should be outbound
    5353
  ];
    #iptables -I INPUT -m pkttype --pkt-type multicast -j ACCEPT
}