DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 5.4 Giving Users Their Own URL

Problem

You want to give each user on your system his own web space.

Solution

If you want users' web locations to be under their home directories, add this to your httpd.conf file:

UserDir public_html

To put all users' web directories under a central location:

UserDir /www/users/*/htdocs

If you have mod_perl installed, you can do something more advanced like this (again, added to your httpd.conf file):

<Perl>
# Folks you don't want to have this privilege
my %forbid = map { $_ => 1 } qw(root postgres bob);
opendir H, '/home/';
my @dir = readdir(H);
closedir H;
foreach my $u (@dir) {
    next if $u =~ m/^\./;
    next if $forbid{$u};
    if (-e "/home/$u/public_html") {
        push @Alias, "/$u/", "/home/$u/public_html/";
    }
}
</Perl>

Discussion

The first solution is the simplest and most widely used of the possible recipes we present here. With this directive in place, all users on your system are able to create a directory called public_html in their home directories and put web content there. Their web space is accessible via a URL starting with a tilde (~), followed by their usernames. So, a user named bacchus accesses his personal web space via the URL:

http://www.example.com/~bacchus/

If you installed Apache from the standard source distribution, your default configuration file includes an example of this configuration. It also contains a <Directory> section referring to the directory /home/*/public_html, with various options and permissions turned on. You need to uncomment that section in order for anyone to have access to these user web sites. This section should look something like the following:

<Directory /home/*/public_html>
    AllowOverride FileInfo AuthConfig Limit
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    <Limit GET POST OPTIONS PROPFIND>
        Order allow,deny
        Allow from all
    </Limit>
    <LimitExcept GET POST OPTIONS PROPFIND>
        Order deny,allow
        Deny from all
    </LimitExcept>
</Directory>

Make sure you understand what each of these directives is enabling before you uncomment this section in your configuration.

The second solution differs in that the argument to UserDir is given as a full pathname and so is not interpreted as relative to the user's home directory, but as an actual file path. The * in the file path is replaced by the username. For example, http://example.com/~smith/ is translated to /www/users/smith/htdocs. This directory structure needs to be configured in a manner similar to the previous example.

The third solution requires mod_perl and provides alias mappings for all top directories under the /home hierarchy (typically user directories). It differs from the first two by not including the tilde prefix; user smith's web location would be specified as http://example.com/smith/ instead of http://example.com/~smith/ but is still the filesystem location /home/smith/public_html.

In each case, the directory in question, and directories in the path leading up to it, need to be readable for the Apache user (usually nobody or www or httpd), and also have the execute bit set for that user, so the Apache server can read content out of that directory. The execute bit is needed in order to get a directory listing. Thus, for user bob, the directories /, /home, /home/bob, and /home/bob/public_html (or the corresponding directory paths for the other solutions) all need to execute access, and the last one also requires read access.

On Unixish systems, you would set these permissions by issuing the following commands:

% chmod o+x / /home /home/bob
% chmod o+rx /home/bob/public_html

The files within the directory need only be readable:

% chmod 644 /home/bob/public_html/*

If you use the first solution, many users may be concerned about these file permissions, and rightly so, as it usually allows all other users read access to these directories. Make sure that your users are aware of this, and that they keep personal files in directories that are not world readable.

The advantage of this approach over the previous one is that these files are stored in a location that is not inside the user's home directory, and so the user may keep sensible file permissions on her home directory. This lets her store personal files there without concern that other users may have free access to them.

The last Solution is completely different and requires that you have mod_perl installed. The list of directives previously mentioned goes in your configuration file, using the <Perl> configuration directive supplied by mod_perl, which allows you to put Perl code in your configuration file to dynamically add things to the configuration file at server startup.

At server startup, the code shown looks in the /home/ directory for any user that has a public_html directory and creates an Alias for them. This has the advantage over the previous two solutions because the URLs no longer contain that annoying tilde character, which people tend to think unprofessional. So user bacchus is now able to access his personal web space via the URL http://www.example.com/bacchus/.

The %forbid list at the top of the code provides a list of users who should not be given this special alias for one reason or another. This allows you to eliminate users for which this feature may cause a security risk, such as root, or users who have shown that they can't be trusted with such privileges.

As with the previous examples, this should be accompanied by a <Directory> section that enables read access for the directory /home/*/public_html.

And, of course, you can have this code point these aliases at any location, if you want to serve content out of some other location rather than the home directories of the users.

See Also

    [ Team LiB ] Previous Section Next Section