how to match # character in a url in nginx through location directive - nginx

How do I match a # character in a url using location directive? I understand that we can use regex(PCRE), but their docs say that :
The location directive only tries to match from the first / after the hostname, to just before the first ? or #. (Within that range, it matches the unescaped url.)"
In short, How to match "example.com/#123456" using
location ~ [someregex] {
return 200 "matched";
}
or with any other alternative

Simple answer, you can't actually, because that part is never sent to the server to begin with, the only way to process this is to use Javascript, using location.hash

You can't because the ID hash isn't actually sent to the server, you might want to use GET variables like example.com?p=1234 if you intend to direct to a certain page or use location.hash if you wish to direct to a location on the page (which is its intended use)
Good luck!

Related

Restrict access to specific endpoint unless certain header value given

As I explained in title I want to restrict access unless the header is satisfied. In the given link, it is explained how to restrict a specific path access, however I couldn't find anything about how to add conditions to this restriction from my researches. Any idea about this problem?
Instead of deny/allow directives you can check any HTTP header value via $http_<name> variable and use return 403 to forbid access. For example, lets call our header X-Secret-Token:
location /some/path {
if ($http_x_secret_token != 'my-super-secret-password') {
return 403; # HTTP 403 Forbidden, the same code as generated by 'deny' directive
}
...
}
If you need some complex checks, you can use several chained map blocks (see the example).
From the research I've made it seems like the token approach presented here before seems to be the only suitable solution, a similar question has been asked here.

Rewrite url without hash in nginx

I am trying to use Nginx rewrite static file path to strip the hash added for cache busting. The hash is always 10-symbol long. For example,
/min/3rd.party.min.1234567899.js has to become /min/3rd.party.min.js
I have tried this, but it doesn't work (fails at configtest) and also looks way to complicated.
location /min/ {
root /opt/app/public;
rewrite ^.*(?<=(.))[a-z0-9]{10}[.](?=(js|css))[js|css]$ $1$3;
}
I have no idea how you arrived at your regular expression pattern, but the following seems to work:
rewrite "^(.*)\.\w{10}\.(js|css)$" $1.$2 break;
Any pattern that contains a brace, must be placed within quotes. Use the break suffix to process the rewritten URI within the same location. See this document for details, and this useful resource on regular expressions.

Nginx - How to block all IPs except one

I'm a total Nginx newbie and I need some help. =]
I have a list of IPs contained within "$proxy_add_x_forwarded_for" which contains IPs separated by commas in this format: "IP, Next IP".
I'd like to return a 403 error code if MY IP is not within this comma separated list.
I thought the easiest way to do it would be to do a simple if statement to say: If $proxy_add_x_forwarded_for doesn't contain MY IP return 403.
Having tried this for ages I can't get anything to work, can anyone help me out? It sounds like this should be really easy.
Edit: Also I'm trying to set this up within the location block because there are other configurations using the Nginx and the IP restriction is only valid for this specific block.
Assuming that your IP address is 123.123.123.123, then the following statement will return 403 if your IP address is not present:
if ($proxy_add_x_forwarded_for !~ \b123\.123\.123\.123\b) { return 403; }
It uses the \b metacharacter to enforce word boundaries (which includes digits) so that the complete IP address is tested.
You can place the expression within a location block if you need to reduce its scope.
The if directive is documented here. See this caution on the use of the if directive. A useful resource for regular expressions is here.

Why do the following rules conflict in NGINX?

I have these two rules :
location ~* ^.+\.(jpg|jpeg|gif|css|js|png)$ {
proxy_pass http://127.0.0.1:44843$request_uri;
}
location /pc {
proxy_pass http://127.0.0.1:12345$request_uri;
}
The URI :
/pc/asser/somefile.js
falls in teh second rule, why ?
is it a question of lower priority of the "location /pc" rule ?
Nginx documentation defines it:
Directives are processed in the following manner:
Exact string matches are processed first. If a match is found, nginx stops searching and fulfills the request.
Remaining literal string directives are processed next. If the "^~" argument is used, then ngnix stops here and fulfills the request. Otherwise, nginx continues to process location directives.
All location directives specified by regular expressions (with the ~ and ~* arguments) are processed. If a regular expression matches the request, nginx stops here and fulfills the request.
When there are no regular expressions, or no regular expressions match, the most specific literal string match is used.
So you should use regular expression for /pc too:
location ~ /pc/.* {
proxy_pass http://127.0.0.1:12345$request_uri;
}
At first nginx check locations defined using the prefix strings (prefix locations).
And only after, it checks locations defined using regular expressions, in the order of their appearance in a configuration file.
http://nginx.org/en/docs/http/ngx_http_core_module.html#location specifies the order in which nging location directives are looked at:
To find a location matching a given request, nginx first checks locations defined
using the prefix strings (prefix locations). Among them, the most specific one is
searched.
Basically the problem here is that prefix locations are always given priority over regex ones
So in your config, if both blocks match, it's the /pc prefix one that gets priority

Rewrite Rule in Nginx

I conisder moving to Nginx but I want you to ask if is possible to rewrite urls into that schema, and if you could help me a bit:
A url like http://example.com/username into profile.php?u=username. But then, will I have problems in accessing other pages like e.g. home.php
A url like http://example.php/questions/102039/that-question into questions.php?quid=102039
Thank you very much!
Yes, it is possible to rewrite URLs with Nginx.
Your first example can be handled easily by wrapping the rewrite with a block which checks if a file (home.php in your example) exists; if it doesn't, then it tries the redirect into the profile.php request. (See the try_files syntax for this.)
Your second example is just as simple:
Rewrite ^/questions/(\d+) /questions.php?quid=$1
(Because the matching expression is not anchored at the end, it should accept any string after the digits, but I haven't checked that so I'd recommend you test it.)

Resources