McSinyx

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, 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[1] 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:

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:

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!

  1. Connecting to the Internet
  2. Local Networking
  3. Wireless Access Point
  4. Name Resolution

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[3], 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 was needed and here is the entire Netplan configuration to connect to the outside world:

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:

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:

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):

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. Netplan doesn't support Wi-Fi hotspot with systemd-networkd but NetworkManager, so the interface had thus to be declared as Ethernet:

network:
  bridges:
    br0:
      interfaces:
        - wlx600dd0g8b33f
  ethernets:
    wlx600dd0g8b33f:
      dhcp4: false

Actual wireless connectivity is handled by hostapd:

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 so I'd rather rely on more reputable resolvers like OpenNIC, which also offers free-of-charge (!) domain names. Most of their tier 2 servers 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:

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:

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:

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.

[1] Not the good one.
[2] Innovation's gone full circle, eMMC is short for embedded MMC.
[3] Basically a futanari of the RJ45 world.

Tags: fun recipe net Nguyễn Gia Phong, 2024-08-03

Comments

Follow the anchor in an author's name to reply. Please read the rules before commenting.