Bird
Raised Fist0
Nginxdevops~10 mins

Proxy headers in Nginx - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Process Flow - Proxy headers
Client sends request
Nginx receives request
Nginx adds/updates proxy headers
Nginx forwards request to backend server
Backend server receives request with headers
Backend processes request and responds
Nginx sends response back to client
The flow shows how Nginx receives a client request, adds or modifies proxy headers, then forwards it to the backend server, which uses these headers for processing.
Execution Sample
Nginx
location /api/ {
  proxy_pass http://backend;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
This Nginx config forwards requests to /api/ to a backend server, adding headers that tell the backend the original host and client IP.
Process Table
StepActionHeader SetValueEffect
1Receive client requestNoneNoneNginx gets request from client
2Set Host headerHost$host (example.com)Backend knows original host
3Set X-Real-IP headerX-Real-IP$remote_addr (192.0.2.1)Backend knows client IP
4Set X-Forwarded-For headerX-Forwarded-For$proxy_add_x_forwarded_for (192.0.2.1)Tracks client IP chain
5Forward requestAll above headersSent to backendBackend receives headers
6Backend processes requestReads headersUses for logging/securityResponds accordingly
7Nginx sends responseNoneNoneClient receives backend response
💡 Request fully proxied with headers set, backend processed and responded
Status Tracker
VariableStartAfter Step 2After Step 3After Step 4Final
Hostunsetexample.comexample.comexample.comexample.com
X-Real-IPunsetunset192.0.2.1192.0.2.1192.0.2.1
X-Forwarded-Forunsetunsetunset192.0.2.1192.0.2.1
Key Moments - 3 Insights
Why do we set the Host header explicitly in proxy headers?
Because the backend server needs to know the original host requested by the client. Without setting Host, the backend might see the proxy's hostname instead, which can cause wrong responses. See execution_table step 2.
What is the difference between X-Real-IP and X-Forwarded-For headers?
X-Real-IP carries the immediate client's IP address, while X-Forwarded-For can hold a chain of IPs if multiple proxies are involved. This helps backend track the original client IP. See execution_table steps 3 and 4.
What happens if proxy headers are not set correctly?
The backend may not know the real client IP or host, which can break logging, security checks, or routing. The request might still work but with incomplete info. See execution_table steps 5 and 6.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what value does the X-Real-IP header have after step 3?
A192.0.2.1
Bexample.com
Cunset
Dproxy server IP
💡 Hint
Check the 'Header Set' and 'Value' columns at step 3 in execution_table.
At which step does Nginx forward the request to the backend with all proxy headers set?
AStep 2
BStep 4
CStep 5
DStep 6
💡 Hint
Look for the step where the action is 'Forward request' in execution_table.
If the X-Forwarded-For header was not set, what would change in the variable_tracker?
AX-Real-IP would be unset
BX-Forwarded-For would remain unset after all steps
CHost would be unset
DNo variables would change
💡 Hint
Check the variable_tracker row for X-Forwarded-For and imagine skipping step 4.
Concept Snapshot
Proxy headers in Nginx add info about the original client request when forwarding.
Use proxy_set_header to set Host, X-Real-IP, and X-Forwarded-For.
Host tells backend the original domain.
X-Real-IP gives backend the client IP.
X-Forwarded-For tracks client IP chain through proxies.
Proper headers help backend logging and security.
Full Transcript
This visual execution shows how Nginx handles proxy headers. When a client sends a request, Nginx receives it and sets headers like Host, X-Real-IP, and X-Forwarded-For before forwarding to the backend server. The Host header tells the backend the original domain requested. X-Real-IP carries the client's IP address. X-Forwarded-For tracks the chain of client IPs if multiple proxies are involved. The backend uses these headers for logging and security. If headers are missing or incorrect, the backend may not get accurate client info. The execution table traces each step, showing header values and effects. The variable tracker shows how header values change step-by-step. Key moments clarify why each header matters. The quiz tests understanding of header values and flow. This helps beginners see how proxy headers work in Nginx.

Practice

(1/5)
1. What is the main purpose of setting proxy headers like X-Real-IP in an nginx configuration?
easy
A. To encrypt the data between nginx and the client
B. To cache the client's request on nginx
C. To pass the original client's IP address to the backend server
D. To block unwanted IP addresses from accessing the server

Solution

  1. Step 1: Understand proxy headers role

    Proxy headers like X-Real-IP carry client info through nginx to backend servers.
  2. Step 2: Identify the purpose of X-Real-IP

    This header specifically passes the original client's IP address to the backend for logging or processing.
  3. Final Answer:

    To pass the original client's IP address to the backend server -> Option C
  4. Quick Check:

    Proxy headers pass client info = B [OK]
Hint: Remember: X-Real-IP shows client's real IP to backend [OK]
Common Mistakes:
  • Confusing proxy headers with encryption settings
  • Thinking proxy headers cache requests
  • Assuming proxy headers block IPs
2. Which of the following is the correct nginx directive to set the X-Forwarded-Proto header to the client's protocol?
easy
A. proxy_set_header X-Forwarded-Proto $scheme;
B. set_header X-Forwarded-Proto $protocol;
C. proxy_header X-Forwarded-Proto $scheme;
D. header_set X-Forwarded-Proto $protocol;

Solution

  1. Step 1: Recall nginx syntax for proxy headers

    The correct directive to set headers in nginx proxy is proxy_set_header.
  2. Step 2: Match variable for client protocol

    The variable $scheme holds the client's protocol (http or https).
  3. Final Answer:

    proxy_set_header X-Forwarded-Proto $scheme; -> Option A
  4. Quick Check:

    proxy_set_header + $scheme = A [OK]
Hint: Use proxy_set_header with $scheme for protocol header [OK]
Common Mistakes:
  • Using incorrect directive names like set_header
  • Using wrong variable names like $protocol
  • Mixing directive order or syntax
3. Given this nginx proxy configuration snippet:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

What will be the value of X-Forwarded-For if the client IP is 10.0.0.1 and the request passed through one proxy with IP 192.168.1.1?
medium
A. 10.0.0.1
B. 192.168.1.1, 10.0.0.1
C. 192.168.1.1
D. 10.0.0.1, 192.168.1.1

Solution

  1. Step 1: Understand $proxy_add_x_forwarded_for behavior

    This variable appends the $remote_addr (proxy IP seen by nginx) to the existing X-Forwarded-For header chain from previous proxies.
  2. Step 2: Order of IPs in X-Forwarded-For

    The chain lists the original client first, then proxy IPs appended. For client 10.0.0.1 via proxy 192.168.1.1, it becomes 10.0.0.1, 192.168.1.1.
  3. Final Answer:

    10.0.0.1, 192.168.1.1 -> Option D
  4. Quick Check:

    Client IP last in X-Forwarded-For = C [OK]
Hint: X-Forwarded-For lists original client first, then proxies [OK]
Common Mistakes:
  • Reversing IP order in X-Forwarded-For
  • Confusing X-Real-IP with X-Forwarded-For
  • Ignoring existing proxy IPs in header
4. You have this nginx config snippet:
proxy_set_header X-Real-IP $remote_addr
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

When reloading nginx, it fails with a syntax error. What is the problem?
medium
A. Missing semicolon at the end of the first proxy_set_header line
B. Incorrect variable name $proxy_add_x_forwarded_for
C. proxy_set_header cannot be used twice in one block
D. X-Real-IP header cannot be set manually

Solution

  1. Step 1: Check nginx directive syntax

    Each directive line must end with a semicolon in nginx configuration.
  2. Step 2: Identify missing semicolon

    The first line lacks a semicolon after $remote_addr, causing syntax error.
  3. Final Answer:

    Missing semicolon at the end of the first proxy_set_header line -> Option A
  4. Quick Check:

    Every directive needs semicolon = D [OK]
Hint: Always end nginx directives with semicolon [OK]
Common Mistakes:
  • Ignoring semicolon syntax rules
  • Assuming variable names are wrong without checking
  • Thinking headers can't be set multiple times
5. You want to ensure your backend server correctly logs the original client IP and protocol when nginx proxies requests. Which complete nginx proxy header configuration snippet achieves this?
hard
A. proxy_set_header X-Real-IP $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $protocol;
B. 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;
C. proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
D. 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

Solution

  1. Step 1: Verify correct variables for headers

    X-Real-IP should be $remote_addr, X-Forwarded-For uses $proxy_add_x_forwarded_for, and X-Forwarded-Proto uses $scheme.
  2. Step 2: Check syntax correctness

    Each directive must end with a semicolon; 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; has correct syntax and variables.
  3. Final Answer:

    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; -> Option B
  4. Quick Check:

    Correct vars + semicolons = A [OK]
Hint: Use $remote_addr, $proxy_add_x_forwarded_for, $scheme with semicolons [OK]
Common Mistakes:
  • Swapping variables between headers
  • Omitting semicolons causing errors
  • Using undefined variables like $protocol