Bird
Raised Fist0
Nginxdevops~10 mins

Proxy headers forwarding in Nginx - Step-by-Step Execution

Choose your learning style10 modes available
Process Flow - Proxy headers forwarding
Client sends request
↓
Nginx receives request
↓
Nginx adds/forwards headers
↓
Nginx sends request to backend
↓
Backend receives request with headers
↓
Backend processes request
↓
Backend sends response
↓
Nginx forwards response to client
The client sends a request to Nginx, which adds or forwards headers before sending the request to the backend server. The backend receives these headers and processes the request accordingly.
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 the original Host, client IP, and X-Forwarded-For headers to the backend server.
Process Table
StepActionHeader Added/ForwardedValueEffect
1Client sends requestHostexample.comOriginal client Host header
2Nginx receives request--Nginx reads incoming headers
3Nginx sets Host headerHost$host (example.com)Backend sees original Host
4Nginx sets X-Real-IP headerX-Real-IP$remote_addr (192.168.1.10)Backend knows client IP
5Nginx sets X-Forwarded-For headerX-Forwarded-For$proxy_add_x_forwarded_for (192.168.1.10)Backend tracks proxy chain
6Nginx sends request to backendAll above headersForwardedBackend receives headers
7Backend processes request--Backend uses headers for logging/security
8Backend sends response--Response sent back to Nginx
9Nginx forwards response--Client receives backend response
💡 Request cycle completes after response is forwarded to client
Status Tracker
VariableStartAfter Step 3After Step 4After Step 5Final
Hostexample.comexample.comexample.comexample.comexample.com
X-Real-IP--192.168.1.10192.168.1.10192.168.1.10
X-Forwarded-For---192.168.1.10192.168.1.10
Key Moments - 3 Insights
Why do we set the Host header explicitly in proxy_set_header?
Because the backend server often needs the original Host to respond correctly. Without setting it, the backend might see the proxy's hostname instead. See execution_table step 3.
What is the difference between X-Real-IP and X-Forwarded-For headers?
X-Real-IP carries the immediate client's IP, while X-Forwarded-For tracks the full chain of client IPs through proxies. See execution_table steps 4 and 5.
What happens if we don't forward these headers?
The backend won't know the original client IP or Host, which can cause logging, security, or routing issues. See execution_table step 7.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what value does the X-Real-IP header have after step 4?
Aexample.com
B192.168.1.10
C-
Dproxy server IP
💡 Hint
Check the 'Header Added/Forwarded' and 'Value' columns at step 4 in execution_table.
At which step does Nginx add the X-Forwarded-For header?
AStep 3
BStep 4
CStep 5
DStep 6
💡 Hint
Look for the row where 'X-Forwarded-For' is set in the 'Header Added/Forwarded' column.
If we remove proxy_set_header Host, what will the backend likely see as Host?
ANginx server hostname or IP
BEmpty Host header
COriginal client Host header
DClient IP address
💡 Hint
Refer to key_moments about why Host header is set explicitly and execution_table step 3.
Concept Snapshot
Nginx proxy headers forwarding:
- Use proxy_set_header to forward headers like Host, X-Real-IP, X-Forwarded-For
- Host header tells backend the original domain requested
- X-Real-IP passes client IP to backend
- X-Forwarded-For tracks client IP chain through proxies
- Proper headers help backend logging, security, and routing
Full Transcript
When a client sends a request to Nginx, Nginx receives it and adds or forwards important headers before sending the request to the backend server. These headers include Host, which tells the backend the original domain the client requested; X-Real-IP, which carries the client's IP address; and X-Forwarded-For, which tracks the chain of IP addresses if multiple proxies are involved. Nginx sets these headers using proxy_set_header directives. The backend receives these headers and can use them for logging, security checks, or routing decisions. Finally, the backend sends a response back through Nginx to the client. Forwarding these headers correctly ensures the backend knows who the client is and what domain was requested, avoiding issues with incorrect logging or routing.

Practice

(1/5)
1. What is the main purpose of using proxy_set_header in an nginx proxy configuration?
easy
A. To cache static files on the proxy server
B. To block client requests based on IP address
C. To compress responses from the backend server
D. To forward original client information like IP and Host to the backend server

Solution

  1. Step 1: Understand proxy_set_header role

    The directive proxy_set_header is used to set or override HTTP headers sent to the backend server.
  2. Step 2: Identify what headers are forwarded

    It forwards client info such as IP address, Host, and protocol to help backend servers process requests correctly.
  3. Final Answer:

    To forward original client information like IP and Host to the backend server -> Option D
  4. Quick Check:

    proxy_set_header forwards client info = D [OK]
Hint: Remember proxy_set_header sends client info to backend [OK]
Common Mistakes:
  • Thinking it blocks requests
  • Confusing it with caching or compression
  • Assuming it modifies client requests directly
2. Which of the following is the correct syntax to forward the original client IP address in nginx proxy configuration?
easy
A. proxy_set_header X-Real-IP $proxy_addr;
B. proxy_pass_header X-Real-IP $remote_addr;
C. proxy_set_header X-Real-IP $remote_addr;
D. proxy_forward_header X-Real-IP $remote_addr;

Solution

  1. Step 1: Identify correct directive for setting headers

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

    The variable $remote_addr holds the original client IP address.
  3. Final Answer:

    proxy_set_header X-Real-IP $remote_addr; -> Option C
  4. Quick Check:

    proxy_set_header + $remote_addr = B [OK]
Hint: Use proxy_set_header with $remote_addr for client IP [OK]
Common Mistakes:
  • Using wrong directive like proxy_pass_header
  • Using $proxy_addr which is invalid
  • Confusing proxy_set_header with proxy_forward_header
3. Given this nginx proxy snippet:
location /api/ {
  proxy_pass http://backend;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

What will be the value of the X-Forwarded-For header sent to the backend if the client IP is 192.168.1.10 and the header already contains 10.0.0.1?
medium
A. 192.168.1.10
B. 10.0.0.1, 192.168.1.10
C. 10.0.0.1
D. $proxy_add_x_forwarded_for

Solution

  1. Step 1: Understand $proxy_add_x_forwarded_for variable

    This variable appends the client IP to the existing X-Forwarded-For header, separated by a comma.
  2. Step 2: Combine existing and client IP

    Since the header already has 10.0.0.1, and client IP is 192.168.1.10, the result is "10.0.0.1, 192.168.1.10".
  3. Final Answer:

    10.0.0.1, 192.168.1.10 -> Option B
  4. Quick Check:

    $proxy_add_x_forwarded_for appends IP = C [OK]
Hint: Remember $proxy_add_x_forwarded_for appends client IP [OK]
Common Mistakes:
  • Assuming it replaces the header instead of appending
  • Confusing $proxy_add_x_forwarded_for with $remote_addr
  • Expecting only client IP without existing values
4. You configured nginx proxy with:
proxy_set_header X-Forwarded-Proto $scheme;

But the backend always receives http even when client uses https. What is the likely cause?
medium
A. nginx is not configured to listen on HTTPS, so $scheme is always http
B. proxy_set_header syntax is incorrect
C. Backend server ignores X-Forwarded-Proto header
D. You must use $https variable instead of $scheme

Solution

  1. Step 1: Understand $scheme variable behavior

    $scheme reflects the protocol used by the client to connect to nginx (http or https).
  2. Step 2: Check nginx HTTPS configuration

    If nginx is not listening on HTTPS, all requests come as http, so $scheme is always "http".
  3. Final Answer:

    nginx is not configured to listen on HTTPS, so $scheme is always http -> Option A
  4. Quick Check:

    $scheme depends on nginx listener protocol = A [OK]
Hint: Check if nginx listens on HTTPS for $scheme to be https [OK]
Common Mistakes:
  • Thinking proxy_set_header syntax is wrong
  • Assuming backend ignores header without checking
  • Using $https variable which is not standard
5. You want to forward the original client IP, host, and protocol to your backend server behind nginx proxy. Which complete configuration snippet correctly forwards these headers?
hard
A. proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme;
B. proxy_set_header X-Real-IP $proxy_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $https;
C. proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $proxy_host; proxy_set_header X-Forwarded-Proto $scheme;
D. proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $http_scheme;

Solution

  1. Step 1: Verify variables for client IP, host, and protocol

    $remote_addr is client IP, $host is original host header, and $scheme is protocol (http or https).
  2. Step 2: Check each option for correctness

    proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; uses correct variables and syntax. Others use invalid variables like $proxy_addr, $proxy_host, or $http_scheme which do not exist.
  3. Final Answer:

    proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; -> Option A
  4. Quick Check:

    Use $remote_addr, $host, $scheme for forwarding headers = A [OK]
Hint: Use $remote_addr, $host, and $scheme for correct forwarding [OK]
Common Mistakes:
  • Using non-existent variables like $proxy_addr or $proxy_host
  • Confusing $https with $scheme
  • Missing one or more headers to forward
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard