On a number of recent occasions, I have needed to quickly configure and deploy OpenVPN. These situations have included simulated attacks, in which the opportunity to deploy OpenVPN as an egress or C2 channel presented itself, or during reconnaissance activities in which it is advantageous to disguise your real IP address for attribution purposes. In these cases, it is desirable to be able to rapidly deploy OpenVPN without compromising on security, and where the situation may not warrant or benefit from the overheads of constructing a full PKI. OpenVPN itself is a very simple tool to configure; the more convoluted part is the generation of digital certificates which is made relatively straightforward through the easy-rsa set of scripts. However, I was in need of a quick way to configure OpenVPN as below:
I therefore chose to repurpose my Certerator code to build a quick OpenVPN configuration and certificate generator. Where possible, it uses pyOpenSSL (python's OpenSSL bindings). When run, it performs the following actions:
If a second signed certificate was desired, you need only change the hardcoded CN (if appropriate), remove client_cert.pem and client_key.pem and re-run the script. It will pick up the fact that those certificates are missing and generate new ones. One benefit of this is that it (mostly) does not use the OpenSSL command line interface directly, meaning that there is no need to set up the OpenSSL file structure that is usually necessary. It does use the OpenSSL binary to generate DH params and uses OpenVPN to generate the HMAC key (ta.key), but everything else is generated through python.
$ ./generate.py .mMMMMMm. MMm M WW W WW RRRRR mMMMMMMMMMMM. MM MM W W W R R /MMMM- -MM. MM MM W W W R R /MMM. _ \/ ^ M M M M W W W W RRRR |M. aRRr /W| M M M M W W W W R R \/ .. ^^^ wWWW| M M M W W R R /WW\. .wWWWW/ M M M W W R R |WWWWWWWWWWW/ .WWWWWW. Server/Client Cert Generator (for OpenVPN) email@example.com | @ukstufus Generating new Server CA.....done Written PEM CA certificate to server_ca.pem Written PEM CA key to server_ca.key Server Fingerprint: CB:3E:D9:CF:AF:AC:FF:D0:03:DA:D9:75:29:22:8A:7E:93:21:66:6F Generating new Client CA.....done Written PEM CA certificate to client_ca.pem Written PEM CA key to client_ca.key Client Fingerprint: 3B:8A:09:BF:E1:95:43:C3:79:77:BE:8A:8F:E2:72:90:43:5D:0C:A2 Generating new server certificate.....done Written PEM certificate to server_cert.pem Written private key to server_cert.key SHA1 server Cert Fingerprint: 1F:6B:73:73:18:F5:06:95:3D:62:AD:A4:8F:38:68:58:02:97:02:60 Generating new client certificate.....done Written PEM certificate to client_cert.pem Written private key to client_cert.key SHA1 client Cert Fingerprint: 9C:5B:99:4A:30:60:0B:95:1F:3E:A4:8A:96:4E:96:F2:8F:C3:D1:B4 Generating new HMAC key... Reusing dh4096.pem On the OpenVPN Server: ca client_ca.pem cert server_cert.pem key server_cert.key On the OpenVPN Client: ca server_ca.pem cert client_cert.pem key client_cert.key Example configs written to example.server.conf and example.client.conf Server configuration and related files are in example.server.tar.gz Client configuration and related files are in example.client.tar.gz
Transfer example.server.tar.gz to the server machine:
[stufus@server ~/openvpn]$ tar zxvf example.server.tar.gz x client_ca.pem x ta.key x dh4096.pem x server_cert.pem x server_cert.key x example.server.conf [stufus@server ~/openvpn]$ cat example.server.conf port 1194 proto udp dev tun ca client_ca.pem cert server_cert.pem key server_cert.key dh dh4096.pem server 10.255.255.0 255.255.255.0 topology net30 ifconfig-pool-persist ipp.txt push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 184.108.40.206" push "dhcp-option DNS 220.127.116.11" keepalive 10 120 tls-auth ta.key 0 cipher AES-128-CBC comp-lzo persist-key persist-tun #user openvpn #group openvpn status openvpn-status.log
Transfer example.client.tar.gz to the client machine:
[stufus@client ~/openvpn]$ tar zxvf example.client.tar.gz x server_ca.pem x ta.key x client_cert.pem x client_cert.key x example.client.conf [stufus@client ~/openvpn]$ cat example.client.conf client dev tun proto udp remote SERVER 1194 resolv-retry infinite nobind #user openvpn #group openvpn persist-key persist-tun ca server_ca.pem cert client_cert.pem key client_cert.key remote-cert-tls server tls-auth ta.key 1 cipher AES-128-CBC comp-lzo #For HTTP proxy uncomment the below #http-proxy-retry #http-proxy HTTPPROXYSERVER HTTPPROXYPORT #http-proxy-option AGENT Mozilla/5.0+(Windows;+U;+Windows+NT+5.0;+en-GB;+rv:1.7.6)+Gecko/20050226+Firefox/1.0.1 #or create a 2 line text file, username on first line, pass on second, call it userpass.txt #http-proxy HTTPPROXYSERVER HTTPPROXYPORT userpass.txt_file basic #http-proxy HTTPPROXYSERVER HTTPPROXYPORT userpass.txt_file ntlm #socks-proxy SERVER PORT
Now start the server, update the client config file with the server IP address and connect to the server. Either edit the file using vi/pico/nano/ee etc or update it inline:
[stufus@client ~/openvpn]$ sed -I "" 's/SERVER/192.168.0.100/' example.client.conf [stufus@client ~/openvpn]$ sudo openvpn example.client.conf Tue Apr 19 14:24:09 2016 OpenVPN 2.3.10 amd64-portbld-freebsd10.2 [SSL (OpenSSL)] [LZO] [MH] [IPv6] built on Feb 2 2016 Tue Apr 19 14:24:09 2016 library versions: OpenSSL 1.0.2g 1 Mar 2016, LZO 2.09 Tue Apr 19 14:24:09 2016 Control Channel Authentication: using 'ta.key' as a OpenVPN static key file Tue Apr 19 14:24:09 2016 UDPv4 link local: [undef] Tue Apr 19 14:24:09 2016 UDPv4 link remote: [AF_INET]192.168.0.100:1194 Tue Apr 19 14:24:09 2016 [Server Cert] Peer Connection Initiated with [AF_INET]192.168.0.100:1194 Tue Apr 19 14:24:11 2016 TUN/TAP device /dev/tun1 opened Tue Apr 19 14:24:11 2016 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0 Tue Apr 19 14:24:11 2016 /sbin/ifconfig tun1 10.255.255.6 10.255.255.5 mtu 1500 netmask 255.255.255.255 up ...snip...
If a second signed client certificate is required, the first need only be removed and a new one generated:
[stufus@client ~/openvpn]$ rm client_cert.pem && rm client_cert.key [stufus@client ~/openvpn]$ ./generate.py ...snip... Reusing server_ca.pem as the Server Server Fingerprint: CB:3E:D9:CF:AF:AC:FF:D0:03:DA:D9:75:29:22:8A:7E:93:21:66:6F Reusing client_ca.pem as the Client Client Fingerprint: 3B:8A:09:BF:E1:95:43:C3:79:77:BE:8A:8F:E2:72:90:43:5D:0C:A2 Reusing server_cert.pem as the server certificate SHA1 server Cert Fingerprint: 1F:6B:73:73:18:F5:06:95:3D:62:AD:A4:8F:38:68:58:02:97:02:60 Generating new client certificate.....done Written PEM certificate to client_cert.pem Written private key to client_cert.key SHA1 client Cert Fingerprint: DB:70:46:52:AE:9B:99:1C:37:55:58:3F:F6:B6:3A:81:5F:13:A4:5D Reusing ta.key Reusing dh4096.pem ...snip...
However the two client certificates would have the same serial number and same CN field; for most practical purposes, it would be sensible to change the serial number and CN manually, which requires modification of the script.
Like so many tools, this started as a quick-and-dirty tool to automate an otherwise tedious task.
I am not planning to add a configuration file, revocation support (e.g. CRL) or any of the other niceties to this because tools such as OpenSSL itself, easy-rsa, tinyCA etc have been specifically designed for this purpose. This project was simply to meet a need, namely to be able to go from nothing to a secure, functioning OpenVPN installation with a minimum of configuration or effort. Although this is built for OpenVPN, the certificates are valid, normal digital certificates and could be used for any mutual TLS authentication scenario. For example, it could be used to generate the required certificates for Apache, nginx etc to facilitate client certificate authentication. The fact that this project is open source will not make any meaningful difference to the cryptographic security because the keys are all generated locally.
The tool can be found at https://github.com/stufus/openvpn-rapid-config. Alternatively the repository can be cloned as follows:
git clone https://github.com/stufus/openvpn-rapid-config.git