+++ rss = "How to set up an Ubuntu system as a router" date = Date(2024, 8, 3) tags = ["fun", "recipe", "net"] +++ # GNU as a Router, the Canonical Way A while ago I noticed that my ISP leases IPv4 addresses out indefinitely. It was everything I'd ever wanted and I gotta seize it to truly _self_-host. As an experiment, I started on something cheaper, like a single-board compooter. In 2024, support for general-purpose RISC-V chips began to ripen, so naturally due to FOMO, I bought a board with JH-7110. Boy, was that a mistake! While the bootloaders' support had been well [upstreamed], certain essential features like PCIe (for NVMe) has yet to reached a mainline Linux release, even worse so on the BSDs. I ended up flashing the _only_ distribution with official support [at the time][goatse], Ubuntu. Funny enough, after over a decade of daily driving GNU, twas the first time I installed Ubuntu on a machine of my own. At the time of writing, the reason for the was more apparent than ever: Canonical had been forcing Snap[^snap] down the users' throat, even on the _server_ edition. Thankfully Snap was still managed by APT and twas easy enough to remove prevent it from coming back. Another annoyance was the lack of manual pages in the minimized installation _and_ that the official way to enable them is through a script that also install other bloats SMFH (the script is quite short and the actually necessary commands can be trivially found, I'd rather they're documented instead). That being said, not everything Ubuntu includes due to NIH is bad. Unity (not the game engine that's proprietary like Snap server) was loved by many; and this article is basically an appreciation post for some others: [Netplan] and [ufw]. Before diving in, lemme finish the story to give you the full context of this setup. The SBC is the VisionFive 2 which is blessed with plenty of IO: * 8 GB of memory * 4 USB 3.0 type-A ports * 2 RJ45 ports (1 Gb and 100/10 Mb) * 1 M.2 slot (I used this as an excuse to buy a larger SSD and put the old 256 GB one here) * 1 eMMC slot[^mmc] (eMMC are cheap, got one also with 256 GB) * 1 TF slot * 40 pin GP(and predefined-purpose)IO * Other stuff for interfacing with humen like HDMI, audio jack, etc. Initially, my plan for the SBC was to host services unlisted on the [loang network]. Official services were not considered because my home network has no IPv6 and sometimes I'll like to have most of the bandwidth for meself. Shortly afterwards, I also purchased a somewhat beefy desktop compooter with even more I/O, especially a bunch of SATA, which are a lot more attractive than connecting hard di\*ks via USB. On the other hand, the SBC barely consume any electricity, well under 10 W with the NVMe drive, a Wi-Fi dongle and a fan connected. Since it cost virtually nothing to keep it up 24/7, I decided to hand it the following two tasks: * Reverse proxying services running on more powerful machines in the local network. * Acting as a virtual router between nodes I manage. This is particularly useful for tunneling to my work network and accessing the servers, allowing me to work remotely with low latency. Setting up the VPN with Wireguard was relatively easy, so I assumed swapping the SBC for the home router couldn't be too hard. Once again, I [chose poorly], this little project'd costed me so many sleepless nights so I figured I should note down what I learned here in case it can save someone else from the same pain. **Do not take inspiration from this!** \toc ## Connecting to the Internet My landlord handles the contract with the ISP so I don't know the details of the subscription, but there's certainly no IPv6 nor any static IPv4 address. Bandwidth to datacenters in the region is approximately 100 Mb/s and the wall socket connects to a Cat 5e cable. I know about the latter because whatever dumb ass did the last maintenance wired that to another short one dangling from the wall socket[^futa], and after getting stabbed in the eyes for months I finally to open it up and made the socket a proper socket. It would not make the slightest of a difference but I connect the SBC's 1 Gb port (identified in Ubuntu as end0) to the Internet and the slower one (end1) to my desktop on the local network. Thankfully no [special setup][router freedom] was needed and here is the entire Netplan configuration to connect to the outside world: ```yaml network: ethernets: end0: dhcp4: true renderer: networkd version: 2 ``` ## Local Networking For simplicity's sake, I decided to use the same subnet for both Ethernet and Wi-Fi under a bridge br0, where addressing and routing is configured: ```yaml network: bridges: br0: addresses: - 192.168.147.254/25 interfaces: - end1 routes: - from: 192.168.147.128/25 on-link: true to: 0.0.0.0/0 type: nat via: 192.168.147.254 ethernets: end1: dhcp4: false ``` As Netplan doesn't configure any DHCP server, that's done separately by udhcpd from busybox: ```plaintext interface br0 start 192.168.147.128 end 192.168.147.253 max_leases 126 option subnet 255.255.255.128 option router 192.168.147.254 ``` I couldn't seem to get a concrete information on the ports used by DHCP so I open the firewall for UDP on both 67 and 68 (I swear this isn't an engagement bait to test out the new mailing list): ```plaintext ufw allow in on br0 to any port 67 proto udp ufw allow in on br0 to any port 68 proto udp ``` ## Wireless Access Point Thanks to systemd, the Wi-Fi dongle is recognized as wlx600dd0g8b33f. Yes, that abomination of a name includes the chip's full MAC address. That being said, I'd like to stick to the basis of a systemd/Linux distro. Even though Netplan doesn't support Wi-Fi hotspot with systemd-networkd but NetworkManager, so the interface had thus to be declared as Ethernet: ```yaml network: bridges: br0: interfaces: - wlx600dd0g8b33f ethernets: wlx600dd0g8b33f: dhcp4: false ``` Actual wireless connectivity is handled by hostapd: ```ini interface=wlx600dd0g8b33f bridge=br0 ssid=YΦ utf8_ssid=1 country_code=KR channel=6 ieee80211d=1 ieee80211h=1 ieee80211n=1 hw_mode=g wmm_enabled=1 wpa=2 wpa_pairwise=TKIP wpa_passphrase=just enter random characters ``` ## Name Resolution My ISP is [known to be evil][KT malware] so I'd rather rely on more reputable resolvers like [OpenNIC] (plus free-of-charge domain names!). Most of their [tier 2] are located on the other side of the globe (200 to 300 ms RTT), so a local cache is almost required. SmartDNS seems to be the best fit for this purpose, as it queries upstream servers simultaneously and also check for the IP with the lowest RTT among the results. Since I don't trust my ISP, connections to the upstream servers are encrypted: ```plaintext bind :53@br0 server-tls 51.254.162.59 -host-name ns1-dot.iriseden.fr server-tls 202.61.197.122 -host-name dns.furrydns.de server-tls 80.152.203.134 -host-name dot.kekew.info server-tls 178.201.248.159 -host-name dot.kekew.info server-tls 178.201.248.160 -host-name dot.kekew.info server-tls 95.216.99.249 -host-name dns.froth.zone ``` For the router itself, the nameserver is set in /etc/resolv.conf and Netplan is told not to change it: ```yaml network: ethernets: end0: dhcp4-use-dns: false ``` After ufw is configured to allow UDP traffic in port 53 on br0, udhcpd is instructed to advertise this local DNS server: ```plaintext option dns 192.168.147.254 ``` I might consider blocking ads at the domain-name level someday, but for now uBlock Origin is working well enough on my systems and I rarely have people over, especially not for looking at _their_ electronic devices. [^snap]: Not [the good one][snap]. [^mmc]: Innovation's gone full circle, _eMMC_ is short for _embedded MMC_. [^futa]: Basically a futanari of the RJ45 world. [upstreamed]: https://rvspace.org/en/project/JH7110_Upstream_Plan [goatse]: https://loa.loang.net/chung/D16T24MXDP3T.3BR1X04I90CGT@guix/t [Netplan]: https://netplan.io [ufw]: https://launchpad.net/ufw [loang network]: https://loang.net [chose poorly]: https://antifandom.com/how-i-met-your-mother/wiki/Knight_Vision [snap]: http://snap.berkeley.edu [router freedom]: https://docs.fsfe.org/en/teams/router-freedom-tech-wiki [KT malware]: https://www.tomshardware.com/tech-industry/cyber-security/south-korean-telecom-company-attacks-torrent-users-with-malware-over-600000-people-report-missing-files-strange-folders-and-disabled-pcs [OpenNIC]: https://opennic.org [tier 2]: https://servers.opennic.org [SmartDNS]: https://pymumu.github.io/smartdns/en