Deep Dive into Nginx Variables
Last updated
Last updated
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 .
Nginx provides built-in and user-defined variables that can be used in configuration files for logging, redirection, proxying, and more.
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.
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.
Logging User IP Address and Request URI
This logs details such as IP, request method, and URI.
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
Redirecting Mobile Users Based on User-Agent
This redirects mobile users to a mobile-specific website.
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
Logging HTTP Protocol Version
This logs the protocol version used by the client.
These are useful for geo-restrictions and traffic management.
Blocking Requests from Specific Countries
This blocks access from China and Russia using GeoIP.
These variables provide information about SSL connections.
$ssl_protocol
SSL/TLS protocol used
$ssl_cipher
Cipher suite used
$ssl_session_id
SSL session ID
Logging SSL Protocol and Cipher
This logs the SSL protocol and cipher used for secure connections.
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
Logging Backend Response Times
This logs backend response times for performance monitoring.
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.
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.
Setting a Custom Variable for Logging
This logs a custom message alongside client IP addresses.
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.
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 or map
) 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.
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.
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.