blog/bypass-cgnat.html

453 lines
29 KiB
HTML
Raw Normal View History

2023-10-31 09:21:46 +00:00
<!DOCTYPE html>
<html lang="en-IN">
<head>
<title>How to Bypass CGNAT - Exposing your home server to the internet with TLS/SSL pass through | Aiquiral's Blog</title>
<meta name="description" content="You've set up a home server, and are hosting some services like Vaultwarden, or Jellyfin, or perhaps Nextcloud. But now, you want to share it with friends and family, or maybe you just need the ability to access it remotely. So, you decided to expose it to the internet, but your ISP does not let you do that. Issues like dynamic IP can be resolved using a service like Duck DNS or No-IP, but if your ISP does not let you forward your ports, then you have to rely on third-parties to forward your traffic.">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href=/assets/logo/favicon.svg />
<link rel="stylesheet" href=/assets/css/style.css />
</head>
<body>
<div class="head">
<div class="line-top"></div>
<nav>
<ul class='nav-bar'>
<li class='logo'><a href=/index.html><img src=/assets/logo/favicon.svg /></a></li>
<input type='checkbox' id='check' />
<span class="menu">
<li><a href="https://blog.aiquiral.me">Home</a></li>
<li><a href="https://portfolio.aiquiral.me">Portfolio</a></li>
<li><a href="https://aiquiral.me/contact">Contact</a></li>
<li><a href="https://aiquiral.me/about">About</a></li>
<label for="check" class="close-menu">X</label>
</span>
<label for="check" class="open-menu"></label>
</ul>
2023-10-31 09:32:30 +00:00
<noscript>
<img src="https://a.aiquiral.me/ingress/3a4a78d5-5d52-4f8e-9272-925d46af3166/pixel.gif">
</noscript>
<script defer src="https://a.aiquiral.me/ingress/3a4a78d5-5d52-4f8e-9272-925d46af3166/script.js"></script>
</nav>
2023-10-31 09:21:46 +00:00
</div>
<div class="blog-post">
<h1 class="post-heading">How to Bypass CGNAT - Exposing your home server to the internet with TLS/SSL pass through</h1>
<p class="post-date">07 October 2023 | Linux Guide, Privacy, Self-hosting</p>
<img src="/assets/posts/2023-10-07-bypass-cgnat/bypass-cgnat.avif" class="featured" alt="A view of server racks with a text overlay reading “Bpass CGNAT - Privactely Expose Services Hosted on Your Homeserver”." title="How to Bypass CGNAT - Exposing your home server to the internet with TLS/SSL pass through"/>
<h2 id="disclaimer">Disclaimer</h2>
<p>Exposing your home server to the internet can be dangerous. Look up some online guides about securing your servers before you do anything stupid. You have been warned. Also, I have not included any instructions related to SELinux.</p>
<h2 id="contents">Contents</h2>
<ol start="0">
<li><a href="#introduction">Introduction</a>
<ul>
<li><a href="#easy-solutions">Easy solutions</a></li>
<li><a href="#my-solution">My solution</a></li>
</ul>
</li>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#preparing-the-servers">Preparing the servers</a>
<ul>
<li><a href="#setting-up-the-vps">VPS</a></li>
<li><a href="#setting-up-your-home-server">Home server</a></li>
</ul>
</li>
<li><a href="#testing-and-finalising-the-wireguard-connection">Testing and finalising the WireGuard connection</a></li>
<li><a href="#optional-configuration-of-home-server">Optional configuration of home server</a>
<ul>
<li><a href="#haproxy">HAProxy</a></li>
<li><a href="#certbot">Certbot</a></li>
</ul>
</li>
<li><a href="#references">References</a></li>
</ol>
<h2 id="introduction">Introduction</h2>
<p>Youve set up a home server, and are hosting some services like Vaultwarden, or Jellyfin, or perhaps Nextcloud. But now, you want to share it with friends and family, or maybe you just need the ability to access it remotely. So, you decided to expose it to the internet, but your ISP does not let you do that. Issues like dynamic IP can be resolved using a service like Duck DNS or No-IP, but if your ISP does not let you forward your ports, then you have to rely on third-parties to forward your traffic.</p>
<h3 id="easy-solutions">Easy Solutions</h3>
<p>There are many easy solutions to this problem. Cloudflare Tunnel is a free and popular solution. And if you just want remote access, Tailscale is another good option. If Tailscales backend servers are not being open-source is an issue, people can rely on Headscale.</p>
<p>But there is something you must know before considering these solutions. All these rely on TLS/SSL termination, which means your data is decrypted in the servers owned by these third parties.</p>
<p>Let me explain this in detail with taking Cloudflare Tunnel as an example.</p>
<p>One of the reasons we use SSL certificates on our websites to ensure that when the client requests data from the servers, or sends any data back to us, nobody else can look at that it, ensuring the clients privacy. When we use Cloudflare Tunnel, the data may be encrypted on our server, but it is decrypted on Cloudflares servers, then re-encrypted and sent to the client. And when client enters any data like passwords, or upload any image, that data is, again, decrypted on Cloudflares servers (e2ee services are different, discussed below), then re-encrypted and sent back to us.</p>
<p>If you set up a Lets Encrypt certificate on your server and route your traffic through a Cloudflare Tunnel, your clients will see a Cloudflare certificate. If you want them to see your Lets Encrypt certificate, you will have to subscribe to their Business or Enterprise plan.</p>
<p>Take a look at this diagram for better understanding:</p>
<p>Diag</p>
<div class=important-note style="padding-top: 0px">
<h4 id="eli5">ELI5</h4>
<p>Lets say you want to send your friend a message, but you dont want anyone else to read it while in transit. So, you put the message in a locked box. So, if the box gets stolen on the way others wont be able to read the message. That is what SSL certificates do.</p>
<p>But, lets say you cannot go out of your house to deliver the box yourself, because your parents, that is, your ISP, wont let you. So, you hire someone else, say, Cloudflare. But what Cloudflare says, is that they will look inside the box before if you want them to deliver it for free, If you want the box locked, you will have to pay them money.</p>
<p>There are some applications, like Vaultwarden, and Nextcloud with end-to-end encryption plugin, that are not affected with this because they encrypt the data themselves in the clients devices, using their own algorithms.</p>
</div>
<h3 id="my-solution">My solution</h3>
<p>Earlier, I used to do the same thing, but manually. I rented a VPS on Hetzner and connected it to my home server using WireGuard. But since, the certificate management was handled by the VPS using Nginx Proxy Manager my VPS provider, Hetzner, could look at the data. So, I decided to learn about implementing TLS passthrough.</p>
<p>Now, my current setup is I host services on my home server, manage certificates locally, and use the VPS to pass the data to the client without terminating the TLS/SSL connection.</p>
<p>Here is a diagram to explain my setup:</p>
<p>Diag</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>If you have looked at the diagram above, you may have already understood what you need to replicate my setup. Here are the details:</p>
<ul>
<li>A home server.</li>
<li>A VPS to route your traffic.
<ul>
<li><a href="https://developer.oracle.com/free.html">Oracle Cloud</a>s and <a href="https://cloud.google.com/free">Google Cloud</a>s free tier is an option if you are not willing to spend any money. But they are neither performant as they have weak vCPUs and limited bandwidth speed, nor reliable as there have been many reports of Oracle randomly shutting down free tier VPS allotments. Another reason I do not use them is because I would like to stay away from them as much as possible due to their privacy invading history. (Read <a href="https://wikiless.northboot.xyz/wiki/Privacy_concerns_regarding_Google">Google</a>, <a href="https://techhq.com/2022/08/oracle-facing-data-backlash-for-violating-the-privacy-of-billions/">Oracle</a>)</li>
<li>Personally, I use Hetzner (here is my <a href="https://hetzner.cloud/?ref=axsjWq6L448M">referral link</a>, which will give you €20 credit for 3 months). I have been using their services for a long time and never had any issue. Also, their privacy policy is far better than others. Their cheapest ARM servers cost €3.29/mo which have 2 vCPUs and 4 GB RAM.</li>
<li>Other options are Digital Ocean, Vultr, or any VPS provider who will give you root access.</li>
</ul>
</li>
<li>Basic command line knowledge.</li>
<li>WireGuard on both, your home server and the VPS, and iptables on the VPS. Instructions are provided below.</li>
<li>Optionally, HAProxy and Certbot on your home server.</li>
</ul>
<h2 id="preparing-the-servers">Preparing the servers</h2>
<p>I am assuming you have already updated and secured both of your machines and have access to both using <code class="language-plaintext highlighter-rouge">ssh</code> or <code class="language-plaintext highlighter-rouge">dropbear</code>.</p>
<p>First, lets install WireGuard on both.</p>
<h4 id="debianubuntu">Debian/Ubuntu</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install wireguard
</code></pre></div></div>
<h4 id="fedora">Fedora</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo dnf install wireguard-tools
</code></pre></div></div>
<h4 id="arch">Arch</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S wireguard-tools
</code></pre></div></div>
<p>For instructions to install WireGuard on other distributions, visit the <a href="https://www.wireguard.com/install/">official documentation</a>.</p>
<p>On both servers, make sure forwarding is enabled.
Run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/sysctl.conf
</code></pre></div></div>
<p>Make sure <code class="language-plaintext highlighter-rouge">net.ipv4.ip_forward=1</code> is present. If it is not, type it at the end of the file. It might also be the case that it is present but has a pound sign (#) at the start of the line. This means that it is commented, and not enabled. Removing the sign will enable it.</p>
<p>Tip If the file is too big, and you cannot find this line, you can press <code class="language-plaintext highlighter-rouge">ctrl + w</code> to find it.</p>
<p>Save and close the file by pressing <code class="language-plaintext highlighter-rouge">ctrl + x</code>, then <code class="language-plaintext highlighter-rouge">y</code>, and then <code class="language-plaintext highlighter-rouge">enter</code>. If you have not made any changes to the file, pressing <code class="language-plaintext highlighter-rouge">ctrl + x</code> will simply close the file.</p>
<p>If you made any changes to the file, run the following command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo sysctl -p
</code></pre></div></div>
<h3 id="setting-up-the-vps">Setting up the VPS</h3>
<p>On most distributions, iptables comes pre-installed. But if, for any reason, it is not, install it using your systems default package manager.</p>
<h5 id="debianubuntu-1">Debian/Ubuntu</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install iptables
</code></pre></div></div>
<h5 id="fedora-1">Fedora</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo dnf install iptables-services
</code></pre></div></div>
<h5 id="arch-1">Arch</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S iptables
</code></pre></div></div>
<p>For other distributions, a quick search on your favourite search engine will fetch you the instructions.</p>
<p>You may have to start the iptables service.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable iptables.service
sudo systemctl start iptables.service
</code></pre></div></div>
<p>Now, let us set up WireGuard. The basic idea is, the both servers will generate a pair of private and public keys. The WireGuard configuration files on both servers will contain their own private key and each others public key. There are many ways of doing it, but I find this way to be the easiest.</p>
<p>Run the following commands:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wg genkey | sudo tee /etc/wireguard/private.key
sudo chmod go= /etc/wireguard/private.key
sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key
</code></pre></div></div>
<p>The first command generates the private key of the VPS, and it will be saved in a specific location. The second command removes any permissions on the file for users and groups other than the root user to ensure that only it can access the private key. And the third command generates the public key of the VPS, and it will be saved in the same location as the private key.</p>
<p>Now, create a new wireguard configuration file using</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/wireguard/wg0.conf
</code></pre></div></div>
<p>Insert these lines:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey =
PostUp = iptables -t nat -A PREROUTING -p tcp -i eth0 '!' --dport 22 -j DNAT --to-destination 10.0.0.2; iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source SERVER-IP
PostUp = iptables -t nat -A PREROUTING -p udp -i eth0 '!' --dport 55107 -j DNAT --to-destination 10.0.0.2;
PostDown = iptables -t nat -D PREROUTING -p tcp -i eth0 '!' --dport 22 -j DNAT --to-destination 10.0.0.2; iptables -t nat -D POSTROUTING -o eth0 -j SNAT --to-source SERVER-IP
PostDown = iptables -t nat -D PREROUTING -p udp -i eth0 '!' --dport 55107 -j DNAT --to-destination 10.0.0.2;
[Peer]
PublicKey =
AllowedIPs = 10.0.0.2/32
</code></pre></div></div>
<p>Replace the <code class="language-plaintext highlighter-rouge">SERVER-IP</code>, at the end of those lines, with the public IP address of your VPS. For now, we will keep the PrivateKey and PublicKey empty.</p>
<p>Press <code class="language-plaintext highlighter-rouge">ctrl +x</code>, then <code class="language-plaintext highlighter-rouge">y</code>, and then <code class="language-plaintext highlighter-rouge">enter</code>, to save the configuration file.</p>
<h3 id="setting-up-your-home-server">Setting up your home server</h3>
<p>Run the same commands as we did on the VPS to generate public and private keys.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wg genkey | sudo tee /etc/wireguard/private.key
sudo chmod go= /etc/wireguard/private.key
sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key
</code></pre></div></div>
<p>Create a new wireguard configuration file using</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/wireguard/wg0.conf
</code></pre></div></div>
<p>Insert these lines:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Interface]
Address = 10.0.0.2/24
PrivateKey =
[Peer]
PublicKey =
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Endpoint = X.X.X.X:51820
</code></pre></div></div>
<p>Replace X.X.X.X with the public IP address of your VPS. So, the last line should look like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Endpoint = 42.11.109.1:51820
</code></pre></div></div>
<p>Press <code class="language-plaintext highlighter-rouge">ctrl +x</code>, then <code class="language-plaintext highlighter-rouge">y</code>, and then <code class="language-plaintext highlighter-rouge">enter</code>, to save the configuration file.</p>
<p>Now, we will insert the public and private keys in the config files. We will have to go back and forth in your home server and the VPS to print keys and change the configuration files.</p>
<p>On your home server, run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo cat /etc/wireguard/private.key
</code></pre></div></div>
<p>This will print out the private key. Copy it. Now open the config file using</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/wireguard/wg0.conf
</code></pre></div></div>
<p>Paste the copied key in front of the <code class="language-plaintext highlighter-rouge">PrivateKey =</code>.
The line should look like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PrivateKey = U9uE2kb/nrrzsEU58GD3pKFU3TLYDMCbetIsnV8eeFE=
</code></pre></div></div>
<p>Save and exit.</p>
<p>Now, run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo cat /etc/wireguard/public.key
</code></pre></div></div>
<p>This will print the public key of your home server. Copy it.</p>
<p>Return to the VPS and run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/wireguard/wg0.conf
</code></pre></div></div>
<p>Paste the copied key in front of the <code class="language-plaintext highlighter-rouge">PublicKey =</code>. Then, save and exit.</p>
<p>Run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo cat /etc/wireguard/private.key
</code></pre></div></div>
<p>This will print out the private key. Copy it. Now open the config file using</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/wireguard/wg0.conf
</code></pre></div></div>
<p>Paste the copied key in front of the <code class="language-plaintext highlighter-rouge">PrivateKey =</code>. Now, save and exit.</p>
<p>Run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo cat /etc/wireguard/public.key
</code></pre></div></div>
<p>This will print the public key of the VPS. Copy it.</p>
<p>Go back to your home server and run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/wireguard/wg0.conf
</code></pre></div></div>
<p>Paste the copied key in front of the <code class="language-plaintext highlighter-rouge">PublicKey =</code>. Then, save and exit.</p>
<p>Finally, run the following command on both of the server to start WireGuard:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo wg-quick up wg0
</code></pre></div></div>
<h2 id="testing-and-finalising-the-wireguard-connection">Testing and finalising the WireGuard connection</h2>
<p>You can test the connection by pinging the WireGuard IP from either of the servers.</p>
<p>On your VPS, run</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ping 10.0.0.2
</code></pre></div></div>
<p>Press <code class="language-plaintext highlighter-rouge">ctrl + c</code> to stop.
If what you see is something like in the following screenshot, then your configuration is okay and everything should be routed through the VPS.</p>
<p>screenshot</p>
<p>If you have any issues, feel free to post a comment, below.</p>
<p>To make sure that WireGuard is turned on automatically after reboot, run the following command on both the systems:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable wg-quick@wg0
</code></pre></div></div>
<p>Now, you can point your domain(s) and/or subdomains to the public IP address of your VPS.</p>
<h2 id="optional-configuration-of-home-server">Optional configuration of home server</h2>
<h3 id="haproxy">HAProxy</h3>
<p>For a reverse proxy, any solution would work. But personally, I shifted from Nginx Proxy Manager to HAProxy because, In my opinion, it is faster, lightweight and provides more control.</p>
<p>To install HAProxy, use your default package manager.</p>
<h4 id="debianubuntu-2">Debian/Ubuntu</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install haproxy
</code></pre></div></div>
<h4 id="fedora-2">Fedora</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo dnf install haproxy
</code></pre></div></div>
<h4 id="arch-2">Arch</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S haproxy
</code></pre></div></div>
<p>For instructions to install a more recent version, or to install on other distributions, use your favourite search engine.</p>
<p>Start the HAProxy service, and enable it to ensure it is started after every boot, using the following command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start haproxy
sudo systemctl enable haproxy
</code></pre></div></div>
<p>To configure haproxy. Use</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/haproxy/haproxy.cfg
</code></pre></div></div>
<p><a href="https://git.aiquiral.me/aiquiral/Bypass-CGNAT/src/branch/main/homeserver-haproxy.cfg">Here</a> is what my configuration looks like.</p>
<p>To enable the changes after editing the configuration file, we must restart the HAProxy service.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart haproxy
</code></pre></div></div>
<p>If you are using my config file, you will see that I have added a location for an SSL certificate. If you restart the service without providing a valid SSL certificate, it will throw an error and the service will stop.</p>
<p>Now, let us jump to generating an SSL certificate.</p>
<h3 id="certbot">Certbot</h3>
<p>The official documentation states that you must install certbot using Snap package manager. I do not like it at all due to its back-end being proprietary. I used my distibutions (Fedoras) package manager to install certbot and it works fine. So, I leave the installtion of certbot to you.</p>
<p>There are many ways to generate a certbot certificate, depending upon your requirements. I recommend setting up a wildcard certificate. You will need your domain providers API key. A simple search on your search engine will help you find a decent guide. Generate a certificate using <code class="language-plaintext highlighter-rouge">certbot certonly</code> command, as we are going to set up HAProxy with the certificate ourselves.</p>
<p>Certbot will generate a private key and a public key certificate in <code class="language-plaintext highlighter-rouge">/etc/letsencrypt/live/YOURDOMAIN.COM</code> folder. We will have to pipe both of them into a single file.</p>
<p>Run the following commands, after replacing <code class="language-plaintext highlighter-rouge">YOURDOMAIN.COM</code> with your actual domain and providing a proper path to certificate:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo cat /etc/letsencrypt/live/YOURDOMAIN.COM/fullchain.pem /etc/letsencrypt/live/YOURDOMAIN.COM/privkey.pem | sudo tee /path/to/certificate.pem
</code></pre></div></div>
<p>After making sure that certbot will be autorenewing your certificate, you can add this command in your root users crontab. Run the following to create a new cronjob:
sudo crontab -e</p>
<p>Add the above command with proper syntax. Add</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0 22 * * * sudo cat /etc/letsencrypt/live/YOURDOMAIN.COM/fullchain.pem /etc/letsencrypt/live/YOURDOMAIN.COM/privkey.pem | sudo tee /path/to/certificate.pem
</code></pre></div></div>
<p>This will copy the generated keys into your single certificate file, everyday at 10 PM.</p>
<p>Save the file and exit the editor.</p>
<p>Confirm the certificate path in your haproxy.cfg, and restart HAProxy using</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart haproxy
</code></pre></div></div>
<p>That is it. You are done. Whenever you create new services, make sure you update your HAProxy configuration file and restart the HAProxy service.</p>
<p>Although, you do not have to touch your VPS anymore, I still recommend loging into the machine updating and rebooting it regularly.</p>
<p>If you have any questions, or suggestions, leave a comment down below, or reach out to me <a href="https://aiquiral.me/contact">directly</a>.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-wireguard-on-ubuntu-20-04">https://www.digitalocean.com/community/tutorials/how-to-set-up-wireguard-on-ubuntu-20-04</a></li>
<li><a href="https://github.com/mochman/Bypass_CGNAT">https://github.com/mochman/Bypass_CGNAT</a></li>
<li><a href="https://certbot.eff.org/instructions">https://www.digitalocean.com/community/tutorials/how-to-create-let-s-encrypt-wildcard-certificates-with-certbot</a></li>
<li><a href="https://certbot.eff.org/instructions">https://skarlso.github.io/2017/02/15/how-to-https-with-hugo-letsencrypt-haproxy/</a></li>
<li><a href="https://certbot.eff.org/instructions">https://certbot.eff.org/instructions</a></li>
</ul>
</div>
<div class="comments">
<hr>
<h2>Comments</h2>
<script>
var remark_config = {
host: 'https://comments.aiquiral.me',
site_id: 'blog',
}
</script>
<script>!function(e,n){for(var o=0;o<e.length;o++){var r=n.createElement("script"),c=".js",d=n.head||n.body;"noModule"in r?(r.type="module",c=".mjs"):r.async=!0,r.defer=!0,r.src=remark_config.host+"/web/"+e[o]+c,d.appendChild(r)}}(remark_config.components||["embed"],document);</script>
<div id="remark42"></div>
</div>
<div class="comments">
<h2>Recent Posts</h2>
<div class="all-posts-table"><div class="allposts-post">
<a href="/bypass-cgnat">
<img src="/assets/posts/2023-10-07-bypass-cgnat/bypass-cgnat.avif" class="latest" />
<h3 style="color: #25252d;">How to Bypass CGNAT - Exposing your home server to the internet with TLS/SSL pass through</h3>
<p>07 October 2023 | Linux Guide, Privacy, Self-hosting</p>
<p>You've set up a home server, and are hosting some services like Vaultwarden, or Jellyfin, or perhaps Nextcloud. But now, you want to share it...</p>
<p style="color: #2ea3f2;">Read More</p>
</a>
</div><div class="allposts-post">
<a href="/remap-keyboard-keys-using-evremap">
<img src="/assets/posts/2023-05-21-remap-keyboard-keys-using-evremap/evremap.avif" class="latest" />
<h3 style="color: #25252d;">Remap keyboard keys using evremap</h3>
<p>21 May 2023 | Linux Guide</p>
<p>Sometimes a key on your keyboard stops working, and you may not have the time or motivation to fix it or get it fixed. Or...</p>
<p style="color: #2ea3f2;">Read More</p>
</a>
</div><div class="allposts-post">
<a href="/proton-vpn-linux-guide">
<img src="/assets/posts/2023-05-19-proton-vpn-linux-guide/proton.svg" class="latest" />
<h3 style="color: #25252d;">Proton VPN Linux Guide How to install, configure, use and auto-connect?</h3>
<p>19 May 2023 | Linux Guide, Privacy</p>
<p>The official Proton VPN Linux client lacks a lot of features, like changing the connection protocol, quickly connecting to the fastest server of a specific...</p>
<p style="color: #2ea3f2;">Read More</p>
</a>
</div></div>
</div>
<div class="foot"><p style="text-align: center;"><a href="https://soundcloud.com/aiquiral">Music</a> <a href="https://git.aiquiral.me/aiquiral">Other Projects</a> <img src=/assets/logo/inline-logo.svg style="position:relative;bottom:-3px" width=28 height=32></img> <a href="https://aiquiral.me/privacy-policy.html">Privacy Policy</a> <a href="https://aiquiral.me/about.html">About</a></p></div>
<div class="line-bottom"></div>
</body>
</html>