Skip to main content

Block URL paths with Nginx

Banning IPs is one way to deal with bad actors. However, sometimes you'll come across a distributed attack from multiple IPs and networks, and this is where blocking certain URL patterns can help.

In this lesson we'll use a shared map in Nginx to quickly block traffic to certain URLs and patterns. We'll write a small Bash script to manage patterns in this list.

Nginx map to block URLs

In a previous lesson we used a $blacklisted_uri map to restrict access to certain URL patterns in Nginx. This map is defined in the main /config/nginx/nginx.conf configuration file, and we can now extend this map to include our additional patterns:

map $uri $blacklisted_uri {
    default 0;
    include /etc/nginx/blacklisted-urls.map;

    # existing patterns ...
}

Don't forget to create this new map file and reload Nginx:

sudo touch /etc/nginx/blacklisted-urls.map
sudo nginx -t
sudo systemctl reload nginx.service

You can now add URL patterns to this map file. However, for more permanent blocks I recommend using the parent map, or a separate file if you like. We can also now create some simple scripts to help manage these blocks.

Block-url.sh script

This helper script will accept a URL path and add it to our map:

URL_PATH="$1"
TARGET="/etc/nginx/blacklisted-urls.map"

if [ -z "$URL_PATH" ]; then
  echo "Usage: $0 URL_PATH"
  exit 1
fi

if grep -q "^$URL_PATH " "$TARGET"; then
  echo "$URL_PATH is already blocked"
  exit 0
fi

LINE="$URL_PATH 1;"
echo "$LINE" >> "$TARGET"
systemctl reload nginx.service

While you can technically use regular expressions with Nginx maps, I tend to stick to just using paths. I've also put some safeguards in place to make sure I don't accidentally block my home page, etc. You can find the extended version in the config demo repository on GitHub.

This article is for premium members only. One-time payment of $196 unlocks lifetime access to all existing and future content on wpshell.com, and many other perks.