#!/usr/bin/perl -w ###### # # Perl CGI Script to implement Fedora Local Mirror # # Name: GLmirrorlist # Version: 1.00 # Copyright 2007 Dax Kelson # # Documentation: http://www.gurulabs.com/goodies/YUM_automatic_local_mirror.php # # This program is free software; you can redistribute it and/or # modify it under the terms of the latest version of the GNU # General Public License as published by the Free Software # Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # http://www.gnu.org/licenses/gpl.txt # ##### use CGI qw/:standard/; use Net::DNS; use LWP::UserAgent; use strict; print header('text/plain'); # For repos that we are locally mirroring, send the client # to the local mirror. if (! param('repo')) { print "# repository not specified"; } elsif (param('repo') eq 'updates-released-fc6' && param('arch') eq 'i386') { # we mirror updates-released-fc6 print "# Redirecting to local mirror\n"; print "# repo = updates-released-fc6 country = US arch = i386\n"; ## FIXME -- edit the next line to be appropriate for your site print "http://fileserver.gurulabs.com/fedora-linux-updates/6/i386/\n"; } elsif (param('repo') eq 'core-6' && param('arch') eq 'i386') { # we mirror core-6 print "# Redirecting to local mirror\n"; print "# repo = core-6 country = US arch = i386\n"; ## FIXME -- edit the next line to be appropriate for your site print "http://fileserver.gurulabs.com/fedora-linux/6/i386/\n"; } else { # For the rest of the repos fallback and pass through the # real answers. This is tricky since, by design, we can't # trust our our local DNS server. # Since local DNS spoofs the IP for mirrors.fedoraproject.org # we need to do our own DNS query bypassing the system resolver. # Do a query to get the name servers responsible for fedoraproject.org my @fpns; my $res = Net::DNS::Resolver->new; my $query = $res->query("fedoraproject.org", "NS"); if ($query) { foreach my $rr (grep { $_->type eq 'NS' } $query->answer) { push @fpns,$rr->nsdname; } } else { print "# NS record lookup for fedoraproject.org failed: ", $res->errorstring, "\n"; exit; } # Query fedoraproject.org name servers directly to get the real IP for # mirrors.fedoraproject.org my $realIP; $res = Net::DNS::Resolver->new; $res->nameservers(@fpns); $query = $res->search('mirrors.fedoraproject.org'); if ($query) { foreach my $rr ($query->answer) { next unless $rr->type eq "A"; $realIP = $rr->address; } } else { print "# DNS query for mirrors.fedoraproject.org failed: ", $res->errorstring, "\n"; exit; } # setup the URI my $uri = "http://$realIP/mirrorlist?repo=" . param('repo') . '&arch=' . param('arch'); my $ua = LWP::UserAgent->new; $ua->agent('GLmirrorlist/1.0'); # Set the Host header properly since our $uri was created using the IP my $req = HTTP::Request->new('GET',$uri, [Host => 'mirrors.fedoraproject.org']); # Send the request on to to real mirrors.fedoraproject.org # and pass the response back to the client print "# Results passed through from $realIP (real IP for mirrors.fedoraproject.org)\n"; my $result = $ua->request($req); if ($result->is_success) { print $result->content; } else { print "# Error getting response from mirrors.fedoraproject.org: " . $result->status_line, "\n"; } }