vsftpd

From trapsink.com
Jump to: navigation, search


Overview

vsftpd is a GPL licensed FTP server for UNIX systems, including Linux. It is the default FTP server daemon as installed and taught by Red Hat, and as such enjoys the status of being the most popular FTP daemon in modern use with most Linux distributions. As a precursor, it's recommended to fully understand Active vs. Passive FTP mode:

This document will cover the basic installation and configuration of vsftpd; more options are available in the vsftpd.conf man page.


Installation

The vsftpd daemon is included in the core distribution repositories:

## RHEL / CentOS
yum -y install vsftpd
service vsftpd start && chkconfig vsftpd on

## Debian / Ubuntu
apt-get update && apt-get -y install vsftpd
mkdir /etc/vsftpd /var/ftp

NOTE: on Ubuntu the vsftpd service is controlled by Upstart; it's automatically started and enabled by default. On Debian the insserv command must be used to enable it.


Configuration Files

There's one key difference between the distributions:

RHEL / CentOS Debian / Ubuntu
/etc/vsftpd/vsftpd.conf /etc/vsftpd.conf
/etc/vsftpd/ftpusers /etc/ftpusers

This also extends into the entire /etc/vsftpd/ subdirectory and a default directory for anonymous users in /var/ftp/ which are only present on a RHEL-style installations from the package install. The Ubuntu package comes with both a systemd and upstart service that are not present on Debian; creating an /etc/vsftpd/ to work in on these distributions is preferred to allow for cross-distro compatibility in setup below.


Configuration Basics

All options refer to the vsftpd.conf configuration file and are detailed in the man page; other options exist than the ones listed herein.

TCP Wrappers

# Disable TCP Wrappers
tcp_wrappers=NO

Login Banner

# Set a direct banner (hide name, version, etc.)
ftpd_banner=FTP server ready.

# Overrides 'ftpd_banner' by specifying a filename
banner_file=/etc/vsftpd/banner.txt

Directory Message

# Shown when changing into the directory
message_file=.message
dirmessage_enable=YES

Logging

# Log all uploads and downloads
xferlog_enable=YES

# Log all FTP commands
log_ftp_protocol=YES
xferlog_std_format=NO

# Log transfers to both /var/log/xferlog and /var/log/vsftpd.log
dual_log_enable=YES

Local Users

# Disable 'write' (upload)
write_enable=NO

# Disable local users
local_enable=NO

Chroot Security

By default users are not in a chroot upon login.

# Basic Local user login chroot to home directory
chroot_local_user=YES
chroot_list_enable=NO

# Enable list of users ONLY to chroot
chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list

# Enable list of users NOT to chroot
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list

Access Control

By default, User ACLs are enabled in /etc/pam.d/vsftpd using the /etc/ftpusers / /etc/vsftpd/ftpusers file:

auth  required  pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed

To also allow manipulation by Group, a line can be added right below it using a (new) group file:

auth  required  pam_listfile.so item=group sense=deny file=/etc/vsftpd/ftpgroups onerr=succeed

Within vsftpd.conf are parameters determining how the ACLs are used:

# Should be configured already by upstream packagers
pam_service_name=vsftpd

# Enable list of users ONLY allowed to log in
userlist_enable=YES
userlist_deny=NO
userlist_file=/etc/vsftpd/ftpusers

# Enable list of users NEVER allowed to log in
userlist_enable=YES
userlist_deny=YES
userlist_file=/etc/vsftpd/ftpusers

Anonymous FTP

# Enable anonymous FTP w/password (email address, usually)
ftp_username=ftp
anonymous_enable=YES
anon_root=/var/ftp
anon_max_rate=0   # bytes/second, 0 = unlimited
anon_umask=077

# Enable only anon users who specify a certain email as password
no_anon_password=NO
secure_email_list_enable=YES
email_password_file=/etc/vsftpd/email_passwords

# Reverse the above, deny these emails when used as anon password
deny_email_enable=YES
banned_email_file=/etc/vsftpd/banned_emails

# Allow anon users to upload/delete/etc. (requires write_enable=YES)
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
anon_upload_enable=YES
anon_world_readable_only=YES
chown_uploads=YES
chown_username=ftp

Connection Restrictions

# Change limits and umask
connect_timeout=60     # in seconds
data_connection_timeout=300
idle_session_timeout=300
max_clients=2000
max_per_ip=10
max_login_fails=3
delay_failed_login=1   # in seconds
local_max_rate=0       # bytes/second, 0 = unlimited
local_umask=077

It's preferred to use iptables to perform restrictions at the IP level; however, if required TCP Wrappers can be used:

# Enable TCP Wrappers
tcp_wrappers=YES

# Deny a subnet
echo 'vsftpd:192.168.1.0/255.255.255.0:twist /bin/cat /etc/vsftpd/denied_message' >> /etc/hosts.deny

Using iptables is preferred.

SSL Connections

# General SSL Options
ssl_enable=YES
ssl_request_cert=YES
validate_cert=NO                          # breaks self-signed certs
ca_certs_file=/path/to/ca-bundle.crt
rsa_cert_file=/path/to/server.crt         # can be a PEM
rsa_private_key_file=/path/to/server.key  # can be a PEM
ssl_ciphers=HIGH:!ADH
ssl_sslv2=NO
ssl_sslv3=NO
ssl_tlsv1=YES
debug_ssl=NO

# Always expect a SSL handshake (not normal - use TLS instead)
implicit_ssl=NO

# Force various SSL options
require_cert=NO    # client SSL cert, not server
force_local_data_ssl=NO
force_local_logins_ssl=NO
require_ssl_reuse=YES
strict_ssl_read_eof=NO
strict_ssl_write_shutdown=NO

# SSL options for Anonymous FTP
allow_anon_ssl=YES
force_anon_ssl=NO
force_anon_data_ssl=NO
force_anon_logins_ssl=NO
force_local_data_ssl=NO


Active vs. Passive

Configuration options exist to facilitate setting of Active ("PORT") and Passive ("PASV") FTP to work around various firewall restrictions. One of the most common techniques is to use the kernel netfilter modules nf_nat_ftp and nf_conntrack_ftp (aliased internally to ip_nat_ftp and ip_conntrack_ftp for compatibility) which will track the FTP connections and attempt to maintain a data connection to the client dynamically.

# RHEL / CentOS   == /etc/sysconfig/iptables-config
IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp"

# Debian / Ubuntu == /etc/modules
ip_nat_ftp
ip_conntrack_ftp

These can be loaded immediately using modprobe (modprobe ip_nat_ftp ip_conntrack_ftp) instead of rebooting.

Additionally, vsftpd includes a number of variables which can also be used to set the behaviour of the static/dynamic ports used in either mode:

# Enable PORT (active) mode FTP and force 20 for data
port_enable=YES
connect_from_port_20=YES
ftp_data_port=20

# Set a specific range of data ports in PASV (passive) mode
pasv_enable=YES
pasv_addr_resolve=NO
pasv_min_port=23000   # 0 = use any port
pasv_max_port=23100   # 0 = use any port


Virtual chroot Users

This section is a description of the general method used in this wiki (but not exactly):

The scripts on that page can be used to perform a majority of this work, however those scripts are missing a few items outlined below based on using the ftp system user to own files rather than the virtual user - use those scripts with caution.

The account user/pass are stored in a Berkeley DB format file, so the proper package must be installed to provide the db_load command:

## RHEL / CentOS
yum -y install db4-utils

## Debian / Ubuntu
apt-get update && apt-get -y install db-util

vsftpd.conf

The configuration can be built to use virtual users based on the user_config_dir variable combined with the others; the key settings for vsftpd.conf:

vsftpd.conf
# These are in addition to any other normal config (SSL, etc.)
anon_world_readable_only=NO
anonymous_enable=NO
chroot_local_user=YES
guest_enable=YES
guest_username=ftp
hide_ids=YES
local_enable=YES
nopriv_user=ftp
pam_service_name=ftp
user_config_dir=/etc/vsftpd/users
userlist_enable=YES
userlist_file=/etc/vsftpd/denied_users
anon_umask=022
local_umask=022
dirlist_enable=NO
download_enable=NO
virtual_use_local_privs=YES

Create the core virtual chroot parent directory as listed above:

mkdir -p /var/ftp/virtual_users

Create the plain text file to store user/pass information imported to a DB:

# This is the input to create a DB hash file
# - for ultimate security it would not be left on the server
touch /etc/vsftpd/accounts.tmp
chmod 0600 /etc/vsftpd/accounts.tmp

PAM ftp

The above config specifies an alternate PAM configuration; create the file /etc/pam.d/ftp with the required config to use an alternate database:

/etc/pam.d/ftp
auth    required pam_userdb.so db=/etc/vsftpd/accounts
account required pam_userdb.so db=/etc/vsftpd/accounts

SELinux

If required, enable SELinux anonymous writes:

setsebool -P allow_ftpd_anon_write 1

Adding a User

First, the core login config for a user has to be created under the directory outlined by user_config_dir which matches the login name. The name testuser will be used as an example:

/etc/vsftpd/users/testuser
dirlist_enable=YES
download_enable=YES
local_root=/var/ftp/virtual_users/testuser
write_enable=YES 

Next, add the user to the core denied users specified by userlist_file above:

echo "testuser" >> /etc/vsftpd/denied_users

Create their system level user and chown their virtual user to ftp instead due to the virtual_use_local_privs setting above:

useradd -d /var/ftp/virtual_users/testuser -s /sbin/nologin testuser
chmod 0750 /var/ftp/virtual_users/testuser
chown ftp:ftp /var/ftp/virtual_users/testuser

# If SELinux is active
chcon -t public_content_rw_t /var/ftp/virtual_users/testuser

Add their account/password to the text DB import file and create the DB:

echo "testuser" >> /etc/vsftpd/accounts.tmp
echo "testpass" >> /etc/vsftpd/accounts.tmp
db_load -T -t hash -f /etc/vsftpd/accounts.tmp /etc/vsftpd/accounts.db.new
mv -f /etc/vsftpd/accounts.db.new /etc/vsftpd/accounts.db
chmod 0600 /etc/vsftpd/accounts.db

Reloading Users

The daemon needs reloaded after user changes:

service vsftpd reload

Updating a User

The Update process is changing the same info used during Add:

  1. Use usermod to alter the system user info as needed
  2. Update the user/pass in /etc/vsftpd/accounts.tmp and rebuild /etc/vsftpd/accounts.db

Typically in this scenario the password is being updated.

Removing a User

The process is an exact reverse of the Add process:

  1. Remove the 2 lines in /etc/vsftpd/accounts.tmp for their user/pass and rebuild /etc/vsftpd/accounts.db
  2. Remove the user from the system using userdel
  3. Remove the user from /etc/vsftpd/denied_users
  4. Remove the user config from /etc/vsftpd/users/ directory

Parts of the steps can be left – for example, if the content of the old $HOME directory is to be preserved, do not run userdel.


References