What changes when you turn a Linux box into a router (patrickmccanna.net)

by 0o_MrPatrick_o0 68 comments 229 points
Read article View on HN

68 comments

[−] ValdikSS 42d ago
The Linux box instantly turns into a router as soon as you run sysctl net.ipv4.ip_forward=1, because the default policy for FORWARD table is ACCEPT.

You need to explicitly reconfigure the iptables/nftables to prevent that from happening.

Some software, say LXD/Incus, enable forwarding automatically upon installation/startup, and do not configure firewall to block non-their traffic, making the machine an open router. I've reported that, the developers said that's by design (despite other virtualization/containerization systems block forwarding if they happen to enable the sysctl).

[−] 0o_MrPatrick_o0 42d ago
Respectfully- I don’t think this statement applies to the scenario I presented.

“The Linux box instantly turns into a router as soon as you run sysctl net.ipv4.ip_forward=1, because the default policy for FORWARD table is ACCEPT.”

In the setup I presented, we are bridging an Ethernet and a WiFi network. This would be desirable if you wanted to use an upstream dhcp server for your WiFi clients- or if you wanted to avoid double nat’ing.

In 802.11 infrastructure mode, a station can only send frames with its own MAC address. The AP won’t accept or forward frames from unknown MACs. So you can’t transparently bridge Ethernet devices’ MAC addresses through a WiFi client interface. This is why we need hostapd.

In every other circumstance- I think your statement holds.

I tried to do some weird alerting on new MAC addresses and ran into this weirdness. Bridging WiFi and Ethernet gets weird.

[−] iam-TJ 41d ago
"So you can’t transparently bridge Ethernet devices’ MAC addresses through a WiFi client interface. This is why we need hostapd."

I think that is incorrect. hostapd handles the authentication side of things, but 4addr tuples are controlled by 'struct wireless_dev.use_4addr', and can be set by 'ip link set type bridge_slave ... proxy_arp_wifi on', `iw dev ... 4addr on', and if using systemd-networkd, with slave interface's

  [Bridge]
  ProxyARPWiFi=yes
(and networkd doesn't need hostapd's bridge= option since networkd handles that aspect.)

Kernel then uses NL80211_IFTYPE_AP_VLAN and handles the proxy operation.

[−] 0o_MrPatrick_o0 41d ago
It may be possible that this has changed. Last year I built a device and crashed into the bridging weirdness when I wanted to use upstream dhcp. There was/is some funkiness lurking with bridging wifi to Ethernet- in particular with broadcasts that traverse the bridge.
[−] tssva 41d ago
Respectfully the scenario you want to present seems to change. The title you submitted this under doesn’t have any mention of switching, firewalls, dhcp server or WiFi access point.

Then the actual title of the article mentions routing and switching but not a firewall, dhcp server or WiFi access point. Then at the end you seem to change the goal to being a WiFi router but really you have presented more steps than required for that. You have also setup switching, a firewall and a dhcp server which are not required to be a router with WiFi access point.

[−] 0o_MrPatrick_o0 41d ago

>> spectfully the scenario you want to present seems to change.

Man that is totally a fair point.

I feel like I’ve struggled with the tutorials on these configs so many times in my life that I’ve kind of munged several ideas together here. There’s so much subtlety to the iptables/nftables rules that I failed to understand for so long, that I forgot that some folks might not understand that WiFi has specific weirdness. You’re right- I open with routing as a topic, but I’m in a very specific nuance right away.

[−] rahimnathwani 42d ago
When regular people say 'router', they assume this one box will be all three of these things:

- router

- NAT gateway

- DHCP server

In a typical scenario, turning IP forwarding on will do nothing unless:

- DHCP has given the devices on the 'inside' IP addresses and told them the gateway address, and

- the router is set up to do IP masquerading

[−] wafflemaker 42d ago
You forgot the -WIFI access point
[−] wofo 41d ago
Could you share more details about this? Do you mean that e.g., if I run LXD/Incus on a machine with a public IP address, anyone on the internet could route traffic through it?
[−] 3abiton 42d ago
A stupid question, what's the risk?
[−] gxs 42d ago
My very first exposure to Linux was in 2000, my school was about to throw away an old gateway computer and I took it home and turned it into router

As a kid with no AI, no google, it was quite a feat and I’m still very proud of it

Was my introduction into how the internet works and I’ll never forget working with ipchains

I remember enduring a lot of people in forums calling me a noob, but only after spending collective hours answering my dumb questions

I credit a big part of my moderate success in tech, to being familiar with stuff at just a tad bit lower of a level than the average bear

To my friend Sam who I haven’t talked to in 20 years, thanks for the idea

[−] Havoc 42d ago
Used to run a virtualized firewall setup. And then one day discovered that somewhere along the lines I had made a change (or an update changed something) that meant proxmox admin interface was being served publicly. That's despite confirming during initial setup that it isn't.

So now I do not do any funky stuff with firewalls anymore. Separate appliance with opnsense bare metal.

[−] chatmasta 42d ago
This is an excellent post and great reference material. I’ve done this a few times before and the information was scattered all over the place. I appreciate the clear and concise writing here. I even added it to my HN favorites - a rare accolade!

One thing I’d add, is that the best explanation I’ve ever seen for this, is the famous diagram [0] on Wikipedia of the netfilter API — I remember when I saw that, everything clicked into place. I’m not sure how up to date it is now, but it’s really good.

[0] https://commons.wikimedia.org/wiki/File:Netfilter-packet-flo...

[−] freetime2 42d ago
Are there any preconfigured images/installers available for a major Linux distro to turn them a router with safe and sensible defaults?

I know there is OpenWrt, but my experience is that is more geared toward running on embedded wifi hardware than an x86 machine. The x86 install comes with a tiny root partition that's actually pretty difficult to resize, for example, and upgrades are quite brittle compared to standard Linux distros.

And there's also pfSense and OPNsense, but these run on FreeBSD which seems to lag behind Linux for hardware support. There's no support for the Aquantia AQC113 NIC, for example (although it looks like this may finally have been added in the last month or so).

Something like an Ubuntu Appliance [1] would be quite nice.

[1] https://ubuntu.com/appliance

[−] sorz 42d ago
I feels wrong to not mention IPv6 in 2026.

- net.ipv6.conf.all.forwarding=1

- nftables is default to ip family which only applies to IPv4. Setting it to inet will allow rules to apply to both IPv4 & 6; or ip6 for IPv6 only. You can skip NAT rules, usually.

- dnsmasq: in addition to DNS and DHCP, turns on router advertisement with SLAAC. Some devices can get IPv6 address from stateful DHCPv6 server, others (e.g. Android) only work with SLAAC.

[−] binkHN 41d ago
While I run Linux on my production workstation, I use OpenBSD as my router and firewall at home. I find the configuration of OpenBSD for this a lot more simple and everything that's needed, even for IPv6, is in the base install.
[−] rkagerer 41d ago
This is a great article.

It explains steps I used to fumble through stabbing in the dark following piecemeal examples trying to bring up quick and dirty networking on an oddball Linux device (like a BPI-R4 or router VM).

[−] evanjrowley 41d ago

  Set Linux as router in one command. Support Internet sharing, redsocks, Wifi hotspot, IPv6. Can also be used for routing VM/containers
https://github.com/garywill/linux-router
[−] jcalvinowens 41d ago
People saying "the FOWARD chain defaults to ACCEPT" are missing the deeper point: with the kconfig most distros use, the filtering code doesn't even exist at all until you load the kernel modules!

At the lowest level, it is impossible to have a default DROP for forwarding, because nftables is an optional piece of the kernel that often isn't loaded.

[−] dfir-lab 41d ago
[flagged]
[−] ValveFan6969 42d ago
[dead]
[−] eqvinox 42d ago
[flagged]