NAT focuses on network-level address translation, allowing packets to reach a destination through IP and port mapping. However, modern applications often require more flexible routing based on application-level information, such as domain names, URLs, headers, or authentication status.
This is where proxies are commonly used.
Proxy (Forward Proxy)
A forward proxy acts on behalf of the client. Instead of directly connecting to a destination server, the client sends requests to the proxy, which forwards the request to the Internet.
Client
│
▼
Forward Proxy
│
▼
Internet Server
The destination server sees the proxy as the requester instead of the original client.
Common use cases
- Enterprise network access control
- Web filtering
- Privacy protection
- Caching frequently accessed resources
Example
Without Proxy:
Client -----------------> Website
With Proxy:
Client -----> Proxy -----> Website
Reverse Proxy
A reverse proxy acts on behalf of the server. Instead of users directly accessing backend services, they connect to the reverse proxy, which decides where to forward the request.
Client
|
v
Reverse Proxy
|
+------------+
| |
v v
Backend A Backend B
The user only knows the reverse proxy address, not the internal backend servers.
Common use cases
- Load balancing
- TLS termination
- Hiding internal services
- Routing requests by domain/path
- Authentication and access control
Example
HTTP Request
|
v
User <================> Nginx Reverse Proxy (Connection A)
|
|
+----------------+----------------+
| (Connection B1) | (Connection B2)
v v
Backend API Image Server
/api/users /api/images
v v
| (Connection B1) | (Connection B2)
+----------------+----------------+
|
|
HTTP Response
|
v
User <================> Nginx Reverse Proxy (Connection A)
NAT vs Reverse Proxy
Although both can redirect traffic, they operate at different levels.
| NAT | Reverse Proxy | |
|---|---|---|
| Layer | Network layer (IP/Port) | Application layer (HTTP) |
| Decision based on | IP address and port | Domain, path, headers, cookies |
| Example | Public IP:443 → Private IP:443 | /api → Backend A |
| Encryption handling | No | Can terminate TLS |
| Awareness of application | No | Yes |
Typical Modern Deployment
In practice, NAT and reverse proxy are often used together:
Internet
|
|
Public IP
|
|
Router
(NAT / Port Forward)
|
|
Reverse Proxy
(Nginx)
+---------+---------+
| |
Frontend Backend API
|
|
Database
- The router solves network-level routing (how does traffic enter my private network?)
- The reverse proxy solves application-level routing (once traffic arrives, which service should handle it?)
Example using Nginx
Change the configuration of Nginx (/etc/nginx/sites-available/your-domain)
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Example using CloudFlare
- Create a named tunnel on CloudFlare dashboard GUI
Networking
|
v
Tunnels
|
v
Create Tunnel
On Linux, start the tunnel connector using the cloudflared agent:
cloudflared tunnel run --token ${CLOUDFLARE_TUNNEL_TOKEN}
This will start the cloudflared agent, authenticate using the tunnel token, establish a connection back to Cloudflare, and join the specified named tunnel. Then configure the routing to the tunnel using the CloudFlare dashboard GUI:
Tunnels
|
v
Configure
|
v
Routes
|
v
Published Application
Once configured, Cloudflare can route requests from the configured domain to the local service:
User
|
| HTTPS request
v
your-domain.com
|
v
Cloudflare Edge
|
v
Named Tunnel
|
v
cloudflared agent
|
v
localhost:3000
The cloudflared agent does not expose port 3000 directly to the Internet. Instead, it creates an outbound tunnel connection to Cloudflare, allowing Cloudflare to forward incoming requests securely through the tunnel to your local service.