VPNMaker takes the teetering jankiness out of setting up and administering OpenVPN VPNs.
To set up your VPN, run:
irb -r vpnmaker >> VPNMaker.generate('foocorp', '/root')
Which will place foocorp.vpn
in /root
. All of the files that OpenVPN needs will be placed in /root/foocorp.vpn/foocorp_data
.
Next, you should create foocorp.config.yaml
in /root/foocorp.vpn
. It should look something like this:
:key_properties: :country: US :province: CA :city: San Francisco :organization: FooCorp Inc :email: security@foocorp.com
The values in foocorp.config.yaml
will be used to generate keys and OpenVPN configuration files.
Administration tasks are carried out with VPNMaker::Manager
.
Creating the Certificate Authority is the first order of business. You’ll want to keep its keys safe from both intruders and data loss.
>> mgr = VPNMaker::Manager.new('/root/foocorp.vpn') >> mgr.build_ca
Behind the scenes, this will create ca.crt
, ca.key
, crl.pem
, dh.pem
, index.txt
and serial
in the foocorp_data
directory. Respectively these are: the public certificate for the CA that every user should get; the private key for signing other certs that should be kept safe; a certificate revocation file you’ll need to revoke signed certificates (e.g. after a laptop is compromised); an encryption key for the server side of the VPN connection; a file for OpenSSL to track key state that you should never need to touch; and another file that OpenSSL uses for tracking key IDs that you shouldn’t have to worry about.
Now that we have a Certificate Authority, we should create a server certificate:
>> mgr.build_server
This creates server.key
and server.crt
in the foocorp_data
directory, both of which are for distribution only to the VPN server. It also creates dh.key
and ta.key
. The first of these is a key for creating TLS connections on the server; the second is a key shared between both the server and clients that provides some additional security. (See the tls-auth section at openvpn.net/index.php/open-source/documentation/howto.html for more details.)
Next, we can create our first user:
>> mgr.create_user('joe', 'Joe Bloggs', 'joe.bloggs@foocorp.com', 'password') >> mgr.users => ['joe'] >> mgr.user('joe') => {:user=>"joe", :revoked=>[], :email=>"joe.bloggs@foocorp.com", :name=>"Joe Bloggs", :modified=>Mon Oct 11 10:42:44 -0700 2010, :active_key=>0}
The most important thing to note here is that Joe Bloggs has no revoked keys, and that his active key is version 0. We can go ahead and give joe-0.key
and joe-0.crt
to Joe. (They’ll be in the foocorp_data
directory.)
Now say Joe loses his laptop. We need to both disable his old key and give him a new one:
>> mgr.regenerate_user('joe', 'newpassword')
This will create new keys for Joe, and update the server’s crl.pem
revocation file. If we check the database, we see that his active_key
is now 1
, while 0
has been added to the list of revoked keys:
>> mgr.user('joe') => {:user=>"joe", :revoked=>[0], :email=>"joe.bloggs@foocorp.com", :name=>"Joe Bloggs", :modified=>Mon Oct 11 10:42:44 -0700 2010, :active_key=>1}
We should now go ahead and distribute joe-1.key
and joe-1.crt
to Joe, as well as make sure our OpenVPN servers get the latest version of the crl.pem
revocation file.
When Joe leaves the company, we can do:
>> mgr.delete_user('joe') >> mgr.user('joe') => {:user=>"joe", :revoked=>[0, 1], :email=>"joe.bloggs@foocorp.com", :name=>"Joe Bloggs", :modified=>Mon Oct 11 11:32:10 -0700 2010, :active_key=>1}
Which does the same revocation as in regenerate_user
, but doesn’t generate new keys.
To get OpenVPN set up, you should go back and edit foocorp.config.yaml
, and add the following section:
:server: :base_ip: 10.10.10.0 :user: nouser :group: nogroup :root: /root/openvpn :log: /var/log/openvpn.log :host: foocorp.com :port: 1194
You may want to modify some of the values. Then, head back to irb, and do something like:
>> puts mgr.config_generator.server
Which will output a config file that you can copy and paste into openvpn.conf
on your server. You’ll want make sure that the following files exist in /root/openvpn
(or whatever your root directory is): ca.crt
(so that the server can verify the validity of client certificates), dh.pem
(for encryption of the connection), server.crt
(the server’s public key), server.key
(the server’s private key), ta.key
(shared secret between server and clients), and crl.pem
(so that the server will reject revoked certificates).
Each client will need: user.key
, user.crt
, ca.crt
and ta.key
. Make sure to enable tls-auth = 1.