HxHippy

Access Control

Restricting access to your Nginx sites by IP, authentication, and more.

Last updated: 2025-01-15

IP-Based Access Control

Allow/Deny by IP

location /admin/ {
    # Allow specific IPs
    allow 192.168.1.100;
    allow 10.0.0.0/8;

    # Deny everyone else
    deny all;
}

Allow Internal Only

location /internal/ {
    # RFC 1918 private networks
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    allow 192.168.0.0/16;
    allow 127.0.0.1;
    deny all;
}

Geo-Based Blocking

# Block by country (requires GeoIP module)
geo $blocked_country {
    default 0;
    include /etc/nginx/geoip/blocked_countries.conf;
}

server {
    if ($blocked_country) {
        return 403;
    }
}

Basic Authentication

Create Password File

# Install htpasswd
sudo apt install apache2-utils  # Debian/Ubuntu
sudo dnf install httpd-tools    # RHEL/CentOS

# Create password file
sudo htpasswd -c /etc/nginx/.htpasswd admin

# Add additional users
sudo htpasswd /etc/nginx/.htpasswd user2

# Set permissions
sudo chmod 640 /etc/nginx/.htpasswd
sudo chown root:nginx /etc/nginx/.htpasswd

Configure Nginx

location /admin/ {
    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;

    # Optional: Combine with IP restriction
    satisfy any;  # OR logic (IP or password)
    # satisfy all;  # AND logic (IP and password)

    allow 192.168.1.0/24;
    deny all;
}

Auth for Specific Files

# Protect specific file types
location ~* \.(env|sql|log)$ {
    deny all;
}

# Protect hidden files
location ~ /\. {
    deny all;
}

# Protect directory
location ^~ /private/ {
    auth_basic "Private Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

JWT/Token Authentication

# Simple token check
map $http_authorization $auth_token {
    default "";
    "~^Bearer (.+)$" $1;
}

server {
    location /api/ {
        if ($auth_token = "") {
            return 401;
        }

        # Pass to backend for validation
        proxy_pass http://backend;
        proxy_set_header Authorization $http_authorization;
    }
}

Subrequest Authentication

# External authentication service
location /api/ {
    auth_request /auth;
    auth_request_set $auth_status $upstream_status;

    proxy_pass http://backend;
}

location = /auth {
    internal;
    proxy_pass http://auth-service/validate;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}

User Agent Blocking

# Block bad bots
if ($http_user_agent ~* (badbot|scraper|crawler)) {
    return 403;
}

# Block empty user agent
if ($http_user_agent = "") {
    return 403;
}

# Block by map
map $http_user_agent $bad_bot {
    default 0;
    ~*badbot 1;
    ~*scraper 1;
}

server {
    if ($bad_bot) {
        return 403;
    }
}

Referer Validation

# Block hotlinking
location ~* \.(jpg|jpeg|png|gif)$ {
    valid_referers none blocked server_names
                   *.example.com example.com;

    if ($invalid_referer) {
        return 403;
    }
}

Complete Access Control Example

server {
    listen 443 ssl http2;
    server_name example.com;

    # Default deny hidden files
    location ~ /\. {
        deny all;
    }

    # Public access
    location / {
        try_files $uri $uri/ =404;
    }

    # Admin area - IP + Basic Auth
    location /admin/ {
        satisfy all;

        # IP whitelist
        allow 192.168.1.0/24;
        deny all;

        # Basic auth
        auth_basic "Admin Area";
        auth_basic_user_file /etc/nginx/.htpasswd;

        proxy_pass http://backend;
    }

    # API - Token required
    location /api/ {
        if ($http_authorization = "") {
            return 401;
        }
        proxy_pass http://backend;
    }
}
intermediate Security Updated 2025-01-15
  • nginx
  • access control
  • ip whitelist
  • authentication
  • basic auth