most of the code was stolen from here:, thank you! i made a gem, converted it to use haml, added bin/vpnmaker cli


VPNMaker takes the teetering jankiness out of setting up and administering OpenVPN.

It comes without any guarantees, the code seems to work for me, your mileage will invariably vary!


  • vpnmaker -h is your best friend

help format sucks, but it’s better then using easy-rsa or doing openssl by hand


>>#vpnmaker init cli conf_name new_dir_path country province city organization organization_unit common_name key_name email

From the forked version:

Key management

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:

  :country: US
  :province: CA
  :city: San Francisco
  :organization: FooCorp Inc
  :email: [email protected]

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 ='/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 for more details.)

Next, we can create our first user:

>> mgr.create_user('joe', 'Joe Bloggs', '[email protected]', 'password')
>> mgr.users
=> ['joe']
>> mgr.user('joe')
=> {:user=>"joe", :revoked=>[], :email=>"[email protected]", :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=>"[email protected]", :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=>"[email protected]", :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.

OpenVPN management

To get OpenVPN set up, you should go back and edit foocorp.config.yaml, and add the following section:

  :user: nouser
  :group: nogroup
  :root: /root/openvpn
  :log: /var/log/openvpn.log
  :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).

OpenVPN client

Each client will need: user.key, user.crt, ca.crt and ta.key. Make sure to enable tls-auth = 1.