Contents (15 sections)
- Why CGNAT blocks everything
- Five workarounds
- 1. Cloudflare Tunnel
- 2. Reverse SSH tunnel
- 3. frp (Fast Reverse Proxy)
- 4. Site-to-site VPN, pfSense to pfSense
- 5. European VPS + WireGuard + socat (recommended)
- The final architecture in detail
- WireGuard configuration on the client side (Proxmox)
- WireGuard configuration on the VPS side
- socat relay on the VPS
- Public reverse proxy in front of socat
- Tunnel security
- Limits and pitfalls
- Conclusion
You have built a tidy Proxmox cluster at home and deployed Nextcloud, Vaultwarden, your mail server, your wiki and your Matomo. Then, when you go to open port 443 to make it all reachable from outside, you discover that your ISP has assigned you an IP address in the 100.64.0.0/10 block. That is CGNAT (Carrier-Grade NAT): your apparent public IP is shared with other customers, you no longer control address translation, and every attempt at port forwarding fails silently.
The bad news: this is increasingly common, especially with mobile operators (fixed 4G/5G, rural boxes) and low-cost alternative ISPs. The good news: there are at least five ways around this lock, and one of them keeps 100% of your traffic under your own control.

Why CGNAT blocks everything #
In a standard internet setup, your router receives a unique public IP and performs NAT between your private LAN and the outside world. You can configure port forwarding 443 → 192.168.1.10:443 on your router and everything works. Under CGNAT, things are different: your router receives an IP from the private 100.64.0.0/10 block, and an upstream router at the ISP puts several hundred subscribers behind a single public IP. You have no access to that carrier router.
The result: your outgoing requests work normally (HTTP, SSH, outgoing WireGuard). But no incoming connection from the internet can reach your LAN: the ISP does not know which customer to send the TCP SYN packet on port 443 to.
Five workarounds #
1. Cloudflare Tunnel #
The simplest setup: install the cloudflared daemon on the internal host; it opens an outgoing tunnel to Cloudflare and exposes your services on a Cloudflare subdomain. No network configuration at all, working in 10 minutes.
2. Reverse SSH tunnel #
The quickest method: ssh -N -R 0.0.0.0:443:127.0.0.1:443 user@mon-vps. The VPS opens its port 443 and forwards all traffic through the SSH tunnel. Sovereign (it is your VPS) and simple to set up. The downside: fragile over long periods, noticeable added latency, and SSH is not optimised for high-throughput web traffic. Good for debugging or occasional admin access, bad for production.
3. frp (Fast Reverse Proxy) #
An open-source tool written in Go, with a server daemon on the VPS and a client on the home LAN. It exposes arbitrary TCP/UDP ports. Faster than SSH -R, simpler than WireGuard. Moderately sovereign (it depends on the upstream project), it remains a good option if you want to avoid the complexity of WireGuard.
4. Site-to-site VPN, pfSense to pfSense #
An enterprise multi-site approach: one pfSense at home, one pfSense on a VPS, with an IPsec or OpenVPN tunnel between them. Very robust, but it requires two dedicated pfSense machines and real networking expertise. Oversized for a single homelab, ideal for connecting several business sites.
5. European VPS + WireGuard + socat (recommended) #
The most balanced option: a VPS with a sovereign European hosting provider (Hetzner, OVH, Scaleway, Infomaniak) as the gateway, an encrypted WireGuard tunnel between the VPS and the Proxmox host, and a socat relay that forwards the VPS's public port 443 traffic to the internal services through the tunnel. End-to-end encryption, full sovereignty and native WireGuard performance.
The final architecture in detail #
Here is how packets travel in the recommended setup. An end client hits port 443 on the VPS, which goes through the public reverse proxy; socat then wraps the TCP stream in the encrypted WireGuard tunnel, which comes out on the Proxmox host behind the CGNAT, where a second socat (or the LXC service directly) receives the stream.

WireGuard configuration on the client side (Proxmox) #
We install WireGuard directly on the Proxmox host (or in a dedicated LXC if you prefer to isolate it). The configuration file looks like this.
# /etc/wireguard/wg0.conf (Proxmox side, behind CGNAT)
[Interface]
PrivateKey = <cle_privee_proxmox>
Address = 10.66.66.2/32
MTU = 1280
[Peer]
PublicKey = <cle_publique_du_vps>
Endpoint = vps.exemple.fr:51820
AllowedIPs = 10.66.66.1/32
PersistentKeepalive = 25The MTU = 1280 directive matters too: it avoids fragmentation of encapsulated UDP packets on mobile networks with a reduced MTU. It is the value WireGuard officially recommends for unreliable paths.
WireGuard configuration on the VPS side #
# /etc/wireguard/wg0.conf (public VPS side)
[Interface]
PrivateKey = <cle_privee_vps>
Address = 10.66.66.1/32
ListenPort = 51820
[Peer]
PublicKey = <cle_publique_du_proxmox>
AllowedIPs = 10.66.66.2/32# Enable at boot on both sides
systemctl enable --now wg-quick@wg0
# Check that the tunnel is up
wg show wg0
# latest handshake must be < 2 minutessocat relay on the VPS #
Once the WireGuard tunnel is up, we configure socat on the VPS to relay TCP traffic from the public port to the Proxmox host's internal IP inside the tunnel. We wrap it in a systemd unit so that the service can be restarted cleanly.
# /etc/systemd/system/socat-nextcloud.service
[Unit]
Description=socat relay 443 vers Nextcloud via WireGuard
After=network-online.target wg-quick@wg0.service
Requires=wg-quick@wg0.service
[Service]
Type=simple
ExecStart=/usr/bin/socat -d -d TCP4-LISTEN:8443,reuseaddr,fork TCP4:10.66.66.2:443
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetsystemctl daemon-reload
systemctl enable --now socat-nextcloud.service
systemctl status socat-nextcloud.servicePublic reverse proxy in front of socat #
To serve several services on the same public port 443, we put Nginx (or Traefik) in front. Each vhost routes to a different socat according to the server_name.
# /etc/nginx/sites-enabled/nextcloud.conf (on the VPS)
server {
listen 443 ssl http2;
server_name cloud.exemple.fr;
ssl_certificate /etc/letsencrypt/live/cloud.exemple.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.exemple.fr/privkey.pem;
client_max_body_size 10G;
proxy_request_buffering off;
location / {
proxy_pass http://127.0.0.1:8443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Tunnel security #
- The WireGuard keys are encrypted on the Proxmox disk with LUKS if the host is physically exposed.
- The VPS firewall only allows port 51820 UDP (WireGuard) and 443 TCP (public reverse proxy). Admin SSH is restricted by source IP.
- The WireGuard tunnel is itself encrypted (ChaCha20-Poly1305). The socat traffic inside is in clear text within the tunnel but already encrypted by TLS at the application level (Nginx terminates TLS for the client, and the internal service runs its own TLS if needed).
- For strict end-to-end encryption with no TLS termination at all on the VPS, use an Nginx
stream { ssl_preread; }block with SNI routing instead of a standard HTTP vhost.
Limits and pitfalls #
- Extra latency: 5 to 30 ms depending on how far away the VPS is. Place it in the same region as your users.
- Bandwidth is limited by the VPS link: a 1 Gbps VPS is more than enough, but check it against your usage.
- If the VPS goes down, every exposed service becomes unreachable. Plan external monitoring (UptimeRobot, or a second standby VPS in DNS round-robin).
- An entry-level VPS costs around €5 to €10 a month with sovereign European hosting providers. Include it in the project's total cost of ownership.
- UDP services (games, VoIP) need a different socat or Nginx stream configuration: think carefully about the protocol being carried before adding a service.
Conclusion #
CGNAT is not a dead end. With a European VPS at a few euros a month, WireGuard and socat (all three open source and mature), you can expose your Proxmox services publicly with the same performance as a direct fixed IP, while keeping 100% of your traffic under your own control. It is more work than a Cloudflare tunnel, but it is consistent with the whole approach: if you are leaving the big platforms, you do not let them back in through the cellar.
To go further with the infrastructure behind this tunnel, the PBS guide explains how to protect the whole fleet with an enterprise-grade backup policy, and the Proxmox vs TrueNAS vs Unraid comparison helps you choose the right base if you are starting from scratch.




