Authorize file upload requests with nginx
I use nginx for most of my projects. It's a fast and robust HTTP server for serving static contents, and a great reverse proxy for serving dynamic pages from a web application.
I recently worked on system where users upload large data files for analysis. To protect the web application from unauthorized uploads, potentially blocking legitimate use of the service, upload authorization is a requirement.
It turns out that authorization of uploads is quite easy to implement, as nginx can do request authorization using the Auth Request module.
This nginx module implements authorization based on sub request result. Hence, a request to a given url is authorized by a subrequest to another url, for example an internal authorization url to your web app.
If you're running a system with a nginx version prior to version 1.5.4, you need to compile nginx from source to use the Auth Request module.
You can follow the instructions below, on how to compile and configure nginx with the Auth Request module.
Building nginx from source
These instructions have been tested on recent Ubuntu distributions.
Get build tools and source package
Install build pre-requsites and nginx config files etc.
sudo apt-get install build-essential libpcre3-dev \
zlib1g-dev libssl-dev nginx-common
Download the nginx source package.
apt-get source nginx
For versions prior to 1.5.4
If the source package contains a version of nginx that is older than version 1.5.4, the Auth Request module is not included with the source code. You then have to download and unpack the Auth Request module's source code.
wget http://mdounin.ru/hg/\
ngx_http_auth_request_module/archive/tip.tar.gz
tar xzf tip.tar.gz
rm tip.tar.gz
Build nginx
Enter the nginx source path (note: version specific).
cd nginx-1.1.19
You may have to edit the file auto/cc/gcc
, removing the compiler option Werror
. This is necessary on some (older) systems to complete the build, which will otherwise fail due to a harmless compiler warning.
Create the makefiles, selecting the modules to include in the build. See the nginx wiki for a complete list of modules, or just use my suggested list.
./configure --prefix=/etc/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-client-body-temp-path=/var/lib/nginx/body \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-log-path=/var/log/nginx/access.log \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--lock-path=/var/lock/nginx.lock \
--pid-path=/var/run/nginx.pid \
--with-http_gzip_static_module \
--with-http_ssl_module --with-ipv6 \
--without-http_browser_module \
--without-http_limit_req_module \
--without-http_limit_conn_module \
--without-http_map_module \
--without-http_memcached_module \
--without-http_referer_module \
--without-http_scgi_module \
--without-http_split_clients_module \
--without-http_ssi_module \
--without-http_userid_module \
--without-http_uwsgi_module \
--with-http_auth_request_module
If you're building a nginx version prior to 1.5.4, just replace the last line with the path the downloaded version of the Auth Request module (note: version specific).
--add-module=../ngx_http_auth_request_module-662785733552
Build the binary and copy it to the right directory (note: there is no need for make install
as the config files etc. are already installed with the nginx-common
package):
make
sudo cp objs/nginx /usr/sbin/
Configuration
After building and installing nginx with the Auth Request module, all that is left, is to change the configuration files to suit your needs.
Edit the /etc/nginx/nginx.conf
and /etc/nginx/sites-available/default
configuration files. See the nginx docs for documentation about the different options.
Specifically, see configuration options for the Auth Request module.
The default settings nginx accepts POST and PUT requests containing up to 1Mb of data in the request body. This limit is configurable using the client_max_body_size
parameter see nginx docs.
Create a symlink to the default site
sudo ln -s -t /etc/nginx/sites-enabled/ /etc/nginx/sites-available/default
Start nginx
sudo invoke-rc.d nginx start
Finally, you now have nginx running with the auth request module.