{"id":112,"date":"2020-03-17T00:00:00","date_gmt":"2020-03-17T00:00:00","guid":{"rendered":"http:\/\/ssdnodes.billabailey.com\/2017\/04\/17\/tutorial-installing-openvpn-on-ubuntu-16-04\/"},"modified":"2025-05-15T15:44:29","modified_gmt":"2025-05-15T15:44:29","slug":"tutorial-installing-openvpn-on-ubuntu-16-04","status":"publish","type":"post","link":"https:\/\/www.ssdnodes.com\/blog\/tutorial-installing-openvpn-on-ubuntu-16-04\/","title":{"rendered":"How To Install OpenVPN On Ubuntu 16.04"},"content":{"rendered":"<p><strong>Note:<\/strong> Ubuntu 16.04 is no longer the most up-to-date release, consider installing <a href=\"https:\/\/www.ssdnodes.com\/blog\/install-openvpn-ubuntu-18-04-tutorial\/\">OpenVPN on Ubuntu 18.04<\/a> as this is the latest stable release...<\/p>\n<\/p>\n<p>In March 2017, the U.S. government made significant changes to rules that dictate how ISPs can package and sell data about their customers. In the weeks since, we saw a massive new interest in virtual private networks (VPNs). While a number of paid VPN solutions exist\u2014think of them like shared hosting\u2014the tech media has been directing users toward setting up their own VPNs rather than relying on the security of another company. Of course, we think that's a great option. In this tutorial, we'll walk you through the steps to install <a href=\"https:\/\/github.com\/OpenVPN\/openvpn\" target=\"_blank\" rel=\"noopener\">OpenVPN<\/a> on Ubuntu 16.04 virtual private server (VPS).<\/p>\n<h2>Prerequisites<\/h2>\n<ul>\n<li>A VPS running Ubuntu 16.04<\/li>\n<li>A regular (non-root) account with sudo privileges. See our <a href=\"https:\/\/www.ssdnodes.com\/blog\/tutorial-setting-up-and-securing-ssh-based-authentication\/\">SSH keys tutorial<\/a> for more information.<\/li>\n<\/ul>\n<hr \/>\n<h3 style=\"text-align: left;\"><a style=\"color: #22eaaa;\" href=\"https:\/\/www.ssdnodes.com\/?blog-openvpn\" target=\"_blank\" rel=\"noopener noreferrer\">Run OpenVPN on an SSD VPS for under $8\/month!<\/a><\/h3>\n<h5 style=\"text-align: left;\"><a style=\"color: black; text-decoration: none;\" href=\"https:\/\/www.ssdnodes.com\/?blog-openvpn\" target=\"_blank\" rel=\"noopener noreferrer\">Don't overpay to get the resources you need for your VPN. Intel and SSD backed VPS servers and Tier-1 network connections give you the performance you need, for less.<span style=\"color: blue;\"> Launch your VPN with SSD Nodes<\/span><\/a>!<\/h5>\n<hr \/>\n<h2>Step 1: Install OpenVPN<\/h2>\n<p>Let's start by updating our <code>apt<\/code> cache and installing both <code>openvpn<\/code> and <code>easy-rsa<\/code>, which we'll use to set up certificates.<\/p>\n<pre><code class=\"language-bash hljs\">$ sudo apt-get update\n$ sudo apt-get install openvpn easy-rsa\n<\/code><\/pre>\n<h2>Step 2: Set up the Certificate Authority<\/h2>\n<p>The OpenVPN server uses certificates to encrypt traffic between the server and various clients. Thus, we need to set up a certificate authority (CA) on the VPS to create and manage these certificates.<\/p>\n<p>We can utilize the <code>easy-rsa<\/code> template by copying it to a new directory, and then entering that directory to move into the configuration.<\/p>\n<pre><code class=\"language-bash hljs\">$ make-cadir ~\/openvpn-ca\n$ <span class=\"hljs-built_in\">cd<\/span> ~\/openvpn-ca\n<\/code><\/pre>\n<p>We need to edit some of the variables that help decide how to create the certificates. Use <code>nano<\/code>\u2014or another favorite editor\u2014to open the file. We'll be editing some variables toward the end of the file.<\/p>\n<pre><code class=\"language-bash hljs\">$ nano vars\n<\/code><\/pre>\n<p>Look for the section below\u2014the <code>easy-rsa<\/code> template provides some default fields for these variables, but you should change them according to your needs. Make sure you also change the <code>KEY_NAME<\/code> variable as well. It's not so important <em>what<\/em> you change these to, rather that you don't leave them in the default state, or blank.<\/p>\n<pre><code class=\"hljs bash\"><span class=\"hljs-comment\"># These are the default values for fields<\/span>\n<span class=\"hljs-comment\"># which will be placed in the certificate.<\/span>\n<span class=\"hljs-comment\"># Don't leave any of these fields blank.<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_COUNTRY=<span class=\"hljs-string\">\"US\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_PROVINCE=<span class=\"hljs-string\">\"CA\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_CITY=<span class=\"hljs-string\">\"SanFrancisco\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_ORG=<span class=\"hljs-string\">\"Fort-Funston\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_EMAIL=<span class=\"hljs-string\">\"me@myhost.mydomain\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_OU=<span class=\"hljs-string\">\"MyOrganizationalUnit\"<\/span>\n\n<span class=\"hljs-comment\"># X509 Subject Field<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_NAME=<span class=\"hljs-string\">\"EasyRSA\"<\/span>\n<\/code><\/pre>\n<p>After some tweaks:<\/p>\n<pre><code class=\"hljs bash\"><span class=\"hljs-comment\"># These are the default values for fields<\/span>\n<span class=\"hljs-comment\"># which will be placed in the certificate.<\/span>\n<span class=\"hljs-comment\"># Don't leave any of these fields blank.<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_COUNTRY=<span class=\"hljs-string\">\"US\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_PROVINCE=<span class=\"hljs-string\">\"CA\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_CITY=<span class=\"hljs-string\">\"Tustin\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_ORG=<span class=\"hljs-string\">\"SSD Nodes\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_EMAIL=<span class=\"hljs-string\">\"joel@example.com\"<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_OU=<span class=\"hljs-string\">\"Marketing\"<\/span>\n\n<span class=\"hljs-comment\"># X509 Subject Field<\/span>\n<span class=\"hljs-built_in\">export<\/span> KEY_NAME=<span class=\"hljs-string\">\"vpnserver\"<\/span>\n<\/code><\/pre>\n<p>Now, source the <code>vars<\/code> file you just edited. If there aren't any errors, you'll see the following output.<\/p>\n<pre><code class=\"language-bash hljs\">$ <span class=\"hljs-built_in\">source<\/span> vars\nNOTE: If you run .\/clean-all, I will be doing a rm -rf on \/home\/user\/openvpn-ca\/keys\n<\/code><\/pre>\n<p>Now we can clean up the environment and then build up our CA.<\/p>\n<pre><code class=\"language-bash hljs\">$ .\/clean-all\n$ .\/build-ca\n<\/code><\/pre>\n<p>A new RSA key will be created, and you'll be asked to confirm the details you entered into the <code>vars<\/code> file earlier. Just hit <code>Enter<\/code> to confirm.<\/p>\n<h2>Step 3: Create the server public\/private keys<\/h2>\n<p>Next up, you need to create the server certificate and key pair. When you run the below command you can change <code>[server]<\/code> to the name of your choice. Later, you'll need to reference this name. For the sake of this tutorial, we're choosing with <code>vpnserver<\/code>.<\/p>\n<p><strong>Note: When prompted, do not enter a password.<\/strong><\/p>\n<p>Finally, you'll be asked two questions about signing the certificate and committing it. Hit <code>y<\/code> and then <code>Enter<\/code> for both, and you'll be done.<\/p>\n<pre><code class=\"language-bash hljs\">$ .\/build-key-server [server]\n<\/code><\/pre>\n<p>Next, you need to build Diffie-Hellman keys.<\/p>\n<pre><code class=\"language-bash hljs\">$ .\/build-dh\n<\/code><\/pre>\n<p>Finally, you need to generate an HMAC signature to strengthen the certificate.<\/p>\n<pre><code class=\"language-bash hljs\">$ openvpn --genkey --secret keys\/ta.key\n<\/code><\/pre>\n<h2>Step 4: Create the client public\/private keys<\/h2>\n<p>This process will create a single client key and certificate. If you have multiple users, you'll want to create multiple pairs.<\/p>\n<p>When running the below command, hit <code>Enter<\/code> to confirm the variables we set and then leave the password field blank.<\/p>\n<pre><code class=\"language-bash hljs\">$ <span class=\"hljs-built_in\">source<\/span> vars\n$ .\/build-key client1\n<\/code><\/pre>\n<p>If you want to create password-protected credentials, use <code>build-key-pass<\/code> instead:<\/p>\n<pre><code class=\"language-bash hljs\">$ <span class=\"hljs-built_in\">source<\/span> vars\n$ .\/build-key-pass client1\n<\/code><\/pre>\n<h2>Step 5: Configure the OpenVPN server<\/h2>\n<p>First, you need to copy the keyfiles we created in <code>~\/openvpn-ca<\/code> into the <code>\/etc\/openvpn<\/code> directory. <strong>Note:<\/strong> change the <code>vpnserver.crt<\/code> and <code>vpnserver.key<\/code> files according to the [server] name you chose earlier.<\/p>\n<pre><code class=\"hljs shell\"><span class=\"hljs-meta\">$<\/span><span class=\"bash\"> <span class=\"hljs-built_in\">cd<\/span> ~\/openvpn-ca\/keys<\/span>\n<span class=\"hljs-meta\">$<\/span><span class=\"bash\"> sudo cp ca.crt ca.key vpnserver.crt vpnserver.key ta.key dh2048.pem \/etc\/openvpn<\/span>\n<\/code><\/pre>\n<p>Now, extract a sample OpenVPN configuration to the default location.<\/p>\n<pre><code class=\"language-bash hljs\">$ gunzip -c \/usr\/share\/doc\/openvpn\/examples\/sample-config-files\/server.conf.gz | sudo tee \/etc\/openvpn\/server.conf\n<\/code><\/pre>\n<p>We now need to make some edits to the configuration file.<\/p>\n<pre><code class=\"hljs shell\"><span class=\"hljs-meta\">$<\/span><span class=\"bash\"> sudo nano \/etc\/openvpn\/server.conf<\/span>\n<\/code><\/pre>\n<p>First, let's ensure that OpenVPN is looking for the right <code>.crt<\/code> and <code>.key<\/code> files.<\/p>\n<p><strong>Before:<\/strong><\/p>\n<pre><code class=\"hljs css\"><span class=\"hljs-selector-tag\">ca<\/span> <span class=\"hljs-selector-tag\">ca<\/span><span class=\"hljs-selector-class\">.crt<\/span>\n<span class=\"hljs-selector-tag\">cert<\/span> <span class=\"hljs-selector-tag\">server<\/span><span class=\"hljs-selector-class\">.crt<\/span>\n<span class=\"hljs-selector-tag\">key<\/span> <span class=\"hljs-selector-tag\">server<\/span><span class=\"hljs-selector-class\">.key<\/span>  # <span class=\"hljs-selector-tag\">This<\/span> <span class=\"hljs-selector-tag\">file<\/span> <span class=\"hljs-selector-tag\">should<\/span> <span class=\"hljs-selector-tag\">be<\/span> <span class=\"hljs-selector-tag\">kept<\/span> <span class=\"hljs-selector-tag\">secret<\/span>\n<\/code><\/pre>\n<p><strong>After (change according to the [server] name you chose earlier):<\/strong><\/p>\n<pre><code class=\"hljs css\"><span class=\"hljs-selector-tag\">ca<\/span> <span class=\"hljs-selector-tag\">ca<\/span><span class=\"hljs-selector-class\">.crt<\/span>\n<span class=\"hljs-selector-tag\">cert<\/span> <span class=\"hljs-selector-tag\">vpnserver<\/span><span class=\"hljs-selector-class\">.crt<\/span>\n<span class=\"hljs-selector-tag\">key<\/span> <span class=\"hljs-selector-tag\">vpnserver<\/span><span class=\"hljs-selector-class\">.key<\/span>  # <span class=\"hljs-selector-tag\">This<\/span> <span class=\"hljs-selector-tag\">file<\/span> <span class=\"hljs-selector-tag\">should<\/span> <span class=\"hljs-selector-tag\">be<\/span> <span class=\"hljs-selector-tag\">kept<\/span> <span class=\"hljs-selector-tag\">secret<\/span>\n<\/code><\/pre>\n<p>Next, enforce identical HMAC between clients and the server.<\/p>\n<p><strong>Before:<\/strong><\/p>\n<pre><code class=\"hljs bash\">;tls-auth ta.key 0 <span class=\"hljs-comment\"># This file is secret<\/span>\n<\/code><\/pre>\n<p><strong>After:<\/strong><\/p>\n<pre><code class=\"hljs bash\">tls-auth ta.key 0 <span class=\"hljs-comment\"># This file is secret<\/span>\nkey-direction 0\n<\/code><\/pre>\n<p>Because we are going to use this VPN to route our traffic to the internet, we need to uncomment a few lines&amp;nbsp;to help us establish DNS. You should also remove <code>bypass-dhcp<\/code> from the first line in question.<\/p>\n<p>If you would prefer to use a DNS other than opendns, you should change the two lines that begin with <code>push &quot;dhcp-option<\/code>.<\/p>\n<p><strong>Before:<\/strong><\/p>\n<pre><code class=\"hljs shell\"><span class=\"hljs-meta\">#<\/span><span class=\"bash\"> If enabled, this directive will configure<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> all clients to redirect their default<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> network gateway through the VPN, causing<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> all IP traffic such as web browsing and<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> and DNS lookups to go through the VPN<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> (The OpenVPN server machine may need to NAT<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> or bridge the TUN\/TAP interface to the internet<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> <span class=\"hljs-keyword\">in<\/span> order <span class=\"hljs-keyword\">for<\/span> this to work properly).<\/span>\n;push \"redirect-gateway def1 bypass-dhcp\"\n<span class=\"hljs-meta\">\n#<\/span><span class=\"bash\"> Certain Windows-specific network settings<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> can be pushed to clients, such as DNS<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> or WINS server addresses.  CAVEAT:<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> http:\/\/openvpn.net\/faq.html<span class=\"hljs-comment\">#dhcpcaveats<\/span><\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> The addresses below refer to the public<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> DNS servers provided by opendns.com.<\/span>\n;push \"dhcp-option DNS 208.67.222.222\"\n;push \"dhcp-option DNS 208.67.220.220\"\n<\/code><\/pre>\n<p><strong>After:<\/strong><\/p>\n<pre><code class=\"hljs shell\"><span class=\"hljs-meta\">#<\/span><span class=\"bash\"> If enabled, this directive will configure<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> all clients to redirect their default<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> network gateway through the VPN, causing<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> all IP traffic such as web browsing and<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> and DNS lookups to go through the VPN<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> (The OpenVPN server machine may need to NAT<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> or bridge the TUN\/TAP interface to the internet<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> <span class=\"hljs-keyword\">in<\/span> order <span class=\"hljs-keyword\">for<\/span> this to work properly).<\/span>\npush \"redirect-gateway def1\"\n<span class=\"hljs-meta\">\n#<\/span><span class=\"bash\"> Certain Windows-specific network settings<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> can be pushed to clients, such as DNS<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> or WINS server addresses.  CAVEAT:<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> http:\/\/openvpn.net\/faq.html<span class=\"hljs-comment\">#dhcpcaveats<\/span><\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> The addresses below refer to the public<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> DNS servers provided by opendns.com.<\/span>\npush \"dhcp-option DNS 208.67.222.222\"\npush \"dhcp-option DNS 208.67.220.220\"\n<\/code><\/pre>\n<p>Then we need to select the ciphers to use. Uncomment the <code>AES<\/code> cipher and change it to <code>256<\/code>, and then add <code>auth SHA512<\/code> at the bottom of the block.<\/p>\n<p><strong>Before:<\/strong><\/p>\n<pre><code class=\"hljs bash\"><span class=\"hljs-comment\"># Select a cryptographic cipher.<\/span>\n<span class=\"hljs-comment\"># This config item must be copied to<\/span>\n<span class=\"hljs-comment\"># the client config file as well.<\/span>\n;cipher BF-CBC        <span class=\"hljs-comment\"># Blowfish (default)<\/span>\n;cipher AES-128-CBC   <span class=\"hljs-comment\"># AES<\/span>\n;cipher DES-EDE3-CBC  <span class=\"hljs-comment\"># Triple-DES<\/span>\n<\/code><\/pre>\n<p><strong>After:<\/strong><\/p>\n<pre><code class=\"hljs bash\"><span class=\"hljs-comment\"># Select a cryptographic cipher.<\/span>\n<span class=\"hljs-comment\"># This config item must be copied to<\/span>\n<span class=\"hljs-comment\"># the client config file as well.<\/span>\n;cipher BF-CBC        <span class=\"hljs-comment\"># Blowfish (default)<\/span>\ncipher AES-256-CBC   <span class=\"hljs-comment\"># AES<\/span>\n;cipher DES-EDE3-CBC  <span class=\"hljs-comment\"># Triple-DES<\/span>\nauth SHA512\n<\/code><\/pre>\n<p>Finally, let's have OpenVPN use a non-privileged user account instead of root, which isn't particularly secure.<\/p>\n<pre><code class=\"hljs cs\">user openvpn\n<span class=\"hljs-keyword\">group<\/span> nogroup\n<\/code><\/pre>\n<p>You can now save and close this file in order to create that user:<\/p>\n<pre><code class=\"language-bash hljs\">$ sudo adduser --system --shell \/usr\/sbin\/nologin --no-create-home openvpn\n<\/code><\/pre>\n<p>The OpenVPN server should now be set up!<\/p>\n<h2>Step 6: Start up the OpenVPN server<\/h2>\n<p>Before we configure our clients, let's make sure the OpenVPN server is running as we hope it will.<\/p>\n<p><strong>Make sure to turn on TUN\/TAP in the SSD Nodes dashboard.<\/strong><\/p>\n<pre><code class=\"language-bash hljs\">$ sudo systemctl <span class=\"hljs-built_in\">enable<\/span> openvpn@server\n$ sudo systemctl start openvpn@server\n<\/code><\/pre>\n<p>You can double-check that OpenVPN is running with the <code>systemctl status<\/code> command:<\/p>\n<pre><code class=\"language-bash hljs\">$ sudo systemctl status openvpn@server\n<\/code><\/pre>\n<p>If you're having problems getting OpenVPN to start, commenting out the <code>LimitNPROC<\/code> in <a href=\"mailto:code&gt;\/lib\/systemd\/system\/openvpn@.service&lt;\/code\">code>\/lib\/systemd\/system\/openvpn@.service<\/code<\/a>, as discovered in this <a href=\"https:\/\/askubuntu.com\/questions\/747023\/systemd-fails-to-start-openvpn-in-lxd-managed-16-04-container\" target=\"_blank\" rel=\"noopener\">Ask Ubuntu thread<\/a> may be useful. You'll then need to run <code>sudo systemctl daemon-reload<\/code> and then <code>sudo systemctl start openvpn@server<\/code>.<\/p>\n<p>You will also need to set up <code>iptables<\/code> to properly direct traffic. First, look for the default interface.<\/p>\n<pre><code class=\"language-bash hljs\">$ sudo ip route | grep default\ndefault dev venet0  scope link\n<\/code><\/pre>\n<p>The <code>venet0<\/code> field is what we're looking for. And then we set up <code>iptables<\/code>. In order to ensure this rule is persistent between reboots, isntall the <code>iptables-persistent<\/code> package, which will prompt you to save existing rules. Choose <code>Yes<\/code> and your rules will be persisted moving forward.<\/p>\n<pre><code class=\"language-bash hljs\">$ sudo iptables -t nat -A POSTROUTING <span class=\"hljs-_\">-s<\/span> 10.8.0.0\/24 -o venet0 -j MASQUERADE\n$ sudo apt-get install iptables-persistent\n<\/code><\/pre>\n<h2>Step 7: Configure clients<\/h2>\n<p>Lastly, you need to create client configurations. You can store these in any folder you'd like\u2014they don't need to be kept secret\u2014as long as it isn't the <code>\/etc\/openvpn<\/code> folder. We'll create a directory in home for this purpose.<\/p>\n<pre><code class=\"language-bash hljs\">$ <span class=\"hljs-built_in\">cd<\/span> ~\n$ mkdir openvpn-clients\n<span class=\"hljs-built_in\">cd<\/span> openvpn-clients\n<\/code><\/pre>\n<p>Now, copy the sample client configuration into this new directory, and then open it in <code>nano<\/code> for editing.<\/p>\n<pre><code class=\"language-bash hljs\">$ cp \/usr\/share\/doc\/openvpn\/examples\/sample-config-files\/client.conf ~\/openvpn-clients\/base.conf\n$ nano base.conf\n<\/code><\/pre>\n<p>Look for the following block of lines. You'll need to change the <code>my-server-1<\/code> to the public IP address of this VPS. You can find this information in the SSD Nodes dashboard, or by typing in the <code>ifconfig<\/code> command and looking for the <code>inet<\/code> field that <em>does not<\/em> look like <code>127.0.0.x<\/code>.<\/p>\n<pre><code class=\"hljs nginx\"><span class=\"hljs-comment\"># The hostname\/IP and port of the server.<\/span>\n<span class=\"hljs-comment\"># You can have multiple remote entries<\/span>\n<span class=\"hljs-comment\"># to load balance between the servers.<\/span>\n<span class=\"hljs-attribute\">remote<\/span> my-server-<span class=\"hljs-number\">1<\/span> <span class=\"hljs-number\">1194<\/span>\n;<span class=\"hljs-attribute\">remote<\/span> my-server-<span class=\"hljs-number\">2<\/span> <span class=\"hljs-number\">1194<\/span>\n<\/code><\/pre>\n<p>Next, uncomment the following two lines by removing the semicolon.<\/p>\n<p><strong>Before:<\/strong><\/p>\n<pre><code class=\"hljs ini\"><span class=\"hljs-comment\"># Downgrade privileges after initialization (non-Windows only)<\/span>\n<span class=\"hljs-comment\">;user nobody<\/span>\n<span class=\"hljs-comment\">;group nogroup<\/span>\n<\/code><\/pre>\n<p><strong>After:<\/strong><\/p>\n<pre><code class=\"hljs cs\"><span class=\"hljs-meta\"># Downgrade privileges after initialization (non-Windows only)<\/span>\nuser nobody\n<span class=\"hljs-keyword\">group<\/span> nogroup\n<\/code><\/pre>\n<p>Because we'll be adding keys and certificates directly into the <code>.ovpn<\/code> file, let's comment out the following lines by adding semicolons to the beginning.<\/p>\n<p><strong>Before:<\/strong><\/p>\n<pre><code class=\"hljs shell\"><span class=\"hljs-meta\">#<\/span><span class=\"bash\"> SSL\/TLS parms.<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> See the server config file <span class=\"hljs-keyword\">for<\/span> more<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> description.  It<span class=\"hljs-string\">'s best to use<\/span><\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"><span class=\"hljs-string\"> a separate .crt\/.key file pair<\/span><\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"><span class=\"hljs-string\"> for each client.  A single ca<\/span><\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"><span class=\"hljs-string\"> file can be used for all clients.<\/span><\/span>\nca ca.crt\ncert client.crt\nkey client.key\n<\/code><\/pre>\n<p><strong>After:<\/strong><\/p>\n<pre><code class=\"hljs shell\"><span class=\"hljs-meta\">#<\/span><span class=\"bash\"> SSL\/TLS parms.<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> See the server config file <span class=\"hljs-keyword\">for<\/span> more<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> description.  It<span class=\"hljs-string\">'s best to use<\/span><\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"><span class=\"hljs-string\"> a separate .crt\/.key file pair<\/span><\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"><span class=\"hljs-string\"> for each client.  A single ca<\/span><\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"><span class=\"hljs-string\"> file can be used for all clients.<\/span><\/span>\n;ca ca.crt\n;cert client.crt\n;key client.key\n<\/code><\/pre>\n<p>Finally, jump to the bottom of the file and add the following lines. The first two mirror the cipher\/auth options we added to the <code>server.conf<\/code> file earlier, and the third establishes that this files will be used to connect to the server, not the other way around.<\/p>\n<p>We're also adding three commented-out files that should be uncommented for Linux-based systems that use <code>update-resolv-conf<\/code>.<\/p>\n<pre><code class=\"hljs shell\"><span class=\"hljs-meta\">#<\/span><span class=\"bash\"> Added lines via SSD Nodes tutorial<\/span>\ncipher AES-256-CBC\nauth SHA512\nkey-direction 1\n<span class=\"hljs-meta\">\n#<\/span><span class=\"bash\"> script-security 2<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> up \/etc\/openvpn\/update-resolv-conf<\/span>\n<span class=\"hljs-meta\">#<\/span><span class=\"bash\"> down \/etc\/openvpn\/update-resolv-conf<\/span>\n<\/code><\/pre>\n<p>Finally, you need to embed the keys and certificates into an <code>.ovpn<\/code> file using <code>base.conf<\/code> as a framework. Copy this entire command and execute it to embed the keys and create a final <code>client1.ovpn<\/code> file.<\/p>\n<pre><code class=\"hljs bash\">$ cat base.conf \n  &lt;(<span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-_\">-e<\/span> <span class=\"hljs-string\">'&lt;ca&gt;'<\/span>) ~\/openvpn-ca\/keys\/ca.crt &lt;(<span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-_\">-e<\/span> <span class=\"hljs-string\">'&lt;\/ca&gt;'<\/span>) \n  &lt;(<span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-_\">-e<\/span> <span class=\"hljs-string\">'&lt;cert&gt;'<\/span>) ~\/openvpn-ca\/keys\/client1.crt &lt;(<span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-_\">-e<\/span> <span class=\"hljs-string\">'&lt;\/cert&gt;n'<\/span>) \n  &lt;(<span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-_\">-e<\/span> <span class=\"hljs-string\">'&lt;key&gt;'<\/span>) ~\/openvpn-ca\/keys\/client1.key &lt;(<span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-_\">-e<\/span> <span class=\"hljs-string\">'&lt;\/key&gt;n'<\/span>) \n  &lt;(<span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-_\">-e<\/span> <span class=\"hljs-string\">'&lt;tls-auth&gt;'<\/span>) ~\/openvpn-ca\/keys\/ta.key &lt;(<span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-_\">-e<\/span> <span class=\"hljs-string\">'&lt;\/tls-auth&gt;'<\/span>) \n  &gt;&gt; client1.ovpn\n<\/code><\/pre>\n<p>This tutorial won't cover client configurations in detail, but we'll share one easy way to transfer the <code>.ovpn<\/code> file to your Linux or OS X client. This command will ssh into your VPS, and then use <code>cat<\/code> to write a new <code>client1.ovpn<\/code> file on your local machine.<\/p>\n<pre><code class=\"hljs ruby\">$ ssh USER@SERVER-IP <span class=\"hljs-string\">\"cat ~\/openvpn-clients\/client1.ovpn\"<\/span> &gt; client1.ovpn\n<\/code><\/pre>\n<p>Once you configure your client, you should be able to connect to the VPN <em>and<\/em> access the wider internet through it. Congratulations!<\/p>\n<h2>Additional resources<\/h2>\n<p>If you're having issues, post them in the comments and we'll do our best to help you work through them. If we see common issues, we'll add a troubleshooting area with workarounds and fixes.<\/p>\n<p>For an easier and more automated method of installing OpenVPN, plus a few other VPN options, consider trying out <a href=\"https:\/\/www.ssdnodes.com\/blog\/streisand-vpn-tutorial\/\" target=\"_blank\" rel=\"noopener noreferrer\">our Streisand tutorial<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Update: August 9, 2017: For an easier and more automated method of installing OpenVPN, plus a few other VPN options, consider trying out our Streisand tutorial.<\/p>\n","protected":false},"author":20,"featured_media":5590,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[18,30],"tags":[244,185],"class_list":["post-112","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-tutorials","tag-openvpn","tag-ubuntu"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/112","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/comments?post=112"}],"version-history":[{"count":3,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/112\/revisions"}],"predecessor-version":[{"id":12936,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/posts\/112\/revisions\/12936"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/media\/5590"}],"wp:attachment":[{"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/media?parent=112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/categories?post=112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ssdnodes.com\/wp-json\/wp\/v2\/tags?post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}