Long pretentious blog titles are apparently my new thing.

One big problem I have had in trying to use cloud infrastructure for Real World Applications is that a huge percentage of those apps (or their protocols) don't communicate securely. For example, I just set up an SMB share (Windows fileshare) on the internet the other day. WHA?? Yeah it's possible, and guess what? SMB is about as encrypted as FTP, which is to say "basically not at all." So if you really need SMB between servers, and you're in the cloud (or anywhere else where you give a rat's ass about security, really, come on people) you're gonna need to wrap some encryption around that protocol. Ideally you won't have to deal with PPTP or buy a bunch of Cisco gear either. Enter IPsec.

IPsec is a feature of most networking stacks that lets your OS encrypt its traffic based on a ruleset. It's kinda like a firewall, but you'll mostly use it when dealing with this exact type of problem: how to communicate securely when using insecure protocols, hence the eponymous IPsec Tunnel. It's got a good buddy IKE which handles the key exchange part of the tunnel, and all of that is wrapped in a key management package called ISAKMP. When you're talking VPN tunnels, this trio can almost be referred to interchangeably, as distinct from PPTP, L2TP, SSL, and other types of tunnels.

So, how do you get an IPsec tunnel working between two boxes, especially virtual boxes, especially when one is Windows and the other is Linux? Apparently the Internet sucks at this part and I banged my head against it for about a week. Some resources I referenced are:

The Ubuntu IPsec HowTo: https://help.ubuntu.com/community/IPSecHowTo

A Microsoft study about Linux-Windows IPsec tunneling which ironically includes detailed instructions for Linux but no instructions for Windows: http://blogs.technet.com/b/port25/archive/2007/05/09/windows-vista-beta-linux-ipsec-interop-testing.aspx

The TechNet article on configuring an IPsec VPN which was next to useless but still appreciated: http://support.microsoft.com/kb/816514

A Cisco article about configuring IPsec in Windows with nice instructions: http://www.cisco.com/en/US/tech/tk583/tk372/technologies_configuration_example09186a00800b12b5.shtml

A Symantec article about using IPsec in Windows 2000 (there's a snapin called IP Security Monitor that is really nifty, plus they explain stuff in English) http://www.symantec.com/connect/articles/using-ipsec-windows-2000-and-xp-part-2

The setkey and racoon.conf linux man pages.

Put that all together, toss in a grizzled network admin, and shake for a few straight days and you'll get:

/etc/ipsec-tools.conf (aka syskey.conf)

# Replace 10.1.1.1 with this computer's IP

and 10.2.2.2 with the remote computer's IP

spdadd 10.1.1.1 10.2.2.2 any -P out ipsec esp/transport//require;

spdadd 10.2.2.2 10.1.1.1 any -P in ipsec esp/transport//require;

/etc/racoon/psk.txt

10.2.2.2 MakeYourOwnPresharedKeyDon'tUseThisOne

/etc/racoon/racoon.conf

path pre_shared_key "/etc/racoon/psk.txt"; path certificate "/etc/racoon/certs";

remote anonymous { exchange_mode main; proposal { encryption_algorithm 3des; hash_algorithm sha1; authentication_method pre_shared_key; dh_group 14; } }

sainfo anonymous { encryption_algorithm 3des; authentication_algorithm hmac_sha1; compression_algorithm deflate; }

That's all you need for Linux (after installing ipsec-tools and racoon of course.) Just type the following commands to flush and apply changes:

setkey -F
setkey -f /etc/ipsec-tools.conf

A command to get racoon running in verbose mode with a log (note: verbose is VERBOSE. Take -v out after testing.)

racoon -f /etc/racoon/racoon.conf -v -ddd -l /etc/racoon/racoon.log

And then you can watch the status with any/all of the following:

setkey -D
setkey -DP
watch tail /etc/racoon/racoon.log
cat /etc/racoon/racoon.log | grep ERROR

Now on to Windows! Don't you wish I could just give you config files? Too bad!

Create a new IP Security policy. Control Panel, Administrative Tools, Local Security Policy, IP Security Policies on Local Computer, Action, Create IP Security Policy.

Name it something like Localhostname - Remotehostname so you'll remember what this tunnel is for. If you've come this far thinking that you'll get away with one rule for all the computers on your network, sorry that's not what this guide is about but I'm sure IPsec can help you somehow. We're creating Host-to-Host tunnels here.

Don't activate the default response rule. Edit properties.

Click the General tab of the policy. Click Settings and then Methods. Edit the security method to be a Diffie-Hellman Group of High (2048). Click OK back to the policy, go to the Rules tab. Add a rule. This rule does not specify a tunnel (it specifies a transport, see the transport lines in ipsec-tools.conf above. Yeah that was 3 hours of debugging.)

Add a new filter list, name it "To 10.2.2.2". Replace 10.2.2.2 with the remote IP. Click the Add button. Uncheck Mirrored. For the "to" rule, make the source any and the destination the specific IP address of 10.2.2.2 . Protocol is Any. Click OK until you're back to the Security Rule Wizard. Ensure "To 10.2.2.2" is checked and click Next. (This relates to the spdadd lines above.)

Add a new filter action, name it 3DES - SHA1 - Negotiate. Choose Negotiate Security. Choose Integrity and Encryption. (This relates to the AH and ESP lines above.) Click OK a few times, on the Security Rule Wizard ensure your new action is selected, click Next.

Choose the authentication method of "Use this string to protect the key exchange (preshared key.)" This is the part that really makes this Host-to-Host: you've gotta stick the PSK in beforehand on every computer. Maybe you can get creative with Kerberos or certificates to make this scale better. Type in the same really long and complex string you used in /etc/racoon/psk.txt in this text box. If it doesn't match exactly (minus the IP address, of course) you're gonna hate your life. Click Next. You're almost done!

Right-click the new policy and click Assign. It should now be active. Check your status by opening Microsoft Management Console (Start, Run, mmc) and File, Add/Remove Snapin. Add the IP Security Monitor. Check that the Active Policy looks nice and peek under Main Mode, Security Associations to see if your tunnel is running.

Now for the big test! Get Wireshark and start sniffing traffic (on the 10.2.2.2 or 10.1.1.1 interface, of course, not your wifi card or whatever.) Ping something close but slightly off like 10.2.2.1 or 10.1.1.2 to make sure you can see pings going to the same network. Then ping 10.1.1.1 or 10.2.2.2 (the other computer) to see if they're encrypted this time. If you've done everything right, you should see some ISAKMP packets going back and forth between 10.1.1.1 and 10.2.2.2. Mine were Identity Protection (Main Mode) followed by a few Quick Mode packets and then ESP packets. Once you see ESP packets, you've probably got it. If you only ever see ISAKMP packets, chances are your settings are off between the two hosts. If you only see packets from one computer, chances are you haven't actually enabled the policy on the other one or there's a firewall (UDP port 500? NAT?) issue. If you see no ISAKMP packets even when trying to ping from both computers, you're probably sniffing the wrong interface or not running Wireshark with enough privileges.

Tada! IPsec between Linux and Windows. Maybe even in the cloud. Rackspace Jesus is smiling upon you.</strong