Moving Out, Working Remotely, and the CGNAT Challenge

Establishing a new Remote Work Setup

As a remote worker, a rock-solid internet connection isn’t just a luxury—it’s absolutely essential. While dropped calls are annoying, losing connectivity mid-SQLPlus session can be downright disastrous. Sure, tools like tmux can mitigate some connectivity hiccups, but a stable foundation is always preferable. My previous setup relied on a standard 100Mbps VDSL line, which proved more than adequate for my needs. It also gave me the freedom to tinker and build my own personalized infrastructure. This ““digital haven”” of mine included:

  • Proxmox VE: My trusty virtualization platform, hosting several virtual machines tailored for specific tasks.
  • OPNSense: A powerful firewall and router.
  • Docker Boxes: Lightweight containers housing various applications, from development environments to media servers.
  • NAS Server: A central repository for all my important data, accessible from anywhere.
  • WireGuard: A secure VPN solution for accessing my home network remotely.
  • Nginx Reverse Proxy: A robust web server powering my personal projects and websites.
  • Monitoring Tools (Grafana/Prometheus Stack): Keeping a vigilant eye on the health and performance of my infrastructure.

This very website, hosted on a humble Raspberry Pi 4, is a testament to my DIY approach. It’s a space to share my experiences, insights, and projects with the world. However, the move presented a new set of challenges..

The area I was considering moving to, while idyllic in many ways, presented a significant hurdle: ADSL. With average downstream speeds hovering around a paltry 8Mbps and upstream speeds barely scraping 1Mbps, it was simply insufficient for my remote work demands. There was no timeline for VDSL or fiber installation, although a network cabin sat tantalizingly close to the property. Upon inquiry, I discovered the cabin was, frustratingly, empty.

Starlink briefly crossed my mind, but the lengthy wait times and hefty price tag were deterrents. But hope wasn’t lost. I wanted to get a good grasp on the 5G coverage in the area, so I used CellMapper to get an initial idea and even went out to test the signal strength firsthand to pinpoint the 5G cell mast that would likely serve me. I also made extensive use of FTTHGR, a community-driven website where users share geotagged information about VDSL/fiber cabinets, to see if there were any future plans for upgrades in the area.

5G Signal Strength

After these investigations, I became convinced that a 5G router would be the solution. Two months before the move, I took the plunge and purchased a 5G router. Back at my current residence, I began running rigorous tests. The results were promising, fueling my optimism about a smooth transition to my new home.

My company even graciously provided me with a free extra SIM, boasting unlimited data, and helped activate the “internet-vpn”, which I was not able to do so on my part, due to the restrictions of the business plan. I also acquired a Mikrotik router, eager to tinker with its capabilities (after all, it’s unwise to keep all your eggs in one basket, especially when OPNSense already runs on one of my servers).

Once I was settled in my new home, I set up the 5G connection and began monitoring bandwidth usage with Grafana to ensure it met my needs.

Bandwidth Usage

As you can see from the screenshot, the bandwidth remained stable and sufficient for my demanding remote work tasks, including video conferencing and large file transfers.

The Impact of Data Caps on Remote Work

So all was going well, until around two weeks post-move. It was around 3 AM when a colleague from monitoring alerted me to a critical issue in production. I immediately tried to connect and check, only to discover I had absolutely no connectivity. Glancing at the 5G modem, I was greeted by the dreaded red LEDs.

Connectivity Loss

While there was no panic, as I was able to tether my phone and resolve the issue that way, a call with my 5G ISP revealed a disheartening truth: the ““unlimited”” data cap had been reduced to a measly 20GB. To add insult to injury, this happened on the very day I moved in. This setback was significant because:

  • I rarely use WiFi if I can avoid it.
  • I need complete control over my network and routing, something tethering simply doesn’t allow.
  • My new 5G modem and Mikrotik router were now effectively paperweights.

CGNAT and its consequences

Scrambling to find a solution, and running on fumes after a sleepless night, I stumbled upon a little-known ISP, offering surprisingly affordable plans. I won’t mention their name for liability purposes, but let’s just say they became my knight in shining armor.

On my previous VDSL connection, I was able to circumvent CGNAT limitations using a service called DDNS (Dynamic DNS). This allowed me to assign a hostname to my home network, which automatically updated even if my public IP address changed. This, in conjunction with port forwarding configured on my router, enabled me to access services running on my home network from anywhere. However, this workaround relies on having a dedicated public IP address, even if it’s shared through CGNAT. My new 5G ISP’s lack of an internet-VPN APN effectively locked me out of this solution. Without a dedicated VPN tunnel to my home network, DDNS couldn’t bridge the gap created by the shared public IP address and the absence of port forwarding capabilities.

A VPS Solution: Code Implementation and Configuration

Luckily, foresight had paid off. I had already purchased a subscription with a VPS provider, intending to use it as a VPN-Reverse Proxy Gateway, channeling traffic to my trusty Raspberry Pi 4, which I mentioned earlier. This was an earlier project, with its own set of challenges, mostly security to be honest, but I’ll elaborate on in a future post.

The main point here is that this website was previously hosted on a free-tier Oracle Cloud VM. Unfortunately, I missed the informational email about its termination due to low resource usage a few days too late, and the site was lost.

But back to the pressing issue: after successfully configuring the WireGuard peers and the Mikrotik router, I was finally greeted with the sweet sound of a successful handshake!

For those interested I will be providing my wireguard configs below.

VPS with Public IP Address

 1[Interface]
 2Address = 10.10.20.1/24
 3PostUp = echo 1 > /proc/sys/net/ipv4/ip_forward;
 4PostUp = echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp
 5PostUp = ip rule add not from 10.10.20.0/24 table main # This is needed to allow SSH access after enabling connection
 6PostUp = iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
 7PostUp = iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
 8PostUp = iptables -A FORWARD -i wg1 -o wg1 -m conntrack --ctstate NEW -j ACCEPT
 9PostDown = ip rule del not from 10.10.20.0/24 table main
10PostDown = iptables -D FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
11PostDown = iptables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
12PostDown = iptables -D FORWARD -i wg1 -o wg1 -m conntrack --ctstate NEW -j ACCEPT
13PostDown = echo 0 > /proc/sys/net/ipv4/ip_forward
14PostDown = echo 0 > /proc/sys/net/ipv4/conf/all/proxy_arp
15FwMark = CORRESPONDS_TO_LISTENING_PORT_CAN_BE_GENERATED_WITH_HEX_GEN
16ListenPort = PORT_GOES_HERE
17PrivateKey = *******************************************
18
19[Peer] # Mobile
20PublicKey = ********************************************
21AllowedIPs = 10.10.20.3/32
22
23[Peer] # WG_Jumphost
24PublicKey = ********************************************
25AllowedIPs = 10.10.20.2/32
26AllowedIPs = 10.10.20.2/32,0.0.0.0/0

WG_Jumphost

 1[Interface]
 2PostUp = echo 1 > /proc/sys/net/ipv4/ip_forward
 3PostUp = echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp
 4PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE;
 5PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE;
 6PostDown = echo 0 > /proc/sys/net/ipv4/ip_forward
 7PostDown = echo 0 > /proc/sys/net/ipv4/conf/all/proxy_arp
 8Address = 10.10.20.2/32
 9PrivateKey = *******************************************
10
11[Peer] # VPS
12PublicKey = ********************************************
13Endpoint = fluorax.cc:PORT_GOES_HERE
14AllowedIPs = 10.10.20.1/24
15PersistentKeepalive = 21

Phone

 1[Interface]
 2Address = 10.10.20.3/32
 3DNS = 192.168.1.104 #PiHole
 4PrivateKey = ********************************************
 5
 6[Peer] #VPS
 7AllowedIPs = 10.10.20.0/24, 0.0.0.0/0, 192.168.0.0/16
 8Endpoint = 45.61.161.200:POST_GOES_HERE
 9PersistentKeepalive = 25
10PublicKey = *********************************************

A slight caveat, I know that listing ports and PublicKeys is considered safe. Call me paranoid, but when I first set up the WG-Reverse Proxy tunnel, I got around 500 attacks in a single day. Not taking any chances here.


2024-08-24