The ngx_http_auth_request_module
is a module authored by
Maxim Dounin, member of the core
Nginx team.
Maxim mantains a mercurial repository with the latest version of the code.
The module allows for the insertion of subrequests in the
authorization process being handled by Nginx. A more or less obvious
application is using this module as a very fast and specific
WAF. Meaning a WAF without all the ugliness that something like
Apache's mod_security
promotes. No bizarre syntax, no reloading of
the config. Just add a small script that implements the set of
filtering rules that you want to implement. There's no need for any
behemoth module that hurts server performance and keep a consultant on
a retainer.
Suppose that you want to filter any occurence of the UNION
, SELECT
and DROP
statement in the URI. Suppose that the backoffice of your
app is located at /bo
. This will do the trick:
location ^~ /bo {
error_page 401 403 $my_error_page;
auth_basic 'Classified Access';
auth_basic_user_file .htpasswd-bo-users;
auth_request /auth;
auth_request_set $my_error_page $upstream_http_x_error_page;
}
location /auth {
if ($request_uri ~* (?:select|union|drop)) {
return 403;
}
return 200;
}
Let's follow the example. There's a request for an URI like this:
/bo/?u=john_doe'; DROP TABLE users--
-
This request is served by the
^~ /bo
location. There therequest_auth
location redirects to/auth
. -
Now we're on
/auth
and we check theif
condition regex. We have a match withDROP
. Hence we deny authorization by returning a 403 status code, i.e.,403 Access Denied
. -
If we had requested an acceptable URI then we returned 200 from the
/auth
location and we proceeded as usual to the following stage. -
The
$my_error_page
variable is set to the value of theX-Error-Page
header. This can be used for having specific error pages for each error, for example. This is the error page for 403 and 401 errors.
You might say that this example didn't needed to use auth_request
in
the first place. Indeed you could have done everything using a simple
map
directive like this:
map $request_uri $attempt_sql_injection {
default 0;
~*(?:select|union|drop) 1;
}
include it in the http
context of your Nginx instance and set:
location ^~ /bo {
auth_basic 'Classified Access';
auth_basic_user_file .htpasswd-bo-users;
if ($attempt_sql_injection) {
return 403;
}
}
Yes. But this was just an example to give you a hint towards realizing all the potential uses of this handy module.
Here's a quick braindump of potential uses of the auth_request
module.
-
Easily implement two-factor authentication by invoking a script in the
/auth
location. -
Implement Single Sign On systems.
-
Filter requests and prevent vulnerabilities like SQL injection, XSS, etc.
-
Complex caching strategies.
-
Web services implementations.
And much, much more. No limit to your imagination. Dream on.
auth_request uri
| off
default: off
context: http
, server
, location
Enables the auth_request
module in a given context where the request
for authorization will be made to the uri
defined.
auth_request_set variable
value
default: none
context: http
, server
, location
Sets the value of the variable
to value
after the completion of
the authorization request.
Note that the module discards the request body. Therefore if you're
proxying to an upstream you must set
proxy_pass_request_body
to off
and set the Content-Length
header to a null string. Here's
and example:
location = /auth {
proxy_pass http://auth_backend;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
You cannot use
proxy_cache
/proxy_store
or
fastcgi_cache
/fastcgi_store
for requests involving auth_request
.
-
Grab the source from the mercurial tip or clone this repo:
git clone git://github.com/perusio/nginx-auth-request-module.git
-
- Add the module to the build configuration by adding
--add-module=/path/to/ngx_http_auth_request_module
.
- Add the module to the build configuration by adding
-
Build the nginx binary.
-
Install nginx binary.
-
Configure contexts where
auth_request
is enabled. -
Done.
If you fancy a bleeding edge Nginx package (from the dev releases) for Debian made to measure then you might be interested in my debian Nginx package. Instructions for using the repository and making the package live happily inside a stable distribution installation are provided.
- Nginx Delay: allows for inserting arbitrary delays when serving client requests. Usefull for abuse control and/or poor man's traffic shapping.
Thanks to Maxim Dounin for making the module available and being so helpful on the Nginx mailing list answering all kinds of issues and particularly regarding this module.