A detailed analysis of the matching rules when Nginx processes requests

  • 2020-05-17 07:51:23
  • OfStack

When nginx receives a request, it first matches an server through server_name, and then continues the match using location in server.

Matching server_name

In nginx, server_name determines which server will be used when a request is received. nginx matches server_name with the Host field in the request header.

An exact match The first wildcard match is *.example.org After the wildcard match, mail.* Regular expression matching

If there is no match, default_server will be used for processing. If it is not defined, default_server will be defined for the first one. Using three simple server as examples, let them listen on port 80, server_name will be set to *.org, *.net, *.com:


server {
 listen 80;
 server_name example.org www.example.org;
 return 401;
}

server {
 listen 80;
 server_name example.net www.example.net;
 return 402;
}

server {
 listen 80;
 server_name example.com www.example.com;
 return 403;
}

In the above configuration, the default server is the first, and random access to a non-existent server will return 401. However, you can manually set a default host using default_server, and default_server is set in the listen field, as follows:


server {
 listen 80 default_server;
 server_name example.net www.example.net;
}

When it matches again later, if it doesn't match it will use this server.

Blocking access

If you want to disable a request without the Host field, you can define server as follows:


server {
 listen 80;
 server_name "";
 return 444;
}

server_name is defined as an empty string. If the Host field is empty or does not exist, it will be matched to this server field and a 404 status code will be returned.

[

The 444 status of Nginx is special. If 444 is returned, the client will not receive the information returned by the server, just like the website cannot connect to 1, and the browser will display 502 directly. However, if the reverse proxy is used, the normal status code will still be displayed

]

If you want to disable access to a nonexistent host, you can define it as follows:


server {
 listen 80 default_server;
 server_name _;
 return 444;
}

_ does not have any special meaning here, because _ does not appear in a domain name, so it will not be the same as any real domain name, and the use of other illegal characters is the same.

Matches IP and server_name at the same time

Now let's take a look at what happens when listening for different IP and different server_name mixed:


server {
 listen 192.168.1.1:80;
 server_name example.org www.example.org;
}

server {
 listen 192.168.1.1:80;
 server_name example.net www.example.net;
}

server {
 listen 192.168.1.2:80;
 server_name example.com www.example.com;
}

In this configuration, nginx first matches IP and then matches server_name. If server_name is not matched, server is used as their default. For example, if a request for a domain name www.example.com comes from 192.168.1.1:80. Neither of these two can match www.example.com, so use the default host in the two server. Since defualt_server is not used to define listening, the default is server, www.example.org. Of course, you can define defualt_server:


server {
 listen 192.168.1.1:80;
 server_name example.org www.example.org;
}

server {
 listen 192.168.1.1:80 default_server;
 server_name example.net www.example.net;
}

server {
 listen 192.168.1.2:80 default_server;
 server_name example.com www.example.com;
}

Matching location

Once nginx is matched to one server, the request continues to be processed via location. Here is an example:


server {
 listen 172.17.0.3:80;
 server_name _;

 location / {
 return 401;
 }

 location ~*\.(gif|jpg|png)$ {
 return 402;
 }
 
 location ~*\.(gif|jpg|png)$ {
 return 404;
 }

 location /api {
 return 403;
 }
}

First, nginx will search for prefixes in all location to match them. After the prefixes are matched, location defined by regular expressions will be matched in order, and the matching will end. If there is no matching, location previously matched to the prefix will be used for processing.

1 / x.gif request, the first prefix to match is /, then the remaining x.gif and location's regular to match, the first match to location ~*\.(gif|jpg|png)$, return 402. 1 / x.pdf request. Since x.pdf cannot be matched, location/is used for processing. 1 / api x gif, first match to the prefix for/api, then use the remaining x. gif with location regular to match, match to the first location \. ~ * (gif | jpg | png) $, back to 402. 1 /api/ x.pdf request. Since x.pdf cannot be matched, location /api is used for processing.

reference

How nginx processes a request server names

conclusion


Related articles: