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.
- 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.
- 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:
- 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.
- 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.
- 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:
- Severely restrict the types of traffic that can pass over the
interface, so that anyone who breaks in can't do anything dangerous to
your local network.
- Protect the gateway machine itself from attack.
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.