IfState: Difference between revisions

Felbinger (talk | contribs)
ifstate/known-issues: add firewall
m dhcpv4: replace custom script with packaged udhcpc/default.script
 
(8 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[https://ifstate.net/2.0/ IfState] is a python 3 utility designed for declarative management of Linux network interfaces. It acts as a frontend to the kernel's Netlink interface, using the <code>pyroute2</code> library to configure network settings such as IP addresses, bridges, traffic control, and WireGuard in an idempotent manner—much like an <code>iproute2</code>/<code>ethtool</code>/<code>tc</code>/<code>wg</code> wrapper.
[https://ifstate.net/2.0/ IfState] is a python 3 utility designed for declarative management of Linux network interfaces. It acts as a frontend to the kernel's Netlink interface, using the <code>pyroute2</code> library to configure network settings such as IP addresses, bridges, traffic control, and WireGuard in an idempotent manner—much like an <code>iproute2</code>/<code>ethtool</code>/<code>tc</code>/<code>wg</code> wrapper.


It will be probably be available with NixOS 25.11 (see https://github.com/NixOS/nixpkgs/pull/431047).
It is available since NixOS 25.11 (see https://github.com/NixOS/nixpkgs/pull/431047).


=== Examples ===
=== Examples ===
You can find several examples on the [https://ifstate.net/2.0/examples/ IfState website]. Due to the fact that these are yaml examples, I decided to provide some nix examples here too:<syntaxhighlight lang="nixos">{
You can find several examples on the [https://ifstate.net/2.0/examples/ IfState website]. Some include NixOS configuration instructions, while the more complex examples are covered in detail here.
  networking.ifstate = {
    enable = true;
    settings = {
      interfaces.enp3s0 = {
        addresses = [
          "192.0.2.10/24"
          "2001:db8:dead:c0de::10/64"
        ];
        link = {
          state = "up";
          kind = "physical";
        };
        identify.perm_address = "00:00:5e:00:53:00";
      };
      routing.routes = [
        {
          to = "0.0.0.0/0";
          via = "192.0.2.1";
        }
        {
          to = "::/0";
          via = "fe80::1";
        }
      ];
    };
  };
}</syntaxhighlight>


==== Network Namespaces (netns) ====
==== Network Namespaces (netns) ====
Line 92: Line 65:


To achieve this, you might want to isolate the provider network from your Global Routing Table (GRT) and bind the WireGuard endpoints. The <code>IfState</code> tool offers a link configuration option called <code>bind_netns</code>, which can be used with tunnel links (such as WireGuard, GRE, SIT, etc.) to implement this separation.
To achieve this, you might want to isolate the provider network from your Global Routing Table (GRT) and bind the WireGuard endpoints. The <code>IfState</code> tool offers a link configuration option called <code>bind_netns</code>, which can be used with tunnel links (such as WireGuard, GRE, SIT, etc.) to implement this separation.
[[File:Ifstate-vpn-gw.png|center|frameless]]


'''Important Note:''' If <code>enp0s3</code> is your provider interface, this configuration will move it into an external network namespace that contains nothing except the bound WireGuard endpoint. As a result, you won’t be able to access systemd services like your SSH server without an active WireGuard connection. Plan accordingly to avoid losing access to critical services.<syntaxhighlight lang="nixos">
'''Important Note:''' If <code>enp0s3</code> is your provider interface, this configuration will move it into an external network namespace that contains nothing except the bound WireGuard endpoint. As a result, you won’t be able to access systemd services like your SSH server without an active WireGuard connection. Plan accordingly to avoid losing access to critical services.<syntaxhighlight lang="nixos">
Line 118: Line 92:
           {
           {
             to = "::/0";
             to = "::/0";
            dev = "enp3s0";
             via = "fe80::1";
             via = "fe80::1";
           }
           }
Line 174: Line 149:
       };
       };
     };
     };
    routing.routes = [
      {
        to = "0.0.0.0/0";
        via = "203.0.113.1";
      }
      {
        to = "::/0";
        via = "2001:db8:bad:c0de::1";
      }
    ];
   };
   };
}
}


</syntaxhighlight>
==== DHCPv4 ====
<syntaxhighlight lang="nixos">
{ lib, pkgs, ... }:
{
  networking.ifstate = {
    enable = true;
    settings = {
      parameters.hooks.dhcp.script = pkgs.writeScript "ifstate-udhcp-wrapper-script.sh" ''
        ${lib.getExe' pkgs.busybox "udhcpc"} --quit --now -i $IFS_IFNAME -b --script ${pkgs.busybox}/default.script
      '';
      interfaces.eth1 = {
        addresses = [ ];
        hooks = [
          { name = "dhcp"; }
        ];
        link = {
          state = "up";
          kind = "physical";
        };
      };
    };
  };
}
</syntaxhighlight>
</syntaxhighlight>


Line 242: Line 252:
}
}
</syntaxhighlight>
</syntaxhighlight>
[[Category:Networking]]
[[Category:Python]]