NAT and Port Forwarding: Route to Internal Services
Configure NAT and port forwarding on VPS. Route external traffic to internal services, access multiple apps on single VPS, expose internal networks.
On this page
NAT (Network Address Translation) rewrites network packets, allowing traffic from one IP/port to reach another IP/port. Port forwarding is NAT's most common use: expose internal services to the internet on a single public IP.
What is NAT?
Basic example:
- Internet user visits yourserver.com:8080
- NAT intercepts traffic on port 8080
- Rewrites packet to internal IP:9000
- Internal app (running on port 9000) responds
- NAT rewrites response back to public IP:8080
- User receives response transparently
Port Forwarding Basics
Three components:
- Public IP: What internet sees (your VPS IP)
- Public port: Port users connect to (80, 443, 8080, etc.)
- Internal service: Private IP:port (localhost:3000, 192.168.1.10:9000)
Common forwarding scenarios:
Internet:80 → localhost:8080 (local web app)
Internet:443 → localhost:443 (local HTTPS)
Internet:3306 → 10.0.0.5:3306 (remote database)
Internet:22 → localhost:2222 (SSH on non-standard port)
Real-World Use Cases
| Use Case | Example |
|---|---|
| Multiple web apps on one VPS | Port 80→8000, 443→8001, etc. |
| Game server | Internet:7777 → localhost:7777 |
| Database access from office | Internet:3306 → internal-db:3306 |
| SSH on custom port | Internet:2222 → localhost:22 |
| Expose internal network | Internet → internal LAN service |
Configure with iptables
Simple port forward (temporary):
# Forward port 8080 to localhost:3000
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 3000
# Forward to different IP (requires ip_forward enabled)
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A PREROUTING -p tcp --dport 3306 -j DNAT --to-destination 10.0.0.5:3306
sudo iptables -A FORWARD -p tcp -d 10.0.0.5 --dport 3306 -j ACCEPT
View current rules:
sudo iptables -t nat -L -n -v
Make Rules Persistent
Rules disappear on reboot. Save permanently:
# Save current rules
sudo iptables-save > /etc/iptables/rules.v4
# Load on boot (Debian/Ubuntu)
sudo apt install iptables-persistent
# Choose 'Yes' when prompted to save IPv4 rules
Or edit /etc/iptables/rules.v4 directly:
# Add this to nat table
-A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 3000
Verify Configuration
# Test port forwarding from another machine
telnet yourserver.com 8080
# Check if port is listening
sudo netstat -tulpn | grep 8080
# Test with curl
curl http://yourserver.com:8080
Advanced Scenarios
Load balance across multiple backends:
# Round-robin between two servers
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1:8000
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2:8000
Forward SSH to different port (security):
# Hide SSH on standard port 22, expose on 2222
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j REDIRECT --to-port 22
# Now: ssh -p 2222 user@server.com
Troubleshooting
| Problem | Solution |
|---|---|
| Port forwarding not working | Check: iptables rules exist, ip_forward enabled, service listening |
| Rules disappear on reboot | Save with iptables-persistent or edit rules.v4 |
| Connection refused | Verify internal service is actually listening on target port |
| Slow connection | NAT overhead is minimal; check network itself |
Port forwarding exposes internal services to the internet. Only forward what you need. Prefer reverse proxies (Nginx) or VPNs for sensitive services.
Related: VPS networking | Firewall setup | Reverse proxy setup
Need a Cloud VPS?
Launch an UnderHost Cloud VPS when you need root access, dedicated resources, custom software, or more control than shared hosting.





















