How to configure FTP server on Debian 9 Stretch Linux

Objective

The objective is to install and configure FTP server on Debian 9 Stretch Linux allowing both anonymous or local user access.

Operating System and Software Versions

  • Operating System: – Debian 9 Stretch
  • Software: – vsFTPd version 3.0.3

Requirements

Privileged access to

Difficulty

MEDIUM

Conventions

  • # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
  • $ – requires given linux commands to be executed as a regular non-privileged user

Instructions

The following tutorial will explain how to install and configure FTP server using vsFTPd daemon. It will also discuss various configurations to allow write or read-only access to anonymous user as well as local users.

vsFTPd Installation

Let’s begin by vsFPTd server and FTP client installation:

# apt install vsftpd ftp

By default the vsFTPd server comes configured to allow system users to access their home directories with read-only access. The following is a default vsFTPd config file /etc/vsftpd.conf:



listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO

As already mentioned the above config file will only grant a read-only access to any system user listed within /etc/passwd file. Use ftp command and attempt to connect using username and password of any of the local system users:

# ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.3)
Name (localhost:root): linuxconfig
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put FILE.TXT
local: FILE.TXT remote: FILE.TXT
200 EPRT command successful. Consider using EPSV.
550 Permission denied.

If you only need read-only access to by your local users you are done.



Allow User Write Access

To add write access for all system local user user uncomment or add the following stanza write_enable=YES. The new configuration file consists of:

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
write_enable=YES

Next, restart your vsFTPd:

# systemctl restart vsftpd

Perform a new test with ftp command to confirm write access:

# ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.3)
Name (localhost:root): linuxconfig
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put FILE.TXT
local: FILE.TXT remote: FILE.TXT
200 EPRT command successful. Consider using EPSV.
150 Ok to send data.
226 Transfer complete.
ftp> ls
200 EPRT command successful. Consider using EPSV.
150 Here comes the directory listing.
-rw-------    1 1000     1000            0 Jun 07 12:45 FILE.TXT
226 Directory send OK.


Allow Specific Users Only

At the moment our FTP server allows access to any system user defined within /etc/passwd file. In order to allow only specific users to be able to login we can include the following lines into our configuration file:

userlist_file=/etc/vsftpd.userlist
userlist_enable=YES

The above will enable a predefined user list where any user listed within /etc/vsftpd.userlist ( one user name per line ) will have access to FTP denied while all other system users will be able to login. Let’s create a new /etc/vsftpd.userlist user list consisting of a single user linuxconfig:

# echo linuxconfig > /etc/vsftpd.userlist

Restart vsFTPd server:

# systemctl restart vsftpd

Perform a new test with ftp command to confirm denied access to FTP server for linuxconfig user:

# ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.3)
Name (localhost:root): linuxconfig
530 Permission denied.
Login failed.
ftp> 

However, if you need to be able to login only with users defined within /etc/vsftpd.userlist, add the following configuration option userlist_deny=NO into your vsFTPd configuration file /etc/vsftpd.conf. Below is our current /etc/vsftpd.conf configuration file:

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
write_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_enable=YES
userlist_deny=NO


Allow Anonymous

At this stage we are also going to allow read-only access by anonymous users. Let’s start be creating a new directory which will be used as a root directory for anonymous user eg. /var/ftp. For testing purposes we can also place some arbitrary testing file within /var/ftp:

# mkdir /var/ftp/
# chmod 555 /var/ftp/
# chown ftp.ftp /var/ftp/
# touch /var/ftp/ANONYMOUS.TXT

Furthermore, include the following lines into /etc/vsftpd.conf configuration file to define anonymous home directory and anonymous access:

anon_root=/var/ftp
anonymous_enable=YES

Optionally, add no_anon_password=YES line to instruct vsFTPd to allow anonymous user to login automatically without the password. Since we have now defined user list we also must add the anonymous user to the list:

# echo anonymous >> /etc/vsftpd.userlist
# cat /etc/vsftpd.userlist 
linuxconfig
anonymous

As usually restart your FTP server and perform a validity of your current configuration:

# systemctl restart vsftpd

Test anonymous login:

# ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.3)
Name (localhost:root): anonymous
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 EPRT command successful. Consider using EPSV.
150 Here comes the directory listing.
-rw-r--r--    1 0        0               0 Jun 07 13:29 ANONYMOUS.TXT
226 Directory send OK.
ftp> 

Below you can find our current vsFTPd configuration file:

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
write_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_enable=YES
userlist_deny=NO
anon_root=/var/ftp
anonymous_enable=YES
no_anon_password=YES


Enable Anonymous Write Access

Next let’s allow anonymous user to upload files and create new directories and more. To do so, create a new directory upload within the /var/ftp directory:

# mkdir /var/ftp/upload
# chown ftp.ftp /var/ftp/upload/

Next, add the following lines into your vsFTPd configuration file:

anon_upload_enable=YES
anon_other_write_enable=YES
anon_mkdir_write_enable=YES

Restart your server:

# systemctl restart vsftpd

After the restart the anonymous user will be able to upload files, create directories rename files:

# ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.3)
Name (localhost:root): anonymous
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 EPRT command successful. Consider using EPSV.
150 Here comes the directory listing.
-rw-r--r--    1 0        0               0 Jun 07 13:29 ANONYMOUS.TXT
drwxr-xr-x    2 108      112          4096 Jun 07 13:57 upload
226 Directory send OK.
ftp> cd upload
250 Directory successfully changed.
ftp> put FILE.TXT
local: FILE.TXT remote: FILE.TXT
200 EPRT command successful. Consider using EPSV.
150 Ok to send data.
226 Transfer complete.
ftp> ls
200 EPRT command successful. Consider using EPSV.
150 Here comes the directory listing.
-rw-------    1 108      112             0 Jun 07 13:57 FILE.TXT
226 Directory send OK.
ftp> rename FILE.TXT NEW.TXT
350 Ready for RNTO.
250 Rename successful.
ftp> ls
200 EPRT command successful. Consider using EPSV.
150 Here comes the directory listing.
-rw-------    1 108      112             0 Jun 07 13:57 NEW.TXT
226 Directory send OK.
ftp> 

Below you can find our final vsFTPd configuration file:

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
write_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_enable=YES
userlist_deny=NO
anon_root=/var/ftp
anonymous_enable=YES
no_anon_password=YES
anon_upload_enable=YES
anon_other_write_enable=YES
anon_mkdir_write_enable=YES

Appendix

Error message:

# ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.3)
Name (localhost:root): anonymous
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
Login failed.
ftp>

The above indicates that your anon_root directory is writable. Solution is to make it read-only. Example:

# chmod 555 /var/ftp

Alternatively try to add the following line into your vsFTPd configuration file:

allow_writeable_chroot=YES