Two-VPS Private Proxy Architecture: Nginx Reverse Proxy Over Wireguard VPN
Overview
Proxy VPS: Public VPS running Nginx reverse proxy with its own public IP.
Backend VPS: Origin VPS running your service (e.g., Gitea, Forgejo), completely private.
Wireguard VPN: Encrypted private tunnel connecting Proxy VPS and Backend VPS.
Traffic flow: Client → Proxy VPS → Wireguard VPN → Backend VPS (service).
Prerequisites
Two Linux VPS servers (Ubuntu recommended).
A domain or subdomain for your service.
Basic Linux command line knowledge.
1. Generate Wireguard Keys on Both VPSes
wg genkey | tee privatekey | wg pubkey > publickey
chmod 600 privatekey publickey
privatekey
holds your private key.publickey
holds your public key.
2. Configure Wireguard on Proxy VPS
Create /etc/wireguard/wg0.conf
:
[Interface]
PrivateKey = <Proxy VPS private key>
Address = 10.200.200.1/24
ListenPort = 51820
[Peer]
PublicKey = <Backend VPS public key>
AllowedIPs = 10.200.200.2/32
Enable and start:
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0
3. Configure Wireguard on Backend VPS
Create /etc/wireguard/wg0.conf
:
[Interface]
PrivateKey = <Backend VPS private key>
Address = 10.200.200.2/24
[Peer]
PublicKey = <Proxy VPS public key>
Endpoint = <Proxy VPS Public IP>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Enable and start:
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0
4. Ensure Backend App Port Is Not Publicly Exposed
4.1 Bind the Service to the VPN IP
Configure your app (Gitea, forgejo, etc) to listen only on VPN IP 10.200.200.2
.
Example for Gitea (app.ini
):
[server]
HTTP_ADDR = 10.200.200.2
HTTP_PORT = 3000
This restricts the app to accept connections only over the secure VPN.
4.2 Firewall Configuration on Backend VPS
Block all incoming traffic except from Proxy VPS VPN IP on the service port (3000):
sudo ufw default deny incoming
sudo ufw allow from 10.200.200.1 to any port 3000 proto tcp
sudo ufw allow 22/tcp # SSH access
sudo ufw enable
sudo ufw reload
Only the Proxy VPS can access your backend service port.
4.3 Verify Port Binding and Traffic Restrictions
Check that service is listening correctly:
sudo ss -tuln | grep 3000
Expected output shows service bound to 10.200.200.2:3000
or 127.0.0.1:3000
, NOT all interfaces (0.0.0.0
).
4.4 Optional: NAT Port Forwarding on Proxy VPS
Alternatively or additionally, on Proxy VPS use iptables to forward incoming public port 443 traffic to backend VPN IP + port 3000:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.200.200.2:3000
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
Add to Wireguard config /etc/wireguard/wg0.conf
on Proxy VPS for automation:
PostUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.200.200.2:3000
PostUp = iptables -t nat -A POSTROUTING -j MASQUERADE
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.200.200.2:3000
PostDown = iptables -t nat -D POSTROUTING -j MASQUERADE
5. Configure Nginx on Proxy VPS
Install Nginx and configure /etc/nginx/sites-available/gitproxy
:
server {
listen 80;
server_name git.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name git.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/git.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.yourdomain.com/privkey.pem;
location / {
proxy_pass http://10.200.200.2:3000/;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Enable site and reload Nginx:
sudo ln -s /etc/nginx/sites-available/gitproxy /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
6. Configure DNS and SSL
Point your domain DNS A record to Proxy VPS public IP.
Obtain SSL with Certbot on Proxy VPS:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d git.yourdomain.com
7. Test Your Setup
Visit:
https://git.yourdomain.com
Access your service securely via the Proxy VPS. Origin VPS IP remains hidden.
Summary Table
Wireguard key gen
Secure keys for VPN connection
Wireguard VPN config
Encrypted tunnel between VPSes
Bind app to VPN IP
Restrict app accessibility
Backend firewall rules
Allow service port only from Proxy VPN IP
Nginx reverse proxy
Proxy requests securely
DNS and SSL setup
Secure domain pointing and encryption
Last updated