The Wireless Gateway’s End Also Killed CheckPoint’s Cleartext Login
One component retired. It killed an entire system on its way out. I only built one of them. Before wifi, Baylor’s residential network ran authentication through CheckPoint using a cleartext, telnet-emulated login. I’d already shipped client software for both Windows and Mac System 7 that talked to it, before I’d ever built an authenticating gateway or touched a router.
Building the Authenticating Gateway
When wifi arrived in 2002, cleartext credentials over open RF became an acute problem in a way they’d never been over wired Ethernet. I built an authenticating gateway off a NASA whitepaper I’d read on their own OpenBSD implementation: a second NIC, kernel routing, a PHP login front end, and RADIUS authentication correlating DHCP lease state with ARP data to bind a browser’s IP to its MAC. The prototype went up that winter on a retired workstation; by the start of that fall semester it was carrying the full wireless population, migrated onto its own dedicated rackmount server as it went from prototype to production.
That gateway carried the wireless population through that academic year. In Spring 2003, 802.1x (the emerging IEEE standard for port-based authentication) took over the actual authentication job. My gateway didn’t disappear so much as go quiet: once 802.1x proved reliable, I rewrote its firewall rules into a simple passthrough, any client admitted on the wireless side let straight through to the core with the same access it used to gate at the login page, now enforced on the wireless edge.
One Shutdown Frees the Next
Perhaps other stories like this end here: after the real standard replaces the stopgap, the builder moves on. Instead, retiring the wireless web frontend freed the same architecture for a problem nobody had thought to assign. One cleartext login remained: a CheckPoint firewall running on Nokia hardware that had itself been coerced into gateway duty years earlier, just to bolt Baylor’s first-generation residential network onto the campus core. I proposed swapping in a purpose-built authenticating gateway there next.
A colleague with a gift for internal politics (how could I know he’d one day end up becoming my CIO?) carried the pitch up the chain. This one was an easier sell, given he had a working system to point to instead of a whitepaper. That same year, I cloned the wireless gateway’s architecture onto its own dedicated box (creatively called it the residential gateway) and with its launch, the CheckPoint cleartext authentication was gone for good. No separate initiative happened to land nearby. My gateway implementation was the direct cause.
The Architecture Underneath
The real engineering lived one layer down. The PHP front end handled RADIUS authentication against AD and MAC registration gating. There was no network admission without a registered device. Copyright/DMCA enforcement was not bolted on afterward: I built it directly into the login path. PHP ran as the web server’s own low-privilege user, exposed directly to the untrusted student segment. On successful auth, it had no ability to touch kernel firewall state itself, by design.
It spoke a plaintext UDP control protocol instead, to a separate, privileged daemon. I extended that daemon from a skeleton written by Carl Bell, author of the IMAP client, maildrop. This was a deliberate privilege separation, not an oversight. The daemon bound to loopback by default. The trust boundary became that internal network position rather than anything in the protocol itself. Only that daemon held the privilege to translate admit/deny commands into OpenBSD, and later FreeBSD, firewall radix-table operations at the kernel level. To learn how to implement ioctl() calls in the daemon, I dug deep into source code and documentation. Calling a wrapper script by shelling out to a firewall CLI did not seem optimal.
I partitioned client IPs across authentication tables by third-octet parity. I deliberately chose this sharding scheme to keep any single table from growing unbounded as the population scaled. Admission was fast because it only ever touched the one radix table an IP belonged to. Revocation didn’t get to make that assumption: a deauth swept every table, not just the one a client’s address should have landed in. A stale entry sitting in the wrong bucket would have meant a client that should have lost access, kept it. Silently leaving that gap open was the real risk. The extra lookups on removal cost nothing by comparison.
A RADIUS Client Nobody Got Right
I’ve told the byte-level version of the RADIUS story already: When the Spec Is the Only Source of Truth. To summarize: I found a PHP RADIUS client online, written by a hobbyist, and it didn’t actually implement the RFC correctly. I read RFC 2865 down to the byte level and repacked the UDP payload by hand to fix the encoding, then came back later to add proper NAS-IP/NAS-Port attribute population once I understood the spec more completely. No vendor documentation existed for any of this. The spec was the only source of truth, because there was no product that did what we needed.
Closing the DHCP Loop
Later, I patched ISC dhcpd’s own source to hook every lease lifecycle event into a MySQL mirror: new leases, renewals, releases, abandonment. From that same hook, I fired a deauthentication command to the firewall daemon whenever a lease was released or abandoned. That closed a loop CheckPoint’s system never had: a client didn’t just get authenticated on login, it got automatically deauthenticated the moment its DHCP lease expired, with no separate TTL or other cleanup process required.
The residential gateway ran continuously from Fall 2003 through 2008 and beyond, serving over 2,000 students at peak, surviving several full rewrites along the way. This gateway project was my classroom. The lessons learned were passed down the line into later projects. For example, I ported many of the telemetry monitoring scripts out to the IP address management system I ran for the next fifteen years. But the gateway’s first job, the one that doesn’t usually make it into the resume version of this story, was ending cleartext authentication on a network that had been running it for years. Not because anyone asked, but because retiring one system freed the tools (and freed me) to go make the case for a job nobody had thought to assign.

Leave a Reply
You must be logged in to post a comment.