Micah is the founder of M*Power Internet Services, a company specializing in software development and security consulting. He can be contacted at: http://www.MPowerIT.com/.
IEEE 802.11b, also known as the "Wi-Fi Standard," is an 11-megabit Ethernet-compatible, wireless network technology (http://standards.ieee.org/getieee802/). Early on, its developers acknowledged security issues with Wi-Fi and came up with Wired Equivalency Privacy (WEP) to make wireless LANs as secure as wired ones. WEP, however, is not without its problems. Through passive and active attacks, for instance, WEP can allow unauthorized use of wireless networks and real-time decryption of traffic on wireless networks. This presents a threat, especially in metropolitan areas with dense proliferation of wireless networks.
It comes as no surprise that there are a number of available techniques (and associated software) to exploit WEP's deficiencies. On the upside, however, these same techniques also let you test wireless networks. In this article, I present one such technique for securing wireless networks using a combination of hardware and the Free Secure Wide Area Network (FreeS/WAN), a freely available IPsec implementation for Linux that integrates with the IPsec functionality built into Windows (http://www.freeswan.org/). This technique lets you completely disable WEP (which you should for performance reasons anyway), so that all packets transmitted over the wireless network are encrypted using the secure IPsec protocol (http://www.ietf.org/rfc/rfc2401.txt). IPsec is a protocol for securing IP traffic at a low levellayer 3 of the OSI network model (http://www.netc.org/network_guide/c.html). IPsec is required in IPv6 (the new version of the TCP/IP Standard) and optional in IPv4 (the current Standard on which the Internet runs).
Wireless access reconnaissance (also known as "war walking") involves walking around with a wireless device to lock on to wireless networks. To see what kind of statistics can be gathered, for instance, I put a Sharp Zaurus (http://www.sharpusa.com/products/ModelLanding/0,1058,698,00.html) with a compact flash wireless card and the Kismet sniffer program (http://www.kismetwireless.net/) in my backpack and walked two blocks in the financial district of New York City. In that short distance, I locked onto 16 distinct wireless networks. About 1 percent of the packets I intercepted were encrypted. Because I was gathering statisticsnot examining incoming packetsmy Zaurus immediately dropped all intercepted packets. Likewise, war driving is a similar technique for discovering wireless networks via driving around in cars. Using the now-famous Pringles can antenna (http://www.oreillynet.com/cs/weblog/ view/wlg/448/), the range on a wireless sniffer is greatly increasedtheoretically 10 milesletting you lock on to regular wireless networks by just driving around.
All this underscores an important point: The wireless access point is the wrong place to secure the wireless network. Not only do algorithmic flaws make WEP ineffective, but the concept itself is lacking. When you can have someone (potentially) miles away examining your network packets, there is no possibility of "wired equivalency." The solution to such problems is to assume that wireless traffic is inherently insecure, then use tried-and-true techniques for securing these insecure networks.
Because IPsec operates at a low level in the protocol stack, it can protect almost any type of traffic that has IP at its basebasically all the traffic on the Internet. Strong higher layer security protocols (such as SSH and SSL) require special configurations or applications that explicitly support them. The Opera browser, for instance, does not explicitly support IPsec. However, if an IPsec connection has been established, all traffic generated by the Opera browser traveling on that connection would automatically be encrypted.
The IPsec Standard has three protocols:
- Internet Key Exchange (IKE) negotiates connections and is responsible for exchanging keys.
- Authentication Header (AH) provides packet-level authentication once a secure connection has been established.
- Encapsulating Security Payload (ESP) is used for encryption/authentication.
FreeS/WAN implements IPsec through: KLIPS (kernel IPsec), which handles AH and ESP within the kernel; Pluto, which handles IKE; and various scripts to administer the system. FreeS/WAN extends the IPsec Standard to include an operational mode called "opportunistic encryption," in which all traffic between two gateways is automatically and seamlessly encrypted. One of the goals of the FreeS/WAN project is to have this extension integrated into the Standard. Opportunistic encryption uses public keys embedded in DNS records to automatically enable IPsec connections.
Technically speaking, two machines involved in an IPsec negotiation are both client and server at different stages of the connection. In terms of FreeS/WAN, a client is a machine that wants to establish a secure connection, while a security gateway is one to which the client connects. Both the client and the security gateway run the same software and have similar configurations.
Figure 1 is a network without IPsec, while Figure 2 is the network with the IPsec security gateway in place. In fact, Figure 2 illustrates my home network, which includes a mix of wired and wireless connections and a broadband connection (cable) to the Internet. The goal is to have all wireless traffic locally secureany traffic between a wireless node and the security gateway should be secured with IPsec. If that traffic is bound for the Internet or one of the wired nodes on the network, it continues on unencrypted (because the security gateway will have decrypted it).
Preparing for FreeS/WAN Tasks
Before installing and configuring FreeS/WAN, I inserted a security gateway machine into the network and made sure a machine behind it could still access the Internet. To test and configure on Linux, I typically use a VMWare (http://www.vmware.com/) virtual machine. For the tasks at hand, I set up two VMsone as the security gateway and the other as a client. The configurations developed on these VMs could then be used on the real machines.
Both machines have a Red Hat 7.3 base install (for Windows, see the accompanying text box entitled "FreeS/WAN Interoperation with Windows"). The security gateway machine has two network adapters (configured through VMWare). I set up this machine as in Figure 2 by creating or editing the files in Listing One. To ensure that packets are forwarded, I edited /etc/sysctl.conf with the line: net.ipv4.ip_forward = 1.
To ensure that packets on the network behind the security gateway are properly masqueraded, I ran the commands in Listing Two. However, this is an unacceptably open firewall. Once FreeS/WAN is properly installed and configured, you lock down the security gateway so that the only connections it accepts are those to establish an IPsec session. (I purposely configured my base installation without firewall capabilities because Red Hat 7.3 configures ipchains by default.)
I set up the client machine (Figure 2) as one of the wireless machines by editing /etc/sysconfig/network-scripts/ifcfg-eth0; see Listing Three. I then restarted network services on both machines, verifying that everything was working properly by issuing a ping command (ping www.ddj.com) from the client machine. Once I saw the ICMP messages going back and forth, I knew the rudimentary configuration of the client and security gateway machines was good.
Installing and Configuring FreeS/WAN
Though there are a number of FreeS/WAN distributions, I built FreeS/WAN from source, focusing on the FreeS/WAN kernel module. At minimum, you need the Kernel source (2.4.18-3) and FreeS/WAN source (1.98b).
Once you've installed FreeS/WAN (per the documentation), you need to configure it. Setting up an IPsec tunnel between two machines requires that they authenticate to each other. By default, FreeS/WAN uses public-key authentication with RSA. FreeS/WAN supports other authentication methods, including X.509 certificates with a patch.
Machines that want to establish IPsec connections must have each other's public keys. The client machine uses the security gateway's public key for authentication and the security gateway uses the client's public key for authentication. Ordinarily, key exchange is tricky when establishing secure communications between machines. In this case, it is more straightforward because everything is happening locally. If you're paranoid, put the public keys on floppy disks and walk them between the machines.
The client and security gateway machines need to have key pairs generated and exchange public keys. Part of the installation process described here created the ipsec.secrets file, which contains both the private and public keys for a machine (and as a result, this file should be carefully protected). To generate a key pair from scratch, issue the command (on each machine): ipsec newhostkey --output /etc/ipsec.secrets. Be careful when using this command; if an ipsec.secrets file already exists, it appends another set of keys that causes confusion with other IPsec commands. (The documentation shows the command differently: ipsec newhostkey > /etc/ipsec.secrets. This is an older style of the command line and doesn't work with the recent versions.)
Next, extract and exchange the public key on each machine. In Figure 2, the security gateway machine is labeled "right" and the client machine is labeled "left." When establishing an IPsec connection, FreeS/WAN needs to know which participant is left and which is right. The choice is arbitrary, but must be configured consistently. To extract the public key for the security gateway, execute ipsec showhostkey --right > SecGW.txt on the security gateway machine. To extract the public key for the client, execute ipsec showhostkey --left > Client.txt on the client machine.
The next step is to configure the /etc/ipsec.conf file. Recall that I created a generic file as part of the installation. Backup this file and start from scratch. Listings Four and Five are the configuration files for the security gateway and client, respectively. Each file has three distinct sections: setup, default connection definition, and one or more specific connection definitions.
Referring to Figure 2, the IPsec connection needs to be bound to eth0 on the security gateway machine. Line 2 of Listing Four does this. Lines 3-4 handle debug options for KLIPS and Pluto. For now, these debug features are disabled. Lines 5-6 contain a list of connections to be automatically loaded and automatically started, respectively. The %search value tells the system to look further in the configuration file for these connections. Line 7 ensures that if a connection exists for a particular ID, and another connection is being made with the same ID, the original connection is dropped. This is useful in situations where connections might be volatile. Client machines might try to reconnect before the security gateway had closed the original connection, for instance.
The default connection definition section (line 9) contains settings that apply to all individual connection definitions. If a variable referenced here is also used in an individual connection definition, the one specified for the individual connection takes precedence.
Line 10 refers to how many times a particular connection tries to reestablish itself if lost. A value of 0 indicates infinite retry. Line 11 indicates how machines authenticate when making connections. The authentication is made using RSA signatures.
Again in Figure 2, the wireless nodes (clients) are referred to as "left" and the security gateway is referred to as "right." In the configuration files for both the client and security gateway machines, you must have consistent left/right designations. Line 12 indicates that machines on the "left" connecting to the security gateway can have any IP address. Line 13 indicates the IP address on the security gateway that is used for IPsec connections. Line 14 ensures that the IPsec connection protects traffic bound for any destination address. This is crucial. If rightsubnet is left out, by default, FreeS/WAN only protects traffic bound specifically for the right IP address (10.0.0.1, in this case). The setting of 0.0.0.0/0 is the most open setting possible. A setting of 192.168.0.0/24 would limit the protection to traffic bound for the wired network only.
Line 15 sets the ID that is used for the security gateway. The "@" character indicates that the subsequent text is presented to FreeS/WAN as the ID for the machine. This is the preferred method for specifying a machine's ID. Other options include using actual hostnames, DNS names, or IP addresses. These options require maintenance (in the case of host names or IP addresses) or unnecessary network activity (in the case of resolving DNS names). It works as long as the ID is consistent across the machines involved in the IPsec connection.
Line 16, abbreviated for readability, is where the public key of the security gateway machine goes. This was generated with the ipsec showhostkey --right command. The documentation claims that it is not necessary to have the local public key in the configuration file for a given machine, but in my tests, FreeS/WAN complained and would not start properly. Remember that since you are dealing with the default connection section, these settings apply to all other connection definitions.
Lines 18 and on define the individual connections allowed to the security gateway machine. These definitions also correspond to Figure 2. Line 18 defines connection names. Line 19 specifies expected IDs used for this connection. Again, the client machine has to have an ID that matches. Line 20 is the public key from the client machine making the connection to the security gateway. Line 21 ensures that this connection definition is loaded into memory at FreeS/WAN start time. Consequently, the security gateway is ready to receive connections from clients.
The remaining lines describe another client connection. Because of the organization of the configuration file, including the left=%any specification in the default connection section, each client connection need only specify its ID and public key.
The setup section of the client configuration (Listing Five) is almost identical to that of the security gateway. The only difference is line 2, where %defaultroute is used since, in the case of the client, you don't care about a specific adapter (and it is expected that there would only be one adapter generally anyway).
The lines in the default connection section have the same meaning as in the security gateway configuration. Lines 14-20 hold the same information as that found in the security gateway configuration. It is this matching of values (ID and public key) that enables the systems to respond properly when a connection is being established. Line 21 could be auto=start for the client machine to automatically establish the connection when FreeS/WAN is started on the client. This file could be used as a template for all client configurations. The only differences between files are the leftid and leftrsasigkey lines.
When configuration files are in place, test that traffic is properly flowing through the IPsec connection. Restart the service on each machine using service ipsec restart. On the client machine, issue ipsec auto --up client, and you should see output similar to Figure 3. The important lines are the ISAKMP SA and IPsec SA messages. ISAKMP (Internet Security Association and Key Management Protocol) is a part of the IKE (Internet Key Exchange) process. The IPsec SA (Security Association) indicates the connection has been established.
Do a test by specifying the ipsec0 adapter using ping -I ipsec0 www.ddj.com. If you see the proper ICMP responses, then your IPsec connection is properly functioning. (Executing this command before establishing the IPsec connection should not work.) If you experience problems, enabling the debugging features in the config files helps resolve any issues. Messages from the Pluto service appear in /var/log/secure. The most common type of problems are not having the leftid and rightid values consistent across the machines or not having IPsec bound to the proper adapter. The final step is to properly lock down the security gateway using a strict iptables configuration.
Once FreeS/WAN is configured, you don't want any direct incoming or outgoing traffic on the security gateway. The only exceptions are those ports/protocols used for IPsec itself. All valid traffic arrives on an IPsec adapter (usually ipsec0) and is then handled by the NAT table where it masquerades as the external (eth1) IP address.
Listing Six is the iptables script used to lockdown the security gateway. Lines 8-9 are for vanilla masquerading. Lines 10-11 ensure that only packets coming in on any IPsec adapter (ipsec+) are allowed on the FORWARD chain. Any traffic destined for the FORWARD chain that did not come in on an IPsec adapter (line 11: ! ipsec+) gets logged. The traffic is then dropped at this point.
Lines 15-21 ensure that only IPsec traffic is allowed on the INPUT/OUTPUT chains. Specifically, UDP port 500 handles the IKE negotiations and protocol 50 is used for ESP. It's easy to get confused between ports and protocols. TCP and UDP are the protocols that are most commonly associated with ports. Other protocols, such as ESP, do not use ports at all. If the traffic is not on UDP port 500 or is not protocol 50, a log message is generated and it is dropped.
Lines 25-27 are crucial. The default behavior is for the INPUT, OUTPUT, and FORWARD chains to ACCEPT traffic. As far as I'm concerned, this should be changed as soon as possible! The default behavior for any system that is to have any reasonable security should be "deny unless explicitly allowed." It is this set of lines that ensures that all traffic not matched to the stated rule is dropped. A thorough discussion of iptables is available at http://www.netfilter.org/.
After executing Listing Six, I issue the command: service iptables save (on Red Hat 7.3) to save the configuration so that if the security gateway is rebooted, these iptables options are restored.
Now test to ensure that the system is properly locked down. After the firewall script is executed and an IPsec connection is established, issue ping -I eth0 www.ddj.com on the client. Notice 100-percent packet loss on the client. On the security gateway, you should see something like: Not IPSEC: IN=eth1 OUT=eth1 SRC=10.0.0.10 DST=126.96.36.199... on the console (as well as in the /var/log/messages file).
You can secure a wireless network with the FreeS/WAN configurations and firewall script presented here. All traffic between individual nodes is encrypted using the IPsec protocol. Only authorized machines can establish IPsec connections because a client and security gateway need each other's public keys in their configuration files. War walkers will not be able to use your bandwidth without permission because of the firewall on the security gateway.
/etc/sysconfig/network-scripts/ifcfg-eth0: DEVICE=eth0 ONBOOT=yes BOOTPROTO=static IPADDR=10.0.0.1 NETMASK=255.255.0.0 /etc/sysconfig/network-scripts/ifcfg-eth1: DEVICE=eth1 ONBOOT=yes BOOTPROTO=static IPADDR=192.168.0.50 NETMASK=255.255.255.0 GATEWAY=192.168.0.1
iptables -P INPUT ACCEPT iptables -P OUTPUT ACCCEPT iptables -P FORWARD ACCEPT iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE service iptables save
DEVICE=eth0 ONBOOT=yes BOOTPROTO=static IPADDR=10.0.0.10 NETMASK=255.255.0.0 GATEWAY=10.0.0.1
1. config setup 2. interfaces="ipsec0=eth0" 3. klipsdebug=none 4. plutodebug=none 5. plutoload=%search 6. plutostart=%search 7. uniqueids=yes 8. 9. conn %default 10. keyingtries=0 11. authby=rsasig 12. left=%any 13. right=10.0.0.1 14. rightsubnet=0.0.0.0/0 15. [email protected] 16. rightrsasigkey=... 17. 18. conn client1 19. [email protected] 20. leftrsasigkey=... 21. auto=add 22. 23. conn client2 24. [email protected] 25. leftrsasigkey=... 26. auto=add
1. config setup 2. interfaces=%defaultroute 3. klipsdebug=none 4. plutodebug=none 5. plutoload=%search 6. plutostart=%search 7. uniqueids=yes 8. 9. conn %default 10. keyingtries=0 11. authby=rsasig 12. 13. conn client 14. left=%defaultroute 15. [email protected] 16. leftrsasigkey=... 17. right=10.0.0.1 18. rightsubnet=0.0.0.0/0 19. [email protected] 20. rightrsasigkey=... 21. auto=add
1. iptables -F 2. iptables -t nat -F 3. iptables -X 4. iptables -t nat -X 5. 6. # NAT and FORWARD 7. 8. iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE 9. iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 10. iptables -A FORWARD -i ipsec+ -j ACCEPT 11. iptables -A FORWARD -i ! ipsec+ -j LOG --log-prefix "Not IPSEC: " 12. 13. # IPSEC 14. 15. iptables -A INPUT -p UDP --sport 500 --dport 500 -j ACCEPT 16. iptables -A INPUT -p 50 -j ACCEPT 17. iptables -A INPUT -j LOG --log-prefix "INPUT DROP: " 18. 19. iptables -A OUTPUT -p UDP --sport 500 --dport 500 -j ACCEPT 20. iptables -A OUTPUT -p 50 -j ACCEPT 21. iptables -A OUTPUT -j LOG --log-prefix "OUTPUT DROP: " 22. 23. # lockdown! 24. 25. iptables -P INPUT DROP 26. iptables -P OUTPUT DROP 27. iptables -P FORWARD DROP