Recently has been doing location configuration, encountered priority issues (if the improper configuration may exist security risks OH), the following is a personal learning experience.
Location of one or more matches
1. Equals matching character: =
equals the equals sign, which can be summed up to two points:
Exact match
Regular expressions are not supported
2. Null matching character
An empty match is characterized by:
Matches the URI that starts with the specified pattern
Regular expressions are not supported
3. Regular matching character: ~
A regular match is a match that can use regular expressions. But the point here is, generally speaking, is:
Matching case-sensitive regular matches
and ~* said:
Case-insensitive regular matching
But for some operating systems that are not case sensitive, there is no difference between the two. The other is ^~, which represents a regular match that starts with a specified pattern.
4. Internal Access character: @
Generally used for error pages, etc., this is not discussed.
Second, matching character priority
1.=
2. Null match to meet exact match
3.^~
4.~ or ~*
5. Null match when the match starts at the specified mode
This is more abstract, let's look at the example.
2.1 equals the empty match when the match matches the exact matching character
Look at the example below (the Hello World module we've done together before):
Copy Code code as follows:
location/poechant {
Hello_world No1;
}
Location =/poechant {
Hello_world NO2;
}
If our request is http://my.domian/poechant, then we find that two location are matched to the requested URI, and in our order of precedence, the first is the exact match of the empty match and the second is equal to the match, so the second priority is high, That is, the output should be:
Hello_world, NO2
It also shows that the locatoin of Nginx is not matched according to the order of writing in the configuration file.
2.2 An exact match with an empty match and a regular match ^~
In the following example, both of them begin to match exactly, and even this regular match is an exact match.
Copy Code code as follows:
Location ^~ ^/poechant$ {
Hello_world No1;
}
location/poechant {
Hello_world NO2;
}
Which one does it match? If you test it, you will get:
Hello_world, NO2
Consistent with the order of precedence that we mentioned above.
2.3 Examples of other matching priority comparisons
Slightly
Iii. Summary of actual combat experience
Priority of 1.location matching (from the practice summary)
(location =) > (location full path >) > (Location ^~ path) > (location ~* Regular) > (location path)
As soon as the match is in, the rest is ignored and then returned to the change match.
Use the following example to test:
Copy Code code as follows:
#1
Location/{
return 500;
}
#2
location/a/{
return 404;
}
#3
Location ~* \.jpg$ {
return 403;
}
#4
Location ^~/a/{
return 402;
}
#5
location/a/1.jpg {
return 401;
}
#6
Location =/a/1.jpg {
return 400;
}
Description: When testing, first of all the comments will be, or will think that the #4 exactly the same. Will prompt: Duplicate configuration, prompts as follows
Copy Code code as follows:
D:\nginx-0.8.7>nginx-s Reload
[Emerg]: Duplicate location "/a/" in d:\nginx-0.8.7/conf/nginx.conf:53
Browse Test: Each time is accessed: http://localhost:9999/a/1.jpg (in Windows installation test, then port is 9999) file a/1.jpg does not exist at all. The key is to test to see the page return situation.
A. Results with the above configuration request
Copy Code code as follows:
Bad Request
--------------------------------------------------------------------------------
nginx/0.8.7
As you can see from the test, the highest priority is: = number. It will match to the first.
B. Next we screen out #6 as follows:
Copy Code code as follows:
#6
# location =/a/1.jpg {
# return 400;
# }
Then overload configures:d:\nginx-0.8.7> Nginx-s Reload and accesses: Http://localhost:9999/a/1.jpg, returning the following results:
Copy Code code as follows:
401 Authorization Required
--------------------------------------------------------------------------------
nginx/0.8.7
Conclusion: From this test, it is found that there is no "=" case, and the full path directly after location is preferred. Through the test found that if: location/a/1.jpg change to: location/a/1\.jpg
There will be an unexpected situation, the direct occurrence is: return 402. From this point of view, it can be inferred that the Nginx match priority is: the site path, and without the regular expression of precedence.
C. The same test shields off #5 as follows: note and reload ditto.
Access: Http://localhost:9999/a/1.jpg returns the following results.
Copy Code code as follows:
402 Payment Required
--------------------------------------------------------------------------------
nginx/0.8.7
Conclusion: Through this test, we can conclude that the location ^~ priority is higher than the location ~* priority, among which: ^~ main back path.
C. The same test shields off #4 as follows: note and reload ditto.
Access: Http://localhost:9999/a/1.jpg returns the following results.
Copy Code code as follows:
403 Forbidden
--------------------------------------------------------------------------------
nginx/0.8.7
Conclusion: From the above comparison, the path matching of regular precedence without any matching characters is obtained.
D. The same test shields off #3 as follows: note and reload ditto. And get rid of the note "#"
Access: Http://localhost:9999/a/1.jpg returns the following results.
Copy Code code as follows:
404 Not Found
--------------------------------------------------------------------------------
nginx/0.8.7
Conclusion: The comparison has meaning is:/a/and/should be the same type of matching expression, you can get, the matching order is, the path from the right match, can be inferred as a character, the first match to, that is the priority. So get it:/a/precedence over/.
The above test, is my test result, priority level with above rule. In the actual writing, we often make mistakes. Remember some time ago: The security team exposed nginx loopholes in fact, the individual think that can not be a nginx loophole, but, we do not understand the nginx compounding rules, and there is a configuration above the fatal loophole. In fact, through the priority above, we may also make a fatal error as often as possible at the time of configuration.
Copy Code code as follows:
#以下是随便写例子, individuals may be different.
#假设站点在:/home/www/html/directory, all PHP and upload files are under this directory.
Location ~* \.php$ {
Proxy_pass http://www.a.com;
}
location/upload/{
alias/home/www/html/upload/;
}
And, this upload directory, which is a static directory, our idea is that all of the following files are not executable, including PHP files.
If a user accesses: Http://www.a.com/upload/1.css, the CSS will be displayed directly, but if a user accesses: http://www.a.com/upload/1.php similar files, as mentioned above, the actual match to: ~* \. It's php$. Upload below is executed.
From this inside, we found a problem, actually did not meet our requirements. The files below the static directory are executed as well. It's a bit of a hassle. Once there is a loophole, someone else on the save a PHP, we thought that our configuration is OK. Feel very safe, missing in imperceptible in someone else opened a door.
So how do we modify it?
Copy Code code as follows:
Location ~* \.php$ {
Proxy_pass http://www.a.com;
}
Location ^~/upload/{
alias/home/www/html/upload/;
}
Yes, it is necessary to use: "^~", so that is not already safe. If you visit again: http://www.a.com/upload/1.php you will find that the source code for this section is displayed. This is actually not for us to see. A section of the display source code, in each search engine, it is easy to pass all the special keywords, search to change the file.
So how do we configure a secure stored directory? Yes, you think about it: Restrict the special file types that are allowed.
Copy Code code as follows:
Location ~* \.php$ {
Proxy_pass http://www.a.com;
}
Location ^~/upload/{
if ($request _filename! ~* \. ( Jpg|jpeg|gif|png|swf|zip|rar|txt) $) {
return 403;
}
alias/home/www/html/upload/;
}
As long as it is not satisfied with the extension file above, it automatically prompts: 403 inaccessible, there can be avoided source code display.
Just from the match result already knew, the sibling does not have any match character, is the right is the quasi match. So, if you're using regular expressions, how do you match them?
The test is as follows: (New configuration file, Server contains)
Copy Code code as follows:
Location ~* \.jpg$ {
return 402;
}
Location ~* 1\.jpg$ {
return 403;
}
The results are as follows:
Copy Code code as follows:
402 Payment Required
--------------------------------------------------------------------------------
nginx/0.8.7
It seems that the return is: 402 above one. According to the theory, 1.jpg configuration is more accurate than. jpg, it seems to be different from the order mentioned above, then it will be the one in the previous match it? Let's Test it again:
Copy Code code as follows:
Location ~* 1\.jpg$ {
return 403;
}
Location ~* \.jpg$ {
return 402;
}
The return result is:
Copy Code code as follows:
403 Forbidden
--------------------------------------------------------------------------------
nginx/0.8.7
Haha, on the contrary, it seems my inference is correct, if all is regular, can match, to the order of the configuration file appears, who in the first priority. A breath said, don't know friend you, understand my train of thought? This will be a lot of comparison, we can test one by one. Familiar with the location configuration, for skilled use of nginx is a necessary basis. Because Nginx is too flexible and too popular. The above question, perhaps friend you, will encounter. I hope it will help you.