Nginx, Reverse Proxy, and DNS
How a domain name turns into a real response: what DNS is, what a reverse proxy is, and how Nginx connects both worlds in any modern web application.

A Bit Of Context
Every time you type an address into your browser and a page shows up, several things actually happened before you saw a single pixel:
- First, someone translated that name into a numeric address.
- And second, another entity decided which real machine was going to answer that request.
These two actors are, respectively, DNS and, very often, a reverse proxy like Nginx.
For a good understanding, you're expected to have general computer science knowledge; however, every networking concept will be covered from its most basic foundation, or at least with a general overview.
Our main points of focus will be:
-
DNS (Domain Name System): The system that translates human-readable names (Domains like
example.com) into IP addresses that machines need in order to connect to each other. Essentially, an address book for the internet. -
Reverse proxy: An intermediary server that receives traffic on behalf of one or several real servers, and internally decides which one to forward each request to. The client never knows what's behind it, it only sees the intermediary.
-
Nginx: The most widely used open-source software in the world for fulfilling that reverse proxy role, in addition to being able to work as a web server, load balancer, and cache server.
Before getting into detail, it helps to have a clear picture of the whole journey, because each piece only makes sense in relation to the others:
- Without DNS, your browser wouldn't know which address to connect to when you type a domain name.
- Without a reverse proxy, every server would have to be directly exposed to the internet, with no one to distribute the load, filter traffic, or handle encryption centrally.
- Nginx is the concrete tool that, in practice, almost always shows up solving that second problem.
Additionally, the following concepts may clear up some doubts or be useful later on:
-
All communication on the internet happens between a client and a server, where the client asks and the server answers.
-
Every device on a network is identified by a unique IP address, and every service within that device is further identified by a port (for example, 80 for HTTP and 443 for HTTPS).
-
Domain names exist only for people; machines always end up talking in terms of IP and port.
-
The same physical or virtual server can serve multiple domains and applications at once, and it's precisely the reverse proxy that puts that traffic in order.
-
HTTP and HTTPS (the encrypted version of HTTP) are the protocols a browser uses to talk to a web server.
Let's Get Started
We'll walk through the three concepts in the same order they occur when you visit a website.
DNS: from a name to an IP address
When you type www.example.com, that name isn't useful on its own to connect to anything, it's just a label meant for humans. The process of turning that label into a real IP is called DNS resolution, and it happens in several steps:
| Step | What happens |
|---|---|
| 1. Query to the resolver | Your device asks a DNS resolver server (your internet provider's, or a public one like 8.8.8.8 or 1.1.1.1) whether it knows the domain's IP. |
| 2. Root servers | If the resolver doesn't have the answer cached, it asks the internet's root servers, which point it to who to ask next based on the domain's ending (.com, .cl, .org, etc.). |
| 3. TLD server | The top-level domain server (for example, all .com domains) responds with the name servers responsible for example.com. |
| 4. Authoritative server | The authoritative name server for example.com finally hands over the real IP. |
| 5. Response and caching | The resolver stores the answer for a period of time (TTL) and delivers it to your device, which can now start the actual connection. |
One of the best analogies is to think of DNS as the contacts in your phone:
You dial a name → the phone looks up the real number in the list → the phone calls it for you.
YOU NEVER NEED TO MEMORIZE THE NUMBER!
DNS only resolves which IP to connect to, it knows nothing about what happens after that. Things like how many servers are behind it, whether there's load balancing, or how the traffic is encrypted. All of that is the responsibility of whatever receives the connection at that IP, and that's where the reverse proxy comes in.
The role of a reverse proxy
Suppose an application doesn't run on a single server, but on several (to handle more traffic), and you also want to manage HTTPS encryption in one single place, without directly exposing each internal server to the internet. That's where the need for an intermediary appears.
A proxy, in general, is any intermediary between two parties that communicate. There are two possible directions:
-
Forward proxy: Acts on behalf of the client, commonly used in corporate networks to filter or control employees' outgoing internet access. The destination server sees the proxy, not the real client.
-
Reverse proxy: Acts on behalf of the server, here the client thinks it's talking directly to "the site", but it's actually talking to the reverse proxy, which internally decides which real server to forward each request to.
For this last one, picture the front desk of an office building. The visitor only tells the receptionist what they need, and it's the receptionist who knows the internal layout and directs the request to the right floor.
The visitor never needs to know, nor finds out, exactly which floor each office is on. A reverse proxy does exactly that with web traffic. Among the different needs it covers, the following are of interest to us:
- Hiding the real infrastructure: Internal servers are never directly exposed to the internet.
- Load balancing: Distributes incoming traffic across several servers doing the same job, preventing any single one from becoming overloaded.
- SSL/TLS termination: Centralizes certificate management and HTTPS encryption, talking plain HTTP with the internal servers.
- Routing by domain or path: Can decide, for example, that
/apigoes to one server and/imagesto another, all under the same public entry point. - Response caching: Can store copies of frequent responses to answer faster.
- Additional security: Can limit requests per second (rate limiting), filter malicious traffic, or compress responses before they reach the real servers.
Nginx: the tool that does all of this in practice
Nginx was born in 2004, created by Igor Sysoev, with a very concrete goal:
"Handle a huge number of simultaneous connections using few hardware resources"
Over time it became one of the most widely used web servers and reverse proxies in the world, alongside Apache. Nginx can fulfill several roles, often at the same time:
| Role | What it does |
|---|---|
| Web server | Directly serves static files (HTML, images, CSS, JS) to clients. |
| Reverse proxy | Receives requests and forwards them to other server(s) or applications. |
| Load balancer | Distributes traffic across several equivalent backend servers. |
| Cache server | Stores copies of responses to speed up future requests. |
It's very common for Nginx to not serve the final content itself, but instead act as the public entry point of an application, while the real work is done by a backend (Node.js, Python, Java, etc.).
Basic configuration as a reverse proxy
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}| Line | What it does |
|---|---|
server { ... } | Defines the configuration for a specific domain or site. |
listen 80; | Listens for incoming connections on port 80 (unencrypted HTTP). |
server_name www.example.com; | Indicates which domain this block applies to, a single Nginx instance can handle several different domains. |
location / { ... } | Defines what to do with requests that match the / path. |
proxy_pass http://127.0.0.1:3000; | This line is the key one, since it forwards the request to the real server, instead of Nginx answering it itself. |
proxy_set_header Host $host; | Preserves the original domain requested by the client when forwarding the request. |
proxy_set_header X-Real-IP $remote_addr; | Tells the backend the client's real IP, since otherwise it would only see Nginx's IP. |
Load balancing across several servers
upstream my_application {
server 10.0.0.1:3000;
server 10.0.0.2:3000;
server 10.0.0.3:3000;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://my_application;
}
}The upstream block defines a group of equivalent backend servers. By default, Nginx distributes incoming requests among them on a rotating basis (round robin), although other strategies exist (such as least_conn and ip_hash) for more specific cases.
SSL/TLS termination (HTTPS) in Nginx
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
server {
listen 80;
server_name www.example.com;
return 301 https://$host$request_uri;
}Here Nginx receives the encrypted traffic on port 443, handles all the decryption work itself using the configured certificate, and talks plain HTTP with the internal backend (which can be on a private network, with no need to handle certificates). The second server block redirects any visit over HTTP (port 80) to the HTTPS version.
Basic commands to manage Nginx
| Command | Description |
|---|---|
sudo systemctl start nginx | Starts the Nginx service. |
sudo systemctl stop nginx | Stops the service. |
sudo systemctl restart nginx | Restarts Nginx, applying configuration changes. |
sudo systemctl reload nginx | Reloads the configuration without dropping active connections. |
sudo nginx -t | Checks that the configuration syntax is valid, without applying it. |
sudo nginx -s reload | Reloads the configuration directly via the Nginx binary. |
tail -f /var/log/nginx/error.log | Shows the error log live, key for diagnosing problems. |
tail -f /var/log/nginx/access.log | Shows the access log live (requests received). |
Before restarting Nginx on a production server, always run sudo nginx -t first. If the configuration has a syntax error, this command warns you without cutting the service, whereas restarting directly with an invalid configuration can indeed bring the site down.
Now we can understand a complete journey
Putting all of the above together, this is the real path a visit to https://www.example.com follows:
- DNS: The browser queries the DNS system and gets a public IP, for example
203.0.113.50. - Connection: The browser opens an HTTPS connection to that IP, on port 443.
- Nginx receives the connection: At that IP there's an Nginx instance configured as a reverse proxy, not the application directly.
- Nginx decides: It decrypts the HTTPS traffic (SSL termination), checks the requested path, and decides which internal server to forward the request to (possibly choosing among several, according to some load balancing rule).
- The backend responds: It generates the real response (for example, by querying a database) and hands it back to Nginx.
- Nginx responds to the client: It delivers that response to the browser, as if it had generated it itself.
The user never finds out that, behind a single visit, there was a DNS resolution and an internal forward to one of several possible servers.
Best Practices And Common Mistakes
As with any piece of infrastructure exposed to the internet, there are habits worth keeping and others worth avoiding.
Best practices:
-
Use
nginx -tbefore everyreload: This prevents the site from going down due to a syntax error. -
Centralize TLS at the reverse proxy: Manage certificates in one single place (Nginx) instead of on each backend server, it's simpler to maintain and renew.
-
Don't expose backends directly to the internet: Only the reverse proxy should have an open public port, application servers should only listen on the internal network.
-
Configure reasonable DNS TTLs: A TTL that's too high delays the propagation of changes (for example, if you migrate servers), one that's too low increases the load on your DNS servers.
-
Check the logs at any odd symptom:
access.loganderror.logalmost always have the answer before you have to guess anything. -
Limit requests per second on sensitive routes: Such as login forms, to mitigate brute-force attacks.
-
Explicitly set the
X-Forwarded-*headers: This is useful when forwarding traffic, so the backend knows the client's real IP and the original protocol (HTTP or HTTPS).
Common mistakes:
-
Using IP addresses instead of domains "by hand" in application code: If the server's IP changes, you have to modify code instead of just updating a DNS record.
-
Leaving database ports or internal services publicly exposed: Because it might sound easier, instead of restricting them to the internal network behind the reverse proxy.
-
Restarting Nginx without validating the configuration first: This can risk a full site outage due to a typo.
-
Not renewing certificates on time: This can leave the site with security warnings or completely inaccessible over HTTPS.
-
Mixing responsibilities without order: For example, letting each backend server manage its own TLS certificate instead of centralizing it at the reverse proxy.
Quick Glossary
| Term | Meaning |
|---|---|
| Client | Whoever initiates a request (browser, app, etc.). |
| Server | Whoever answers a request. |
| IP address | A device's unique numeric identifier on a network. |
| Port | A number that identifies a specific service within the same IP. |
| DNS | The system that translates domain names into IP addresses. |
| HTTP / HTTPS | Communication protocols between browser and web server (HTTPS is the encrypted version). |
| Proxy | An intermediary between two parties that communicate. |
| Forward proxy | A proxy that acts on behalf of the client. |
| Reverse proxy | A proxy that acts on behalf of the server, hiding the real infrastructure. |
| Load balancer | A component that distributes traffic across several servers. |
| Nginx | Software that can act as a web server, reverse proxy, load balancer, and cache. |
| Upstream | In Nginx, the group of backend servers traffic can be forwarded to. |
Extras
Official documentation and useful links to keep digging deeper.
Nginx
- Official Nginx documentation: https://nginx.org/en/docs
- Nginx as a reverse proxy guide (nginx.com): https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy
DNS
- IANA (Internet Assigned Numbers Authority): https://www.iana.org
- Cloudflare, What is DNS?: https://www.cloudflare.com/learning/dns/what-is-dns
- Google Public DNS (
8.8.8.8): https://developers.google.com/speed/public-dns - Cloudflare Public DNS (
1.1.1.1): https://1.1.1.1
Certificates and HTTPS
- Let's Encrypt (free TLS certificates): https://letsencrypt.org
- Certbot (automates certificate issuance and renewal): https://certbot.eff.org
References
- Nginx, Inc. (n.d.). NGINX Documentation. https://nginx.org/en/docs
- Internet Assigned Numbers Authority. (n.d.). IANA. https://www.iana.org
- Cloudflare. (n.d.). What is DNS?. https://www.cloudflare.com/learning/dns/what-is-dns
- Internet Engineering Task Force. (1987). RFC 1035 - Domain Names, Implementation and Specification. https://www.ietf.org/rfc/rfc1035.txt
- Electronic Frontier Foundation. (n.d.). Certbot. https://certbot.eff.org
Authors
Ignacio Padilla
Training Cell