NGINX: How to accept only local requests

Updated: January 20, 2024 By: Guest Contributor Post a comment

Introduction

NGINX is a versatile web server that can be configured for various networking scenarios. One common requirement, especially in development environments or APIs meant for internal use, is to configure NGINX to accept requests only from local clients. The following tutorial will walk you through setting up your NGINX server to restrict access to local network requests.

Basic NGINX Configuration

Let’s start with a basic NGINX setup and then explain how to modify it to restrict access:

server {
    listen 80;
    server_name localhost;
    location / {
        root /var/www/html;
        index index.html index.htm;
    }
}

In the above configuration, NGINX serves content from the /var/www/html directory on HTTP port 80. Requests from any client are accepted.

Restricting Access by IP

To restrict access to local requests, you need to specify which IP addresses are considered ‘local.’ The most straightforward case is allowing only the localhost (127.0.0.1).

server {
    listen 80;
    server_name localhost;
    location / {
        allow 127.0.0.1;
        deny all;
        root /var/www/html;
        index index.html index.htm;
    }
}

This configuration will ensure that only requests originating from the server itself (localhost) will be processed.

Access for Localhost and Local Network

What if you want to allow not just the localhost, but an entire local network? For example, you might want to allow the 192.168.1.0/24 subnet.

server {
    listen 80;
    server_name localhost;
    location / {
        allow 127.0.0.1;
        allow 192.168.1.0/24;
        deny all;
        root /var/www/html;
        index index.html index.htm;
    }
}

Now, NGINX will serve requests from localhost and any machines on the 192.168.1.xxx network.

Advanced Configuration Using Geo Module

For more complex scenarios or dynamic IP handling, you can use NGINX’s Geo module. This module allows you to define variables based on the client’s IP address, which you can then use in your access rules. Here is how you can set it up:

http {
    geo $local_network {
        default         0;
        127.0.0.1      1;
        192.168.1.0/24 1;
    }
    server {
        listen 80;
        server_name localhost;
        location / {
            if ($local_network = 0) {
                return 403;
            }
            root /var/www/html;
            index index.html index.htm;
        }
    }
}

In this configuration, requests are checked against the Geo module’s $local_network variable. If a request does not come from the listed IP addresses (0 indicates no match), NGINX returns a 403 Forbidden error.

Securing NGINX with HTTPS

For added security, especially when handling sensitive internal information, consider using HTTPS (SSL/TLS) for your requests. You can still apply local request restrictions over an encrypted connection.

server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

    location / {
        allow 127.0.0.1;
        deny all;
        root /var/www/html;
        index index.html index.htm;
    }
}

After generating your certificates and configuring SSL settings, you simply add the allow and deny directives to enforce local access under the secure protocol.

Testing the Configuration

After any changes to the NGINX configuration, you should test to ensure there are no syntax errors:

sudo nginx -t

If the configuration test is successful, you will see an output like:

nginx: configuration file /etc/nginx/nginx.conf test is successful

Once the configuration is confirmed to be correct, reload NGINX to apply the changes:

sudo systemctl reload nginx

Now you can verify that the server is only accepting local requests by using tools like curl from a remote host and seeing that the access is denied:

curl http://localhost/ # Should be available locally

curl http://[your-server-ip]/ # Should deny access

Conclusion

In this tutorial, we’ve looked at how you can configure your NGINX server to accept only local requests. By utilizing NGINX’s access rules with the allow and deny directives, and potentially the Geo module for more complex configurations, you can ensure that your server’s content is accessible solely within a local network environment.