Unlock Nginx’s Built‑in Variables: From Simple Math to Custom Firewalls

This article introduces Nginx’s extensive built‑in variables, shows how to access them in OpenResty with ngx.var, and provides step‑by‑step Lua examples ranging from a simple arithmetic endpoint to a basic IP‑based firewall and rate‑limiting configuration.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Unlock Nginx’s Built‑in Variables: From Simple Math to Custom Firewalls

Overview

Nginx, as a mature load‑balancing software, offers a rich set of built‑in variables that increase control over its network behavior. Most variables are parsed when a request arrives and cached for later use.

Built‑in variable list
$arg_name

: the name parameter in the request $args: all request arguments $binary_remote_addr: binary representation of the client IP $body_bytes_sent: number of bytes sent in the response body $content_length: value of the HTTP Content‑Length header $content_type: value of the HTTP Content‑Type header $document_root: root directory for the current request $document_uri: same as $uri, e.g.,

/test2/test.php
$host

: the Host header or the server name if absent $hostname: system hostname from

gethostname()
$http_cookie

: cookie header $http_referer: referrer URL $http_user_agent: client user‑agent string $http_via: IP of the last proxy that forwarded the request $http_x_forwarded_for: client IP chain $is_args: returns "?" if the request has arguments, otherwise empty $limit_rate: per‑request transfer‑rate limit $nginx_version: running Nginx version $pid: worker process PID $query_string: same as

$args
$realpath_root

: absolute path resolved from root or alias, with symlinks resolved $remote_addr: client IP address $remote_port: client port $remote_user: authenticated username $request: full original request line $request_body: request body (available from 0.7.58+) $request_body_file: temporary file name for the request body $request_completion: "OK" if request succeeded, empty otherwise $request_filename: file system path of the requested resource $request_method: HTTP method, e.g., "GET" or "POST" $request_uri: URI with arguments $scheme: protocol scheme, e.g., http or

https
$server_addr

: server IP (may trigger a system call if not set by listen) $server_name: name of the server handling the request $server_port: port on which the request arrived $server_protocol: HTTP protocol version, e.g.,

HTTP/1.1
$uri

: normalized request URI, may differ from the original after rewrites

These variables are continuously expanded as Nginx evolves, and many obscure ones enable creative uses.

Usage

In OpenResty, variables are accessed via ngx.var.VARIABLE.

Simple arithmetic example (adds a and b query parameters):

server {
    listen 80;
    server_name openresty.tinywan.com;

    location /resty_sum {
        content_by_lua_block {
            local a = tonumber(ngx.var.arg_a) or 0
            local b = tonumber(ngx.var.arg_b) or 0
            ngx.say("[x] sum: ", a + b)
        }
    }
}

Result of curl "http://openresty.tinywan.com/resty_sum?a=2024&b=24":

HTTP/1.1 200 OK
Server: openresty/1.17.8.2
Date: Mon, 22 Jul 2024 07:28:47 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive

[x] sum: 2048

Next, a basic firewall that blocks a specific IP address using the access_by_lua_block phase:

server {
    listen 80;
    server_name openresty.tinywan.com;

    location /resty_access_sum {
        # Access phase for admission control
        access_by_lua_block {
            local black_ips = {["172.18.0.1"] = true}
            local ip = ngx.var.remote_addr
            if true == black_ips[ip] then
                ngx.exit(ngx.HTTP_FORBIDDEN)
            end
        }

        # Business logic
        content_by_lua_block {
            local a = tonumber(ngx.var.arg_a) or 0
            local b = tonumber(ngx.var.arg_b) or 0
            ngx.say("[x] sum:", a + b)
        }
    }
}

Testing from a non‑blacklisted client returns 200 OK, while a request from 172.18.0.1 receives 403 Forbidden. A custom error page can be sent before exiting:

location /resty_access_sum {
  access_by_lua_block {
    local black_ips = {["172.18.0.1"] = true}
    local ip = ngx.var.remote_addr
    if true == black_ips[ip] then
      ngx.say("<html><body>Sorry, 403 Forbidden. 开源技术小栈.</body></html>")
      ngx.exit(ngx.HTTP_FORBIDDEN)
    end
  }
}

Finally, writable variables such as limit_rate can be set to control transfer speed per request:

location /resty_download {
    access_by_lua_block {
        ngx.var.limit_rate = 1000
    }
}

Downloading a file from this location with

wget "http://openresty.tinywan.com/resty_download/tinywan.lua"

shows the rate limit in effect.

These examples demonstrate how Nginx’s built‑in variables can be read and, where allowed, written to implement lightweight request processing, access control, and rate limiting directly within OpenResty configurations.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

NginxLuaOpenRestyVariables
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.