Loading...


Related Products


Date Published: February 6, 2025

How to configure Drupal behind a CDN or WAF (reverse proxy)

Issue

When hosting Drupal on the Acquia platform, it operates behind a reverse proxy by default. 

A frequent challenge encountered under this setup is the masking of original client IP addresses. Logs within Drupal, including other related logs, tend to display the CDN's IP address rather than the actual originating IPs of the requests. This can complicate the process of diagnosing and resolving issues with your website.

In scenarios where your Drupal application is situated behind additional reverse proxies, it's necessary to augment Drupal's existing reverse proxy configuration to ensure proper IP address handling and logging.

Resolution

On a general note, if you're adding information about specific reverse proxies (e.g. you want to include the IP address of your reverse proxy server), take care not to inadvertently overwrite existing information which relates to the Acquia platform. This typically means that you should add IP addresses to the existing reverse_proxy_addresses array, rather than creating a new array which overwrites existing elements.

If you have a WAF or CDN in front of your application, you may want to make use of a HTTP header which the CDN uses to identify client IPs. Examples of this header include Cloudflare's CF-Connecting-IP, and True-Client-IP which is used by multiple CDNs.

For Drupal 7 versions

Drupal 7 has a specific setting for this, as documented in the `sites/default/default.settings.php` file, and shown below.
Reference: https://git.drupalcode.org/project/drupal/-/blob/7.99/sites/default/default.settings.php?ref_type=tags#L453-458

/**
 * Set this value if your proxy server sends the client IP in a header
 * other than X-Forwarded-For.
 */
# $conf['reverse_proxy_header'] = 'HTTP_X_CLUSTER_CLIENT_IP';

For example:

/**
 * Tell Drupal to use the True-Client-IP HTTP header.
 */
if (isset($_SERVER['HTTP_TRUE_CLIENT_IP'])) {
  $conf['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP';
}
 

For Drupal 8 and higher versions

Warning

The recommendation below is currently under review in the drupal.org issue queue. 
Please see https://www.drupal.org/project/drupal/issues/3223280 for more details.


Drupal 8, and later versions, use Symfony for most of their HTTP request handling, and there is no longer a specific Drupal setting for this purpose. Instead the default.settings.php suggests the following below.

    * In order for this setting to be used you must specify every possible
     * reverse proxy IP address in $settings['reverse_proxy_addresses'].
     * If a complete list of reverse proxies is not available in your
     * environment (for example, if you use a CDN) then an alternative
     * implementation must be used depending on your CDN header configuration.
     *
     * Be aware that misconfiguration of this setting could allow for IP address
     * spoofing.
     *
     * See https://www.drupal.org/project/drupal/issues/3223280 for more information
     * and examples.
     */

    Referencing:  



    A couple of examples...

    Example 1 : using $_SERVER['REMOTE_ADDR']

    As suggested in https://www.drupal.org/project/drupal/issues/3223280#comment-14198776

    $settings['reverse_proxy_addresses'] = [$_SERVER['REMOTE_ADDR']];

    Example 2 : A Cloudflare version

    As suggested in https://www.drupal.org/project/drupal/issues/3223280#comment-14236799  :

    if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
      // If the CloudFlare header is contained in the X-Forwarded-For header, then
      // all IP addresses to the right of that entry are reverse-proxies, which are
      // additional to the value in $_SERVER['REMOTE_ADDR].
      // E.g. <client> --- <CDN> --- <Varnish> --- <drupal>.
      $client = $_SERVER['HTTP_CF_CONNECTING_IP'];
      $ips = explode(', ', $_SERVER['HTTP_X_FORWARDED_FOR']);
      if ($keys = array_keys($ips, $client)) {
        $position = end($keys);
        $reverseProxies = array_slice($ips, $position + 1);
        $reverseProxies[] = $_SERVER['REMOTE_ADDR'];
    
        $settings['reverse_proxy'] = TRUE;
        $settings['reverse_proxy_addresses'] = $reverseProxies;
      }
    }

     
    Workaround
    One workaround that has been proposed is the use of the Reverse Proxy Header  module.
    This module provides an equivalent of the reverse_proxy_header setting, which was deprecated in Drupal core 8.7.x , and finally completely removed in Drupal 9. The Reverse Proxy Header  module is available only for Drupal 9 and above, not for Drupal 8.

    For more details, see https://www.drupal.org/project/reverse_proxy_header.

    For Drupal 7 and Drupal 8+ versions

    For cases for Drupal 7 and Drupal 8+ versions, you may wish to add some additional validation of the value of HTTP header (e.g. using filter_var() and FILTER_VALIDATE_IP - note that there are constants for IPv4 and IPv6).

    You may also wish to add additional checks to ensure that the request originated from your CDN / WAF.

     

    References

    Did not find what you were looking for?

    If this content did not answer your questions, try searching or contacting our support team for further assistance.

    Back to Section navigation
    Back to Site navigation