Deep Dive into Nginx Variables
Nginx is a powerful web server and reverse proxy known for its high performance and flexibility. One of its key features is the use of variables, which allow dynamic behaviour and customization.
For a complete list of variables, refer to the official Nginx documentation.
1. Understanding Nginx Variables
Nginx provides built-in and user-defined variables that can be used in configuration files for logging, redirection, proxying, and more.
Types of Variables in Nginx:
Core Variables – Built-in variables that provide request-specific information.
HTTP Variables – Variables related to HTTP headers and requests.
Server Variables – Variables related to the server and connection.
Geo Variables – Used for geo-based filtering and restrictions.
SSL Variables – Variables related to SSL connections.
Upstream Variables – Used in reverse proxying and load balancing.
Custom Variables – User-defined variables using
set
.
Let's explore these with practical examples.
2. Core Nginx Variables
These variables provide fundamental information about the request and response.
$remote_addr
Client's IP address
$remote_port
Client's port
$server_addr
Server IP address
$server_port
Port on which the request was received.
$scheme
Request scheme (HTTP/HTTPS)
$request_method
HTTP method (GET, POST, etc.)
$request_uri
Full request URI
$uri
It is the normalized URI after processing rewrite rules, ensuring backend systems receive a consistent URL.
Example:
Logging User IP Address and Request URI
log_format custom '$remote_addr - $remote_user [$time_local] "$request_method $request_uri"';
access_log /var/log/nginx/access.log custom;
This logs details such as IP, request method, and URI.
3. HTTP Request Variables
These variables store information about HTTP headers and request content.
$http_host
Host header sent by the client
$host
A processed version of the "Host" header. It’s typically the same as $http_host, but if that is empty, Nginx falls back to the server name specified in the configuration.
$http_user_agent
User-Agent of the request
$http_referer
Referer URL
$http_cookie
Cookies sent in the request
Example:
Redirecting Mobile Users Based on User-Agent
if ($http_user_agent ~* "mobile") {
return 302 https://m.example.com;
}
This redirects mobile users to a mobile-specific website.
4. Server and Connection Variables
These provide details about the server and its connections.
$server_protocol
Protocol used (HTTP/1.1, HTTP/2)
$connection
Connection number
$connection_requests
Number of requests per connection
Example:
Logging HTTP Protocol Version
log_format protocol_logs 'Client IP: $remote_addr, Protocol: $server_protocol';
access_log /var/log/nginx/protocol.log protocol_logs;
This logs the protocol version used by the client.
5. Geo Variables (Location-Based Handling)
These are useful for geo-restrictions and traffic management.
Example:
Blocking Requests from Specific Countries
geo $country {
default ZZ;
include /etc/nginx/geoip.conf;
}
map $country $block_access {
US 0;
CN 1;
RU 1;
}
server {
if ($block_access = 1) {
return 403;
}
}
This blocks access from China and Russia using GeoIP.
6. SSL/TLS Variables
These variables provide information about SSL connections.
$ssl_protocol
SSL/TLS protocol used
$ssl_cipher
Cipher suite used
$ssl_session_id
SSL session ID
Example:
Logging SSL Protocol and Cipher
log_format ssl_logs 'Client IP: $remote_addr, SSL Protocol: $ssl_protocol, Cipher: $ssl_cipher';
access_log /var/log/nginx/ssl.log ssl_logs;
This logs the SSL protocol and cipher used for secure connections.
7. Upstream (Reverse Proxy) Variables
When using Nginx as a reverse proxy, these variables store information about backend responses.
$upstream_addr
Backend server address
$upstream_status
Response code from backend
$upstream_response_time
Response time from backend
Example:
Logging Backend Response Times
log_format upstream_logs '$remote_addr - Backend: $upstream_addr, Status: $upstream_status, Response Time: $upstream_response_time';
access_log /var/log/nginx/upstream.log upstream_logs;
This logs backend response times for performance monitoring.
8. Custom Variables (User-Defined Variables)
Custom variables in Nginx are a powerful way to store and manipulate dynamic values. We can define our own variables using set
directive or even better, using the map
directive for conditional logic. They can be defined in the server block, location block, or even within if-statements.
Where to Create Custom Variables
Server or Location Blocks: Use the
set
directive to define a variable that is local to the block.Maps: For more complex conditions based on input values, the
map
directive allows you to define a variable whose value is determined by a set of key-value pairs.If Statements: Although using
if
comes with caveats in Nginx (especially for rewrite conditions), they can be used to set temporary variables.
Example:
Setting a Custom Variable for Logging
set $my_variable "Custom Log Data";
log_format custom_logs '$remote_addr - $my_variable';
access_log /var/log/nginx/custom.log custom_logs;
This logs a custom message alongside client IP addresses.
Example: Using set in a Location Block
server {
listen 80;
server_name example.com;
location / {
# Create a custom variable based on a condition
set $custom_message "Default Message";
if ($request_method = "POST") {
set $custom_message "Received a POST Request";
}
# Use the custom variable in logging and header responses
add_header X-Custom-Message "$custom_message";
log_format custom_log 'Client: $remote_addr, Message: $custom_message';
access_log /var/log/nginx/custom.log custom_log;
proxy_pass http://backend;
}
}
Example: Using map for Conditional Variable Assignment
# Define a variable based on the value of the $host variable.
map $host $target_backend {
default "http://default_backend";
"api.example.com" "http://api_backend";
"shop.example.com" "http://shop_backend";
}
server {
listen 80;
server_name example.com;
location / {
# Forward requests to different backends based on $host
proxy_pass $target_backend;
}
}
In this configuration, the map directive examines the value of $host
and assigns an appropriate backend. This is especially useful in multi-tenant or multi-service architectures where a single Nginx instance serves multiple domains or subdomains.
9. How Nginx Handles Variables
When a request comes into Nginx, it goes through several phases (such as rewrite, access, content, and logging). During these phases, variables are either computed on the fly or already preset by the server:
Evaluation on Request: Many built-in variables (for example,
$host
,$uri
,$remote_addr
) are evaluated at runtime based on the incoming request.Normalization and Rewrite: Variables like
$uri
are normalized after any rewrite rules are applied. This means that if you change a URL using a rewrite rule, subsequent references to$uri
will reflect the modified path.Lazy Calculation: Nginx optimizes performance by calculating variables only when needed. If a variable isn’t used in a particular configuration block, its value may never be computed.
Scope and Phases: Custom variables (defined with the
set
directive ormap
) are usually evaluated during the rewrite phase and are available in later processing phases. Remember that these variables are request-scoped and reset with every new request.
10. Production Considerations for Using Variables
When deploying Nginx in production, it’s essential to consider the following points regarding variable usage:
Performance Impact: Although variable evaluation is lightweight, excessive use in high-traffic environments (especially complex conditional logic) can add up. Always test performance impacts in a staging environment.
Logging Consistency: Use normalized variables like
$host
and$uri
to ensure consistency across logs, which is crucial for debugging and audit trails.Security: Variables like
$http_*
(e.g.,$http_user_agent
) can be manipulated by clients. Always sanitize or validate these when used in security-critical rules.Configuration Maintenance: Clearly document any custom variables and maps in your configuration. This makes troubleshooting easier and ensures that new team members understand the logic behind dynamic routing or logging.
Conclusion
Nginx variables are incredibly powerful for managing requests, logging, security, and performance monitoring. By leveraging these variables effectively, you can build robust, production-ready configurations.
Last updated