{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreiegcrvxtwsrcx4e56e3djkewy2mub35y6mjje4itrw5yyyll7tp44",
"uri": "at://did:plc:46ti67tc37qcmwp2vaynk6fq/app.bsky.feed.post/3mexlx4xd4mv2"
},
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreif76otfy5zorpvfp5liaumf2yccxbo2d5mfb45mhjotzhkinlueq4"
},
"mimeType": "image/png",
"size": 22729
},
"path": "/blog/2026-02-15-kernel-only-network-configuration/",
"publishedAt": "2026-02-16T08:09:42.849Z",
"site": "https://anarc.at",
"tags": [
"Debian wiki claims",
"at least 2000",
"in the Debian wiki",
"NetworkManager",
"Debian reference Doc Chapter 5",
"Netplan",
"Debian reference Doc Chapter 5",
"the Debian wiki",
"Linux kernel command line",
"2002 commit",
"nfsroot.txt",
"Red Hat manual",
"2025-08-20-luks-ukify-conversion",
"Arch",
"Fedora",
"RHEL mentions grubby",
"Gentoo",
"dropbear-initramfs",
"this documentation",
"at scale",
"A/I",
"AI"
],
"textContent": "What if I told you there is a way to configure the network on any Linux server that:\n\n 1. works across all distributions\n 2. doesn't require any software installed apart from the kernel and a boot loader (no `systemd-networkd`, `ifupdown`, `NetworkManager`, nothing)\n 3. is backwards compatible all the way back to Linux 2.0, in 1996\n\n\n\nIt has literally 8 different caveats on top of that, but is still totally worth your time.\n\n# Known options in Debian\n\nPeople following Debian development might have noticed there are now _four_ ways of configuring the network Debian system. At least that is what the Debian wiki claims, namely:\n\n * `ifupdown` (`/etc/network/interfaces`): traditional static configuration system, mostly for workstations and servers that has been there forever in Debian (since at least 2000), documented in the Debian wiki\n\n * NetworkManager: self-proclaimed \"standard Linux network configuration\", mostly used on desktops but technically supports servers as well, see the Debian wiki page (introduced in 2004)\n\n * `systemd-network`: used more for servers, see Debian reference Doc Chapter 5 (introduced some time around Debian 8 \"jessie\", in 2015)\n\n * Netplan: latest entry (2018), YAML-based configuration abstraction layer on top of the above two, see also Debian reference Doc Chapter 5 and the Debian wiki\n\n\n\n\nAt this point, I feel `ifupdown` is on its way out, possibly replaced by `systemd-networkd`. NetworkManager already manages most desktop configurations.\n\n# A \"new\" network configuration system\n\nThe method is this:\n\n * `ip=` on the Linux kernel command line: for servers with a single IPv4 or IPv6 address, no software required other than the kernel and a boot loader (since 2002 or older)\n\n\n\n> So by \"new\" I mean \"new to me\". This option is _really_ old. The `nfsroot.txt` where it is documented predates the git import of the Linux kernel: it's part of the 2005 git import of 2.6.12-rc2. That's already 20+ years old already.\n>\n> The oldest trace I found is in this 2002 commit, which imports the whole file at once, but the option might goes back as far as 1996-1997, if the copyright on the file is correct and the option was present back then.\n\n# What are you doing.\n\nThe trick is to add an `ip=` parameter to the kernel's command-line. The syntax, as mentioned above, is in nfsroot.txt and looks like this:\n\n\n ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>:<ntp0-ip>\n\n\nMost settings are pretty self-explanatory, if you ignore the useless ones:\n\n * `<client-ip>`: IP address of the server\n * `<gw-ip>`: address of the gateway\n * `<netmask>`: netmask, in quad notation\n * `<device>`: interface name, if multiple available\n * `<autoconf>`: how to configure the interface, namely:\n * `off` or `none`: no autoconfiguration (static)\n * `on` or `any`: use any protocol (default)\n * `dhcp`, essentially like `on` for all intents and purposes\n\n\n\nNote that the Red Hat manual has a different opinion:\n\n\n ip=[<server-id>]:<gateway-IP-number>:<netmask>:<client-hostname>:inteface:[dhcp|dhcp6|auto6|on|any|none|off]\n\n\nIt's essentially the same (although `server-id` is weird), and the `autoconf` variable has other settings, so that's a bit odd.\n\n# Examples\n\nFor example, this command-line setting:\n\n\n ip=192.0.2.42::192.0.2.1:255.255.255.0:::off\n\n\n... will set the IP address to 192.0.2.42/24 and the gateway to 192.0.2.1. This will properly guess the network interface if there's a single one.\n\nA DHCP only configuration will look like this:\n\n\n ip=::::::dhcp\n\n\nOf course, you don't want to type this by hand every time you boot the machine. That wouldn't work. You need to configure the kernel commandline, and that depends on your boot loader.\n\n## GRUB\n\nWith GRUB, you need to edit (on Debian), the file `/etc/default/grub` (ugh) and find a line like:\n\n\n GRUB_CMDLINE_LINUX=\n\n\nand change it to:\n\n\n GRUB_CMDLINE_LINUX=ip=::::::dhcp\n\n\n## systemd-boot and UKI setups\n\nFor `systemd-boot` UKI setups, it's simpler: just add the setting to the `/etc/kernel/cmdline` file. Don't forget to include anything that's non-default from `/proc/cmdline`.\n\nThis assumes that is the `Cmdline=@` setting in `/etc/kernel/uki.conf`. See 2025-08-20-luks-ukify-conversion for my minimal documentation on this.\n\n## Other systems\n\nThis is perhaps where this is much less portable than it might first look, because of course each distribution has its own way of configuring those options. Here are some that I know of:\n\n * Arch (11 options, mostly `/etc/default/grub`, `/boot/loader/entries/arch.conf` for `systemd-boot` or `/etc/kernel/cmdline` for UKI)\n * Fedora (mostly `/etc/default/grub`, may be more RHEL mentions grubby, possibly some `systemd-boot` things here as well)\n * Gentoo (5 options, mostly `/etc/default/grub`, `/efi/loader/entries/gentoo-sources-kernel.conf` for `systemd-boot`, or `/etc/kernel/install.d/95-uki-with-custom-opts.install`)\n\n\n\nIt's interesting that `/etc/default/grub` is consistent across all distributions above, while the `systemd-boot` setups are _all over the place_ (except for the UKI case), while I would have expected those be _more_ standard than GRUB.\n\n## dropbear-initramfs\n\nIf `dropbear-initramfs` is setup, it already _requires_ you to have such a configuration, and it might not work out of the box.\n\nThis is because, by default, it _disables_ the interfaces configured in the kernel after completing its tasks (typically unlocking the encrypted disks).\n\nTo fix this, you need to _disable_ that \"feature\":\n\n\n IFDOWN=\"none\"\n\n\nThis will keep `dropbear-initramfs` from disabling the configured interface.\n\n# Why?\n\nTraditionally, I've always setup my servers with `ifupdown` on servers and NetworkManager on laptops, because that's essentially the default. But on some machines, I've started using `systemd-networkd` because `ifupdown` has ... issues, particularly with reloading network configurations. `ifupdown` is a old hack, feels like legacy, and is Debian-specific.\n\nNot excited about configuring another service, I figured I would try something else: just configure the network at boot, through the kernel command-line.\n\nI was already doing such configurations for dropbear-initramfs (see this documentation), which requires the network the be up for unlocking the full-disk encryption keys.\n\nSo in a sense, this is a \"Don't Repeat Yourself\" solution.\n\n# Caveats\n\nAlso known as: \"wait, that works?\" Yes, it does! That said...\n\n 1. This is useful for servers where the network configuration will not change after boot. Of course, this won't work on laptops or any mobile device.\n\n 2. This only works for single interface configurations. If you have multiple interfaces, bridges, VLANs, wifi, none of this will work.\n\n 3. It does support IPv6 and feels like the best way to configure IPv6 hosts: true zero configuration.\n\n 4. It likely does _not_ work with a _dual-stack_ IPv4/IPv6 static configuration. It _might_ work with a _dynamic_ dual stack configuration, but I doubt it.\n\n 5. I don't know what happens when a DHCP lease expires. No daemon seems to be running so I assume leases are not renewed, so this is more useful for static configurations, which includes server-side reserved fixed IP addresses. (A non-renewed lease risks getting reallocated to another machine, which would cause an addressing conflict.)\n\n 6. It will not automatically reconfigure the interface on link changes, but `ifupdown` does not either.\n\n 7. It will _not_ write a good `resolv.conf` for you, that you need to configure separately. _Maybe_ passing those `dns0-ip` settings will work? Untested, but DNS is, after all, a mostly user-level implementation (typically in `libc`), the kernel doesn't (again, typically) care about DNS.\n\n 8. I have not really tested this at scale: only a single, test server at home.\n\n\n\n\nYes, that's a lot of caveats, but it happens to cover a _lot_ of machines for me, and it works surprisingly well. My main doubts are about long-term DHCP behaviour, but I don't see why that would be a problem with a statically defined lease.\n\n# Cleanup\n\nOnce you have this configuration, you don't need _any_ \"user\" level network system, so you can get rid of _everything_ :\n\n\n apt purge systemd-networkd ifupdown network-manager netplan.io\n\n\nNote that `ifupdown` (and probably others) leave stray files in (e.g.) `/etc/network` which you might want to cleanup, or keep in case all this fails and I have put you in utter misery. Configuration files for other packages might also be left behind, I haven't tested this, no warranty.\n\n# Credits\n\nThis whole idea came from the A/I folks (not to be confused with AI) who have been doing this forever, thanks!",
"title": "Antoine Beaupré: Kernel-only network configuration on Linux",
"updatedAt": "2026-02-16T04:18:28.000Z"
}