During an epic debugging session with an NGinx configuration for a project, I discovered some useful, but not so common (at least to me) configuration.
Debug
NGinx do not provide so much help (by default) when it comes to debugging internal redirect,
proxying and other rewrite rules. But it comes with a handy debug
module which allows you
to get a lot more info.
You have to enable it at compile time:
./configure --with-debug
And then in your configuration you can set:
http {
# At the http level activate debug log for eveything
error_log /path/to/my/detailed_error_log debug;
server {
# At the server level activate debug log only for this server
error_log /path/to/my/detailed_error_log debug;
}
server {
# At the server level without the debug keywords it disable debug for this server
error_log /path/to/my/error_log;
}
}
You can even debug only some connections:
error_log /path/to/my/detailed_error_log debug;
events {
debug_connection 10.0.0.1;
debug_connection 10.0.1.0/24;
}
Source: NGinx Debugging Log
Proxying
NGinx is well known for its proxy/reverse-proxy/caching-proxy capabilities, but you’d better know how some things works to not waste your time on some odd behaviors.
When proxying to remote host by URL
s, be aware that NGinx use its own internal resolver for DNS name.
This means in some cases it can’t resolve domains unless you specify which DNS
to use.
Let’s take an example:
server {
# Let's match everything which starts with /remote_download/
location ~_^/remote_download/(._) {
# but only when coming from internal request (proxy, rewrite, ...)
internal;
# Set the URI using the matched location
set $remote_download_uri $1;
# Set the host to use in request proxied (useful if remote is using vhost
# but you're using its IP address to reach it in the proxy_pass config)
set $remote_download_host download.mydomain.tld;
# Set the url we want to proxy to
# Using IP address of server, be sure to set the $remote_download_host
set $remote_download_url https://10.0.0.1/$remote_download_uri;
# Or using the full domain
# set $remote_download_url https://$remote_download_host/$remote_download_uri;
# Set Host header for vhost to work
proxy_set_header Host $download_host;
# This clears the Authorization
proxy_set_header Authorization '';
# If your remote server needs some auth you can set it there
# Basic auth would be something like
# proxy_set_header Authorization 'Basic kjslkjsalkdjaslasdoiejldfkj=';
# Disable local file caching, when serving file
proxy_max_temp_file_size 0;
# Finally send query to remote and response back to client
proxy_pass $download_url;
}
try_files $uri @fallback;
location @fallback {
proxy_pass http://my_backend;
}
}
Example adapted from Nginx-Fu: X-Accel-Redirect From Remote Servers
This example is fully working because we used an IP address
for $remote_download_url
,
but if we were using the domain (eg: download.mydomain.tld), any request would fail
with a 502 Bad Gateway
error.
This is due to the way NGinx default resolver works. It’s smart enough to resolve
the domains in proxy_pass
directives as long as they are statics (it can get them
at boot time) and they are in /etc/hosts. But as we are constructing the URL here,
it does not try to resolve it. Fortunately you can specify which DNS server
it should use in such cases by setting:
http {
# Globally
resolver 127.0.0.1; # Local DNS
server {
# By server
resolver 8.8.8.8; # Google DNS
location /demo {
# Or even at location level
resolver 208.67.222.222; # OpenDNS
}
}
}