ProFTPD is a versatile ftp server. I recently integrated it in my Kolab 3.3 server environment, so that user access be can easily organized by the standard kolab-webadmin. The design looks as follows:
Kolab users are be able to login to ProFTPD but every user gets jailed in his own separate (physical) home directory. According to his group memberships, aditional shared folders can be displayed and accessed within this home directory.
You will need proftpd with support for ldap and virtual root environments. In Debian and Ubuntu, this is achieved via module packages:
On other platforms you may need to compile your own proftpd.
Via kolab-webadmin I created a new organizational unit FTPGroups within parent unit Groups. Within this unit, you can now add groups of type (Pure) POSIX Group. These groups are later used to restrict or permit access to certain directories or apply other custom settings per group by using the
directive of ProFTPD.
Note, that you stick to sub-units of ou=Groups here, so that this unit will be recognized by the kolab-webadmin. The LDAP-record of such a group may look like this:
dn: cn=ftp_test_group,ou=FTPGroups,ou=Groups,dc=domain,dc=com cn: ftp_test_group gidnumber: 1234 objectclass: top objectclass: groupofuniquenames objectclass: posixgroup uniquemember: uid=testuser,ou=People,dc=domain,dc=com
To make sure that our kolab-users and groups within the sub-unit get mapped correctly to their equivalents in the ftp-server, we have to edit the directives for
mod_ldap. Just start with my working sample configuration
ldap.conf on pastebin, which should be included in your main proftpd configuration.
Because we use the standard kolab ldap-schema, the users do neither posess a user nor group ID. Therefore, ProFTPD will fallback to the
LDAPDefaultUID (example: ID of “nobody”) and
LDAPDefaultGID (example: 10000). From the system side, a user with this combination of UID and GID should be allowed to read from (and maybe write to) your physical FTP directory tree. You can either add the user or group to your system and set the permissions accordingly or use the access control list (ACL). Since I use the acl-approach, the group with ID 10000 does not have to exist in
/etc/group. You may install acl by executing
~# apt-get install acl
and mount your ftp storage device with the acl option (to be persistent add it in
/etc/fstab) by executing
~# mount -o remount,defaults,noexec,rw,acl /dev/sda1 /var/ftp
To allow the access for users in our default group 10000 (for both existing and newly created files), we have to use the
setfacl command. Think carefully about this. We want the users not to be able to remove one of the shared folders accidentally!
~# setfacl -m g:10000:rx /var/ftp/ ~# setfacl -d -m g:10000:rx /var/ftp/ ~# setfacl -d -Rm g:10000:rwx /var/ftp/* ~# setfacl -Rm g:10000:rwx /var/ftp/*
We wanted all users to have their own home directory, which resides in
/var/ftp/home/, so make sure this directory exists. To jail each user to their own home directory, change the
DefaultRoot directive in your main configuration file
/etc/proftpd.conf to look like
Nonexistent home directories
/var/ftp/home/username will be created as requested by
ldap.conf (see above). At this point, ldap users should be able to login and will be dropped in their empty home directory. Now we have to setup the directory permissions and have shared directories linked to the home directory. To achieve this we will make extensive use of the
IfGroup directive. It’s very important, that the module
mod_ifsession.c is the last module to load in
/etc/proftpd/modules.conf! Additionally you should have lines, which load
Linking is very simple and works as follows:
<IfGroup ftp_test_group> VRootAlias /var/ftp/share /share> </IfGroup>
Very useful in terms of security is to limit the use of particular FTP-Commands to the admin group
# limit login to users with valid ftp_* groups <Limit LOGIN> AllowGroup ftp_admin_group,ftp_test_group </Limit> # in general allow ftp-commands for all users <Directory /> <Limit ALL ALL FTP> AllowGroup ftp_admin_group,ftp_test_group </Limit> </Directory> # deny deletion of files (does not cover overwriting) <Directory /> <Limit DELE RMD> DenyGroup !ftp_admin_group </Limit> </Directory>
I think we are done here now. Restart your ftp server by
~# service proftpd restart
Here you go! For testing purposes set the log level to debug and monitor the login process. Also force SSL (
mod_tls.c), because otherwise everything, even passwords, will be transferred as cleartext! If you run into trouble somewhere, just let me know.