How to configure WiFi (or zone) dependent firewall rules?

I am moving from Fedora on my workstation. But I do not know how to configure firewall rules per WiFi hotspot.

For example, in firewalld I can open ports on my home WiFi zone but on public WiFi it will use public zone which restricts SSH, Samba etc.

I currently have following settings in NixOS

  networking.nftables.enable = true;
  networking.firewall = {
    enable = true;
    interfaces."enp1s0" = {
      allowedTCPPorts = [
        22000
      ];
      allowedUDPPorts = [
        22000
        21027
      ];
    };
  };

But it is applied to the interface rather than a zone. So even if I connect to a public WiFi, it will allow these ports. How do I restrict this?

Any help would be appreciated.

While not quite what you’re asking, you can achieve the same thing using specialisation.

example configuration.

# configuration.nix
{ ... }: {
    imports = [
        # given below
        ./privatezone.nix
    ];

    specialisation.publiczone = {
        inheritParentConfig = true;
        configuration = { ... }: {
            # ...
            # firewall rules for publiczone
            # ...
            # you can include anything (except specialisation) that you'd put in configuration.nix
            # even imports
            # imports = [ ./publiczoneFirewall.nix ];
        };
    };
}
# privatezone.nix
({ config, lib, ... }: {
    config = lib.mkIf (config.specialisation != {}) {
        # ...
        # firewall rules for privatezone
        # ...
        # you cannot use imports here, but other options should be fine
    };
})

To use specialisation publiczone,
run nixos-rebuild switch --specialisation publiczone or /run/current-system/specialisation/publiczone/bin/switch-to-configuration switch

AFAIK you can’t switch to non-specialisation without rebooting/rebuilding though.

1 Like

Firewalld is packaged although there doesn’t seem to be a service module for it. I miss that feature too.

I just found this module. nixos-nftables-firewall — nixos-nftables-firewall documentation

It mentions zones… I’m not sure if Networkmanager can tie into it though since AFAIK networkmanager uses dbus with firewalld.

Thanks for the solutions. @eity Specialization is something I didn’t know about. But looks like it still requires me to manually switch to a different configuration when I’m on public WiFi. Please correct me if I’m wrong.

@p4p4j0hn nixos-nftables-firewall seems to be a good option to achieve what I want. Let me dig into that.

@bitestring networking.networkmanager.dispatcherScripts might be another option. According to NetworkManager-dispatcher: NetworkManager Reference Manual you can run some scripts. Variables like CONNECTION_ID are available so we could probably run some nft or iptables commands to open and close ports based on which networks we are connected to.

Thank you for highlighting specialisations. I’d not come across them before but they were exactly what I needed. I have now set up zones and can easily switch between them.

It’s worth noting that you can switch back to non-specialisation with /nix/var/nix/profiles/system/bin/switch-to-configuration switch and between specialisations with /nix/var/nix/profiles/system/specialisation/publiczone/bin/switch-to-configuration switch. These have the advantage of continuing to work after you’ve switched to a specialisation.