summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Luevano Alvarado <david@luevano.xyz>2021-08-01 03:24:52 -0600
committerDavid Luevano Alvarado <david@luevano.xyz>2021-08-01 03:24:52 -0600
commitba8affd807fcba8041988c8247d9c4396078be91 (patch)
tree1710a83db15a623e0d976f3cb5f2e5713e947d69
parent8cf2d0e2b2e2d6cee2f0136bb6265abf10772d16 (diff)
add vpn entry
-rw-r--r--blog/dst/a/hoy_toco_desarrollo_personaje.html6
-rw-r--r--blog/dst/a/vpn_server_with_openvpn.html415
-rw-r--r--blog/dst/a/xmpp_server_with_prosody.html4
-rw-r--r--blog/dst/index.html4
-rw-r--r--blog/dst/rss.xml292
-rw-r--r--blog/dst/sitemap.xml22
-rw-r--r--blog/dst/tag/@english.html4
-rw-r--r--blog/dst/tag/@server.html4
-rw-r--r--blog/dst/tag/@tools.html4
-rw-r--r--blog/dst/tag/@tutorial.html4
-rw-r--r--blog/src/.files3
-rw-r--r--blog/src/a/vpn_server_with_openvpn.md361
-rw-r--r--blog/src/a/xmpp_server_with_prosody.md2
13 files changed, 1105 insertions, 20 deletions
diff --git a/blog/dst/a/hoy_toco_desarrollo_personaje.html b/blog/dst/a/hoy_toco_desarrollo_personaje.html
index 1985335..35dcbf1 100644
--- a/blog/dst/a/hoy_toco_desarrollo_personaje.html
+++ b/blog/dst/a/hoy_toco_desarrollo_personaje.html
@@ -92,6 +92,12 @@
<p>Y pues ya, este pex ya me sirvió para desahogarme, una disculpa por la redacción tan <em>pitera</em>. Sobres.</p>
<div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/vpn_server_with_openvpn.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
<span class="index">
<a href="https://blog.luevano.xyz" alt="Index">
diff --git a/blog/dst/a/vpn_server_with_openvpn.html b/blog/dst/a/vpn_server_with_openvpn.html
new file mode 100644
index 0000000..5c4eeda
--- /dev/null
+++ b/blog/dst/a/vpn_server_with_openvpn.html
@@ -0,0 +1,415 @@
+<!DOCTYPE html>
+<html class="theme-dark" lang="en"
+ prefix="og: https://ogp.me/ns#">
+ <head>
+ <base href="https://static.luevano.xyz">
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Create a VPN server with OpenVPN (IPv4) -- Luévano's Blog</title>
+ <meta name="description" content"How to create a VPN server using OpenVPN on a server running Nginx. Only for IPv4."/>
+ <link rel="alternate" type="application/rss+xml" href="https://blog.luevano.xyz/rss.xml" title="Luévano's Blog RSS">
+ <link rel="icon" href="images/icons/favicon.ico">
+
+ <!-- general style -->
+ <link rel="stylesheet" type="text/css" href="css/style.css">
+ <link rel="stylesheet" type="text/css" href="fork-awesome/css/fork-awesome.min.css">
+ <link rel="stylesheet" type="text/css" href="font-awesome/css/all.min.css">
+
+ <!-- highlight support for code blocks -->
+ <script type="text/javascript" src="hl/highlight.min.js"></script>
+ <!--<script type="text/javascript" src="hl/highlight-ln.min.js"></script>-->
+ <script type="text/javascript">
+ hljs.initHighlightingOnLoad();
+ // hljs.initLineNumbersOnLoad();
+ </script>
+
+ <!-- theme related -->
+ <script type="text/javascript" src="scripts/theme.js"></script>
+ <link id="theme-css" rel="stylesheet" type="text/css" href="css/theme.css">
+ <link id="code-theme-css" rel="stylesheet" type="text/css" href="hl/styles/nord.min.css">
+
+ <!-- og meta -->
+ <meta property="og:title" content="Create a VPN server with OpenVPN (IPv4) -- Luévano's Blog"/>
+ <meta property="og:type" content="article"/>
+ <meta property="og:url" content="https://blog.luevano.xyz/a/vpn_server_with_openvpn.html"/>
+ <meta property="og:image" content="https://static.luevano.xyz//images/b/default.png"/>
+ <meta property="og:description" content="How to create a VPN server using OpenVPN on a server running Nginx. Only for IPv4."/>
+ <meta property="og:locale" content="en"/>
+ <meta property="og:site_name" content="Luévano's Blog"/>
+ </head>
+
+ <body>
+ <header>
+ <nav>
+ <ul>
+ <li>
+ <a href="https://luevano.xyz/"><i class="fas fa-home" alt="Home"></i><span>Home</span></a>
+ </li>
+
+ <li>
+ <a href="https://blog.luevano.xyz/"><i class="fas fa-book-open" alt="Blog"></i><span>Blog</span></a>
+ </li>
+
+ <li>
+ <a href="https://art.luevano.xyz/"><i class="fas fa-paint-brush" alt="Art"></i><span>Art</span></a>
+ </li>
+
+ <li><i class="fab fa-git" alt="Git"></i><span>Git</span>
+ <ul>
+ <li><a href="https://git.luevano.xyz/" target="_blank"><i class="fab fa-git-alt" alt="Git-alt"></i></a></li>
+
+ <li><a href="https://github.com/luevano" target="_blank"><i class="fab fa-github" alt="Github"></i></a></li>
+
+ <li><a href="https://gitlab.com/dluevano" target="_blank"><i class="fab fa-gitlab" alt="Gitlab"></i></a></li>
+ </ul>
+ </li>
+
+ <li><i class="fas fa-box-open" alt="Stuff"></i><span>Stuff</span>
+ <ul>
+ <li><a href="https://gb.luevano.xyz/"><i class="fas fa-gamepad" alt="Gameboy"></i><span>Gameboy</span></a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+
+ <button class="theme-switcher" onclick="toggleTheme()"><i class="fas fa-moon"></i><i class="fas fa-sun"></i></button>
+ </header>
+
+ <main>
+ <h1>Create a VPN server with OpenVPN (IPv4)</h1>
+
+ <p>I&rsquo;ve been wanting to do this entry, but had no time to do it since I also have to set up the VPN service as well to make sure what I&rsquo;m writing makes sense, today is the day.</p>
+<p>Like with any other of my entries I based my setup on the <a href="https://wiki.archlinux.org/title/OpenVPN">Arch Wiki</a>, <a href="https://github.com/Nyr/openvpn-install">this install script</a> and <a href="https://github.com/graysky2/ovpngen">this profile generator script</a>.</p>
+<p>This will be installed and working alongside the other stuff I&rsquo;ve wrote about on other posts (see the <a href="https://blog.luevano.xyz/tag/@server.html">server</a> tag). All commands here are executes as root unless specified otherwise. Also, this is intended only for IPv4 (it&rsquo;s not that hard to include IPv6, but meh).</p>
+<h2 id="prerequisites">Prerequisites</h2>
+<p>Pretty simple:</p>
+<ul>
+<li>Working server with root access, and with Ufw as the firewall.</li>
+<li>Depending on what port you want to run the VPN on, the default <code>1194</code>, or as a fallback on <code>443</code> (click <a href="https://openvpn.net/vpn-server-resources/advanced-option-settings-on-the-command-line/">here</a> for more). I will do mine on port <code>1194</code> but it&rsquo;s just a matter of changing 2 lines of configuration and one Ufw rule.</li>
+</ul>
+<h2 id="create-pki-from-scratch">Create PKI from scratch</h2>
+<p>PKI stands for <em>Public Key Infrastructure</em> and basically it&rsquo;s required for certificates, private keys and more. This is supposed to work between two servers and one client: a server in charge of creating, signing and verifying the certificates, a server with the OpenVPN service running and the client making the request.</p>
+<p>This is supposed to work something like: 1) a client wants to use the VPN service, so it creates a requests and sends it to the signing server, 2) this server checks the requests and signs the request, returning the certificates to both the VPN service and the client and 3) the client can now connect to the VPN service using the signed certificate which the OpenVPN server knows about. In a nutshell, I&rsquo;m no expert.</p>
+<p>&hellip; but, to be honest, all of this is a hassle and (in my case) I want something simple to use and manage. So I&rsquo;m gonna do all on one server and then just give away the configuration file for the clients, effectively generating files that anyone can run and will work, meaning that you need to be careful who you give this files (it also comes with a revoking mechanism, so no worries).</p>
+<p>This is done with <a href="https://wiki.archlinux.org/title/Easy-RSA">Easy-RSA</a>.</p>
+<p>Install the <code>easy-rsa</code> package:</p>
+<pre><code class="language-sh">pacman -S easy-rsa
+</code></pre>
+<p>Initialize the PKI and generate the CA keypair:</p>
+<pre><code class="language-sh">cd /etc/easy-rsa
+easyrsa init-pki
+easyrsa build-ca nopass
+</code></pre>
+<p>Create the server certificate and private key (while in the same directory):</p>
+<pre><code class="language-sh">EASYRSA_CERT_EXPIRE=3650 easyrsa build-server-full server nopass
+</code></pre>
+<p>Where <code>server</code> is just a name to identify your server certificate keypair, I just use <code>server</code> but could be anything (like <code>luevano.xyz</code> in my case).</p>
+<p>Create the client revocation list AKA CRL (will be used later, but might as well have it now):</p>
+<pre><code class="language-sh">EASYRSA_CRL_DAYS=3650 easyrsa gen-crl
+</code></pre>
+<p>After this we should have 6 new files:</p>
+<pre><code>/etc/easy-rsa/pki/ca.crt
+/etc/easy-rsa/pki/private/ca.key
+/etc/easy-rsa/pki/issued/server.crt
+/etc/easy-rsa/pki/reqs/server.req
+/etc/easy-rsa/pki/private/server.key
+/etc/easy-rsa/pki/crl.pem
+</code></pre>
+<p>It is recommended to copy some of these files over to the <code>openvpn</code> directory, but I prefer to keep them here and just change some of the permissions:</p>
+<pre><code class="language-sh">chmod o+rx pki
+chmod o+rx pki/ca.crt
+chmod o+rx pki/issued
+chmod o+rx pki/issued/server.crt
+chmod o+rx pki/private
+chmod o+rx pki/private/server.key
+chown nobody:nobody pki/crl.pem
+chmod o+r pki/crl.pem
+</code></pre>
+<p>Now, go to the <code>openvpn</code> directory and create the required files there:</p>
+<pre><code class="language-sh">cd /etc/openvpn/server
+openssl dhparam -out dh.pem 2048
+openvpn --genkey secret ta.key
+</code></pre>
+<p>That&rsquo;s it for the PKI stuff and general certificate configuration.</p>
+<h2 id="openvpn">OpenVPN</h2>
+<p><a href="https://wiki.archlinux.org/title/OpenVPN">OpenVPN</a> is a robust and highly flexible VPN daemon, that&rsquo;s pretty complete feature wise.</p>
+<p>Install the <code>openvpn</code> package:</p>
+<pre><code class="language-sh">pacman -S openvpn
+</code></pre>
+<p>Now, most of the stuff is going to be handled by (each, if you have more than one) server configuration. This might be the hardest thing to configure, but I&rsquo;ve used a basic configuration file that worked a lot to me, which is a compilation of stuff that I found on the internet while configuring the file a while back.</p>
+<pre><code># Server ip addres (ipv4).
+local 1.2.3.4 # your server public ip
+
+# Port.
+port 1194 # Might want to change it to 443
+
+# TCP or UDP.
+;proto tcp
+proto udp # If ip changes to 443, you should change this to tcp, too
+
+# &quot;dev tun&quot; will create a routed IP tunnel,
+# &quot;dev tap&quot; will create an ethernet tunnel.
+;dev tap
+dev tun
+
+# Server specific certificates and more.
+ca /etc/easy-rsa/pki/ca.crt
+cert /etc/easy-rsa/pki/issued/server.crt
+key /etc/easy-rsa/pki/private/server.key # This file should be kept secret.
+dh /etc/openvpn/server/dh.pem
+auth SHA512
+tls-crypt /etc/openvpn/server/ta.key 0 # This file is secret.
+crl-verify /etc/easy-rsa/pki/crl.pem
+
+# Network topology.
+topology subnet
+
+# Configure server mode and supply a VPN subnet
+# for OpenVPN to draw client addresses from.
+server 10.8.0.0 255.255.255.0
+
+# Maintain a record of client &lt;-&gt; virtual IP address
+# associations in this file.
+ifconfig-pool-persist ipp.txt
+
+# Push routes to the client to allow it
+# to reach other private subnets behind
+# the server.
+;push &quot;route 192.168.10.0 255.255.255.0&quot;
+;push &quot;route 192.168.20.0 255.255.255.0&quot;
+
+# If enabled, this directive will configure
+# all clients to redirect their default
+# network gateway through the VPN, causing
+# all IP traffic such as web browsing and
+# and DNS lookups to go through the VPN
+push &quot;redirect-gateway def1 bypass-dhcp&quot;
+
+# Certain Windows-specific network settings
+# can be pushed to clients, such as DNS
+# or WINS server addresses.
+# Google DNS.
+;push &quot;dhcp-option DNS 8.8.8.8&quot;
+;push &quot;dhcp-option DNS 8.8.4.4&quot;
+
+# The keepalive directive causes ping-like
+# messages to be sent back and forth over
+# the link so that each side knows when
+# the other side has gone down.
+keepalive 10 120
+
+# The maximum number of concurrently connected
+# clients we want to allow.
+max-clients 5
+
+# It's a good idea to reduce the OpenVPN
+# daemon's privileges after initialization.
+user nobody
+group nobody
+
+# The persist options will try to avoid
+# accessing certain resources on restart
+# that may no longer be accessible because
+# of the privilege downgrade.
+persist-key
+persist-tun
+
+# Output a short status file showing
+# current connections, truncated
+# and rewritten every minute.
+status openvpn-status.log
+
+# Set the appropriate level of log
+# file verbosity.
+#
+# 0 is silent, except for fatal errors
+# 4 is reasonable for general usage
+# 5 and 6 can help to debug connection problems
+# 9 is extremely verbose
+verb 3
+
+# Notify the client that when the server restarts so it
+# can automatically reconnect.
+# Only usable with udp.
+explicit-exit-notify 1
+</code></pre>
+<p><code>#</code> and <code>;</code> are comments. Read each and every line, you might want to change some stuff (like the logging).</p>
+<p>Now, we need to enable <em>packet forwarding</em>, which can be enabled on the interface level or globally (you can check the different options with <code>sysctl -a | grep forward</code>). I&rsquo;ll do it globally, run:</p>
+<pre><code class="language-sh">sysctl net.ipv4.ip_forward=1
+</code></pre>
+<p>And create/edit the file <code>/etc/sysctl.d/30-ipforward.conf</code>:</p>
+<pre><code>net.ipv4.ip_forward=1
+</code></pre>
+<p>Now we need to configure <code>ufw</code> to forward traffic through the VPN. Append the following to <code>/etc/default/ufw</code> (or edit the existing line):</p>
+<pre><code>...
+DEFAULT_FORWARD_POLICY=&quot;ACCEPT&quot;
+</code></pre>
+<p>And change the <code>/etc/ufw/before.rules</code>, appending the following lines after the header <strong>but before the *filter line</strong>:</p>
+<pre><code>...
+# NAT (Network Address Translation) table rules
+*nat
+:POSTROUTING ACCEPT [0:0]
+
+# Allow traffic from clients to the interface
+-A POSTROUTING -s 10.8.0.0/24 -o interface -j MASQUERADE
+
+# do not delete the &quot;COMMIT&quot; line or the NAT table rules above will not be processed
+COMMIT
+
+# Don't delete these required lines, otherwise there will be errors
+*filter
+...
+</code></pre>
+<p>Where <code>interface</code> must be changed depending on your interface (in my case is <code>ens3</code>, another common one is <code>eth0</code>); I always check this by running <code>ip addr</code>, you will get a list of interfaces of which the one containing your public ip is the one that you want, for me it looks something like:</p>
+<pre><code>...
+2: ens3: &lt;SOMETHING,SOMETHING&gt; bla bla
+ link/ether bla:bla
+ altname enp0s3
+ inet my.public.ip.addr bla bla
+...
+</code></pre>
+<p>And also make sure the <code>10.8.0.0/24</code> matches the subnet mask specified in the <code>server.conf</code> file (in this example it matches). You should check this very carefully, because I just spend a good 2 hours debugging why my configuration wasn&rsquo;t working, and this was te reason (I could connect to the VPN, but had no external connection to the web).</p>
+<p>Finally, allow the OpenVPN port you specified (in this example its <code>1194/udp</code>) and reload <code>ufw</code>:</p>
+<pre><code class="language-sh">ufw allow 1194/udp comment &quot;OpenVPN&quot;
+ufw reload
+</code></pre>
+<p>At this point, the server-side configuration is done and you can start and enable the service:</p>
+<pre><code class="language-sh">systemctl start openvpn-server@server.service
+systemctl enable openvpn-server@server.service
+</code></pre>
+<p>Where the <code>server</code> after <code>@</code> is your specific configuration, in my case it is called just <code>server</code>.</p>
+<h3 id="create-client-configurations">Create client configurations</h3>
+<p>You might notice that I didn&rsquo;t specify how to actually connect to our server. For that we need to do a few more steps. We actually need a configuration file similar to the <code>server.conf</code> file that we created.</p>
+<p>The real way of doing this would be to run similar steps as the ones with <code>easy-rsa</code> locally, send them to the server, sign them, and retrieve them. Nah, we&rsquo;ll just create all configuration files on the server as I was mentioning earlier.</p>
+<p>Also, the client configuration file has to match the server one (to some degree), to make this easier you can create a <code>client-common</code> file in <code>/etc/openvpn/server</code> with the following content:</p>
+<pre><code>client
+dev tun
+remote 1.2.3.4 1194 udp # change this to match your ip and port
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+remote-cert-tls server
+auth SHA512
+verb 3
+</code></pre>
+<p>Where you should make any changes necessary, depending on your configuration.</p>
+<p>Now, we need a way to create and revoke new configuration files. For this I created a script, heavily based on one of the links I mentioned at the beginning, by the way. You can place these scripts anywhere you like, and you should take a look before running them because you&rsquo;ll be running them as root.</p>
+<p>In a nutshell, what it does is: generate a new client certificate keypair, update the CRL and create a new <code>.ovpn</code> configuration file that consists on the <code>client-common</code> data and all of the required certificates; or, revoke an existing client and refresh the CRL. The file is placed under <code>~/ovpn</code>.</p>
+<p>Create a new file with the following content (name it whatever you like) and don&rsquo;t forget to make it executable (<code>chmod +x script_name</code>):</p>
+<pre><code>#!/bin/sh
+# Client ovpn configuration creation and revoking.
+MODE=$1
+if [ ! &quot;$MODE&quot; = &quot;new&quot; -a ! &quot;$MODE&quot; = &quot;rev&quot; ]; then
+ echo &quot;$1 is not a valid mode, using default 'new'&quot;
+ MODE=new
+fi
+
+CLIENT=${2:-guest}
+if [ -z $2 ];then
+ echo &quot;there was no client name passed as second argument, using 'guest' as default&quot;
+fi
+
+# Expiration config.
+EASYRSA_CERT_EXPIRE=3650
+EASYRSA_CRL_DAYS=3650
+
+# Current PWD.
+CPWD=$PWD
+cd /etc/easy-rsa/
+
+if [ &quot;$MODE&quot; = &quot;rev&quot; ]; then
+ easyrsa --batch revoke $CLIENT
+
+ echo &quot;$CLIENT revoked.&quot;
+elif [ &quot;$MODE&quot; = &quot;new&quot; ]; then
+ easyrsa build-client-full $CLIENT nopass
+
+ # This is what actually generates the config file.
+ {
+ cat /etc/openvpn/server/client-common
+ echo &quot;&lt;ca&gt;&quot;
+ cat /etc/easy-rsa/pki/ca.crt
+ echo &quot;&lt;/ca&gt;&quot;
+ echo &quot;&lt;cert&gt;&quot;
+ sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/easy-rsa/pki/issued/$CLIENT.crt
+ echo &quot;&lt;/cert&gt;&quot;
+ echo &quot;&lt;key&gt;&quot;
+ cat /etc/easy-rsa/pki/private/$CLIENT.key
+ echo &quot;&lt;/key&gt;&quot;
+ echo &quot;&lt;tls-crypt&gt;&quot;
+ sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/ta.key
+ echo &quot;&lt;/tls-crypt&gt;&quot;
+ } &gt; &quot;$(eval echo ~${SUDO_USER:-$USER}/ovpn/$CLIENT.ovpn)&quot;
+
+ eval echo &quot;~${SUDO_USER:-$USER}/ovpn/$CLIENT.ovpn file generated.&quot;
+fi
+
+# Finish up, re-generates the crl
+easyrsa gen-crl
+chown nobody:nobody pki/crl.pem
+chmod o+r pki/crl.pem
+cd $CPWD
+</code></pre>
+<p>And the way to use is to run <code>ovpn_script new/rev client_name</code> as sudo (when revoking, it doesn&rsquo;t actually deletes the <code>.ovpn</code> file in <code>~/ovpn</code>). Again, this is a little script that I put together, so you should check it out, it might need tweaks (depending on your directory structure for <code>easy-rsa</code>) and it might have errors.</p>
+<p>Now, just get the <code>.ovpn</code> file generated, import it to OpenVPN in your client of preference and you should have a working VPN service.</p>
+
+ <div class="page-nav">
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/hoy_toco_desarrollo_personaje.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
+ <hr>
+ <div class="article-info">
+ <p>By David Luévano</p>
+ <p>Created: Sun, Aug 01, 2021 @ 09:23 UTC</p>
+ <div class="article-tags">
+ <p>Tags:
+<a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@server.html">server</a>, <a href="https://blog.luevano.xyz/tag/@tools.html">tools</a>, <a href="https://blog.luevano.xyz/tag/@tutorial.html">tutorial</a> </p>
+</div>
+
+ </div>
+ </main>
+
+ <footer>
+ <span>
+ <i class="fas fa-address-card" alt="Contact"></i>
+ <a href="https://luevano.xyz/contact.html">Contact</a>
+ </span>
+
+ <span>
+ <i class="fas fa-donate" alt="Donate"></i>
+ <a href="https://luevano.xyz/donate.html">Donate</a>
+ </span>
+
+ <span>
+ <i class="fas fa-rss" alt="RSS"></i>
+ <a target="_blank" href="https://blog.luevano.xyz/rss.xml">RSS</a>
+ </span>
+
+ <br>
+ <span class="created-with">
+ <i class="fas fa-hammer" alt="Hammer"></i>
+ Created with <a href="https://github.com/luevano/pyssg">pyssg</a>
+ </span>
+
+ <br>
+ <span class="copyright">
+ Copyright <i class="far fa-copyright" alt="Copyright"></i> 2021 David Luévano Alvarado
+ </span>
+ </footer>
+ </body>
+</html> \ No newline at end of file
diff --git a/blog/dst/a/xmpp_server_with_prosody.html b/blog/dst/a/xmpp_server_with_prosody.html
index be946f2..ae833e8 100644
--- a/blog/dst/a/xmpp_server_with_prosody.html
+++ b/blog/dst/a/xmpp_server_with_prosody.html
@@ -100,7 +100,7 @@
</li>
<li>SSL certificates for the previous subdomains; similar that with my other entries just create the appropriate <code>prosody.conf</code> (where <code>server_name</code> will be all the subdomains defined above) file and run <code>certbot --nginx</code>. You can find the example configuration file almost at the end of this entry.</li>
<li>Email addresses for <code>admin</code>, <code>abuse</code>, <code>contact</code>, <code>security</code>, etc. Or use your own email for all of them, doesn&rsquo;t really matter much as long as you define them in the configuration and are valid, I have aliases so those emails are forwarded to me.</li>
-<li>Allow ports 5000, 5222, 5269, 5280 and 5281 for <a href="https://prosody.im/doc/ports">Prosody</a> and, 3478 and 5349 for <a href="https://webrtc.org/getting-started/turn-server">Turnserver</a> which are the defaults for <code>coturn</code>.</li>
+<li>Allow ports <code>5000</code>, <code>5222</code>, <code>5269</code>, <code>5280</code> and <code>5281</code> for <a href="https://prosody.im/doc/ports">Prosody</a> and, <code>3478</code> and <code>5349</code> for <a href="https://webrtc.org/getting-started/turn-server">Turnserver</a> which are the defaults for <code>coturn</code>.</li>
</ul>
<h2 id="prosody">Prosody</h2>
<p><a href="https://wiki.archlinux.org/title/Prosody">Prosody</a> is an implementation of the XMPP protocol that is flexible and extensible.</p>
@@ -603,7 +603,7 @@ systemctl enable prosody.service
<div class="article-info">
<p>By David Luévano</p>
<p>Created: Wed, Jun 09, 2021 @ 05:24 UTC</p>
- <p>Modified: Thu, Jun 10, 2021 @ 04:42 UTC</p>
+ <p>Modified: Sun, Aug 01, 2021 @ 09:24 UTC</p>
<div class="article-tags">
<p>Tags:
<a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@server.html">server</a>, <a href="https://blog.luevano.xyz/tag/@tools.html">tools</a>, <a href="https://blog.luevano.xyz/tag/@tutorial.html">tutorial</a> </p>
diff --git a/blog/dst/index.html b/blog/dst/index.html
index 5e53319..0fd8702 100644
--- a/blog/dst/index.html
+++ b/blog/dst/index.html
@@ -94,7 +94,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>July 2021</h3>
+ <h3>August 2021</h3>
+ <li>Aug 01 - <a href="https://blog.luevano.xyz/a/vpn_server_with_openvpn.html">Create a VPN server with OpenVPN (IPv4)</a></li>
+ <h3>July 2021</h3>
<li>Jul 28 - <a href="https://blog.luevano.xyz/a/hoy_toco_desarrollo_personaje.html">Hoy me tocó desarrollo de personaje</a></li>
<li>Jul 18 - <a href="https://blog.luevano.xyz/a/tenia_esto_descuidado.html">Tenia este pex algo descuidado</a></li>
<h3>June 2021</h3>
diff --git a/blog/dst/rss.xml b/blog/dst/rss.xml
index 424eb6e..d4324c1 100644
--- a/blog/dst/rss.xml
+++ b/blog/dst/rss.xml
@@ -13,8 +13,8 @@
<copyright>Copyright 2021 David Luévano Alvarado</copyright>
<managingEditor>david@luevano.xyz (David Luévano Alvarado)</managingEditor>
<webMaster>david@luevano.xyz (David Luévano Alvarado)</webMaster>
- <pubDate>Wed, 28 Jul 2021 06:11:36 GMT</pubDate>
- <lastBuildDate>Wed, 28 Jul 2021 06:11:36 GMT</lastBuildDate>
+ <pubDate>Sun, 01 Aug 2021 09:24:35 GMT</pubDate>
+ <lastBuildDate>Sun, 01 Aug 2021 09:24:35 GMT</lastBuildDate>
<generator>pyssg v0.5.9</generator>
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
<ttl>30</ttl>
@@ -24,6 +24,292 @@
<link>https://blog.luevano.xyz</link>
</image>
<item>
+ <title>Create a VPN server with OpenVPN (IPv4)</title>
+ <link>https://blog.luevano.xyz/a/vpn_server_with_openvpn.html</link>
+ <guid isPermaLink="true">https://blog.luevano.xyz/a/vpn_server_with_openvpn.html</guid>
+ <pubDate>Sun, 01 Aug 2021 09:23:42 GMT</pubDate>
+ <category>English</category>
+ <category>Server</category>
+ <category>Tools</category>
+ <category>Tutorial</category>
+ <description>How to create a VPN server using OpenVPN on a server running Nginx. Only for IPv4.</description>
+ <content:encoded><![CDATA[<p>I&rsquo;ve been wanting to do this entry, but had no time to do it since I also have to set up the VPN service as well to make sure what I&rsquo;m writing makes sense, today is the day.</p>
+<p>Like with any other of my entries I based my setup on the <a href="https://wiki.archlinux.org/title/OpenVPN">Arch Wiki</a>, <a href="https://github.com/Nyr/openvpn-install">this install script</a> and <a href="https://github.com/graysky2/ovpngen">this profile generator script</a>.</p>
+<p>This will be installed and working alongside the other stuff I&rsquo;ve wrote about on other posts (see the <a href="https://blog.luevano.xyz/tag/@server.html">server</a> tag). All commands here are executes as root unless specified otherwise. Also, this is intended only for IPv4 (it&rsquo;s not that hard to include IPv6, but meh).</p>
+<h2 id="prerequisites">Prerequisites</h2>
+<p>Pretty simple:</p>
+<ul>
+<li>Working server with root access, and with Ufw as the firewall.</li>
+<li>Depending on what port you want to run the VPN on, the default <code>1194</code>, or as a fallback on <code>443</code> (click <a href="https://openvpn.net/vpn-server-resources/advanced-option-settings-on-the-command-line/">here</a> for more). I will do mine on port <code>1194</code> but it&rsquo;s just a matter of changing 2 lines of configuration and one Ufw rule.</li>
+</ul>
+<h2 id="create-pki-from-scratch">Create PKI from scratch</h2>
+<p>PKI stands for <em>Public Key Infrastructure</em> and basically it&rsquo;s required for certificates, private keys and more. This is supposed to work between two servers and one client: a server in charge of creating, signing and verifying the certificates, a server with the OpenVPN service running and the client making the request.</p>
+<p>This is supposed to work something like: 1) a client wants to use the VPN service, so it creates a requests and sends it to the signing server, 2) this server checks the requests and signs the request, returning the certificates to both the VPN service and the client and 3) the client can now connect to the VPN service using the signed certificate which the OpenVPN server knows about. In a nutshell, I&rsquo;m no expert.</p>
+<p>&hellip; but, to be honest, all of this is a hassle and (in my case) I want something simple to use and manage. So I&rsquo;m gonna do all on one server and then just give away the configuration file for the clients, effectively generating files that anyone can run and will work, meaning that you need to be careful who you give this files (it also comes with a revoking mechanism, so no worries).</p>
+<p>This is done with <a href="https://wiki.archlinux.org/title/Easy-RSA">Easy-RSA</a>.</p>
+<p>Install the <code>easy-rsa</code> package:</p>
+<pre><code class="language-sh">pacman -S easy-rsa
+</code></pre>
+<p>Initialize the PKI and generate the CA keypair:</p>
+<pre><code class="language-sh">cd /etc/easy-rsa
+easyrsa init-pki
+easyrsa build-ca nopass
+</code></pre>
+<p>Create the server certificate and private key (while in the same directory):</p>
+<pre><code class="language-sh">EASYRSA_CERT_EXPIRE=3650 easyrsa build-server-full server nopass
+</code></pre>
+<p>Where <code>server</code> is just a name to identify your server certificate keypair, I just use <code>server</code> but could be anything (like <code>luevano.xyz</code> in my case).</p>
+<p>Create the client revocation list AKA CRL (will be used later, but might as well have it now):</p>
+<pre><code class="language-sh">EASYRSA_CRL_DAYS=3650 easyrsa gen-crl
+</code></pre>
+<p>After this we should have 6 new files:</p>
+<pre><code>/etc/easy-rsa/pki/ca.crt
+/etc/easy-rsa/pki/private/ca.key
+/etc/easy-rsa/pki/issued/server.crt
+/etc/easy-rsa/pki/reqs/server.req
+/etc/easy-rsa/pki/private/server.key
+/etc/easy-rsa/pki/crl.pem
+</code></pre>
+<p>It is recommended to copy some of these files over to the <code>openvpn</code> directory, but I prefer to keep them here and just change some of the permissions:</p>
+<pre><code class="language-sh">chmod o+rx pki
+chmod o+rx pki/ca.crt
+chmod o+rx pki/issued
+chmod o+rx pki/issued/server.crt
+chmod o+rx pki/private
+chmod o+rx pki/private/server.key
+chown nobody:nobody pki/crl.pem
+chmod o+r pki/crl.pem
+</code></pre>
+<p>Now, go to the <code>openvpn</code> directory and create the required files there:</p>
+<pre><code class="language-sh">cd /etc/openvpn/server
+openssl dhparam -out dh.pem 2048
+openvpn --genkey secret ta.key
+</code></pre>
+<p>That&rsquo;s it for the PKI stuff and general certificate configuration.</p>
+<h2 id="openvpn">OpenVPN</h2>
+<p><a href="https://wiki.archlinux.org/title/OpenVPN">OpenVPN</a> is a robust and highly flexible VPN daemon, that&rsquo;s pretty complete feature wise.</p>
+<p>Install the <code>openvpn</code> package:</p>
+<pre><code class="language-sh">pacman -S openvpn
+</code></pre>
+<p>Now, most of the stuff is going to be handled by (each, if you have more than one) server configuration. This might be the hardest thing to configure, but I&rsquo;ve used a basic configuration file that worked a lot to me, which is a compilation of stuff that I found on the internet while configuring the file a while back.</p>
+<pre><code># Server ip addres (ipv4).
+local 1.2.3.4 # your server public ip
+
+# Port.
+port 1194 # Might want to change it to 443
+
+# TCP or UDP.
+;proto tcp
+proto udp # If ip changes to 443, you should change this to tcp, too
+
+# &quot;dev tun&quot; will create a routed IP tunnel,
+# &quot;dev tap&quot; will create an ethernet tunnel.
+;dev tap
+dev tun
+
+# Server specific certificates and more.
+ca /etc/easy-rsa/pki/ca.crt
+cert /etc/easy-rsa/pki/issued/server.crt
+key /etc/easy-rsa/pki/private/server.key # This file should be kept secret.
+dh /etc/openvpn/server/dh.pem
+auth SHA512
+tls-crypt /etc/openvpn/server/ta.key 0 # This file is secret.
+crl-verify /etc/easy-rsa/pki/crl.pem
+
+# Network topology.
+topology subnet
+
+# Configure server mode and supply a VPN subnet
+# for OpenVPN to draw client addresses from.
+server 10.8.0.0 255.255.255.0
+
+# Maintain a record of client &lt;-&gt; virtual IP address
+# associations in this file.
+ifconfig-pool-persist ipp.txt
+
+# Push routes to the client to allow it
+# to reach other private subnets behind
+# the server.
+;push &quot;route 192.168.10.0 255.255.255.0&quot;
+;push &quot;route 192.168.20.0 255.255.255.0&quot;
+
+# If enabled, this directive will configure
+# all clients to redirect their default
+# network gateway through the VPN, causing
+# all IP traffic such as web browsing and
+# and DNS lookups to go through the VPN
+push &quot;redirect-gateway def1 bypass-dhcp&quot;
+
+# Certain Windows-specific network settings
+# can be pushed to clients, such as DNS
+# or WINS server addresses.
+# Google DNS.
+;push &quot;dhcp-option DNS 8.8.8.8&quot;
+;push &quot;dhcp-option DNS 8.8.4.4&quot;
+
+# The keepalive directive causes ping-like
+# messages to be sent back and forth over
+# the link so that each side knows when
+# the other side has gone down.
+keepalive 10 120
+
+# The maximum number of concurrently connected
+# clients we want to allow.
+max-clients 5
+
+# It's a good idea to reduce the OpenVPN
+# daemon's privileges after initialization.
+user nobody
+group nobody
+
+# The persist options will try to avoid
+# accessing certain resources on restart
+# that may no longer be accessible because
+# of the privilege downgrade.
+persist-key
+persist-tun
+
+# Output a short status file showing
+# current connections, truncated
+# and rewritten every minute.
+status openvpn-status.log
+
+# Set the appropriate level of log
+# file verbosity.
+#
+# 0 is silent, except for fatal errors
+# 4 is reasonable for general usage
+# 5 and 6 can help to debug connection problems
+# 9 is extremely verbose
+verb 3
+
+# Notify the client that when the server restarts so it
+# can automatically reconnect.
+# Only usable with udp.
+explicit-exit-notify 1
+</code></pre>
+<p><code>#</code> and <code>;</code> are comments. Read each and every line, you might want to change some stuff (like the logging).</p>
+<p>Now, we need to enable <em>packet forwarding</em>, which can be enabled on the interface level or globally (you can check the different options with <code>sysctl -a | grep forward</code>). I&rsquo;ll do it globally, run:</p>
+<pre><code class="language-sh">sysctl net.ipv4.ip_forward=1
+</code></pre>
+<p>And create/edit the file <code>/etc/sysctl.d/30-ipforward.conf</code>:</p>
+<pre><code>net.ipv4.ip_forward=1
+</code></pre>
+<p>Now we need to configure <code>ufw</code> to forward traffic through the VPN. Append the following to <code>/etc/default/ufw</code> (or edit the existing line):</p>
+<pre><code>...
+DEFAULT_FORWARD_POLICY=&quot;ACCEPT&quot;
+</code></pre>
+<p>And change the <code>/etc/ufw/before.rules</code>, appending the following lines after the header <strong>but before the *filter line</strong>:</p>
+<pre><code>...
+# NAT (Network Address Translation) table rules
+*nat
+:POSTROUTING ACCEPT [0:0]
+
+# Allow traffic from clients to the interface
+-A POSTROUTING -s 10.8.0.0/24 -o interface -j MASQUERADE
+
+# do not delete the &quot;COMMIT&quot; line or the NAT table rules above will not be processed
+COMMIT
+
+# Don't delete these required lines, otherwise there will be errors
+*filter
+...
+</code></pre>
+<p>Where <code>interface</code> must be changed depending on your interface (in my case is <code>ens3</code>, another common one is <code>eth0</code>); I always check this by running <code>ip addr</code>, you will get a list of interfaces of which the one containing your public ip is the one that you want, for me it looks something like:</p>
+<pre><code>...
+2: ens3: &lt;SOMETHING,SOMETHING&gt; bla bla
+ link/ether bla:bla
+ altname enp0s3
+ inet my.public.ip.addr bla bla
+...
+</code></pre>
+<p>And also make sure the <code>10.8.0.0/24</code> matches the subnet mask specified in the <code>server.conf</code> file (in this example it matches). You should check this very carefully, because I just spend a good 2 hours debugging why my configuration wasn&rsquo;t working, and this was te reason (I could connect to the VPN, but had no external connection to the web).</p>
+<p>Finally, allow the OpenVPN port you specified (in this example its <code>1194/udp</code>) and reload <code>ufw</code>:</p>
+<pre><code class="language-sh">ufw allow 1194/udp comment &quot;OpenVPN&quot;
+ufw reload
+</code></pre>
+<p>At this point, the server-side configuration is done and you can start and enable the service:</p>
+<pre><code class="language-sh">systemctl start openvpn-server@server.service
+systemctl enable openvpn-server@server.service
+</code></pre>
+<p>Where the <code>server</code> after <code>@</code> is your specific configuration, in my case it is called just <code>server</code>.</p>
+<h3 id="create-client-configurations">Create client configurations</h3>
+<p>You might notice that I didn&rsquo;t specify how to actually connect to our server. For that we need to do a few more steps. We actually need a configuration file similar to the <code>server.conf</code> file that we created.</p>
+<p>The real way of doing this would be to run similar steps as the ones with <code>easy-rsa</code> locally, send them to the server, sign them, and retrieve them. Nah, we&rsquo;ll just create all configuration files on the server as I was mentioning earlier.</p>
+<p>Also, the client configuration file has to match the server one (to some degree), to make this easier you can create a <code>client-common</code> file in <code>/etc/openvpn/server</code> with the following content:</p>
+<pre><code>client
+dev tun
+remote 1.2.3.4 1194 udp # change this to match your ip and port
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+remote-cert-tls server
+auth SHA512
+verb 3
+</code></pre>
+<p>Where you should make any changes necessary, depending on your configuration.</p>
+<p>Now, we need a way to create and revoke new configuration files. For this I created a script, heavily based on one of the links I mentioned at the beginning, by the way. You can place these scripts anywhere you like, and you should take a look before running them because you&rsquo;ll be running them as root.</p>
+<p>In a nutshell, what it does is: generate a new client certificate keypair, update the CRL and create a new <code>.ovpn</code> configuration file that consists on the <code>client-common</code> data and all of the required certificates; or, revoke an existing client and refresh the CRL. The file is placed under <code>~/ovpn</code>.</p>
+<p>Create a new file with the following content (name it whatever you like) and don&rsquo;t forget to make it executable (<code>chmod +x script_name</code>):</p>
+<pre><code>#!/bin/sh
+# Client ovpn configuration creation and revoking.
+MODE=$1
+if [ ! &quot;$MODE&quot; = &quot;new&quot; -a ! &quot;$MODE&quot; = &quot;rev&quot; ]; then
+ echo &quot;$1 is not a valid mode, using default 'new'&quot;
+ MODE=new
+fi
+
+CLIENT=${2:-guest}
+if [ -z $2 ];then
+ echo &quot;there was no client name passed as second argument, using 'guest' as default&quot;
+fi
+
+# Expiration config.
+EASYRSA_CERT_EXPIRE=3650
+EASYRSA_CRL_DAYS=3650
+
+# Current PWD.
+CPWD=$PWD
+cd /etc/easy-rsa/
+
+if [ &quot;$MODE&quot; = &quot;rev&quot; ]; then
+ easyrsa --batch revoke $CLIENT
+
+ echo &quot;$CLIENT revoked.&quot;
+elif [ &quot;$MODE&quot; = &quot;new&quot; ]; then
+ easyrsa build-client-full $CLIENT nopass
+
+ # This is what actually generates the config file.
+ {
+ cat /etc/openvpn/server/client-common
+ echo &quot;&lt;ca&gt;&quot;
+ cat /etc/easy-rsa/pki/ca.crt
+ echo &quot;&lt;/ca&gt;&quot;
+ echo &quot;&lt;cert&gt;&quot;
+ sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/easy-rsa/pki/issued/$CLIENT.crt
+ echo &quot;&lt;/cert&gt;&quot;
+ echo &quot;&lt;key&gt;&quot;
+ cat /etc/easy-rsa/pki/private/$CLIENT.key
+ echo &quot;&lt;/key&gt;&quot;
+ echo &quot;&lt;tls-crypt&gt;&quot;
+ sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/ta.key
+ echo &quot;&lt;/tls-crypt&gt;&quot;
+ } &gt; &quot;$(eval echo ~${SUDO_USER:-$USER}/ovpn/$CLIENT.ovpn)&quot;
+
+ eval echo &quot;~${SUDO_USER:-$USER}/ovpn/$CLIENT.ovpn file generated.&quot;
+fi
+
+# Finish up, re-generates the crl
+easyrsa gen-crl
+chown nobody:nobody pki/crl.pem
+chmod o+r pki/crl.pem
+cd $CPWD
+</code></pre>
+<p>And the way to use is to run <code>ovpn_script new/rev client_name</code> as sudo (when revoking, it doesn&rsquo;t actually deletes the <code>.ovpn</code> file in <code>~/ovpn</code>). Again, this is a little script that I put together, so you should check it out, it might need tweaks (depending on your directory structure for <code>easy-rsa</code>) and it might have errors.</p>
+<p>Now, just get the <code>.ovpn</code> file generated, import it to OpenVPN in your client of preference and you should have a working VPN service.</p>]]></content:encoded>
+ </item>
+ <item>
<title>Hoy me tocó desarrollo de personaje</title>
<link>https://blog.luevano.xyz/a/hoy_toco_desarrollo_personaje.html</link>
<guid isPermaLink="true">https://blog.luevano.xyz/a/hoy_toco_desarrollo_personaje.html</guid>
@@ -91,7 +377,7 @@
</li>
<li>SSL certificates for the previous subdomains; similar that with my other entries just create the appropriate <code>prosody.conf</code> (where <code>server_name</code> will be all the subdomains defined above) file and run <code>certbot --nginx</code>. You can find the example configuration file almost at the end of this entry.</li>
<li>Email addresses for <code>admin</code>, <code>abuse</code>, <code>contact</code>, <code>security</code>, etc. Or use your own email for all of them, doesn&rsquo;t really matter much as long as you define them in the configuration and are valid, I have aliases so those emails are forwarded to me.</li>
-<li>Allow ports 5000, 5222, 5269, 5280 and 5281 for <a href="https://prosody.im/doc/ports">Prosody</a> and, 3478 and 5349 for <a href="https://webrtc.org/getting-started/turn-server">Turnserver</a> which are the defaults for <code>coturn</code>.</li>
+<li>Allow ports <code>5000</code>, <code>5222</code>, <code>5269</code>, <code>5280</code> and <code>5281</code> for <a href="https://prosody.im/doc/ports">Prosody</a> and, <code>3478</code> and <code>5349</code> for <a href="https://webrtc.org/getting-started/turn-server">Turnserver</a> which are the defaults for <code>coturn</code>.</li>
</ul>
<h2 id="prosody">Prosody</h2>
<p><a href="https://wiki.archlinux.org/title/Prosody">Prosody</a> is an implementation of the XMPP protocol that is flexible and extensible.</p>
diff --git a/blog/dst/sitemap.xml b/blog/dst/sitemap.xml
index 760e2db..3249556 100644
--- a/blog/dst/sitemap.xml
+++ b/blog/dst/sitemap.xml
@@ -3,6 +3,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
+ <loc>https://blog.luevano.xyz/a/vpn_server_with_openvpn.html</loc>
+ <lastmod>2021-08-01</lastmod>
+ <changefreq>weekly</changefreq>
+ <priority>1.0</priority>
+ </url>
+ <url>
<loc>https://blog.luevano.xyz/a/hoy_toco_desarrollo_personaje.html</loc>
<lastmod>2021-07-28</lastmod>
<changefreq>weekly</changefreq>
@@ -16,7 +22,7 @@
</url>
<url>
<loc>https://blog.luevano.xyz/a/xmpp_server_with_prosody.html</loc>
- <lastmod>2021-06-10</lastmod>
+ <lastmod>2021-08-01</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
@@ -71,43 +77,43 @@
<url>
<loc>https://blog.luevano.xyz/tag/@english.html</loc>
- <lastmod>2021-07-28</lastmod>
+ <lastmod>2021-08-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@server.html</loc>
- <lastmod>2021-07-28</lastmod>
+ <lastmod>2021-08-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@short.html</loc>
- <lastmod>2021-07-28</lastmod>
+ <lastmod>2021-08-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@spanish.html</loc>
- <lastmod>2021-07-28</lastmod>
+ <lastmod>2021-08-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@tools.html</loc>
- <lastmod>2021-07-28</lastmod>
+ <lastmod>2021-08-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@tutorial.html</loc>
- <lastmod>2021-07-28</lastmod>
+ <lastmod>2021-08-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@update.html</loc>
- <lastmod>2021-07-28</lastmod>
+ <lastmod>2021-08-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
diff --git a/blog/dst/tag/@english.html b/blog/dst/tag/@english.html
index 121609a..65833c2 100644
--- a/blog/dst/tag/@english.html
+++ b/blog/dst/tag/@english.html
@@ -80,7 +80,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>June 2021</h3>
+ <h3>August 2021</h3>
+ <li>Aug 01 - <a href="https://blog.luevano.xyz/a/vpn_server_with_openvpn.html">Create a VPN server with OpenVPN (IPv4)</a></li>
+ <h3>June 2021</h3>
<li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
<h3>May 2021</h3>
<li>May 28 - <a href="https://blog.luevano.xyz/a/new_blogging_system.html">I'm using a new blogging system</a></li>
diff --git a/blog/dst/tag/@server.html b/blog/dst/tag/@server.html
index 18fbf43..f60f663 100644
--- a/blog/dst/tag/@server.html
+++ b/blog/dst/tag/@server.html
@@ -80,7 +80,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>June 2021</h3>
+ <h3>August 2021</h3>
+ <li>Aug 01 - <a href="https://blog.luevano.xyz/a/vpn_server_with_openvpn.html">Create a VPN server with OpenVPN (IPv4)</a></li>
+ <h3>June 2021</h3>
<li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
<h3>March 2021</h3>
<li>Mar 21 - <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html">Create a git server and setup cgit web app (on Nginx)</a></li>
diff --git a/blog/dst/tag/@tools.html b/blog/dst/tag/@tools.html
index c1daced..44f4b72 100644
--- a/blog/dst/tag/@tools.html
+++ b/blog/dst/tag/@tools.html
@@ -80,7 +80,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>June 2021</h3>
+ <h3>August 2021</h3>
+ <li>Aug 01 - <a href="https://blog.luevano.xyz/a/vpn_server_with_openvpn.html">Create a VPN server with OpenVPN (IPv4)</a></li>
+ <h3>June 2021</h3>
<li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
<h3>May 2021</h3>
<li>May 28 - <a href="https://blog.luevano.xyz/a/new_blogging_system.html">I'm using a new blogging system</a></li>
diff --git a/blog/dst/tag/@tutorial.html b/blog/dst/tag/@tutorial.html
index f979ad2..4a78b74 100644
--- a/blog/dst/tag/@tutorial.html
+++ b/blog/dst/tag/@tutorial.html
@@ -80,7 +80,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>June 2021</h3>
+ <h3>August 2021</h3>
+ <li>Aug 01 - <a href="https://blog.luevano.xyz/a/vpn_server_with_openvpn.html">Create a VPN server with OpenVPN (IPv4)</a></li>
+ <h3>June 2021</h3>
<li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
<h3>March 2021</h3>
<li>Mar 21 - <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html">Create a git server and setup cgit web app (on Nginx)</a></li>
diff --git a/blog/src/.files b/blog/src/.files
index 72e4f53..7eb1583 100644
--- a/blog/src/.files
+++ b/blog/src/.files
@@ -9,6 +9,7 @@ a/mail_server_with_postfix.md 1616299559.6570284 1623137344.8639452 english,serv
a/new_blogging_system.md 1622172099.117893 1622173322.4337702 english,short,tools,update
a/asi_nomas_esta_quedando.md 1622795043.0874712 0.0 short,spanish,update
a/acomodada_la_pagina_de_arte.md 1623006369.6071973 1623006525.2665823 short,spanish,update
-a/xmpp_server_with_prosody.md 1623216270.0372887 1623300135.5528305 english,server,tools,tutorial
+a/xmpp_server_with_prosody.md 1623216270.0372887 1627809865.4920528 english,server,tools,tutorial
a/tenia_esto_descuidado.md 1626594710.918819 0.0 short,spanish,update
a/hoy_toco_desarrollo_personaje.md 1627452655.5560262 0.0 spanish
+a/vpn_server_with_openvpn.md 1627809822.9715295 0.0 english,server,tools,tutorial
diff --git a/blog/src/a/vpn_server_with_openvpn.md b/blog/src/a/vpn_server_with_openvpn.md
new file mode 100644
index 0000000..ae3530e
--- /dev/null
+++ b/blog/src/a/vpn_server_with_openvpn.md
@@ -0,0 +1,361 @@
+title: Create a VPN server with OpenVPN (IPv4)
+author: David Luévano
+lang: en
+summary: How to create a VPN server using OpenVPN on a server running Nginx. Only for IPv4.
+tags: server
+ tools
+ tutorial
+ english
+
+I've been wanting to do this entry, but had no time to do it since I also have to set up the VPN service as well to make sure what I'm writing makes sense, today is the day.
+
+Like with any other of my entries I based my setup on the [Arch Wiki](https://wiki.archlinux.org/title/OpenVPN), [this install script](https://github.com/Nyr/openvpn-install) and [this profile generator script](https://github.com/graysky2/ovpngen).
+
+This will be installed and working alongside the other stuff I've wrote about on other posts (see the [server](https://blog.luevano.xyz/tag/@server.html) tag). All commands here are executes as root unless specified otherwise. Also, this is intended only for IPv4 (it's not that hard to include IPv6, but meh).
+
+## Prerequisites
+
+Pretty simple:
+
+- Working server with root access, and with Ufw as the firewall.
+- Depending on what port you want to run the VPN on, the default `1194`, or as a fallback on `443` (click [here](https://openvpn.net/vpn-server-resources/advanced-option-settings-on-the-command-line/) for more). I will do mine on port `1194` but it's just a matter of changing 2 lines of configuration and one Ufw rule.
+
+## Create PKI from scratch
+
+PKI stands for *Public Key Infrastructure* and basically it's required for certificates, private keys and more. This is supposed to work between two servers and one client: a server in charge of creating, signing and verifying the certificates, a server with the OpenVPN service running and the client making the request.
+
+This is supposed to work something like: 1) a client wants to use the VPN service, so it creates a requests and sends it to the signing server, 2) this server checks the requests and signs the request, returning the certificates to both the VPN service and the client and 3) the client can now connect to the VPN service using the signed certificate which the OpenVPN server knows about. In a nutshell, I'm no expert.
+
+... but, to be honest, all of this is a hassle and (in my case) I want something simple to use and manage. So I'm gonna do all on one server and then just give away the configuration file for the clients, effectively generating files that anyone can run and will work, meaning that you need to be careful who you give this files (it also comes with a revoking mechanism, so no worries).
+
+This is done with [Easy-RSA](https://wiki.archlinux.org/title/Easy-RSA).
+
+Install the `easy-rsa` package:
+
+```sh
+pacman -S easy-rsa
+```
+
+Initialize the PKI and generate the CA keypair:
+
+```sh
+cd /etc/easy-rsa
+easyrsa init-pki
+easyrsa build-ca nopass
+```
+
+Create the server certificate and private key (while in the same directory):
+
+```sh
+EASYRSA_CERT_EXPIRE=3650 easyrsa build-server-full server nopass
+```
+
+Where `server` is just a name to identify your server certificate keypair, I just use `server` but could be anything (like `luevano.xyz` in my case).
+
+Create the client revocation list AKA CRL (will be used later, but might as well have it now):
+
+```sh
+EASYRSA_CRL_DAYS=3650 easyrsa gen-crl
+```
+
+After this we should have 6 new files:
+
+```
+/etc/easy-rsa/pki/ca.crt
+/etc/easy-rsa/pki/private/ca.key
+/etc/easy-rsa/pki/issued/server.crt
+/etc/easy-rsa/pki/reqs/server.req
+/etc/easy-rsa/pki/private/server.key
+/etc/easy-rsa/pki/crl.pem
+```
+
+It is recommended to copy some of these files over to the `openvpn` directory, but I prefer to keep them here and just change some of the permissions:
+
+```sh
+chmod o+rx pki
+chmod o+rx pki/ca.crt
+chmod o+rx pki/issued
+chmod o+rx pki/issued/server.crt
+chmod o+rx pki/private
+chmod o+rx pki/private/server.key
+chown nobody:nobody pki/crl.pem
+chmod o+r pki/crl.pem
+```
+
+Now, go to the `openvpn` directory and create the required files there:
+
+```sh
+cd /etc/openvpn/server
+openssl dhparam -out dh.pem 2048
+openvpn --genkey secret ta.key
+```
+
+That's it for the PKI stuff and general certificate configuration.
+
+## OpenVPN
+
+[OpenVPN](https://wiki.archlinux.org/title/OpenVPN) is a robust and highly flexible VPN daemon, that's pretty complete feature wise.
+
+Install the `openvpn` package:
+
+```sh
+pacman -S openvpn
+```
+
+Now, most of the stuff is going to be handled by (each, if you have more than one) server configuration. This might be the hardest thing to configure, but I've used a basic configuration file that worked a lot to me, which is a compilation of stuff that I found on the internet while configuring the file a while back.
+
+```
+# Server ip addres (ipv4).
+local 1.2.3.4 # your server public ip
+
+# Port.
+port 1194 # Might want to change it to 443
+
+# TCP or UDP.
+;proto tcp
+proto udp # If ip changes to 443, you should change this to tcp, too
+
+# "dev tun" will create a routed IP tunnel,
+# "dev tap" will create an ethernet tunnel.
+;dev tap
+dev tun
+
+# Server specific certificates and more.
+ca /etc/easy-rsa/pki/ca.crt
+cert /etc/easy-rsa/pki/issued/server.crt
+key /etc/easy-rsa/pki/private/server.key # This file should be kept secret.
+dh /etc/openvpn/server/dh.pem
+auth SHA512
+tls-crypt /etc/openvpn/server/ta.key 0 # This file is secret.
+crl-verify /etc/easy-rsa/pki/crl.pem
+
+# Network topology.
+topology subnet
+
+# Configure server mode and supply a VPN subnet
+# for OpenVPN to draw client addresses from.
+server 10.8.0.0 255.255.255.0
+
+# Maintain a record of client <-> virtual IP address
+# associations in this file.
+ifconfig-pool-persist ipp.txt
+
+# Push routes to the client to allow it
+# to reach other private subnets behind
+# the server.
+;push "route 192.168.10.0 255.255.255.0"
+;push "route 192.168.20.0 255.255.255.0"
+
+# If enabled, this directive will configure
+# all clients to redirect their default
+# network gateway through the VPN, causing
+# all IP traffic such as web browsing and
+# and DNS lookups to go through the VPN
+push "redirect-gateway def1 bypass-dhcp"
+
+# Certain Windows-specific network settings
+# can be pushed to clients, such as DNS
+# or WINS server addresses.
+# Google DNS.
+;push "dhcp-option DNS 8.8.8.8"
+;push "dhcp-option DNS 8.8.4.4"
+
+# The keepalive directive causes ping-like
+# messages to be sent back and forth over
+# the link so that each side knows when
+# the other side has gone down.
+keepalive 10 120
+
+# The maximum number of concurrently connected
+# clients we want to allow.
+max-clients 5
+
+# It's a good idea to reduce the OpenVPN
+# daemon's privileges after initialization.
+user nobody
+group nobody
+
+# The persist options will try to avoid
+# accessing certain resources on restart
+# that may no longer be accessible because
+# of the privilege downgrade.
+persist-key
+persist-tun
+
+# Output a short status file showing
+# current connections, truncated
+# and rewritten every minute.
+status openvpn-status.log
+
+# Set the appropriate level of log
+# file verbosity.
+#
+# 0 is silent, except for fatal errors
+# 4 is reasonable for general usage
+# 5 and 6 can help to debug connection problems
+# 9 is extremely verbose
+verb 3
+
+# Notify the client that when the server restarts so it
+# can automatically reconnect.
+# Only usable with udp.
+explicit-exit-notify 1
+```
+
+`#` and `;` are comments. Read each and every line, you might want to change some stuff (like the logging).
+
+Now, we need to enable *packet forwarding*, which can be enabled on the interface level or globally (you can check the different options with `sysctl -a | grep forward`). I'll do it globally, run:
+
+```sh
+sysctl net.ipv4.ip_forward=1
+```
+
+And create/edit the file `/etc/sysctl.d/30-ipforward.conf`:
+
+```
+net.ipv4.ip_forward=1
+```
+
+Now we need to configure `ufw` to forward traffic through the VPN. Append the following to `/etc/default/ufw` (or edit the existing line):
+
+```
+...
+DEFAULT_FORWARD_POLICY="ACCEPT"
+```
+
+And change the `/etc/ufw/before.rules`, appending the following lines after the header **but before the \*filter line**:
+
+```
+...
+# NAT (Network Address Translation) table rules
+*nat
+:POSTROUTING ACCEPT [0:0]
+
+# Allow traffic from clients to the interface
+-A POSTROUTING -s 10.8.0.0/24 -o interface -j MASQUERADE
+
+# do not delete the "COMMIT" line or the NAT table rules above will not be processed
+COMMIT
+
+# Don't delete these required lines, otherwise there will be errors
+*filter
+...
+```
+
+Where `interface` must be changed depending on your interface (in my case is `ens3`, another common one is `eth0`); I always check this by running `ip addr`, you will get a list of interfaces of which the one containing your public ip is the one that you want, for me it looks something like:
+
+```
+...
+2: ens3: <SOMETHING,SOMETHING> bla bla
+ link/ether bla:bla
+ altname enp0s3
+ inet my.public.ip.addr bla bla
+...
+```
+
+And also make sure the `10.8.0.0/24` matches the subnet mask specified in the `server.conf` file (in this example it matches). You should check this very carefully, because I just spend a good 2 hours debugging why my configuration wasn't working, and this was te reason (I could connect to the VPN, but had no external connection to the web).
+
+Finally, allow the OpenVPN port you specified (in this example its `1194/udp`) and reload `ufw`:
+
+```sh
+ufw allow 1194/udp comment "OpenVPN"
+ufw reload
+```
+
+At this point, the server-side configuration is done and you can start and enable the service:
+
+```sh
+systemctl start openvpn-server@server.service
+systemctl enable openvpn-server@server.service
+```
+
+Where the `server` after `@` is your specific configuration, in my case it is called just `server`.
+
+### Create client configurations
+
+You might notice that I didn't specify how to actually connect to our server. For that we need to do a few more steps. We actually need a configuration file similar to the `server.conf` file that we created.
+
+The real way of doing this would be to run similar steps as the ones with `easy-rsa` locally, send them to the server, sign them, and retrieve them. Nah, we'll just create all configuration files on the server as I was mentioning earlier.
+
+Also, the client configuration file has to match the server one (to some degree), to make this easier you can create a `client-common` file in `/etc/openvpn/server` with the following content:
+
+```
+client
+dev tun
+remote 1.2.3.4 1194 udp # change this to match your ip and port
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+remote-cert-tls server
+auth SHA512
+verb 3
+```
+
+Where you should make any changes necessary, depending on your configuration.
+
+Now, we need a way to create and revoke new configuration files. For this I created a script, heavily based on one of the links I mentioned at the beginning, by the way. You can place these scripts anywhere you like, and you should take a look before running them because you'll be running them as root.
+
+In a nutshell, what it does is: generate a new client certificate keypair, update the CRL and create a new `.ovpn` configuration file that consists on the `client-common` data and all of the required certificates; or, revoke an existing client and refresh the CRL. The file is placed under `~/ovpn`.
+
+Create a new file with the following content (name it whatever you like) and don't forget to make it executable (`chmod +x script_name`):
+
+```
+#!/bin/sh
+# Client ovpn configuration creation and revoking.
+MODE=$1
+if [ ! "$MODE" = "new" -a ! "$MODE" = "rev" ]; then
+ echo "$1 is not a valid mode, using default 'new'"
+ MODE=new
+fi
+
+CLIENT=${2:-guest}
+if [ -z $2 ];then
+ echo "there was no client name passed as second argument, using 'guest' as default"
+fi
+
+# Expiration config.
+EASYRSA_CERT_EXPIRE=3650
+EASYRSA_CRL_DAYS=3650
+
+# Current PWD.
+CPWD=$PWD
+cd /etc/easy-rsa/
+
+if [ "$MODE" = "rev" ]; then
+ easyrsa --batch revoke $CLIENT
+
+ echo "$CLIENT revoked."
+elif [ "$MODE" = "new" ]; then
+ easyrsa build-client-full $CLIENT nopass
+
+ # This is what actually generates the config file.
+ {
+ cat /etc/openvpn/server/client-common
+ echo "<ca>"
+ cat /etc/easy-rsa/pki/ca.crt
+ echo "</ca>"
+ echo "<cert>"
+ sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/easy-rsa/pki/issued/$CLIENT.crt
+ echo "</cert>"
+ echo "<key>"
+ cat /etc/easy-rsa/pki/private/$CLIENT.key
+ echo "</key>"
+ echo "<tls-crypt>"
+ sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/ta.key
+ echo "</tls-crypt>"
+ } > "$(eval echo ~${SUDO_USER:-$USER}/ovpn/$CLIENT.ovpn)"
+
+ eval echo "~${SUDO_USER:-$USER}/ovpn/$CLIENT.ovpn file generated."
+fi
+
+# Finish up, re-generates the crl
+easyrsa gen-crl
+chown nobody:nobody pki/crl.pem
+chmod o+r pki/crl.pem
+cd $CPWD
+```
+
+And the way to use is to run `ovpn_script new/rev client_name` as sudo (when revoking, it doesn't actually deletes the `.ovpn` file in `~/ovpn`). Again, this is a little script that I put together, so you should check it out, it might need tweaks (depending on your directory structure for `easy-rsa`) and it might have errors.
+
+Now, just get the `.ovpn` file generated, import it to OpenVPN in your client of preference and you should have a working VPN service.
diff --git a/blog/src/a/xmpp_server_with_prosody.md b/blog/src/a/xmpp_server_with_prosody.md
index e5d9607..e3e33b5 100644
--- a/blog/src/a/xmpp_server_with_prosody.md
+++ b/blog/src/a/xmpp_server_with_prosody.md
@@ -29,7 +29,7 @@ Same as with my other entries ([website](https://luevano.xyz/a/website_with_ngin
- `_xmpp-server._tcp.muc.**your.domain**.` for port `5269` pointing to `xmpp.**your.domain**.`
* SSL certificates for the previous subdomains; similar that with my other entries just create the appropriate `prosody.conf` (where `server_name` will be all the subdomains defined above) file and run `certbot --nginx`. You can find the example configuration file almost at the end of this entry.
- Email addresses for `admin`, `abuse`, `contact`, `security`, etc. Or use your own email for all of them, doesn't really matter much as long as you define them in the configuration and are valid, I have aliases so those emails are forwarded to me.
-- Allow ports 5000, 5222, 5269, 5280 and 5281 for [Prosody](https://prosody.im/doc/ports) and, 3478 and 5349 for [Turnserver](https://webrtc.org/getting-started/turn-server) which are the defaults for `coturn`.
+- Allow ports `5000`, `5222`, `5269`, `5280` and `5281` for [Prosody](https://prosody.im/doc/ports) and, `3478` and `5349` for [Turnserver](https://webrtc.org/getting-started/turn-server) which are the defaults for `coturn`.
## Prosody