Introduction

By using a reverse proxy, it is possible to create an HTTP mirror without of the heavy burden of rsync and a large amount of allocated space. The reverse proxy will cache the particular files (with special cases to exclude repository files)

Some practical applications might include:

  • Network installs
  • Primary repository for OS updates
  • Anycast installation HTTP servers for larger deployments
  • Booting test images w/o uploading to remote server

Note: The advantages of this proxy won't be seen with only one to two hosts except in the cases where they are being reinstalled constantly.

Requirements

  • 300 MB of disk space
  • LAN w/internet router :)

Varnish Config

Make a /etc/varnish/public-mirror.vcl and edit the startup settings for varnish (On redhat, it's /etc/sysconfig/varnish, In gentoo it's /etc/conf.d/varnishd, …). This particular configuration uses http://mirrors.kernel.org (from the US) as it is a very reliable and usually a Teir 1 or 2 mirror with most projects. Not to say that it couldn't be used with another source such as http://jailtime.org and it's many mirrors as well.

This configuration has been tested and is currently in use with minor OS tweaks for performance.

backend kernelorg_1 {                                                                                     
        #.host = "mirrors.kernel.org";
        .host = "149.20.20.135";                                                                          
        .port = "80";                                                                                     
        .probe = {
                .request =
                "HEAD /index.html HTTP/1.1"
                "Host: mirrors.kernel.org"
                "Connection: close";
                .timeout = 0.3 s;
                .window = 8;
                .threshold = 3;
        }
}
 
backend kernelorg_2 { 
        #.host = "mirrors.kernel.org";
        .host = "204.152.191.39";     
        .port = "80";                 
        .probe = {                    
                .request =            
                "HEAD /index.html HTTP/1.1"
                "Host: mirrors.kernel.org" 
                "Connection: close";       
                .timeout = 0.3 s;          
                .window = 8;               
                .threshold = 3;            
        }                                  
}                                          
 
// A director acts as a router for backends
director ubuntu random {
        # { .backend = ubuntu_us_1; .weight = 1; }
        # { .backend = ubuntu_us_2; .weight = 1; }
        # { .backend = ubuntu_us_3; .weight = 1; }
        # { .backend = ubuntu_us_4; .weight = 1; }
        # { .backend = ubuntu_osuosl_1; .weight = 50; }
        # { .backend = ubuntu_osuosl_2; .weight = 50; }
        { .backend = kernelorg_2; .weight = 1; }
        { .backend = kernelorg_1; .weight = 1; }
}
 
sub vcl_recv {
 
        // BACKEND declarations have to happen first so that dead hosts are 
        // properly excluded
 
        // In this case, all these base directories are handled by this single 
        // backend.  It could also look like req.host ~ "linux.etherboot.org"
        // for virtual host based setups
        if ( req.url ~ "^/(ubuntu|debian|centos|opensuse|suse|fedora|gentoo)" ) {
                set req.http.host = "mirrors.kernel.org";
                set req.backend = ubuntu;
        }
 
        // Skip repository files (apt)
        if ( req.url ~ "/(Release|Packages|Sources)(|\.gz|\.bz2|\.gpg|)$") {
                pass;
        }
        // Skip repository files (yum)
        if ( req.url ~ "/repodata/.*" ) {
                pass;
        }
 
 
        // Basic housekeeping for dead backends
        // Continue serving stale files for up to an hour while the backend recovers
        if (req.backend.healthy) {
                set req.grace = 30s;
        } else {
                set req.grace = 1h;
        }
}
 
sub vcl_fetch {
        // Debugging info 
        set obj.http.X-Varnish-Url = req.url;
 
        // Keep cachable objects up to 1day
        set obj.ttl = 1d;
        // Serve the stale file for up to 15m while a newer version is fetched 
        set obj.grace = 15m;
        #set beresp.grace = 15m;
        // not used yet
        set obj.prefetch = -30s;
}
 
sub vcl_miss {
        // Nasty spiders!! DIE!!  
        if (req.http.user-agent ~ "spider") {
                error 503 "Not presently in cache, please try again later";
        }
}
 
sub vcl_deliver {
        // Debugging headers
        if (obj.hits > 0 ) {
                set resp.http.X-Cache = "HIT";
        } else {
                set resp.http.X-Cache = "MISS";
        }
}

QR Code
QR Code appnotes:varnishmirror (generated for current page)