Restricting access by IP in Nginx reduces exposure of administrative endpoints and internal tools by limiting a URL to trusted networks. This approach keeps sensitive paths available to office subnets, VPN ranges, or specific bastion hosts without changing application code.

The access rules in Nginx are expressed with allow and deny directives placed in http, server, or (most commonly) a specific location block. Rules are evaluated in order until a match occurs, so an allowlist is typically written as one or more allow lines followed by deny all to block everything else.

IP-based restrictions depend on the client address that Nginx sees as the remote peer, so reverse proxies, load balancers, and CDNs often require real-IP handling before allowlists behave as intended. A mistake in the location matcher or trusted ranges can block legitimate management access, so narrow matching, configuration testing, and staged verification reduce lockout risk.

Steps to restrict access by IP in Nginx:

  1. Select the URL path to protect.

    Common targets: /admin/, /status, /metrics, /nginx_status; prefer a narrow location matcher to avoid restricting unrelated paths.

  2. Collect the trusted IP addresses or CIDR ranges to allow.

    Examples: 198.51.100.0/24, 192.0.2.10, 2001:db8:1234::/48.

  3. Add the allowlist rules followed by a default deny inside the target location block.
    location /admin/ {
        allow 198.51.100.0/24;
        allow 192.0.2.10;
        deny all;
    }

    A too-broad location match (for example, location /) can block the entire site once deny all is applied.

  4. Configure real client IP handling when traffic arrives through a reverse proxy or CDN.
    # Place in the http {} context, or in an included file loaded from http {}.
    set_real_ip_from 192.0.2.0/24;
    set_real_ip_from 203.0.113.5;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    Only trust X-Forwarded-For (or a vendor header) from known proxy IPs via set_real_ip_from, otherwise client IP spoofing can bypass allowlists.

  5. Test the Nginx configuration for syntax errors.
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
  6. Reload Nginx to apply the updated configuration.
    $ sudo systemctl reload nginx
  7. Confirm that an untrusted source receives HTTP 403 for the protected path.
    $ curl -i https://example.net/admin/
    HTTP/1.1 403 Forbidden
    Server: nginx
    Content-Type: text/html
    Content-Length: 153
    Connection: keep-alive
    
    <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>
    <hr><center>nginx</center>
    </body>
    </html>

    Run from a network outside the allowlist (for example, a mobile hotspot) to validate the block.

  8. Confirm that a trusted source can still reach the protected path.
    $ curl -i https://example.net/admin/
    HTTP/1.1 200 OK
    Server: nginx
    Content-Type: text/html; charset=utf-8
    Content-Length: 1234
    Connection: keep-alive
    ##### snipped #####
Discuss the article:

Comment anonymously. Login not required.