Introduction
When working with NGINX, a popular HTTP and reverse proxy server, understanding and properly-configuring header field names is critical. By default, NGINX does not recognize headers with underscores in them. This setting can affect applications that rely on custom header names. This tutorial explores the underscores_in_headers
directive in NGINX, explains its functionality, and provides examples of how to use it effectively.
Understanding Headers in HTTP
HTTP headers are the name/value pairs that are sent in HTTP requests and responses. Header names are case-insensitive and conventionally use hyphens rather than underscores. However, some applications may incorrectly generate header names with underscores, an issue that NGINX addresses with the underscores_in_headers
directive.
The Default Behavior of NGINX
By default, NGINX ignores headers that contain underscores. This behavior is designed to prevent ambiguities and security issues. For instance, the header X_User_Auth
will be ignored by NGINX, while X-User-Auth
will be read correctly.
Enabling Underscore in Headers
To allow NGINX to read headers with underscores, you need to set the underscores_in_headers
directive to ‘on’ in your NGINX configuration:
http {
...
underscores_in_headers on;
}
This will instruct NGINX to recognize and accept headers with underscores.
Examples
Basic Configuration
Let’s start with a basic example. Consider an upstream application that requires a custom header API_KEY
. We would include the directive in our NGINX server block configuration:
server {
...
location / {
...
underscores_in_headers on;
}
}
With this setting, NGINX will accept the API_KEY
header from incoming requests.
Using map
with underscores in headers
You can map headers with underscores to variables within the NGINX configuration. Below is an example of mapping the X_User_Type
header to a variable and applying logic based on its value:
http {
...
map $http_x_user_type $user_type {
default 'guest';
admin 'administrator';
user 'registered_user';
}
server {
...
underscores_in_headers on;
location /adminpanel {
if ($user_type != 'administrator') {
return 403;
}
}
}
}
In this example, we’ve securely restricted access to the /adminpanel
location, based on the user’s type obtained from the headers.
Conditional Logging
If your application sends specific headers with underscores for debugging purposes such as X_Debug_Info
, you can conditionally log those headers. To achieve this, use the following configuration:
http {
...
underscores_in_headers on;
map $http_x_debug_info $loggable_debug_info {
~^.{5,} 1;
default 0;
}
access_log /path/to/access.log combined if=$loggable_debug_info;
}
Here, we only log requests that include a X_Debug_Info
header with a value that is at least 5 characters long.
Securing Proxy Headers
When setting headers in an NGINX reverse proxy scenario, it’s essential to sanitize incoming headers to avoid conflicts with the ones set by your server configuration. See the following example:
server {
...
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://backend;
underscores_in_headers off;
}
}
In the proxy scenario above, we’ve turned off underscores_in_headers
to ensure only sanitized headers, like X-Real-IP
, pass through to the proxy.
Best Practices
When dealing with headers in NGINX, keep the following best practices in mind:
- Use a consistent convention for header names, preferably hyphenated names to avoid needing
underscores_in_headers
. - Only enable
underscores_in_headers
if absolutely necessary, as underscores in header names are non-standard and may be deprecated in the future. - When working with upstream services that require headers with underscores, ensure that these services are trusted and the headers are not used for important transactions, avoiding potential security risks.
Conclusion
In conclusion, the underscores_in_headers
directive in NGINX is a powerful but often overlooked feature. By carefully evaluating the use cases and following best practices, administrators can ensure the reliability and security of their web applications’ communication.