How To Add A Custom Response Header In Nginx With Proxy_Pass?

Published August 31, 2024

Problem: Adding Custom Response Headers with Nginx and Proxy_Pass

Adding custom response headers in Nginx when using proxy_pass can be tricky. This setup is often needed to add specific information or change the response from an upstream server before it reaches the client.

Using add_header with Proxy_Pass

Configuring Nginx for Custom Headers

The add_header directive in Nginx works with proxy_pass, letting you add custom headers to responses from upstream servers. This feature is useful for adding extra information or changing the response before it reaches the client.

To use add_header with proxy_pass, include it in the same location block as your proxy_pass directive. Here's a sample Nginx configuration:

server {
    server_name example.com;

    location / {
        proxy_pass http://backend_server;
        add_header X-Custom-Header "Custom Value";
    }
}

In this setup, Nginx will add the X-Custom-Header with the value "Custom Value" to all responses from the backend_server. This header will be in the response sent to the client, whether Nginx or the upstream server generated the response.

The add_header directive applies to the current level and all lower levels unless overridden. If you want to add headers only for specific locations, place the add_header directive in the right location block.

Tip: Conditional Headers

You can use Nginx variables to add headers conditionally. For example:

location / {
    proxy_pass http://backend_server;
    add_header X-Response-Time $request_time;
    add_header X-Cache-Status $upstream_cache_status;
}

This configuration adds the response time and cache status as custom headers, providing useful debugging information.

Implementing the Solution

Step-by-Step Guide

To add custom headers when using proxy_pass in Nginx, follow these steps:

  1. Edit the Nginx configuration file: Open your Nginx configuration file with a text editor. The file is usually at /etc/nginx/nginx.conf or /usr/local/nginx/conf/nginx.conf.

  2. Add the add_header directive: In the server or location block, add the add_header directive. Put it after the proxy_pass directive to apply it to the proxied responses.

  3. Set the custom header and its value: Define your custom header name and value using the add_header directive. The syntax is:

    add_header <header_name> <header_value>;

Here's an example of how your configuration might look:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend_server;
        add_header X-Custom-Header "Custom Value";
        add_header X-Served-By $hostname;
    }
}

In this example, two custom headers are added:

  • X-Custom-Header with a static value "Custom Value"
  • X-Served-By with the value of the $hostname variable, which has the name of the Nginx server

After making these changes, save the configuration file and reload Nginx to apply the new settings:

sudo nginx -t
sudo nginx -s reload

The first command checks the configuration for syntax errors, while the second one reloads Nginx with the new configuration.

Tip: Using Variables in Custom Headers

You can use Nginx variables in your custom headers to add dynamic information. For example:

add_header X-Request-ID $request_id;
add_header X-Client-IP $remote_addr;

These headers will include the unique request ID and the client's IP address, respectively.

Advanced Configuration Options

Using the 'always' Parameter

The 'always' parameter in Nginx's add_header directive lets you add custom headers to all responses, including error responses. This feature is useful when you want your custom headers in every response, regardless of the status code.

Nginx adds custom headers only to successful responses (2xx and 3xx status codes) by default. To include custom headers in error responses (4xx and 5xx status codes), use the 'always' parameter.

Here's how to use the 'always' parameter:

location / {
    proxy_pass http://backend_server;
    add_header X-Custom-Header "Custom Value" always;
}

In this setup, the X-Custom-Header will be added to all responses, including error responses.

You can use the 'always' parameter with multiple headers:

location / {
    proxy_pass http://backend_server;
    add_header X-Custom-Header1 "Value1" always;
    add_header X-Custom-Header2 "Value2" always;
    add_header X-Server-Name $hostname always;
}

This setup adds three custom headers to all responses, including those with error status codes.

Tip: Conditional Headers with 'always'

You can combine the 'always' parameter with conditional statements for more control:

location / {
    proxy_pass http://backend_server;
    add_header X-Cache-Status $upstream_cache_status always;
    if ($status = 404) {
        add_header X-Error-Type "Not Found" always;
    }
}

This setup adds the X-Cache-Status header to all responses and an X-Error-Type header only for 404 errors.

Example: Using 'always' for Security Headers

To improve security, you can use the 'always' parameter to add important security headers to all responses:

server {
    listen 80;
    server_name example.com;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self';" always;

    location / {
        proxy_pass http://backend_server;
    }
}

This example adds several security headers to all responses, helping to protect against common web vulnerabilities.

Remember that using the 'always' parameter can show sensitive information in error responses. Review your custom headers to avoid leaking any sensitive data.