FloydATC has asked for the wisdom of the Perl Monks concerning the following question:
I'm trying to get a Perl section in Apache 2.4 to work, the idea is to pull virtualhost definitions from a MySQL table during httpd startup. Here's the relevant configuration file under "/etc/httpd/conf.d/":
<Perl> use DBI; use Data::Dumper; my $dbtype = "mysql"; my $dbhost = "XXXXXXXX.XXX.XX"; my $dbname = "XXXXXXXX"; my $dbuser = "XXXXXXXX"; my $dbpass = "XXXXXXXX"; my %users = (); my %groups = (); while ( my $user = getpwent() ) { $users{$user} = 1; } while ( my $group = getgrent() ) { $groups{$group} = 1; } my $self = Apache2::ServerUtil->server; my $flags = { PrintError => 1 }; my $dbh = DBI->connect("dbi:$dbtype:$dbname:$dbhost", $dbuser, $dbpass +, $flags); if (defined $dbh) { # Load configuration from MySQL table my $sth = $dbh->prepare(" SELECT * FROM virtualhosts ORDER BY ServerName "); $sth->execute; while (my $record = $sth->fetchrow_hashref) { my $url = $record->{'ServerName'}; my $docroot = $record->{'DocumentRoot'}; my $cacheroot = "/var/www/mason/$url"; my $uid = $record->{'Username'}; my $gid = $record->{'Groupname'}; # Verify DocumentRoot exists unless ( -d $docroot ) { warn "Skipped $record->{'ServerName'}: DocumentRoot '$docroot' i +nvalid\n"; next; } # Verify Username exists unless ( $users{$uid} ) { warn "Skipped $record->{'ServerName'}: Username '$uid' invalid\n +"; next; } # Verify Groupname exists unless ( $groups{$gid} ) { warn "Skipped $record->{'ServerName'}: Groupname '$gid' invalid\ +n"; next; } push @{$VirtualHost{'*:80'}}, { ServerName => $url, ServerAdmin => $record->{'ServerAdmin'}, DocumentRoot => $docroot, SuexecUserGroup => "$uid $gid", }; } open(my $fh, '>', '/var/log/httpd/debug.log'); print $fh Dumper(\%VirtualHost); close $fh; } else { die "MySQL error: ".$DBI::errstr; } </Perl>
You'll notice that I'm dumping the generated hash to a debug logfile, here's what it ends up looking like (actual names redacted):
$VAR1 = { '*:80' => [ { 'ServerName' => 'vsite1.XXX.XX', 'SuexecUserGroup' => 'XXXXXXXX XXXXXXXX', 'ServerAdmin' => 'XXXXXXXX@XXX.XX', 'DocumentRoot' => '/home/XXXXXXXX/public_html' }, { 'ServerName' => 'vsite2.XXX.XX', 'SuexecUserGroup' => 'XXXXXXXX XXXXXXXX', 'ServerAdmin' => 'XXXXXXXX@XXX.XX', 'DocumentRoot' => '/home/XXXXXXXX/public_html' }, { 'ServerName' => 'vsite3.XXX.XX', 'SuexecUserGroup' => 'XXXXXXXX XXXXXXXX', 'ServerAdmin' => 'XXXXXXXX@XXX.XX', 'DocumentRoot' => '/home/XXXXXXXX/public_html' } ] };
Now, here's what Apache seems to think of the configuration. This looks almost like I had expected, except each entry shows up twice. I don't understand why. I know it's not because the VirtualHosts are defined somewhere else, because if I make a simple change to the Perl section (like adding something to $url) the changed name still shows up twice. Maybe the whole section is executed twice, I don't know:
$ httpd -S [Mon Dec 01 18:11:12.970705 2014] [so:warn] [pid 19208] AH01574: modul +e apreq_module is already loaded, skipping [Mon Dec 01 18:11:12.971179 2014] [so:warn] [pid 19208] AH01574: modul +e perl_module is already loaded, skipping VirtualHost configuration: *:80 is a NameVirtualHost default server vsite1.XXX.XX (mod_perl:1) port 80 namevhost vsite1.XXX.XX (mod_perl:1) port 80 namevhost vsite1.XXX.XX (mod_perl:1) port 80 namevhost vsite2.XXX.XX (mod_perl:7) port 80 namevhost vsite2.XXX.XX (mod_perl:7) port 80 namevhost vsite3.XXX.XX (mod_perl:13) port 80 namevhost vsite3.XXX.XX (mod_perl:13) ServerRoot: "/etc/httpd" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/etc/httpd/logs/error_log" Mutex default: dir="/run/httpd/" mechanism=default Mutex mpm-accept: using_defaults Mutex authdigest-opaque: using_defaults Mutex proxy-balancer-shm: using_defaults Mutex rewrite-map: using_defaults Mutex authdigest-client: using_defaults Mutex proxy: using_defaults Mutex authn-socache: using_defaults PidFile: "/run/httpd/httpd.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG Define: MODPERL2 User: name="apache" id=48 Group: name="apache" id=48
But that's not the real problem. The real problem is that no matter what I do with the virtualhosts, Apache keeps serving "/var/www/html" to everyone. If I define the VirtualHosts manually (outside the Perl section) they work as intended, but the Perl magic simply does absolutely nothing except confuse me.
This is all taking place on a test server running Centos 7. I have an old Centos 5 server running a similar setup based on mod_perl 1 and it has served wonderfully for several years so I know the idea isn't completely retarded.
Besides, it looks so very easy when explained here: http://modperlbook.org/html/4-4-1-Constructing-lt-Perl-gt-Sections.html
Does anyone have a clue why it isn't working?
This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-li +nux-thread-multi Linux XXXX.XXX.XX 3.10.0-123.9.3.el7.x86_64 #1 SMP Thu Nov 6 15:06:03 +UTC 2014 x86_64 x86_64 x86_64 GNU/Linux httpd-2.4.6-18.el7.centos.x86_64 mod_perl-2.0.8-10.20140624svn1602105.el7.x86_64
Solved
...and it only took two days of beating my head against the wall.
It turns out that for some reason, getpwent() and getgrent() return user and group names as expected when I execute httpd -S but when actually reloading/restarting the web server they return undef. This causes my script to skip those hosts, a fact that did not become obvious until I enabled PerlSwitches -w (which is commented out in perl.conf by default).
As soon as I disabled the username/groupname checks by commenting out the 'next;' statements, the virtualhosts behaved as expected.
Now all I have to do is figure out why getpwent() and getgrent() don't work properly under mod_perl 2.
Time flies when you don't know what you're doing
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Configuring Apache VirtualHosts using mod_perl 2
by Anonymous Monk on Dec 01, 2014 at 18:47 UTC | |
by FloydATC (Deacon) on Dec 01, 2014 at 21:11 UTC | |
|
Re: [SOLVED] Configuring Apache VirtualHosts using mod_perl 2
by Anonymous Monk on Dec 02, 2014 at 12:59 UTC | |
by FloydATC (Deacon) on Dec 02, 2014 at 16:35 UTC | |
by Anonymous Monk on Dec 02, 2014 at 23:26 UTC | |
by FloydATC (Deacon) on Dec 03, 2014 at 14:17 UTC | |
by Anonymous Monk on Dec 03, 2014 at 20:22 UTC | |
| |
by FloydATC (Deacon) on Dec 04, 2014 at 07:15 UTC |