Difference between revisions of "Very Secure FTP Daemon"

From ArchWiki
Jump to: navigation, search
(vsftpd: refusing to run with writable root inside chroot())
(Port configurations: more explanations provided and style improved)
 
(53 intermediate revisions by 28 users not shown)
Line 3: Line 3:
 
[[es:Very Secure FTP Daemon]]
 
[[es:Very Secure FTP Daemon]]
 
[[it:Very Secure FTP Daemon]]
 
[[it:Very Secure FTP Daemon]]
 +
[[ja:Very Secure FTP Daemon]]
 
[[ru:Very Secure FTP Daemon]]
 
[[ru:Very Secure FTP Daemon]]
[[zh-CN:Very Secure FTP Daemon]]
+
[[zh-hans:Very Secure FTP Daemon]]
'''vsftpd''' (Very Secure FTP Daemon) is a lightweight, stable and secure FTP server for UNIX-like systems.
+
[https://security.appspot.com/vsftpd.html vsftpd] (Very Secure FTP Daemon) is a lightweight, stable and secure FTP server for UNIX-like systems.
  
 
== Installation ==
 
== Installation ==
Simply install {{pkg|vsftpd}} from the [[Official Repositories]].
 
  
To start the server:
+
[[Install]] {{pkg|vsftpd}} and [[start/enable]] the {{ic|vsftpd.service}} daemon.
# systemctl start vsftpd.service
 
  
If you want it to be started automatically at boot:
+
To use [[Wikipedia:xinetd|xinetd]] for monitoring and controlling vsftpd connections, see [[#Using xinetd]].
# systemctl enable vsftpd.service
 
  
See the xinetd section below for procedures to use vsftpd with xinetd.
+
== Configuration ==
 +
Most of the settings in vsftpd are done by editing the file {{ic|/etc/vsftpd.conf}}. The file itself is well-documented, so this section only highlights some important changes you may want to modify. For all available options and documentation, see the man page for vsftpd.conf (5), or [https://security.appspot.com/vsftpd/vsftpd_conf.html view it online]. Files are served by default from {{ic|/srv/ftp}}.
  
== Configuration ==
+
Enable connections {{ic|/etc/hosts.allow}}:
Most of the settings in vsftpd are done by editing the file {{ic|/etc/vsftpd.conf}}. The file itself is well-documented, so this section only highlights some important changes you may want to modify. For all available options and documentation, one can man vsftpd.conf (5). Files are served by default from {{ic|/srv/ftp}}.
+
# Allow all connections
 +
vsftpd: ALL
 +
# IP adress range
 +
vsftpd: 10.0.0.0/255.255.255.0
  
 
=== Enabling uploading ===
 
=== Enabling uploading ===
Line 26: Line 28:
  
 
=== Local user login ===
 
=== Local user login ===
One must set the line to {{ic|/etc/vsftpd.conf}} to allow users in {{ic|/etc/passwd}} to login:
+
One must set the line {{ic|local_enable}} in {{ic|/etc/vsftpd.conf}} to {{ic|YES}} in order to allow users in {{ic|/etc/passwd}} to login:
 
  local_enable=YES
 
  local_enable=YES
  
 
=== Anonymous login ===
 
=== Anonymous login ===
The line in {{ic|/etc/vsftpd.conf}} controls whether anonymous users can login:
+
These lines controls whether anonymous users can login. By default, anonymous logins are enabled for download only from {{ic|/srv/ftp}}:
# Allow anonymous login
+
{{hc|1=/etc/vsftpd.conf|2=
anonymous_enable=YES
+
...
# No password is required for an anonymous login           
+
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
no_anon_password=YES
+
anonymous_enable=YES
# Maximum transfer rate for an anonymous client in Bytes/second           
+
...
anon_max_rate=30000  
+
# Uncomment this to allow the anonymous FTP user to upload files. This only
# Directory to be used for an anonymous login          
+
# has an effect if the above global write enable is activated. Also, you will
anon_root=/example/directory/
+
# obviously need to create a directory writable by the FTP user.
 +
#anon_upload_enable=YES
 +
#
 +
# Uncomment this if you want the anonymous FTP user to be able to create
 +
# new directories.
 +
#anon_mkdir_write_enable=YES
 +
...
 +
}}
 +
You may also add e.g. the following options (see {{man|5|vsftpd.conf}} for more):
 +
{{hc|1=/etc/vsftpd.conf|2=
 +
# No password is required for an anonymous login           
 +
no_anon_password=YES
 +
 
 +
# Maximum transfer rate for an anonymous client in Bytes/second           
 +
anon_max_rate=30000
 +
 
 +
# Directory to be used for an anonymous login
 +
anon_root=/example/directory/
 +
}}
  
 
=== Chroot jail ===
 
=== Chroot jail ===
One can set up a chroot environment which prevents the user from leaving its home directory. To enable this, add the following lines to {{ic|/etc/vsftpd.conf}}:
+
A chroot environment that prevents the user from leaving its home directory can be set up. To enable this, add the following lines to {{ic|/etc/vsftpd.conf}}:
 
  chroot_list_enable=YES
 
  chroot_list_enable=YES
 
  chroot_list_file=/etc/vsftpd.chroot_list
 
  chroot_list_file=/etc/vsftpd.chroot_list
 
The {{Ic|chroot_list_file}} variable specifies the file which contains users that are jailed.
 
The {{Ic|chroot_list_file}} variable specifies the file which contains users that are jailed.
  
For a more restricted environment, one can specify the line:
+
For a more restricted environment, specify the line:
 
  chroot_local_user=YES
 
  chroot_local_user=YES
 
This will make local users jailed by default. In this case, the file specified by {{Ic|chroot_list_file}} lists users that are '''not''' in a chroot jail.
 
This will make local users jailed by default. In this case, the file specified by {{Ic|chroot_list_file}} lists users that are '''not''' in a chroot jail.
Line 61: Line 81:
  
 
=== Limiting connections ===
 
=== Limiting connections ===
One can limit the data transfer rate, number of clients and connections per IP for local users by adding the information in {{ic|/etc/vsftpd.conf}}:
+
The data transfer rate, i.e. number of clients and connections per IP for local users can be limited by adding the information in {{ic|/etc/vsftpd.conf}}:
 
  local_max_rate=1000000 # Maximum data transfer rate in bytes per second
 
  local_max_rate=1000000 # Maximum data transfer rate in bytes per second
 
  max_clients=50        # Maximum number of clients that may be connected
 
  max_clients=50        # Maximum number of clients that may be connected
Line 67: Line 87:
  
 
=== Using xinetd ===
 
=== Using xinetd ===
{{Out of date|Contains reference to rc.conf, which does not exist anymore.}}
+
 
If you want to use vsftpd with xinetd, add the following lines to {{ic|/etc/xinetd.d/vsftpd}}:
+
Xinetd provides enhanced capabilities for monitoring and controlling connections. It is not necessary though for a basic good working vsftpd-server.
 +
 
 +
Installation of vsftpd will add a necessary service file, {{ic|/etc/xinetd.d/vsftpd}}. By default services are disabled. Enable the ftp service:
 
<pre>
 
<pre>
 
service ftp
 
service ftp
Line 82: Line 104:
 
</pre>
 
</pre>
  
The option below should be set in {{ic|/etc/vsftpd.conf}}:
+
If you have set the vsftpd daemon to run in standalone mode make the following change in {{ic|/etc/vsftpd.conf}}:
  pam_service_name=ftp
+
  listen=NO
 +
Otherwise connection will fail:
 +
500 OOPS: could not bind listening IPv4 socket
  
Finally, add xinetd to your daemons line in {{ic|/etc/rc.conf}}. You do not need to add vsftpd, as it will be called by xinetd whenever necessary.
+
Instead of starting the vsftpd daemon start and [[enable]] {{ic|xinetd.service}}.
  
If you get errors like this while connecting to the server:
+
=== Using SSL/TLS to secure FTP ===
  500 OOPS: cap_set_proc
 
You need to add ''capability'' in MODULES= line in {{ic|/etc/rc.conf}}.
 
  
While upgrading to version 2.1.0 you might get an error like this when connecting to the server from a client:
+
First, you need a ''X.509 SSL/TLS'' certificate to use TLS. If you do not have one, you can easily generate a self-signed certificate as follows:  
500 OOPS: could not bind listening IPv4 socket
 
In earlier versions it has been enough to leave the following lines commented:
 
# Use this to use vsftpd in standalone mode, otherwise it runs through (x)inetd
 
# listen=YES
 
In this newer version, and maybe future releases, it is necessary however to explicitly configure it to '''not''' run in a standalone mode, like this:
 
# Use this to use vsftpd in standalone mode, otherwise it runs through (x)inetd
 
listen=NO
 
 
 
=== Using SSL to Secure FTP  ===
 
 
 
Generate an SSL Cert, e.g. like that:  
 
 
  # cd /etc/ssl/certs
 
  # cd /etc/ssl/certs
  # openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /etc/ssl/certs/vsftpd.pem -out /etc/ssl/certs/vsftpd.pem
+
  # openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout vsftpd.pem -out vsftpd.pem
  # chmod 600 /etc/ssl/certs/vsftpd.pem
+
  # chmod 600 vsftpd.pem
You will be asked a lot of Questions about your Company etc., as your Certificate is not a trusted one it doesn't really matter what you fill in. You will use this for encryption! If you plan to use this in a matter of trust get one from a CA like thawte, verisign etc.  
+
You will be asked questions about your company, etc. As your certificate is not a trusted one, it does not really matter what is filled in, it will be used for encryption. To use a trusted certificate, you can get one from a certificate authority like [[Let's Encrypt]].  
  
edit your configuration {{ic|/etc/vsftpd.conf}}
+
Then, edit the configuration file:
<pre>
+
{{hc|/etc/vsftpd.conf|2=ssl_enable=YES
#this is important
 
ssl_enable=YES
 
  
#choose what you like, if you accept anon-connections
+
#choose what you like, if you accept anonymous connections, you may want to enable this
# you may want to enable this
 
 
# allow_anon_ssl=NO
 
# allow_anon_ssl=NO
  
#choose what you like,
+
#by default all non anonymous logins and forced to use SSL to send and receive password and data, set to NO to allow non secure connections
# it's a matter of performance i guess
+
force_local_logins_ssl=NO
# force_local_data_ssl=NO
+
force_local_data_ssl=NO
 
 
#choose what you like
 
force_local_logins_ssl=YES
 
  
#you should at least enable this if you enable ssl...
+
#you should at least enable TLS v1 if you enable SSL
 
ssl_tlsv1=YES
 
ssl_tlsv1=YES
#choose what you like
+
#these options will permit or prevent SSL v2 and v3 protocol connections. TLS v1 connections are preferred.
ssl_sslv2=YES
+
ssl_sslv2=NO
#choose what you like
 
 
ssl_sslv3=YES
 
ssl_sslv3=YES
#give the correct path to your currently generated *.pem file
+
 
 +
#give the correct path to your .pem file
 
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
 
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
#the *.pem file contains both the key and cert
+
#the .pem file also contains the private key
 
rsa_private_key_file=/etc/ssl/certs/vsftpd.pem
 
rsa_private_key_file=/etc/ssl/certs/vsftpd.pem
</pre>
+
}}
  
=== Dynamic DNS ===
+
=== Resolve hostname in passive mode ===
Make sure you put the following two lines in {{ic|/etc/vsftpd.conf}}:
+
To override the IP address vsftpd advertises in passive mode by the hostname of your server and have it DNS resolved at startup, add the following two lines in {{ic|/etc/vsftpd.conf}}:
 
  pasv_addr_resolve=YES
 
  pasv_addr_resolve=YES
  pasv_address=yourdomain.noip.info
+
  pasv_address=''yourdomain.org''
It is '''not''' necessary to use a script that updates pasv_address periodically and restarts the server, as it can be found elsewhere!
 
{{Note|You won't be able to connect in passive mode via LAN anymore. Try the active mode on your LAN PC's FTP client.}}
 
  
 +
{{Note|
 +
* For dynamic DNS, it is '''not''' necessary to periodically update ''pasv_address'' and restart the server as it can sometimes be read.
 +
* You may not be able to connect in passive mode via LAN anymore, in this case try the active mode instead from the LAN clients.
 +
}}
  
 
=== Port configurations ===
 
=== Port configurations ===
Especially for private FTP servers that are exposed to the web it's recommended to change the listening port to something other that the standard port 21. This can be done using the following lines in {{ic|/etc/vsftpd.conf}}:
+
For FTP servers that are exposed to the web, to reduce the likelihood of the server being attacked, the listening port can be changed to something other than the standard port 21. To limit the passive mode ports to open ports, a range can be provided. These port configurations changes can be done using the following lines:
listen_port=2211
+
{{hc|/etc/vsftpd.conf|2=
Furthermore a custom passive port range can be given by:
+
listen_port=2211
pasv_min_port=49152
+
 
pasv_max_port=65534
+
pasv_min_port=5000
 +
pasv_max_port=5003
 +
}}
  
 
=== Configuring iptables ===
 
=== Configuring iptables ===
 
Often the server running the FTP daemon is protected by an [[iptables]] firewall. To allow access to the FTP server the corresponding port needs to be opened using something like
 
Often the server running the FTP daemon is protected by an [[iptables]] firewall. To allow access to the FTP server the corresponding port needs to be opened using something like
  # iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 2211 -j ACCEPT
+
  # iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
 
This article won't provide any instruction on how to set up iptables but here is an example: [[Simple stateful firewall]].
 
This article won't provide any instruction on how to set up iptables but here is an example: [[Simple stateful firewall]].
  
There are some kernel modules needed for proper FTP connection handling by iptables that should be referenced here. Among those especially ''ip_conntrack_ftp''. It is needed as FTP uses the given ''listen_port'' (21 by default) for commands only; all the data transfer is done over different ports. These ports are chosen by the FTP daemon at random and for each session (also depending on whether active or passive mode is used). To tell iptables that packets on ports should be accepted, ''ip_conntrack_ftp'' is required. To load it automatically on boot create a new file in {{ic|/etc/modules-load.d}} e.g.:
+
There are some kernel modules needed for proper FTP connection handling by iptables that should be referenced here. Among those especially ''nf_conntrack_ftp''. It is needed as FTP uses the given ''listen_port'' (21 by default) for commands only; all the data transfer is done over different ports. These ports are chosen by the FTP daemon at random and for each session (also depending on whether active or passive mode is used). To tell iptables that packets on ports should be accepted, ''nf_conntrack_ftp'' is required. To load it automatically on boot create a new file in {{ic|/etc/modules-load.d}} e.g.:
  # echo ip_conntrack_ftp > /etc/modules-load.d/ip_conntrack_ftp.conf
+
  # echo nf_conntrack_ftp > /etc/modules-load.d/nf_conntrack_ftp.conf
  
If you changed the ''listen_port'' you also need to configure the conntrack module accordingly:
+
If the kernel >= 4.7 you either need to set ''net.netfilter.nf_conntrack_helper=1'' via ''sysctl'' e.g.
{{hc|/etc/modprobe.d/ip_conntrack_ftp.conf|<nowiki>
+
# echo net.netfilter.nf_conntrack_helper=1 > /etc/sysctl.d/70-conntrack.conf
options nf_conntrack_ftp ports=2211
+
or use
options ip_conntrack_ftp ports=2211</nowiki>}}
+
# iptables -A PREROUTING -t raw -p tcp --dport 21 -j CT --helper ftp
  
 
== Tips and tricks ==
 
== Tips and tricks ==
 
=== PAM with virtual users ===
 
=== PAM with virtual users ===
Using virtual users has the advantage of not requiring a real login account on the system. Keeping the environment in a container is of course a more secure option.
+
Since [[PAM]] no longer provides {{ic|pam_userdb.so}} another easy method is to use {{AUR|libpam_pwdfile}}. For environments with many users another option could be {{AUR|pam_mysql}}{{Broken package link|{{aur-mirror|pam_mysql}}}}. This section is however limited to explain how to configure a chroot environment and authentication by {{ic|pam_pwdfile.so}}.
 +
 
 +
In this example we create the directory {{ic|vsftpd}}:
 +
# mkdir /etc/vsftpd
 +
 
 +
One option to create and store user names and passwords is to use the Apache generator htpasswd:
 +
# htpasswd -c /etc/vsftpd/.passwd
 +
A problem with the above command is that vsftpd might not be able to read the generated MD5 hashed password. If running the same command with the -d switch, crypt() encryption, password become readable by vsftpd, but the downside of this is less security and a password limited to 8 characters. Openssl could be used to produce a MD5 based BSD password with algorithm 1:
 +
# openssl passwd -1
 +
 
 +
Whatever solution the produced {{ic|/etc/vsftpd/.passwd}} should look like this:
 +
username1:hashed_password1
 +
username2:hashed_password2
 +
...
 +
 
 +
Next you need to create a PAM service using {{ic|pam_pwdfile.so}} and the generated {{ic|/etc/vsftpd/.passwd}} file. In this example we create a PAM policy for ''vsftpd'' with the following content:
 +
{{hc|/etc/pam.d/vsftpd|auth required pam_pwdfile.so pwdfile /etc/vsftpd/.passwd
 +
account required pam_permit.so}}
  
A virtual users database has to be created by first making a simple text file like this:
 
user1
 
password1
 
user2
 
password2
 
Include as many virtual users as you wish according to the structure in the example. Save it as logins.txt; the file name does not have any significance. Next step depends on Berkeley database system, which is included in the core system of Arch. As root create the actual database with the help of the logins.txt file, or what you chose to call it:
 
# db_load -T -t hash -f logins.txt /etc/vsftpd_login.db
 
It is recommended to restrict permissions for the now created {{ic|vsftpd_login.db}} file:
 
# chmod 600 /etc/vsftpd_login.db
 
{{Warning|Be aware that stocking passwords in plain text is not safe. Don't forget to remove your temporary file with {{Ic|rm logins.txt}}.}}
 
PAM should now be set to make use of vsftpd_login.db. To make PAM check for user authentication create a file named ftp in the {{ic|/etc/pam.d/}} directory with the following information:
 
auth required pam_userdb.so db=/etc/vsftpd_login crypt=hash
 
account required pam_userdb.so db=/etc/vsftpd_login crypt=hash
 
{{Note|We use /etc/vsftpd_login without .db extension in PAM-config!}}
 
 
Now it is time to create a home for the virtual users. In the example {{ic|/srv/ftp}} is decided to host data for virtual users, which also reflects the default directory structure of Arch. First create the general user virtual and make {{ic|/srv/ftp}} its home:
 
Now it is time to create a home for the virtual users. In the example {{ic|/srv/ftp}} is decided to host data for virtual users, which also reflects the default directory structure of Arch. First create the general user virtual and make {{ic|/srv/ftp}} its home:
 
  # useradd -d /srv/ftp virtual
 
  # useradd -d /srv/ftp virtual
 
Make virtual the owner:
 
Make virtual the owner:
 
  # chown virtual:virtual /srv/ftp
 
  # chown virtual:virtual /srv/ftp
Configure vsftpd to use the created environment by editing {{ic|/etc/vsftpd.conf}}. These are the necessary settings to make vsftpd restrict access to virtual users, by user-name and password, and restrict their access to the specified area {{ic|/srv/ftp}}:
+
 
 +
A basic {{ic|/etc/vsftpd.conf}} with no private folders configured, which will default to the home folder of the virtual user:
 +
# pointing to the correct PAM service file
 +
pam_service_name=vsftpd
 +
write_enable=YES
 +
hide_ids=YES
 +
listen=YES
 +
connect_from_port_20=YES
 
  anonymous_enable=NO
 
  anonymous_enable=NO
 
  local_enable=YES
 
  local_enable=YES
 +
dirmessage_enable=YES
 +
xferlog_enable=YES
 
  chroot_local_user=YES
 
  chroot_local_user=YES
 
  guest_enable=YES
 
  guest_enable=YES
 
  guest_username=virtual
 
  guest_username=virtual
 
  virtual_use_local_privs=YES
 
  virtual_use_local_privs=YES
If the xinetd method is used start the service. You should now only be allowed to login by user-name and password according to the made database.
+
 
 +
Some parameters might not be necessary for your own setup. If you want the chroot environment to be writable you will need to add the following to the configuration file:
 +
allow_writeable_chroot=YES
 +
Otherwise vsftpd because of default security settings will complain if it detects that chroot is writable.
 +
 
 +
[[Start]] {{ic|vsftpd.service}}.
 +
 
 +
You should now be able to login from a ftp-client with any of the users and passwords stored in {{ic|/etc/vsftpd/.passwd}}.
  
 
==== Adding private folders for the virtual users ====
 
==== Adding private folders for the virtual users ====
Line 222: Line 250:
 
  # chmod 550 /srv/ftp/user
 
  # chmod 550 /srv/ftp/user
 
  # chmod 750 /srv/ftp/user/upload
 
  # chmod 750 /srv/ftp/user/upload
 
  
 
If you must:
 
If you must:
Line 230: Line 257:
 
or alternative:
 
or alternative:
  
Install vsftpd-ext from AUR and set in the conf file allow_writable_root=YES
+
Install {{AUR|vsftpd-ext}}{{Broken package link|{{aur-mirror|vsftpd-ext}}}} and set in the conf file allow_writable_root=YES
  
=== FileZilla Client: GnuTLS error -8 when connecting via SSL ===
+
=== FileZilla Client: GnuTLS error -8 -15 -110 when connecting via SSL ===
vsftpd tries to display plain-text error messages in the SSL session. In order to debug this, temporarily disable encryption and you will see the correct error message.[http://ramblings.linkerror.com/?p=45]
+
vsftpd tries to display plain-text error messages in the SSL session. In order to debug this, temporarily disable encryption and you will see the correct error message.[http://ramblings.linkerror.com/?p=45] [https://serverfault.com/questions/772494/vsftpd-list-causes-gnutls-error-15]
  
 
=== vsftpd.service fails to run on boot ===
 
=== vsftpd.service fails to run on boot ===
Line 243: Line 270:
 
After=network.target
 
After=network.target
 
}}
 
}}
 +
 +
=== ipv6 only fails with: 500 OOPS: run two copies of vsftpd for IPv4 and IPv6 ===
 +
you most likely have commented out the line
 +
 +
# When "listen" directive is enabled, vsftpd runs in standalone mode and
 +
# listens on IPv4 sockets. This directive cannot be used in conjunction
 +
# with the listen_ipv6 directive.
 +
#listen=YES
 +
#
 +
# This directive enables listening on IPv6 sockets. To listen on IPv4 and IPv6
 +
# sockets, you must run two copies of vsftpd with two configuration files.
 +
# Make sure, that one of the listen options is commented !!
 +
listen_ipv6=YES
 +
 +
instead of setting
 +
 +
# When "listen" directive is enabled, vsftpd runs in standalone mode and
 +
# listens on IPv4 sockets. This directive cannot be used in conjunction
 +
# with the listen_ipv6 directive.
 +
listen=NO
  
 
== See also ==
 
== See also ==
 
* [http://vsftpd.beasts.org/ vsftpd official homepage]
 
* [http://vsftpd.beasts.org/ vsftpd official homepage]
 
* [http://vsftpd.beasts.org/vsftpd_conf.html vsftpd.conf man page]
 
* [http://vsftpd.beasts.org/vsftpd_conf.html vsftpd.conf man page]

Latest revision as of 12:48, 16 December 2017

vsftpd (Very Secure FTP Daemon) is a lightweight, stable and secure FTP server for UNIX-like systems.

Installation

Install vsftpd and start/enable the vsftpd.service daemon.

To use xinetd for monitoring and controlling vsftpd connections, see #Using xinetd.

Configuration

Most of the settings in vsftpd are done by editing the file /etc/vsftpd.conf. The file itself is well-documented, so this section only highlights some important changes you may want to modify. For all available options and documentation, see the man page for vsftpd.conf (5), or view it online. Files are served by default from /srv/ftp.

Enable connections /etc/hosts.allow:

# Allow all connections
vsftpd: ALL
# IP adress range
vsftpd: 10.0.0.0/255.255.255.0

Enabling uploading

The WRITE_ENABLE flag must be set to YES in /etc/vsftpd.conf in order to allow changes to the filesystem, such as uploading:

write_enable=YES

Local user login

One must set the line local_enable in /etc/vsftpd.conf to YES in order to allow users in /etc/passwd to login:

local_enable=YES

Anonymous login

These lines controls whether anonymous users can login. By default, anonymous logins are enabled for download only from /srv/ftp:

/etc/vsftpd.conf
...
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=YES
...
# Uncomment this to allow the anonymous FTP user to upload files. This only
# has an effect if the above global write enable is activated. Also, you will
# obviously need to create a directory writable by the FTP user.
#anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be able to create
# new directories.
#anon_mkdir_write_enable=YES
...

You may also add e.g. the following options (see vsftpd.conf(5) for more):

/etc/vsftpd.conf
# No password is required for an anonymous login          
no_anon_password=YES

# Maximum transfer rate for an anonymous client in Bytes/second          
anon_max_rate=30000

# Directory to be used for an anonymous login  
anon_root=/example/directory/

Chroot jail

A chroot environment that prevents the user from leaving its home directory can be set up. To enable this, add the following lines to /etc/vsftpd.conf:

chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list

The chroot_list_file variable specifies the file which contains users that are jailed.

For a more restricted environment, specify the line:

chroot_local_user=YES

This will make local users jailed by default. In this case, the file specified by chroot_list_file lists users that are not in a chroot jail.

Limiting user login

It's possible to prevent users from logging into the FTP server by adding two lines to /etc/vsftpd.conf:

userlist_enable=YES
userlist_file=/etc/vsftpd.user_list

userlist_file now specifies the file which lists users that are not able to login.

If you only want to allow certain users to login, add the line:

userlist_deny=NO

The file specified by userlist_file will now contain users that are able to login.

Limiting connections

The data transfer rate, i.e. number of clients and connections per IP for local users can be limited by adding the information in /etc/vsftpd.conf:

local_max_rate=1000000 # Maximum data transfer rate in bytes per second
max_clients=50         # Maximum number of clients that may be connected
max_per_ip=2           # Maximum connections per IP

Using xinetd

Xinetd provides enhanced capabilities for monitoring and controlling connections. It is not necessary though for a basic good working vsftpd-server.

Installation of vsftpd will add a necessary service file, /etc/xinetd.d/vsftpd. By default services are disabled. Enable the ftp service:

service ftp
{
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/bin/vsftpd
        log_on_success  += HOST DURATION
        log_on_failure  += HOST
        disable                 = no
}

If you have set the vsftpd daemon to run in standalone mode make the following change in /etc/vsftpd.conf:

listen=NO

Otherwise connection will fail:

500 OOPS: could not bind listening IPv4 socket

Instead of starting the vsftpd daemon start and enable xinetd.service.

Using SSL/TLS to secure FTP

First, you need a X.509 SSL/TLS certificate to use TLS. If you do not have one, you can easily generate a self-signed certificate as follows:

# cd /etc/ssl/certs
# openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout vsftpd.pem -out vsftpd.pem
# chmod 600 vsftpd.pem

You will be asked questions about your company, etc. As your certificate is not a trusted one, it does not really matter what is filled in, it will be used for encryption. To use a trusted certificate, you can get one from a certificate authority like Let's Encrypt.

Then, edit the configuration file:

/etc/vsftpd.conf
ssl_enable=YES

#choose what you like, if you accept anonymous connections, you may want to enable this
# allow_anon_ssl=NO

#by default all non anonymous logins and forced to use SSL to send and receive password and data, set to NO to allow non secure connections
force_local_logins_ssl=NO
force_local_data_ssl=NO

#you should at least enable TLS v1 if you enable SSL
ssl_tlsv1=YES
#these options will permit or prevent SSL v2 and v3 protocol connections. TLS v1 connections are preferred. 
ssl_sslv2=NO
ssl_sslv3=YES

#give the correct path to your .pem file
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
#the .pem file also contains the private key
rsa_private_key_file=/etc/ssl/certs/vsftpd.pem

Resolve hostname in passive mode

To override the IP address vsftpd advertises in passive mode by the hostname of your server and have it DNS resolved at startup, add the following two lines in /etc/vsftpd.conf:

pasv_addr_resolve=YES
pasv_address=yourdomain.org
Note:
  • For dynamic DNS, it is not necessary to periodically update pasv_address and restart the server as it can sometimes be read.
  • You may not be able to connect in passive mode via LAN anymore, in this case try the active mode instead from the LAN clients.

Port configurations

For FTP servers that are exposed to the web, to reduce the likelihood of the server being attacked, the listening port can be changed to something other than the standard port 21. To limit the passive mode ports to open ports, a range can be provided. These port configurations changes can be done using the following lines:

/etc/vsftpd.conf
listen_port=2211

pasv_min_port=5000
pasv_max_port=5003

Configuring iptables

Often the server running the FTP daemon is protected by an iptables firewall. To allow access to the FTP server the corresponding port needs to be opened using something like

# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT

This article won't provide any instruction on how to set up iptables but here is an example: Simple stateful firewall.

There are some kernel modules needed for proper FTP connection handling by iptables that should be referenced here. Among those especially nf_conntrack_ftp. It is needed as FTP uses the given listen_port (21 by default) for commands only; all the data transfer is done over different ports. These ports are chosen by the FTP daemon at random and for each session (also depending on whether active or passive mode is used). To tell iptables that packets on ports should be accepted, nf_conntrack_ftp is required. To load it automatically on boot create a new file in /etc/modules-load.d e.g.:

# echo nf_conntrack_ftp > /etc/modules-load.d/nf_conntrack_ftp.conf

If the kernel >= 4.7 you either need to set net.netfilter.nf_conntrack_helper=1 via sysctl e.g.

# echo net.netfilter.nf_conntrack_helper=1 > /etc/sysctl.d/70-conntrack.conf

or use

# iptables -A PREROUTING -t raw -p tcp --dport 21 -j CT --helper ftp

Tips and tricks

PAM with virtual users

Since PAM no longer provides pam_userdb.so another easy method is to use libpam_pwdfileAUR. For environments with many users another option could be pam_mysqlAUR[broken link: archived in aur-mirror]. This section is however limited to explain how to configure a chroot environment and authentication by pam_pwdfile.so.

In this example we create the directory vsftpd:

# mkdir /etc/vsftpd

One option to create and store user names and passwords is to use the Apache generator htpasswd:

# htpasswd -c /etc/vsftpd/.passwd

A problem with the above command is that vsftpd might not be able to read the generated MD5 hashed password. If running the same command with the -d switch, crypt() encryption, password become readable by vsftpd, but the downside of this is less security and a password limited to 8 characters. Openssl could be used to produce a MD5 based BSD password with algorithm 1:

# openssl passwd -1

Whatever solution the produced /etc/vsftpd/.passwd should look like this:

username1:hashed_password1
username2:hashed_password2
...

Next you need to create a PAM service using pam_pwdfile.so and the generated /etc/vsftpd/.passwd file. In this example we create a PAM policy for vsftpd with the following content:

/etc/pam.d/vsftpd
auth required pam_pwdfile.so pwdfile /etc/vsftpd/.passwd
account required pam_permit.so

Now it is time to create a home for the virtual users. In the example /srv/ftp is decided to host data for virtual users, which also reflects the default directory structure of Arch. First create the general user virtual and make /srv/ftp its home:

# useradd -d /srv/ftp virtual

Make virtual the owner:

# chown virtual:virtual /srv/ftp

A basic /etc/vsftpd.conf with no private folders configured, which will default to the home folder of the virtual user:

# pointing to the correct PAM service file
pam_service_name=vsftpd
write_enable=YES
hide_ids=YES
listen=YES
connect_from_port_20=YES
anonymous_enable=NO
local_enable=YES
dirmessage_enable=YES
xferlog_enable=YES
chroot_local_user=YES
guest_enable=YES
guest_username=virtual
virtual_use_local_privs=YES

Some parameters might not be necessary for your own setup. If you want the chroot environment to be writable you will need to add the following to the configuration file:

allow_writeable_chroot=YES

Otherwise vsftpd because of default security settings will complain if it detects that chroot is writable.

Start vsftpd.service.

You should now be able to login from a ftp-client with any of the users and passwords stored in /etc/vsftpd/.passwd.

Adding private folders for the virtual users

First create directories for users:

# mkdir /srv/ftp/user1
# mkdir /srv/ftp/user2
# chown virtual:virtual /srv/ftp/user?/

Then, add the following lines to /etc/vsftpd.conf:

local_root=/srv/ftp/$USER
user_sub_token=$USER

Troubleshooting

vsftpd: no connection (Error 500) with recent kernels (3.5 and newer) and .service

add this to your /etc/vsftpd.conf

seccomp_sandbox=NO

vsftpd: refusing to run with writable root inside chroot()

As of vsftpd 2.3.5, the chroot directory that users are locked to must not be writable. This is in order to prevent a security vulnerabilty.

The safe way to allow upload is to keep chroot enabled, and configure your FTP directories.

local_root=/srv/ftp/user
# mkdir -p /srv/ftp/user/upload
#
# chmod 550 /srv/ftp/user
# chmod 750 /srv/ftp/user/upload

If you must:

You can put this into your /etc/vsftpd.conf to workaround this security enhancement (since vsftpd 3.0.0; from Fixing 500 OOPS: vsftpd: refusing to run with writable root inside chroot ()):

allow_writeable_chroot=YES

or alternative:

Install vsftpd-extAUR[broken link: archived in aur-mirror] and set in the conf file allow_writable_root=YES

FileZilla Client: GnuTLS error -8 -15 -110 when connecting via SSL

vsftpd tries to display plain-text error messages in the SSL session. In order to debug this, temporarily disable encryption and you will see the correct error message.[1] [2]

vsftpd.service fails to run on boot

If you have enabled the vsftpd service and it fails to run on boot, make sure it is set to load after network.target in the service file:

/usr/lib/systemd/system/vsftpd.service
[Unit]
Description=vsftpd daemon
After=network.target

ipv6 only fails with: 500 OOPS: run two copies of vsftpd for IPv4 and IPv6

you most likely have commented out the line

# When "listen" directive is enabled, vsftpd runs in standalone mode and
# listens on IPv4 sockets. This directive cannot be used in conjunction
# with the listen_ipv6 directive.
#listen=YES
#
# This directive enables listening on IPv6 sockets. To listen on IPv4 and IPv6
# sockets, you must run two copies of vsftpd with two configuration files.
# Make sure, that one of the listen options is commented !!
listen_ipv6=YES

instead of setting

# When "listen" directive is enabled, vsftpd runs in standalone mode and
# listens on IPv4 sockets. This directive cannot be used in conjunction
# with the listen_ipv6 directive.
listen=NO

See also