Manage websites and FTP permissions with Webmin

Tue 28 October 2014
By alex

So the question at hand is, how can we setup Webmin to create websites and have an ftp user that can manage the sites with minimal overhead? This can be done in 3 steps:

1) Create an ftp user, make their home directory the toplevel directory of the default DocumentRoot and add them to the apache group.

adduser uploader --home=/var/www --shell=/sbin/nologin --gid=apache

2) Change the permissions of DocumentRoot directories that Webmin creates to group writeable

This requires modifying Webmin's core files. Aside from the obvious threat of breaking Webmin, the not so obvious danger is that if Webmin is updated then the modifications may be lost. So it's important to take notes of what's been done.

The file that controls creating apache virtualhosts is /usr/libexec/webmin/apache/create_virt.cgi. There aren't any functions in the file, so we're looking for a comment to locate what we need, # Check if the root directory is allowed.

# Check if the root directory is allowed
!$in{'root'} || &allowed_auth_file($in{'root'}) ||
        &error(&text('cvirt_eroot3', $in{'root'}));

if ($in{'root'} && !-d $in{'root'}) {
        # create the document root
        mkdir($in{'root'}, 0755) ||
                &error(&text('cvirt_eroot2', $in{'root'}, $!));
        $user = &find_directive("User", $conf);
        $group = &find_directive("Group", $conf);
        $uid = $user ? getpwnam($user) : 0;
        $gid = $group ? getgrnam($group) : 0;
        chown($uid, $gid, $in{'root'});
        }

To modify the DocumentRoot's, permissions add a call to chmod after the directory has been created.

Original:

if ($in{'root'} && !-d $in{'root'}) {
        # create the document root
        mkdir($in{'root'}, 0755) ||
                &error(&text('cvirt_eroot2', $in{'root'}, $!));
        $user = &find_directive("User", $conf);
        $group = &find_directive("Group", $conf);

Modified:

if ($in{'root'} && !-d $in{'root'}) {
        # create the document root
        mkdir($in{'root'}, 0755) ||
                &error(&text('cvirt_eroot2', $in{'root'}, $!));
        chmod 0775, $in{'root'};
        $user = &find_directive("User", $conf);
        $group = &find_directive("Group", $conf);

3) The final step is to change the umask settings for the FTP server. This will control the permissions of all newly created files and directories

vsftpd

vi /etc/vsftpd/vsftpd.conf
local_umask=002

ProFTPD

vi /etc/proftpd.conf
Umask                           002

4) Restart services

service proftpd restart
service webmin restart


These settings will allow a website to be bootstrapped using Webmin and FTP uploads, however it should be noted that having a site's DocumentRoot writable by the webserver process is considered a security vulnerability and should be evaluated for it's actual usefulness.