FreeBSD Wi-Fi IPsec easy-setup guide Timothy Ham Mar, 2004 Version 1.0.2 The latest version of this file can be found at: http://www.nth-order.com/~tim/wifi-ipsec.txt 0. Abstract ----------- An IPsec tunneling connection was set up between a MS-Windows host with wireless ethernet and a FreeBSD NAT gateway. This setup allowed the mobile host to have a secure and encrypted connection over an inherently insecure wi-fi radio network. 1. Introduction --------------- Recently I have purchased a "Wireless Bundle", consisting of a wireless NAT router and a PCMCIA 802.11b card, for not a lot of money (I love cheap hardware). Being a consumer device, it was very easy to set up and to get it working with my existing home LAN. But difficulties arose when I tried to secure the connection, and also when I tried to protect the rest of my LAN from any intrusion through the wireless access point. The choice of IPsec over WEP was for me obvious. Besides WEP being insecure (secret key can be recovered easily), my PCMCIA card had a buggy firmware, which kept dropping connections when WEP was turned on. The problem was well documented on various web boards and the manufacturer had no updates to fix the problem (I hate cheap hardware). As such, I was left with a superior, but harder to setup, choice. There were some resources available on the web to set up IPsec VPN, but none of them were specific enough for my case. As such, I thought I would share my experience hoping it will be useful for others. 2. Isolating the Wireless LAN ----------------------------- My existing home LAN was as follows. I had a dual-homed FreeBSD NAT gateway with dhcpd running to dole out private IP address to any machine connected to the LAN. A guest could come by and connect their laptop to the LAN and surf the web. A typical setup. The first step was segregating the wireless LAN from the rest of my home LAN. I made this easy by installing another ethernet card ($10) into the FreeBSD box, and giving it a separate address space. For example, my existing LAN was using 192.168.1.x. The new ethernet card has 192.168.2.1. With proper firewall rules and IPsec, this segment can be isolated from the rest of my home LAN. Because my wireless access point is sold as a router/switch (it was much cheaper than a stand-alone access point--go figure) its router functions (DHPCD, NAT) had to be disabled. It had a web interface to change its settings. I also gave the wifi net a name. The router had 4 ethernet ports labeled "LAN", and one port labeled "WAN". Since I'm just using the wireless/switch portion, I connected my new ethernet card (192.168.2.1) to one of the "LAN" ports. The laptop was given a permanent IP of 192.168.2.10. 3. Transport Mode vs. Tunnel Mode -------------------------------- This part had confused me a great deal because the literature out there (including the FreeBSD handbook) mentions IPsec tunnels in terms of VPNs--that is, two gateway machines connecting two sub-nets over a secure tunnel using a virtual interface gif. So at first, I thought what I wanted was a transport layer, that encrypted packets end-to-end. But this is *not* what you want. All packets between the laptop (host) and the gateway (192.168.2.10<->192.168.2.1) were encrypted. However, any other packets destined to the rest of the internet were not (192.168.2.10->www.yahoo.com). This is not what you want. What you *do* want is a encrypted tunnel between the host and the gateway that carries packets from the host to the rest of the internet. Here is what should happen: Any outgoing packet from the host to anywhere (192.168.2.10->www.yahoo.com) should be encrypted and encapsulated in another packet designated to the gateway (192.168.2.10->192.168.2.1). Once the gateway receives the packet, it is decrypted and forwarded to www.yahoo.com. A returning packet (www.yahoo.com->192.168.2.10) should be encrypted and encapsulated by the gateway and sent to the host (192.168.2.1->192.168.2.10). The host will decrypt the packet and read the contents. The existing NAT machinery will handle the private IP address translation at the public internet interface. 4. Setting up the Gateway ------------------------- With the above in mind, here is how the gateway was set up. A. Recompile the kernel with IPsec support by adding the following to the kernel config file: options IPSEC options IPSEC_ESP Recompile, reinstall, and reboot with the new kernel. Add the following to /etc/rc.conf ipsec_enable="YES" ipsec_file="/etc/ipsec.conf" B. Setup the security policy. Create /etc/ipsec.conf with the following. In this example, 192.168.2.10 is the laptop host and 192.168.2.1 is the gateway interface. flush; spdflush; spdadd 192.168.2.10/32 0.0.0.0/0 any -P in ipsec esp/tunnel/192.168.2.10-192.168.2.1/require; spdadd 0.0.0.0/0 192.168.2.10/32 any -P out ipsec esp/tunnel/192.168.2.1-192.168.2.10/require; Run 'setkey -f /etc/ipsec.conf' to use the security policy. C. Install and configure racoon. Racoon is found in /usr/ports/security/racoon. Make install Once installed, set up /usr/local/etc/racoon/psk.txt. This lists the pre-shared-keys for your hosts. For example: 192.168.2.10 SecretKey Try to make the secret key hard to guess. A good resource is the "Passphrase FAQ" on the web. Now, create /usr/local/etc/racoon/racoon.conf. I copied the racoon.conf.dist file and changed and modified the "listen" directive and the "life time" values in the "remote anonymous" and "sainfo anonymous" directives. I set the life time to 24 hours and 12 hours for "remote" and "sainfo" respectively, following suggestions from 'man racoon.conf'. D. Start racoon Run 'racoon -F -v' as root to have racoon run in foreground and display debugging info to the standard output. 5. Setting up the Windows Machine --------------------------------- Windows 2000 and XP have similar but slightly different dialogs and wizards, but the idea and the final results are the same. I put a summary at the end, which is the same in either version. - Go to the Start menu and click on Run. Type mmc and . - Select Console (or File)->Add/Remove Snap In. - Select Add... - Choose IP Security Policy Management and click Add. - Select Local Computer and click Finish. - [In XP, also add IP Security Monitor snap-in] - Select Close to close the Add standalone Snap-in dialog. - Select OK to close Add/Remove Snap-in dialog. You have now added the IP Security Policies snap-in. Now to setup a wifi policy. - Select IP Security Policies on Local Machine and right click and select Create IP Security Policy. - Give the security policy a name (ex, wifi). Click Next. - Un select Activate the default response rule. Click Next. - Un select Edit Properties. Click Finish. Now along with Client, Secure Server, and Server, you should have a policy called "wifi". Now to set up filtering rules: - Right click on IP Security Policies leaf on Console Root and select Manage IP filter lists and filter actions. - click Add. - Name this filter list OutboundIPsec. Then click on Add. - Follow the wizard and select My IP Address as the Source, Any IP Address as the destination address, and any protocol type. Check the Edit Properties box. When the edit properties come up, un-check "mirrored". Finish. Now there should be one filter in the OutboundIPsec list. Select Close. Add a second filter list and name it InboundIPsec, repeating the steps above. This time, add a filter with Any IP Address as the source and My IP Address as the destination addresses. Be careful here. There should be two new IP filter Lists, each List with 1 rule, not one filter List with two in/out rules. Make sure filters are not "mirrored." Close everything until you get back to the Console1 view. Now to use the filters we've created in the policy: - Double click on the wifi policy. - Click Add to add new IP Security Rules. - Select "The tunnel endpoint is specified" radio button and enter in the gateway (ex, 192.168.2.1). Click Next. - Select Local area network (LAN). Click Next. - Select "Use this string to protect the key exchange", and enter the pre-shared-key passphrase from racoon setup above. Click Next. - Select "OutboundIPsec" IP filter list you just created. Click Next. - Select Require Security. Click Next. - Un select edit properties. Click Next. Repeat the above and enter the host (ex, 192.168.2.10) in the third step, and "InboundIPsec" IP filter list in step 6. Everything else is the same. Now that's everything. I'll summarize what you should see here (applies to both 2000 and XP). - "Console root" has a branch called "IP Sec Policies on Local Machine". - IP Sec Polocies should have many folders, one of which is named "wifi". - Double clicking on "wifi" brings up its properties. It should have two Rules, both of them checked, and with the following properties (which can be seen by scrolling right): Property InboundIPsec OutboundIPsec ------------------------------------------------------------ Filter Action Require Security Require Security Authentication Preshared Key Preshared Key Tunnel Setting 192.168.2.10 192.168.2.1 Connection Type LAN LAN Save the Console by selecting Console->Save As... menu. Name it Wifi console. 5. Testing it out ----------------- First, make sure the gateway is ready. Run 'setkey -f /etc/ipsec.conf' and have racoon running in the foreground in verbose mode ('racoon -F -v'). On the Windows machine, make sure the wifi-card can see your wifi LAN and have good signal strength. Have the wifi console you created open. Make sure the "wifi" policy is Unassigned. Also have the services list open by right clicking "My Computer" on the desktop, select Manage, and select "Services and Applications" -> "Services". It should give a list of all the services running on the machine. Have the IPSEC policy agent selected (In XP, the name is slightly different). Also, have a command prompt open. (Note: Windows 2000 has a utility called ipsecmon which can be run from the command prompt. In WinXP this utility exists as a snap-in which I mentioned above.) Ping the gateway from the prompt: "ping -t 192.168.2.1". You should be able to ping the gateway at this point. Go to the Wifi console, right click on the "wifi" policy, and select "Assign". Go to the Computer Management window and right click on IPsec Policy Agent and select "restart". At this point, you should see lots of debugging messages from racoon as the host tries to negotiate keys. The ping command in the Windows machine should show "Negotiating IPSEC" for a few seconds, after which pings should be returning normally. When ping command becomes normal, run tcpdump on the gateway to see if the packets are really encrypted by running 'tcpdump -i ep0' or 'tcpdump -i ep0 -x -X -s 14400' for more detail. Replace ep0 with your wifi interface, of course. Fire up your browser and see that all the packets visible on the wifi interface are between the gateway and host, and the contents are encrypted. 6. Some Known Issues -------------------- - After setting up everything, the ping and tracert work fine, ping packets appear encrypted under tcpdump, but no sites are reachable. Disable the built-in "IP Firewall" in the TCP/IP setting for the wifi interface. The help files say it interferes with VPN tunnels. - The ping command returns "Negotiating IPsec" for several seconds then "Request timed out." Keep pinging with the -t flag, meanwhile, restart the IPsec Policy manager service. I'm not sure what causes this, but it could take anywhere from a few seconds to few minutes before the ping command starts to work. - When the connection is idle for a while (minutes), connectivity is lost. When an IPsec tunnel is idle for a while, it is closed. And it could take several seconds to reconnect (see above). I don't know of a way to force the tunnel to stay open except by keep sending messages through it. I do this by having an ssh session open, or having a web page that reloads frequently. Any other workarounds (especially at the gateway end) would be welcome. - The instructions do not work. I am running FreeBSD 5.2.1 There are some bugs introduced into IPSEC between 5.1 and 5.2, and even the latest patches did not fix the problem. One problem was that the kernel will force "require" on key-exchange packets on port 500, when these packets should be allowed in the clear. And strangely enough, the kernel allows incoming k-e packets, but not out going k-e packets, thus breaking key negotiation. Until IPSEC is properly fixed, I'm using a workaround where I substitute "use" instead of "require" in the ipsec.conf file. This should be ok as long as the Windows machine has "Require Security" properly set-up. I will update this entry when IPSEC is fixed. 7. Conclusion ------------- At this point you should have a secure Wifi connection between your laptop and your gateway. Anyone sniffing the access point should only see packets going to and from the host and the gateway in encrypted form. I hope this document was helpful for you. Any suggestions, corrections, and tweaks are more than welcome. (C) Timothy Ham 2004 Redistribution of this text is permitted as long as the copyright is retained. End of File