How can I bypass CGNAT by using a VPS with a public IPv4 address?
I want to move away from Cloudflare tunnels, so I rented a cheap VPS from Hetzner and tried to follow this guide. Unfortunately, the WireGuard setup didn't work. I'm trying to forward all traffic from the VPS to my homeserver and vice versa. Are there any other ways to solve this issue?
You don't want to forward all traffic. You can do SNAT port forwards across the VPN, but that requires the clients in your LAN to use the VPS as their gateway (I do this for a few services that I can't run through a proxy; its clunky but works well).
Typically, you'll want to proxy requests to your services rather than forwarding traffic.
Setup Wireguard or OpenVPN on the VPS as a server VPN. Allow whatever listener port in the firewall (I use ufw on Debian, but you can use iptables if you want)
Install HAProxy or Nginx (or Nginx Proxy Manager) on the VPS to act as your frotnend. Those will listen on ports 80/443 and proxy requests to your backend servers. They'll also be responsible for SSL termination, and your public-facing certs will be set there.
Point your DNS records for your services to the VPS's public IPv4
On your LAN, configure your router to connect to the VPS as a VPN client and route into your LAN from the VPN subnet -or- install the VPN client (WG/OVPN) on each host
In your VPS's reverse proxy (HAProxy, etc), set the backend server address and port to the VPN address of your host
I've done this since ~2013 (before CF tunnels were even a product) and has worked great.
My original use case was to setup direct connectivity between a Raspberry PI with a 3G dongle with a server a home on satellite internet. Both ends of that were behind CG-NAT, so this was the solution I came up with.
Out of curiosity, why not a simple reverse proxy on the VPS (that only adds client real IP to headers), tunneled to a full reverse proxy on the home server (that does host routing and everything else) through a SSH tunnel?
The biggest obstacle for me is the connection between the VPS and my homeserver. I have tried this today and I tried pinging 10.0.0.2 (the homeserver IP via WireGuard) and get this as a result:
Can you post your WG config (masking the public IPs and private key if necessary)?
With wireguard, the allowed-ips setting is basically the routing table for it.
Also, you don't want to set the endpoint address (on the VPS) for your homeserver peer since it's behind NAT. You'll only want to set that on the 'client' side. Since you're behind NAT, you'll also want to set the persistent keepalive in the client peer so the tunnel remains open.
I use this too, and it should be noted that this does not require wireguard or any VPN solution. Rathole can be served publicly, allowing a machine behind a NAT or firewall to connect.
I like that its really simple and obvious, with a good confif file structure.
Server forwards a port to a client.
Client forwards that to an ip:port.
If you need to know the real IP, its up to you to run reverse-proxies that support PROXY TCP headers or insert x-forward-for, or whatever.
Rathole does its thing, only its thing, and does it well.
And so mywebsite.com is accessible on the clearnet through the VPS
Though given you're getting rid of cloudflare tunnles I don't know if you'd want to get into Tailscale. There's Headscale too but I haven't worked with it so I can't comment
I don't have to fiddle with IPTables or PostUp / PostDown rules. I just run that container on both my local machine and the VPS, and use the wg0.conf and peer1.conf it spits out for me.
Not sure exactly how good this would work for your use case of all traffic, but I use autossh and ssh reverse tunneling to forward a few local ports/services from my local machine to my VPS, where I can then proxy those ports in nginx or apache on the VPS. It might take a bit of extra configuration to go this route, but it's been reliable for years for me. Wireguard is probably the "newer, right way" to do what I'm doing, but personally I find using ssh tunnels a bit simpler to wrap my head around and manage.
Technically wireguard would have a touch less latency, but most of the latency will be due to the round trip distance between you and your VPS and the difference in protocols is comparatively negligible.
This one works , I myself have done it cause my shitty isp needs a huge payment for a static public ip. A 5$ VPS was much cheaper .
Server behind NAT
I can help if you got any doubts
I had a similar problem like you. My provider only gives me a public IPv6 but no public IPv4. Im using a VPS with an IPv4 with jool to set up SIIT-DC https://nicmx.github.io/Jool/en/siit-dc.html
This converts all IPv4 traffic arriving at the VPS to IPv6 traffic which gets then directly routed to my homeserver.
Not sure if this setup would work for you. This is not a viable solution if you are completly behind a CGNAT without even a public IPv6.
Pro:
Works without any sensitive Data on the VPS (SSl certificates/passwords...)
Works for all IP based traffic (TCP,UDP,ICMP)
The original source IPv4 can be restored by the homeserver
Contra:
AFAIK you cannot choose to only forward some TCP ports. Everything gets redirected.
You cannot access the VPS via IPv4 anymore since it gets redirected to your homeserver. (I only access my VPS via IPv6)
No (additional) encryption. (This is no problem for me since all my traffic is already e2e encrypted)
I did this. Works flawlessly for half year now. I have x86 thin client at home running all my stuff, it creates tunnel to my VPS (I use Free tier Oracle VPS - yes, it is a shit company, I know, no need to let me know again in the comments). Works like a charm. This GitHub repo has automated installer for Oracle, Amazon,... https://github.com/mochman/Bypass_CGNAT/wiki/Oracle-Cloud-(Automatic-Installer-Script) - it installs and configures Wireguard on both server (VPS) and client (your home machine).