= Using [http://www.puppetlabs.com/puppet/ Puppet] for certificate management = If you're using Puppet for configuration management, you've already set up a certificate authority and generated certificates for your managed hosts. Why not use these certificates for OpenVPN host authentication as well? Thanks to a [https://groups.google.com/group/puppet-users/browse_thread/thread/9176ee3bbee27547/5928f331d94e58bd helpful jumpstart] from Ben in the puppet-users Google Group, this was quite straighforward to accomplish. I'm using Puppet 2.6.4 on a RHEL6 server and Puppet 0.25.5 on RHEL5 clients, all with OpenVPN 2.1.4. My Puppet 0.25.5 packages come from [http://fedoraproject.org/wiki/EPEL EPEL], and all the others come from [http://rpmrepo.net/RPMforge RPMforge]. It should go without saying that before you start this procedure, you need to be sure that your client is registered with the Puppet master and successfully communicating. :) Enter the following directives in your server's config: {{{ #!rst ca /var/lib/puppet/ssl/certs/ca.pem cert /var/lib/puppet/ssl/certs/.pem key /var/lib/puppet/ssl/private_keys/.pem }}} Make sure that any {{{tls-auth}}} directive is commented out: {{{ #!rst ;tls-auth ta.key 0 # This file is secret }}} Generate the Diffie-Hellman parameter file (the Puppet CA generates 1024-bit keys): {{{ #!sh # openssl dhparam -out dh1024.pem 1024 }}} At this point you should be able to start the OpenVPN service on your server. Now, enter the following directives in your client's config: {{{ #!rst remote 1194 ca /var/lib/puppet/ssl/certs/ca.pem cert /var/lib/puppet/ssl/certs/.pem key /var/lib/puppet/ssl/private_keys/.pem }}} Make sure that any {{{tls-auth}}} directive is commented out: {{{ #!rst ;tls-auth ta.key 0 # This file is secret }}} Make sure that any {{{ns-cert-type}}} directive is commented out (the Puppet CA doesn't set any {{{nsCertType}}} property at all): {{{ #!rst ;ns-cert-type server }}} You're all set to start the OpenVPN service on your client. Hooray! {{{ ... Feb 9 13:11:09 client openvpn[29492]: TUN/TAP device tun0 opened Feb 9 13:11:09 client openvpn[29492]: TUN/TAP TX queue length set to 100 Feb 9 13:11:09 client openvpn[29492]: /sbin/ip link set dev tun0 up mtu 1500 Feb 9 13:11:09 client openvpn[29492]: /sbin/ip addr add dev tun0 local 10.8.0.6 peer 10.8.0.5 Feb 9 13:11:09 client openvpn[29492]: /sbin/ip route add 10.8.0.1/32 via 10.8.0.5 Feb 9 13:11:09 client openvpn[29492]: GID set to nobody Feb 9 13:11:09 client openvpn[29492]: UID set to nobody Feb 9 13:11:09 client openvpn[29492]: Initialization Sequence Completed [root@client ~]# ping 10.8.0.1 PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data. 64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=24.2 ms 64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=25.2 ms 64 bytes from 10.8.0.1: icmp_seq=3 ttl=64 time=30.8 ms --- 10.8.0.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 24.272/26.790/30.852/2.902 ms }}} == Further development == This procedure could be improved in a number of ways. Here are a few logical next steps: Use Puppet to automate the OpenVPN configuration! There are a few OpenVPN modules out on the web; I haven't yet tested out any of them. Use Puppet to distribute a TLS key so that you can enable {{{tls-auth}}}. Modify the Puppet CA's behavior so that it adds a {{{nsCertType}}} property to the server certificates, so that you can enable {{{ns-cert-type}}}.