请求协助编写Nginx规则拦截特定URL(含问号问题)
Got it, let's tackle this Nginx rule issue you're facing! The problem where the question mark in your target URL gets treated as the start of the query string (making your initial rules ineffective) is super common—here's exactly how to fix it.
Key Background
By default, Nginx's location directive only matches the URI part of a request (everything before the ?). To target URLs that include query strings, you need to use Nginx variables that capture the full request or just the query string itself.
Method 1: Match the Query String with $args
The $args variable stores everything after the ? in the URL. Use this if you only care about the query parameters, not the base URI.
Example 1: Block requests containing a specific parameter
If you want to block any request where the query string includes bad_param (case-insensitive):
server { listen 80; server_name yourdomain.com; # Block requests with "bad_param" in the query string if ($args ~* "bad_param") { return 403 Forbidden; } # Your regular site configuration location / { root /var/www/html; index index.html index.htm; } }
Example 2: Block requests with an exact query string
If you need to block a precise query string (e.g., id=malicious):
if ($args = "id=malicious") { return 403 Forbidden; }
Method 2: Match the Full Request URL with $request_uri
The $request_uri variable captures the entire request URL, including the base URI, ?, and query string. Use this if you need to target a specific full URL path + query string combo.
Example: Block a specific full URL
Suppose you want to block https://yourdomain.com/api/endpoint?action=hack:
server { listen 80; server_name yourdomain.com; # Note: Escape the ? with \? since it's a special regex character if ($request_uri ~* "^/api/endpoint\?action=hack$") { return 403 Forbidden; } # Your regular site configuration location / { root /var/www/html; index index.html index.htm; } }
Important Notes
- Avoid nested
ifdirectives: Nginx'sifcan behave unexpectedly insidelocationblocks. It's safer to place theseifchecks directly in theserverblock. - Combine multiple conditions: Use the
|regex operator to block multiple patterns, e.g.:if ($args ~* "bad_param|malicious_action|fake_token") { return 403 Forbidden; } - Test before reloading: Always validate your configuration with
nginx -tfirst, then reload Nginx withsystemctl reload nginx(or your distro's equivalent command).
内容的提问来源于stack exchange,提问作者user1517598

