Apr 302012
 

Varnish is an open source “web accelerator” which you can use to speed up your website.

It can cache certain static elements, such as images or javascript but you can also use it for other purposes such as Load balancing or some additional security, in general most of the people want to try it and test their website to see if it’s really so amazing (IMO yes, but test it yourself).

The traditional guides will tell you to move your webserver to another port, perhaps 81,8080 or just bind to localhost, configure Varnish to listen to port 80 and use the web server as backend, the server where Varnish will forward requests not found in his cache.

This is the “normal” configuration and it works fine, but sometimes you just want to make a quick Test or perhaps you are using a Control Panel, such as Cpanel, Kloxo or ISPConfig and in my experience change the standard listening ports of Apache is not a decision to be taken lightly with these tools.

So in a VPS (with Kloxo) I’ve used a different approach: iptables.



In my approach I’ve left the webserver (Apache for me) sitting on port 80, so no change at all on this side.
I’ve configured varnish to listen on port 8080 and set as backend the Apache on port 80.
I started Varnish and, as expected, going to the port 8080 I’ve seen the site correctly (provided by Apache).

And now some iptables “magic”, all request that goes to port 80 of the server are silently redirected to port 8080, and so Varnish becomes our front-end server with no change on Apache configuration.

How to do it

As you have probably guessed the only “trick” is to use one of the many iptables features, iptables is a user space application that allows to configure the tables provided by the Linux kernel firewall, and in particular I’ve used the nat table with the PREROUTING chain using the action redirect.

From the iptables man page:

nat:
This table is consulted when a packet that creates a new connection is encountered. It consists of three
built-ins: PREROUTING (for altering packets as soon as they come in), OUTPUT (for altering locally-generated
packets before routing), and POSTROUTING (for altering packets as they are about to go out).

So as soon as a packet enters the “firewall”, iptables, checks if it has a destination port of 80 if so it apply an action, in my case redirect, so the packet is redirected to port 8080 where Varnish is listening.

Iptables Rules and Alias

To put the rules that redirect all the traffic from port 80 to 8080 open a terminal as root and use the command:

#iptables -t nat  -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080

If you want to remove Varnish as Front end server you can simply remove that rule with the command:

#iptables -t nat  -D PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080

And to check if the redirect is active, just ask it to iptables with:

#iptables -L -t nat

If you see a line like the following, it means that the redirect is active, if there is nothing in the output it means that it’s inactive.

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 redir ports 8080



But there is an easier way to use these commands, as root just add in your ~/.bashrc file these 3 alias:

alias varnishon='iptables -t nat  -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080'
alias varnishoff='iptables -t nat  -D PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080'
alias varnishstatus='iptables -L -t nat |grep -q 8080; if [ "test$?" = "test0" ]; then echo "Varnish On"; else echo "Varnish Off"; fi'

And now you can turn on and off Varnish with just 1 command.

Final Notes

I’ve not tested with a benchmark how worst perform this configuration in comparison of a traditional solution, probably not much as iptables is a kernel service and is really light, anyway if you have a site with a lot of traffic use this configuration just to test varnish, and if you like it do a traditional installation.

Popular Posts:

flattr this!

  10 Responses to “How to put Varnish in front of your Webserver without doing any change.”

  1. It is even easier on FreeBSD (I have never tried it on Linux). We have Apache listening on *:80 (localhost and all interfaces). When we started up varnish we set it up to listen on the external interface only (eg 20.30.40.50:80) and to use localhost:80 as the backend. Since its listening was more specific than Apache, Varnish did the right thing for us, it took over listening on the external interface and did backend requests to localhost:80 which was being served by Apache. It also did the right thing when we shut down varnish, the external interface was served directly by Apache.

    • On Linux this don’t work, when you try to start Varnish you get a “cannot bind to XXX port already in use”, i don’t know that freebsd has this behavior, nice to know.

      Thanks Ryan

  2. Excellent Ricardo.

    I usually like to make less changes to defaults, as if you have to move your server to another hosting later (months or years later) you do not have to remember all tweaks done.

  3. Thank you this tutorial looks intriguing. What is needed to make it work on cPanel?

    • As long as you can connect as root via ssh you should no problems at all, you’ll continue to manage your webserver with apache and varnish Manually.

  4. i, it doesn’t work for me when i view the page in varnish defualt port, it leads to the apache test page for Kloxo panel.

  5. Here’s my config for editing /etc/varnish/default.vcl

    backend default {
    .host = “127.0.0.1″;
    .port = “80″;
    }
    I also tried editing the host to my actually IP but then i see kloxo default page…..
    then i edited /etc/sysconfig/varnish and changed
    VARNISH_LISTEN_PORT=6081

    to
    VARNISH_LISTEN_PORT=8080
    then i stopped since i could only see the test page and not the actually webpage displaying.

    • Hi,
      I have the same problem with kloxo it seems you have to change:
      .host = “127.0.0.1″;
      to your external IP valid,
      .host = “x.x.x.x″;

  6. how i can do this With tow Different IP Addresses : varnich_ip : v.v.v.v and webser_ip : w.w.w.w

 Leave a Reply

(required)

(required)


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>