One of the things we decided that we should add to the Jaguar office was wireless Internet for visitors. We wanted visitors to be able to use wifi to get on the Internet with their laptops and smartphones. At the same time, we wanted this guest network to be separate from our office LAN. We didn’t want users of the guest wifi to have any network access to the internal servers and services we’re running inside the Jaguar office. Based on these requirements, I knew that the answer would lie in the use of routers powered by DD-WRT, the very flexible open-source firmware for wifi routers. I ran into many tutorials how to create a separate VLAN on a DD-WRT router. The issue with these tutorials, for our purposes, is that they assumed that the DD-WRT device was acting as a router. That’s a reasonable assumption for home users, but in our case, our DD-WRT device serves purely as an access point. I did, however, want the guest wifi to behave like a router at the access point level. I did not see a clear way to have our wireless access point still act like an access point for our main wifi network, while acting like a router for the guest VLAN. I imagine there may be a way to bend DD-WRT to make one device be an access point for one VLAN and a full-blown router for another, but that configuration was beyond my level of commitment. My solution to this problem was simply to get a second wireless router, install DD-WRT on it, and make that device power the guest wifi.
Configuration & Restrictions
Even though this is our guest wifi, I still insisted on WPA2 encryption. I’m not at all keen on the idea of broadcasting an open wifi network. It’s not too much to ask of a visitor to type in a simple password.
For maximum compatibility, I set the encryption mode to WPA2 Personal Mixed, which allows older devices with only WPA support to still function. I’m not willing to leave a WEP-encrypted network running 24/7, but in the event that we have someone come in with an old machine that can only do WEP, I can quickly add a virtual interface to the router and enable WEP encryption on that, and shut it down when it’s no longer needed, without interfering with the normal guest wifi setup.
For the WPA2 interface, I set the encryption to TKIP+AES, so devices failing to support AES can fall back to TKIP. And I set the 802.11 mode to Mixed, so B, G, and N clients can all function. Not the best setup for high performance, but when someone walks in waving around an Orinoco Silver card, it should work.
Given that this was to be our “guest” wifi, there were certain restrictions I wanted enforced:
- The guest wifi was to be on its own subnet
- The office network subnet was to be unreachable from the guest wifi
- A certain level of content filtering was to be enforced
- Some traffic controls to restrict overly taxing our Internet pipe
First Up, Secure the Device Itself
A router’s only as secure as its admin panel. If someone can get into the admin panel, any security settings administered there are rendered moot. My quick checklist for setting up DD-WRT:
- Define a strong password for the admin panel
- Change the admin panel username (which is usually “root” by default) to something else
- Disable remote administration (usually disabled by default)
- Disable telnet, enable SSH instead
- Disable passworded SSH access, use public key authentication instead
- Ensure SPI firewall is enabled (should be by default)
- Disable unneeded services
- Disable unused VPN firewall passthroughs
One thing I’ve learned from using DD-WRT is to not forget to set up SSH access. It comes in handy when something goes wrong with the web panel, especially if you’re maintaining the device from two time zones away, like me. I don’t have SSH set up to accept remote connections, however – instead, I get to it by connecting to the VPN and making myself a local LAN node.
(Important note for SSH access: even if you’ve changed the web panel username from “root” to something else, when connecting by SSH, you will still use “root” for the user). All unneeded services are disabled.
Separate Subnet for Guest Wifi
With a traditional home wifi setup, users plug their cable/DSL/etc modem into the router’s WAN port. For us, our office LAN is the guest wifi’s WAN, so we plug a cable from the wall to the guest router’s WAN port. The router gets a “WAN IP” that is an address on our office LAN. In the router’s DHCP server setup, we define a different subnet for the router’s own network. For the sake of this article, we’ll define 10.10.10.x as our office subnet, and 10.10.20.x as the guest wifi subnet.
Blocking Access to Office LAN
In order to restrict guest wifi clients from being able to reach the office LAN, I defined firewall rules for the guest router that will drop any outbound traffic intended for the office LAN’s subnet.
# Block outbound traffic intended for office LAN iptables -I FORWARD -d 10.10.10.0/24 -J logdrop
With this rule, the router won’t forward any traffic from client machines to the office LAN. It will, however, still route traffic destined to the Internet through the office LAN’s gateway, which is good, because that’s the way to the Internet.
Coming at the same problem from the other direction, I also added firewall rules to certain internal LAN services to block any traffic coming from the guest wifi subnet. The guest router’s own firewall rule should be sufficient on its own, but it never hurts to add another layer of safety.
We don’t want our guest wifi becoming Porn & Bittorrent Central. Granted, since it’s an encryption-secured access point, there isn’t a great deal of risk of that, but at the same time, we don’t intend on being overly stingy with the WPA2 key. It seems appropriate to perform a bit of filtering. My solution for this need was to use OpenDNS on the guest wifi, and put the OpenDNS service’s content filtering features to use. In addition to filtering out unwanted content, OpenDNS can also filter out things that are security risks. In the DHCP server settings, I set the three Static DNS entries to OpenDNS servers. In order to prevent users bypassing the OpenDNS filtering by trying to set their own DNS servers, I took a hint from the DD-WRT wiki’s OpenDNS page and enabled a couple of firewall rules that intercept attempts to resolve DNS via different servers:
# Intercept DNS queries to external servers, re-route to local DNS iptables -t nat -A PREROUTING -i br0 -p udp --dport 53 -j DNAT --to $(nvram get lan_ipaddr) iptables -t nat -A PREROUTING -i br0 -p tcp --dport 53 -j DNAT --to $(nvram get lan_ipaddr)
Don’t Hog Our Pipe
One of the reasons P2P services like Bittorrent can be such a network strain is the sheer number of connections they open. In order to help guard against this on our guest wifi, I’ve added a couple of connection limiting rules to the firewall script:
iptables -I FORWARD -p tcp -s 10.10.20.0/24 -m connlimit --connlimit-above 50 -j DROP iptables -I FORWARD -p ! tcp -s 10.10.20.0/24 -m connlimit --connlimit-above 25 -j DROP
These rules drop any additional TCP connections a client tries to make above 50, or 25 for non-TCP connections. Those numbers should be high enough to not as to interfere with any non-P2P use, but will prevent a single P2P peer from flooding the device with open connections.
There is much more that can be done to restrict excessive wifi usage, but that is a deep, dark rabbit hole, and well beyond the needs of our own use case.
Up and Running
One could easily take things even further. There are numerous pieces of software for setting up public wifi points. Some are even open source and included in DD-WRT, like Chillispot. DD-WRT also provides features like remote logging and limiting access to certain times of day, which I left for possible future exploration. For now, though, I’m happy with the above setup. DD-WRT’s capability of letting users define iptables rules is a very powerful feature, and a big reason why I insist on using wireless access point that are well-supported by DD-WRT.