Painless IPSec setup for a home network.

I have written a script to painlessly set up fully secured encrypted network traffic between systems on a small LAN or home network. Although more specialized than other IPSec solutions such as SWAN or Racoon, it does provide for the common use case of securing otherwise sensitive protocols such as nfs, dns, web based device configuration pages, and samba that are often sent in the clear or with minimal authentication.

Network security has always been something of a pain, different protocols require completely different systems that must be independently learned and implemented. A signed certificate for https, a kerberos server for secure NFS, the woefully uncommon DNSSEC for DNS as well as many protocols that have no easy way to add security other than piggybacking on something such as SSH or stunnel.

IPSec makes all of this a non-issue. All traffic between hosts is encrypted and verified, no matter what the underlying protocol is. The encryption and verification is done in the kernel and is fully transparent to apps. Unfortunately, it also can be a bit complicated to set up in general due to the need for a daemon to handle the public key exchange, However for the common case of secure communications within a LAN between known hosts a lot of the usual complications can go away since you can pre-distribute the keys beforehand resulting in a simpler setup. I have written a script to automate this process.

My script works for situations where all the computers you wish to securely communicate with are on the same LAN. It does not inhibit communication outside the network so implementing it on just some systems such as important servers and clients is just fine. My script generates codes that work out of the box on linux and likely many BSD variants but the same generated keys will work on other systems if you manually translate them. No server infrastructure or new daemons are needed, it is fully point to point and directly sets the keys in the kernels security association tables using portable shell scripts, so running it on resource restricted routers that don’t have space for new programs is not an issue.

tl;dr HOWTO

grab my script from http://repetae.net/repos/createnet/createnet.prl

perl createnet.prl hostname1 hostname2 hostname3 ...

This will create a shell script for each host, named setup_crypto_hostname1, setup_crypto_hostname2, setup_crypto_hostname3 and a hosts_crypto file. Simply run the setup script on the corresponding machine and add the contents of hosts_crypto to your /etc/hosts file and you are done. Each host now has an alias ending in .crypto and whenever that name is used in any protocol the traffic will be fully encrypted and verified.

So for secure nfs, just make your exports file list the hostname.crypto name, for secure dns add the crypto address of your server, to securely access a web admin daemon just use a url like http://foo.crypto/ and it is encrypted. Anywhere you can use a hostname you can use the crypto version and all communication is fully encrypted and verified. Your normal non-encrypted network links are not affected so an error in key setup does not make your system unreachable via normal means. (unless you specifically disable it of course, keeping ssh open over non-encrypted links is quite handy for debugging and establishing the crypto links to begin with)

To have the encrypted network automatically be set up when your network is, copy the setup_crypto file to /etc/network/if-up.d/ as it will also work as a network script.

How it works

A random master key is generated, after the scripts are created the master key is destroyed ensuring there is no way to compromise the entire network. rooting a host will only get you the keys necessary to communicate as that host and no others. (You may stow the master key to allow incremental growth of the network with the -k option, but regenerating all the keys from a fresh master is painless and more secure)

A unique /48 IPv6 network such as fdcc::d63d:fed7::/48 is created via the ULA protocol, I fudge the protocol a little to ensure the network starts with fdcc:: to make it visually obvious which networks are encrypted but you can override this with the -p option.

A unique fdcc:: address is created for each host, From the master key a key is generated for every possible _connection_ between the machines, so for 3 hosts, 12 keys are generated. Then the corresponding keys relevant to a particular host are placed in their setup_crypto file. Since all keys are independent and the setup file only contains keys relevant to communicating with the host, a single host compromise can only compromise traffic from and to that particular host. The hosts_crypto establishes the foo.crypto names and maps them to the generated fdcc:: names. If you have a local DNS server you can add its entries there rather than copy them to individual hosts, such as placing it in the /var/hosts/ directory on an OpenWRT router.

Rules are setup such that all traffic to or from the fdcc::XXXX:YYYY::/48 network must be encrypted or it is discarded, a route is set up such that traffic to/from fdcc:: hosts comes from ones own fdcc:: address. Since the .crypto names all refer to fdcc:: addresses, all communication via them is fully encrypted and authenticated. done and done.

As far as security goes, it is much more secure than simply using something like standard wi-fi encryption, not only have all previous wifi standards been broken but they do not protect against malicious or trojaned devices on the network itself. Since a home network is often shared among things not under your direct control such as set top boxes, phones, and tablets or guest’s laptops. Kerberos can provide a finer granularity of encryption at the per user level, but is really only aplicable to a certain set of protocols. It is more secure than local https in that authentication happens in both directions, not only does the client verify it is talking to the right server, but the server cryptographically verifies it is talking to a valid client which is generally not done in SSL. Not to mention much easier to set up as local https usually requires a self-signed certificate that must be manually imported to browsers/clients.

There are tradeoffs when it comes to public key exchange IPSec, it is much, much easier to set up, but you must generate all the hosts keys beforehand. However, Unlike PKI there is no private key to lose as a single point of failure, the keys are effectively random and unrelated. Since we do not re-key as happens with IKE, we need to ensure we use an encryption algorithm that is safe for long term use of the same key. aes-cbc with aes-xcbc-mac authentication are suitable for this use and chosen by default.

Post a Comment

Your email is never published nor shared. Required fields are marked *