Place of all tech articles

techarticles

  • Home
  • About
  • Contact Info

Getting real client IP through Varnish

28th June, 2014 · techinf1 1 Comment

Getting real client IP through Varnish

After installation Varnish as frontend caching server your Web server ( like Apache, Nginx etc.) and application (PHP, ASP, JSP etc.) will not see real client IP from which request is coming. Rather than they will see client IP as 127.0.0.1 if Varnish and Web server are installed in the same machine. If varnish is installed in separate host then that host IP will be seen as client IP. In my earlier post Optimization of Apache Webserver With Varnish Installation you can see how Varnish is installed as front end caching server whereas Apache is installed as back end Web server. Follow the steps for “Getting real client IP through Varnish”

  1. Open up the /etc/varnish/default.vcl file and change it as mentioned
    # vi /etc/varnish/default.vcl
    

    This file tells Varnish where to look for the webserver content. In the sub vcl_recv section you need to mention set req.http.X-Forwarded-For = client.ip;
    The default configuration file already has all necessary configuration lines. You just need to uncomment those lines. The configuration file should look like this:

    # This is a basic VCL configuration file for varnish.  See the vcl(7)
    # man page for details on VCL syntax and semantics.
    #
    # Default backend definition.  Set this to point to your content
    # server.
    #
    backend default {
      .host = "127.0.0.1";
      .port = "8080";
    }
    
    # Below is a commented-out copy of the default VCL logic.  If you
    # redefine any of these subroutines, the built-in logic will be
    # appended to your code.
     sub vcl_recv {
         if (req.restarts == 0) {
            if (req.http.x-forwarded-for) {
                set req.http.X-Forwarded-For =
                    req.http.X-Forwarded-For + ", " + client.ip;
            } else {
                set req.http.X-Forwarded-For = client.ip;
            }
        }
      
     if (req.request != "GET" &&
           req.request != "HEAD" &&
           req.request != "PUT" &&
           req.request != "POST" &&
           req.request != "TRACE" &&
           req.request != "OPTIONS" &&
           req.request != "DELETE") {
    #         /* Non-RFC2616 or CONNECT which is weird. */
             return (pipe);
         }
         if (req.request != "GET" && req.request != "HEAD") {
    #         /* We only deal with GET and HEAD by default */
             return (pass);
         }
         if (req.http.Authorization || req.http.Cookie) {
    #         /* Not cacheable by default */
             return (pass);
         }
       return (lookup);
      #   return (pipe);
     }
    #
     sub vcl_pipe {
    #     # Note that only the first request to the backend will have
    #     # X-Forwarded-For set.  If you use X-Forwarded-For and want to
    #     # have it set for all requests, make sure to have:
          set bereq.http.connection = "close";
    #     # here.  It is not set by default as it might break some broken web
    #     # applications, like IIS with NTLM authentication.
         return (pipe);
     }
    
  2. Restart Apache and Varnish to make the changes effective
    # /etc/init.d/varnish restart
    
  3. Edit httpd.conf file to get client IP in Apache access log file
    Just add the following lines inside your Virtualhost declaration:

    LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnish
    CustomLog /var/log/httpd/yourdomain_log varnish
    

    So for a domain www.example.com virtual host configuration for Apache would be

    <VirtualHost *:8080>
        ServerAdmin webmaster@dummy-host.example.com
        DocumentRoot /var/www/www.example.com
        ServerName www.example.com
        ErrorLog /var/log/httpd/example.com-error_log
        LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnish
        CustomLog /var/log/httpd/example.com_log varnish
    </VirtualHost> 
    
  4. Change application coding to have real client IP
    In PHP we use $_SERVER[‘REMOTE_ADDR’] to get client IP. Now, you have to use $_SERVER[“HTTP_X_FORWARDED_FOR”] to get remote client IP. You can check it by making a test.php in your  website directory and browse it from any browser

    <?php
    echo $_SERVER["REMOTE_ADDR"];
    echo $_SERVER["HTTP_X_FORWARDED_FOR"];
    ?>
    

    The first line should print 127.0.0.1 or other IP where Varnish is installed. The second line should print the real client IP. So, in you all pages you should replace $_SERVER[“REMOTE_ADDR”] by $_SERVER[“HTTP_X_FORWARDED_FOR”].
    If you think it is hazard for you there is another trick to solve this. You just need to automatically prepend the following PHP script to all PHP files that are ran behind Varnish. Open a file editor to create /etc/httpd/conf.d/varnish_client_ip.php, then add the following:

    <?php
    if( isset( $_SERVER[ 'HTTP_X_FORWARDED_FOR' ] ) ) {
      $_SERVER[ 'REMOTE_ADDR' ] = $_SERVER[ 'HTTP_X_FORWARDED_FOR' ];
    }
    

    You then need to  add the following lines inside your Virtualhost declaration of Apache:

    <Directory "/var/www/www.example.com">
        php_value auto_prepend_file "/etc/httpd/conf.d/varnish_client_ip.php"
    </Directory>
    

    Here /var/www/www.example.com is the document root for your domain www.example.com. So  for a domain www.example.com virtual host configuration for Apache would be

    <VirtualHost *:8080>
        ServerAdmin webmaster@dummy-host.example.com
        DocumentRoot /var/www/www.example.com
        ServerName www.example.com
        ErrorLog /var/log/httpd/example.com-error_log
        LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnish
        CustomLog /var/log/httpd/example.com_log varnish
        <Directory "/var/www/www.example.com">
           php_value auto_prepend_file "/etc/httpd/conf.d/varnish_client_ip.php"
        </Directory>
    </VirtualHost> 
    

Now enjoy the faster web server and  feed your application and Apache by  Getting real client IP through Varnish.

Posted in Apache, Varnish, Webserver |
« Optimization of Apache webserver with Varnish installation
Install Google mod_pagespeed »

One thought on “Getting real client IP through Varnish”

  1. Galab Parchev (Gabo) says:
    2017-06-20 at 8:25 am

    still have the varnish IP in auth.log on failed http logins, instead the client ip. Only Access log shows the real client ip. Any ideas?

    Reply

Leave a comment Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts

  • Ansible Exam (RHCE 8) full solution with explanation
  • Install Ansible on CentOS 8
  • Recover MySQL 5.7 root Password in Redhat/CentOS 7
  • SSH login without password in Linux
  • How to write automated FTP script in Linux

Categories

Pages

  • About
  • aStore
  • Contact Info
  • google pagerank checker
  • SEO Keyword Rank
  • SEO Page Audit
  • Tools
  • whois

Archives

  • March 2022
  • February 2022
  • August 2017
  • May 2017
  • November 2015
  • October 2015
  • August 2015
  • May 2015
  • March 2015
  • February 2015
  • January 2015
  • December 2014
  • November 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014

Categories

  • Adsense (1)
  • Ansible (2)
  • Database (17)
    • MySQL (15)
    • Oracle (2)
  • FTP (1)
  • Google Map (2)
  • HTML5 (1)
  • Linux (8)
    • AWK (1)
  • PageSpeed (1)
  • PHP (3)
  • phpMyAdmin (1)
  • Social Networking (1)
  • Varnish (3)
  • Webpage Optimization (1)
  • Webserver (5)
    • Apache (4)
    • Nginx (1)
  • Website Migration (1)
  • WordPress (6)

WordPress

  • Log in
  • WordPress
© Techinfobest is the house of tech articles
  • Home