FTP server with virtual users on Debian Lenny

Had to setup an FTP server at work (yuck), guides I found elsewhere didn't do exactly what I was after, so it took some trial and error to achieve the setup I needed.

Objectives:

  • Be able to create multiple virtual users without having to create a shell account for every FTP user
  • Individually set permissions for each FTP user
  • FTP users should by default be locked inside a chroot
  • However, need to be able to provide read/write access outside the chroot on exception basis

I used Proftpd on Debian Lenny to achieve the above.

Note: ip_conntrack_ftp kernel module is not loaded by default on Debian Lenny. Without it, everything will seem to work, except FTP LIST command will return "Connection timed out" and "Failed to retrieve directory listing" errors.

To resolve, load the module:

1
sudo modprobe ip_conntrack_ftp

To ensure it gets loaded on reboot, do:

1
sudo echo ip_conntrack_ftp >> /etc/modules

1. Install proftpd

1
sudo aptitude install proftpd

2. Create home directories for the virtual ftp users (we're just creating two for this example):

1
2
sudo mkdir -p /var/ftp/user{1,2}/{read,write}
sudo chown -R proftpd:nogroup /var/ftp/

3. Get the uid and gid of the proftpd user (profptd install script should have created it):

1
2
sudo grep ftp /etc/passwd
proftpd:x:109:65534::/var/run/proftpd:/bin/false

4. Create virtual ftp users

1
2
sudo ftpasswd --passwd --name=user1 --uid=109 --gid=65534 --home=/var/ftp/user1 --shell=/bin/false --file=/etc/proftpd/passwd
sudo ftpasswd --passwd --name=user2 --uid=109 --gid=65534 --home=/var/ftp/user2 --shell=/bin/false --file=/etc/proftpd/passwd

Note: to change the password for the virtual FTP user, do:

1
sudo ftpasswd --change-password --passwd --name=user1 --file=/etc/proftpd/passwd

5. Add some directives to proftpd config file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
AuthUserFile            /etc/proftpd/passwd
DefaultRoot             ~
RequireValidShell       off
 
# VALID LOGINS
<Limit LOGIN>
   AllowUser user1
   AllowUser user2
   DenyALL
</Limit>
 
# USER 1
<Directory /var/ftp/user1/read>
    <Limit ALL>
        DenyAll
    </Limit>
    <Limit DIRS READ>
        AllowUser user1
    </Limit>
</Directory>
<Directory /var/ftp/user1/write>
    <Limit ALL>
        DenyAll
    </Limit>
    <Limit DIRS READ WRITE>
        AllowUser user1
    </Limit>
</Directory>
 
# USER 2
<Directory /var/ftp/user2/read>
    <Limit ALL>
        DenyAll
    </Limit>
    <Limit DIRS READ>
        AllowUser user2
    </Limit>
</Directory>
<Directory /var/ftp/user2/write>
    <Limit ALL>
        DenyAll
    </Limit>
    <Limit DIRS READ WRITE>
        AllowUser user2
    </Limit>
</Directory>

6. If you use a firewall, don't forget to open up port 21. If you can get away with it, it's of course best to open it up to a narrowly defined set of IPs.

7. Restart proftpd and you should be able to connect with an FTP client using the credentials for users we setup.

8. For read only file system access outside of the chroot:

1
2
mkdir /var/ftp/user1/read/blah
sudo mount --bind -r /path/to/somewhere/ /var/ftp/user1/read/blah/

Useful links:

  1. ProFTPD-mini-HOWTO-Limit
  2. ProFTPD-mini-HOWTO-VirtualUsers
  3. ProFTPD-mini-HOWTO-AuthFiles
  4. ProFTPD ftpasswd
  5. ProFTPD-mini-HOWTO-Chroot

2 Comments

  • 1. Andrejs Semovs replies at 18th February 2013, 8:48 am :

    Thank you for the excellent tutorial!

    Should there be “ftp” user instead of “proftpd” in the step 2, when changing /var/ftp ownership? I couldn’t write to FTP, until I changed that line to:

    sudo chown -R ftp:nogroup /var/ftp/

  • 2. Erlend replies at 19th May 2014, 12:10 pm :

    Thank you, this was very helpful for setting up my proftpd :)

Leave a comment

NOTE: Enclose quotes in <blockquote></blockquote>. Enclose code in <pre lang="LANG"></pre> (where LANG is one of these).