Tips and Tricks for Linux Admins: OpenVPN & PKI
Managing your own OpenSSL-based Public Key Infrastructure (PKI) is a great way to centralize control of encryption keys and certificates, and to add substantial security to any service that supports using SSL. The sticky part is creating your Certificate Authority and certificates in the first place, because the OpenSSL commands are complex and confusing, so it's easy to make mistakes. Well goshdarnit, you say, why hasn't someone devised an easier way? I'm so glad you asked, because someone has. In fact there are two easier ways.
The fine maintainers of OpenVPN have created a set of scripts for setting up and managing your PKI. With these scripts you can easily create your own Certificate Authority, server key pairs, and multiple client key pairs. This is a great time-saver- you can roll out your certificates quickly, and you get the benefit of the Certificate Revocation List (CRL), which lets you easily cancel certificates. They are especially nice for peer authentication, because you have to create individual client certificates. Peer authentication is very strong security, and a must for those situations where you want to keep out untrusted clients and authenticate only trusted clients, such as with OpenVPN tunnels and FreeRADIUS clients.
A Vital VPN Tangent
Permit me a brief detour here, if you please. The world is cram-full of commercial VPN (Virtual Private Networks) gateways that are not really VPNs at all, but merely (usually expensive) SSL portals. This is not a silly little typo, or a small difference of opinion in terminology, but a big fat fib. A VPN is a secure encrypted tunnel over untrusted networks between two endpoints. Both endpoints must authenticate to each other. Any and all network traffic, unless otherwise restricted by you, the ace network admin, flows through this "tunnel." It's like having a dedicated Ethernet cable between your LAN and a remote client.
So a real VPN is not a prettified Web page that allows untrusted clients to log into specific services. Don't trust your network security to prettified Web pages. Read Charlie Hosner's classic paper OpenVPN and the SSL VPN Revolution to get some excellent background on the subject.
Now, getting back to our main subject, which is easing the task of managing your own PKI- creating your own Certificate Authority means you'll be using self-signed certificates. This is a common practice for non-commercial Web sites and mail servers. You've probably seen messages like "this certificate is self-signed and thus may not be trustworthy" pop up on Web sites, or on your own mail host. Using self-signed certificates makes sense when you're not authenticating to random strangers on an online shopping site, for one example- you don't need to pay a third-party Certificate Authority like Thawte or Verisign for your own private use.
The nice OpenVPN people have posted these scripts online, plus good instructions. The scripts are simple and easy to modify. You might want a different expiration period than the default of 3650 days, or use different names for your keys and certificates. They've done an especially nice job with the scripts for creating client certificates; build-key-pass creates a password-protected key, build-key-pkcs12 creates a Windows client key, and build-key generates a client key with no password.
Graphical PKI Manager
As lovely as these scripts are, some folks like nice graphical tools. TinyCA is a great little frontend to OpenSSL. You need to know the basic steps and types of certificates you need, but TinyCA makes it all pretty darned easy. It comes with most Linux distributions, so it should be just an aptitude-install or yum install away.
Linux Routing With Ease and Panaché
Now for some real fun stuff: building your own little routing test lab in five minutes. Linux comes with some powerhouse routing abilities; in fact you can save money and have more power and control with Linux on x86 hardware, instead of going into hock the rest of your life with expensive snooty brand-name commercial gear.
While all system and network administrators should understand routing fundamentals, in practice it's unlikely you'll ever do more than manage static routes. (Unless you work for an ISP, and if that's the case you're going to need some serious routing mojo.) With three or four little old PCs that nobody wants, a switch or two, and a couple of crossover cables you can build a good networking test lab.
Suppose you want to simulate a border router or firewall. You could connect four PCs like this:
host1/192.168.1.10 -> |switch ->192.168.1.12/host3/10.0.0.1 -> host4/172.16.0.10
host2/192.168.1.11 -> | LAN WAN
LAN hosts interface interface Internet
These have addresses from the three private ranges to make it easier to keep track. We'll assign their IP addresses from the command line, using the good old ifconfig command to do it:
root@host1:~# ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up
root@host2:~# ifconfig eth0 192.168.1.11 netmask 255.255.255.0 up
root@host3:~# ifconfig eth0 192.168.1.12 netmask 255.255.255.0 up
root@host3:~# ifconfig eth0 10.0.0.1 netmask 255.255.255.0 up
root@host4:~# ifconfig eth0 172.16.0.10 netmask 255.255.255.0 up
Now turn on IP forwarding on Host3:
root@host3:~# echo 1 > /proc/sys/net/ipv4/ip_forward
And now you're ready to start setting up routes. There may be some already in place, which you can see with the route command:
Destination Gateway Genmask Flags Metric Ref Use Iface
172.16.0.0 * 255.255.255.0 U 0 0 0 eth1
192.168.1.0 * 255.255.255.0 U 0 0 0 eth0
default 192.168.1.50 0.0.0.0 UG 0 0 0 eth0
Delete the default routes first on every PC:
root@host3:~$ route del default
These commands create a route between Host4, the "Internet" PC, and Host3, the router:
root@host4:~# route add -net 10.0.0.0/24 gw 172.16.0.10 eth0
root@host3:~# route add -net 172.16.0.0/24 gw 10.0.0.1 eth1
You don't need to add routes between hosts on the same subnet. But you do need to set the default gateway for the LAN hosts:
root@host1:~# route add default gw 192.168.1.12
root@host2:~# route add default gw 192.168.1.12
Now you should be able to ping everybody from everybody. Try running traceroute; it's rather fun to see 1- and 2-hop traces, and it will confirm that your routes are working as you expect.
Routes can be deleted just as easily:
root@host3:~$ route del -net 172.16.0.10/24
The -net option creates a route to another network. You may also create routes to single hosts, like this:
root@host3:~# route add -host 172.16.0.10 gw 10.0.0.1 eth1
Which are deleted like this:
root@host3:~# route del -host 172.16.0.10
This particular setup is a great way to test iptables rules, rather than doing "live fire" over the Internet, and with this little four-node network you test just about any client/server applications.