Semi-secure Wi-fi

This page will eventually describe a simple way of making a semi-secure wireless network using a Linux machine as a gateway/router. The object here is to minimise (ideally to zero) the damage that an attacker can do to your real LAN, rather than to reduce to zero the chances that he'll get into the WLAN. The page is currently under construction and may not reflect the current real implementation of this scheme. Use at your own risk.

The problem

The basic problem is that the encryption protocol used by the wireless LAN, WEP, is insecure. With simple off-the-shelf tools like AirSnort it is possible to guess the 128-bit encryption key. An attacker who can get within range of your wireless network and monitor it can eventually see all the traffic that goes across it: moreover, he can masquerade as a real user of your network, and if that allows him accesss to any important machines, you have a problem. A typical home or small office wireless network will probably hand out DHCP IP addresses to known MAC addresses, but once the attacker has acquired the WEP key, he only needs to determine one valid MAC address and then wait until it relinquishes its DHCP lease to be in, since the DHCP process includes no authentication. You can reduce the danger from this attack by regularly changing the WEP key, but that's cumbersome, particularly if you have Windows machines on your network.

Approaches

There are two approaches to dealing with this problem.
  1. Authenticate and encrypt connections. A popular way of doing this is with PPPoE. However, this is relatively cumbersome, and there are technical reasons why it's a bad idea. Probably IPsec would be better, but it's less widely supported and non-trivial to administer. In any case, these are possibly overkill for a home or small office setup.
  2. Prevent an attacker from doing damage. This is the approach I will document here.

The basic idea

We accept the possibility that a sufficiently determined attacker may be able to acquire your WEP key and get some access to your network. There are three possible motivations for this:
  1. Bandwidth theft. While annoying, this is relatively benign, particularly if you already have sensible firewalling in place between your network and the global internet. It's unlikely in any case that an attacker will want to spend the time breaking into your network just in order to surf the web on your ADSL or cable connection. Moreover, by doing so, he renders himself liable to detection if you're doing any sort of traffic monitoring.
  2. Snooping. The attacker can see all traffic between wireless-enabled machines and the access point. This is only a problem if you want to run inherently insecure, unencrypted services, like Windows file sharing or NFS, across your wireless network. If it is a problem for you, then you need one of the fully encrypted, authenticated solutions described above: look elsewhere. If you are happy for your wireless-enabled machines simply to have access to services that are encrypted by default (e.g., ssh) or not generally a security problem (e.g., www) then read on.
  3. Mounting an attack on a local system. This is what we must prevent at all costs. If your wireless access point is simply attached to your LAN, then the attacker has a chance to get at all the unsecured machines behind your firewall, or even the firewall machine itself from the inside. Therefore, it's clear that we need to firewall off the wireless network from the rest of the LAN.

Firewalling

The easiest and, I think, the best way to keep control over your firewall in general is to use a PC with multiple network cards as the firewall. What you run on this PC is a matter of individual choice. As I'm familiar only with Linux firewalling, that's what I'll describe here. For simplicity, I'll describe a system with two network cards: one connected to the local LAN and thence to the Internet, and one that will support the wireless LAN. I'll assume that you already have a firewall in place to protect your LAN from the outside world, although it would in fact be possible (and even in some ways desirable) to have the same machine do both tasks.

Let's assume then that you have an ordinary Linux PC behind a firewall and you wish to set it up as a wireless firewall. You've put an extra network card in it. Let's say that the LAN interface is eth0 and the new card appears as eth1.

Your first task is to set up a private network on eth1. Pick one of the private class C address ranges - say 192.168.1.xxx. Your machine will be 192.168.1.1. Add some appropriate lines to /etc/network/interfaces, if you have it, or your network configuration file if not:

auto eth1
iface eth1 inet static
       address 192.168.1.1
       netmask 255.255.255.0
       network 192.168.1.0
       broadcast 192.168.1.255
Next, if your access point is like mine and gets its network address by DHCP (and proxies DHCP requests from machines on the wireless network), you will want to set up a DHCP server to listen on this network. [...]

At this stage you can attach the access point to the network. At least some access points are designed to plug into a hub, so that you will need a crossover ethernet cable to plug them directly into the ethernet card corresponding to eth1. Others will work directly. You may find it useful to have a hub for this `public' network in any case, if you frequently have to deal with visitors' machines with conventional wired ethernet. In any case, attach your access point and verify that you can ping it. (If it obtains its address by DHCP, you should also check the system logs at this point to verify that it's done so successfully and got the address you expect.)

So far users of the wireless network can only access other machines on the private network, 192.168.1.xxx (probably only the Linux machine itself, 192.168.1.1, and the access point). We now need to set up some firewalling and forwarding rules.

How you do this is again up to you. My Debian system comes with an /etc/init.d/iptables script and some associated files, including a stern warning not to use this method. For other firewalls I've built I've tended to write my own set of commands directly calling iptables. So this is what I'll document here. If you don't have iptables, go off and install it. If your kernel is too old to support it, go and install a better kernel.

We have to do two things:

Here's how I do the first:

LOCAL=eth1
WORLD=eth0

echo "1" > /proc/sys/net/ipv4/ip_forward

/sbin/iptables -F INPUT

/sbin/iptables -t nat -F PREROUTING
/sbin/iptables -t nat -F POSTROUTING

/sbin/iptables -t nat -A POSTROUTING -o $WORLD -j MASQUERADE

/sbin/iptables -F FORWARD
/sbin/iptables -P FORWARD DROP

# allow forwarding of traffic from the local network
/sbin/iptables -p tcp -A FORWARD -o $WORLD -i $LOCAL --dport 22 -j ACCEPT
/sbin/iptables -p tcp -A FORWARD -o $WORLD -i $LOCAL --dport 80 -j ACCEPT
/sbin/iptables -p udp -A FORWARD -o $WORLD -i $LOCAL --dport 53 -j ACCEPT
/sbin/iptables -p udp -A FORWARD -o $WORLD -i $LOCAL --dport 123 -j ACCEPT
# allow related forwards back -- i.e. MASQUERADING
/sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

/sbin/iptables -A FORWARD -j LOG --log-prefix 'Forward '
What's happening here? We've set up IP masquerading, but then set the default policy for forwarding to DROP - in other words, any type of traffic not explicitly permitted will be thrown away. Then we have allowed certain types of traffic from the wireless (LOCAL) network to the external one (WORLD): ssh (22), web (80), DNS (53) and NTP (123). Remember, the wireless network is not secure, so on no account should you enable any protocol over which sensitive information (like passwords) can travel unencrypted. ssh is safe for this reason. You will almost certainly want DNS and web access if you are allowing access to the global internet. Keep the services you allow to a minimum. Finally, we log all failed forward attempts - a useful way to spot someone on the network doing something they shouldn't. Note that by doing this we've disabled common network tools like ping and traceroute. This is intentional - we don't want an attacker finding out anything about the network on the other side of the firewall.

Next we should make sure that the gateway machine itself is secure. If this machine is exposed to the global internet it presumably already has a firewall that can be adapted. If it's behind a firewall already, something simple like this could be used:

/sbin/iptables -P INPUT DROP
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A INPUT -i $WORLD -s 192.168.1.0/24  -j DROP
/sbin/iptables -A INPUT -i $WORLD -j ACCEPT
/sbin/iptables -p tcp -A INPUT -i $LOCAL --dport 22 -j ACCEPT
/sbin/iptables -p udp -A INPUT -i $LOCAL --sport 68 --dport 67 -j ACCEPT
Here we are allowing all traffic on the loopback interface (lo) and the external interface (WORLD), on the assumption that the latter's already protected, but the only traffic that we allow on the wireless interface is ssh (to allow a login) and DHCP (assuming that we're DHCP-serving).

Finally

You should also ensure that any machine attached to the wireless network is secure, since we have basically accepted that the security of this LAN can be compromised. This means that no machine without its own firewall (of a quality suitable to allow the machine to be attached directly to the global internet) should be attached to the wireless network. At a minumum, you should close all unnecessary services on all the wireless machines (and make sure that you've done so effectively with a utility like nmap). The chances of an attacker breaking into your wireless network simply in order to attack someone else's laptop are slim, but shouldn't be ignored. Of course, as you probably expect to use your wireless-enabled device on other, untrusted networks, this is just elementary good practice in any case.