Guide: Configuring a proFTPd SFTP chroot on Linux

On a previous blog from many years ago this little tutorial was surprisingly by far the most popular so I decided  I would start my new blog off with an updated version.

First you will need the current version of the awesome little FTP app proFTPd found here: http://www.proftpd.org/download.html

Once you’ve got it on your server and unzipped, change to the source directory and run the following:

./configure --with_modules=mod_sftp
make
make install

Easy enough, shouldn’t encounter any complications. Now edit /etc/proftpd.conf

# This is a basic ProFTPD configuration file (rename it to
# 'proftpd.conf' for actual use.  It establishes a single server
# and a single anonymous login.  It assumes that you have a user/group
# "nobody" and "ftp" for normal operation and anon.

ServerName                      "FTP Server"
ServerType                      standalone
DefaultServer                   on

# Port 21 is the standard FTP port.
Port                            21

# Don't use IPv6 support by default.
UseIPv6                         off

# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable.
Umask                           022

# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd).
MaxInstances                    30

# Set the user and group under which the server will run.
User                            nobody
Group                           nogroup

# To cause every FTP user to be "jailed" (chrooted) into their home
# directory, uncomment this line.
DefaultRoot ~

# Normally, we want files to be overwriteable.
AllowOverwrite          on

ExtendedLog                     /var/log/ftp.log
SystemLog                       /var/log/ftpsyslog.log

# Bar use of SITE CHMOD by default
<limit SITE_CHMOD>
  DenyAll
</Limit>

# Create home for users that don't have one http://www.proftpd.org/docs/howto/CreateHome.html
CreateHome on 700 dirmode 700

# Stop proFTPd from trying to do reverse lookups and ident lookups. If these features are not configured then leaving them on will cause slow logins and timeouts
UseReverseDNS off
<Global>
   IdentLookups off
</Global>

<virtualhost IPOfThisServerHere>
    SFTPEngine on
    SFTPLog /var/log/sftp.log
    # We are presumably using port 22 for standard Shell login, so move SFTP to another port
    Port 2222
    SFTPHostKey /etc/ssh/ssh_host_rsa_key
    SFTPHostKey /etc/ssh/ssh_host_dsa_key
    SFTPCompression delayed
    MaxLoginAttempts 6
    DefaultRoot ~
    Umask 022
    CreateHome on 700 dirmode 700

<limit SITE_CHMOD>
  DenyAll
</Limit>

</VirtualHost></pre>

So now we have chrooted FTP and SFTP, two more step to go. proFTPd is one of those apps that doesn't create itself an init.d entry so we should probably add one of those. I personally use the one from: <http://www.howtoforge.com/perfect-server-opensuse-11.2-x86_64-ispconfig-2-p5> but I've mirrored it again below:
#! /bin/sh
# Copyright (c) 2000-2001 SuSE GmbH Nuernberg, Germany.
# All rights reserved.
#
# Original author: Marius Tomaschewski <mt@suse.de>
#
# Slightly modified in 2003 for use with SuSE Linux 8.1,
# by http://www.learnlinux.co.uk/
#
# Slightly modified in 2005 for use with SuSE Linux 9.2,
# by Falko Timme
#
# /etc/init.d/proftpd
#
### BEGIN INIT INFO
# Provides:                proftpd
# Required-Start:        $network $remote_fs $syslog $named
# Required-Stop:
# Default-Start:        3 5
# Default-Stop:        0 1 2 6
# Description:                Starts ProFTPD server
### END INIT INFO
# Determine the base and follow a runlevel link name.
base=${0##*/}
link=${base#*[SK][0-9][0-9]}
# Force execution if not called by a runlevel directory.
test $link = $base && START_PROFTPD=yes  # Modified by learnlinux.co.uk
test "$START_PROFTPD" = yes || exit 0    # Modified by learnlinux.co.uk
# Return values acc. to LSB for all commands but
# status (see below):
#
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
proftpd_cfg="/etc/proftpd.conf"
proftpd_bin="/usr/local/sbin/proftpd"
proftpd_pid="/usr/local/var/proftpd.pid"
[ -r $proftpd_cfg ] || exit 6
[ -x $proftpd_bin ] || exit 5
# Source status functions
. /etc/rc.status
# First reset status of this service
rc_reset
case "$1" in
    start)
  echo -n "Starting ProFTPD Server: "
  test -f /etc/shutmsg && rm -f /etc/shutmsg
  /sbin/startproc $proftpd_bin
  rc_status -v
  ;;
    stop)
  echo -n "Shutting down ProFTPD Server: "
  test -x /usr/local/sbin/ftpshut && /usr/local/sbin/ftpshut now && sleep 1
  /sbin/killproc -TERM $proftpd_bin
  test -f /etc/shutmsg && rm -f /etc/shutmsg
  rc_status -v
  ;;
    restart)
  ## If first returns OK call the second, if first or
  ## second command fails, set echo return value.
  $0 stop
  $0 start
  rc_status
  ;;
    try-restart)
  ## Stop the service and if this succeeds (i.e. the
  ## service was running before), start it again.
  ## Note: not (yet) part of LSB (as of 0.7.5)
  $0 status >/dev/null &&  $0 restart
  rc_status
  ;;
    reload|force-reload)
  ## Exclusive possibility: Some services must be stopped
  ## and started to force a new load of the configuration.
  echo -n "Reload ProFTPD Server: "
  /sbin/killproc -HUP $proftpd_bin
  rc_status -v
  ;;
    status)
  # Status has a slightly different for the status command:
  # 0 - service running
  # 1 - service dead, but /var/run/  pid  file exists
  # 2 - service dead, but /var/lock/ lock file exists
  # 3 - service not running
  echo -n "Checking for ProFTPD Server: "
  checkproc $proftpd_bin
  rc_status -v
  ;;
    probe)
  ## Optional: Probe for the necessity of a reload,
  ## give out the argument which is required for a reload.
  [ $proftpd_cfg -nt $proftpd_pid ] && echo reload
  ;;
    *)
  echo "Usage: $0 {start|stop|status|restart|reload|try-restart|probe}"
  exit 1
  ;;
esac
# Set an exit status.
rc_exit

Once back on the command line:

chmod +x /etc/init.d/proftpd

Last step is to add users! This configuration will allow any valid log on user to connect, if you need to deny specific users access you can use the /etc/ftpaccess file to specify who can’t connect. Adding an FTP user is as simple as creating a local logon… just don’t give them a shell and set their home to wherever you are chrooting them!

useradd username -d /srv/ftp -s /bin/false

I would probably create a special ftpUsers group to put your ftpUsers in as well for that extra added bit of security. There are some really cool things you can do with proFTPd and a lot of plugin modules that further enhance its capabilities, so do yourself and a favour and check out the doco.

comments powered by Disqus