Nginx - Additional Modules, Limits and Restrictions
The following modules allow you to regulate access to the documents of your websites — require users to authenticate, match a set of rules, or simply restrict access to certain visitors.
Auth_basic Module
The auth_basic module enables the basic authentication functionality. With the two directives that it reveals, you can make it so that a specific location of your website (or your server) is restricted to users that authenticate using a username and password:
location /admin/ {
auth_basic "Admin control panel";
auth_basic_user_file access/password_file;
}
The first directive, auth_basic, can be set to either off or a text message usually referred to as authentication challenge or authentication realm. This message is displayed by web browsers in a username/password box when a client attempts to access the protected resource.
The second one, auth_basic_user_file, defines the path of the password file relative to the directory of the configuration file. A password file is formed of lines respecting the following syntax: username:password[:comment]. The password must be encrypted with the crypt(3) function, for example, using the htpasswd command-line utility from Apache.
If you aren't too keen on installing Apache on your system just for the sake of the htpasswd tool, you may resort to online tools as there are plenty of them available. Fire up your favorite search engine and type "online htpasswd".
Access
Two important directives are brought up by this module: allow and deny. They let you allow or deny access to a resource for a specific IP address or IP address range. Both directives have the same syntax: allow IP | CIDR | all, where IP is an IP address, CIDR is an IP address range (CIDR syntax), and all specifies that the directive applies to all clients:
location {
allow 127.0.0.1; # allow local IP address
deny all; # deny all other IP addresses
}
Note that rules are processed from top-down — if your first instruction is deny all, all possible allow exceptions that you place afterwards will have no effect. The opposite is also true — if you start with allow all, all possible deny directives that you place afterwards will have no effect, as you already allowed all IP addresses.
Limit Connections
The mechanism induced by this module is a little more complex than regular ones. It allows you to define the maximum amount of simultaneous connections to the server for a specific zone.
The first step is to define the zone using the limit_conn_zone directive:
- Directive syntax: limit_conn_zone $variable zone=name:size;
- $variable is the variable that will be used to differentiate one client from another, typically $binary_remote_addr — the IP address of the client in binary format (more efficient than ASCII)
- name is an arbitrary name given to the zone
- size is the maximum size you allocate to the table storing session states
The following example defines zones based on the client IP addresses:
limit_conn_zone $binary_remote_addr zone=myzone:10m;
Now that you have defined a zone, you may limit connections using limit_conn:
limit_conn zone_name connection_limit;
When applied to the previous example it becomes:
location /downloads/ {
limit_conn myzone 1;
}
As a result, requests that share the same $binary_remote_addr are subject to the connection limit (one simultaneous connection). If the limit is reached, all additional concurrent requests will be answered with a 503 Service Unavailable HTTP response. If you wish to log client requests that are affected by the limits you have set, enable the limit_conn_log_level directive and specify the log level (info | notice | warn | error).
Limit Request
In a similar fashion, the Limit Request module allows you to limit the amount of requests for a defined zone.
Defining the zone is done via the limit_req_zone directive; its syntax differs from the Limit zone equivalent directive:
limit_req_zone $variable zone=name:max_memory_size rate=rate;
The directive parameters are identical, except for the trailing rate: expressed in requests per second (r/s) or requests per minute (r/m). It defines a request rate that will be applied to clients where the zone is enabled. To apply a zone to a location, use the limit_req directive:
limit_req zone=name burst=burst [nodelay];
The burst parameter defines the maximum possible bursts of requests — when the amount of requests received from a client exceeds the limit defined in the zone, the responses are delayed in a manner that respects the rate that you defined. To a certain extent, only a maximum of burst requests will be accepted simultaneously. Past this limit, Nginx returns a 503 Service Unavailable HTTP error response:
limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/s;
[…]
location /downloads/ {
limit_req zone=myzone burst=10;
}
If you wish to log client requests that are affected by the limits you have set, enable the limit_req_log_level directive and specify the log level (info | notice | warn | error).