Tutorial: ftpserver

Sometimes you want to create an easy way to share files, or you want to give access to a friend helping you on some php problems.

But you do not want to give them ssh/scp access to your vps.

There are two easy ways: webdav and good old ftp.

This tutorial will cover the ftp part.

1. Install required packages

sudo apt-get install vsftpd openssl apache2-utils libpam-pwdfile

2. Create config folder and ssl files

#one folder to hold all certs and passwd files
sudo mkdir /etc/vsftpd
#create ssl key and cert
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/vsftpd/vsftpd.key -out /etc/vsftpd/vsftpd.pem
#ftp chroot dir
sudo mkdir /var/www
sudo chown ftp:www-data /var/www

3. Change vsftpd auth method

sudo nano /etc/pam.d/vsftpd
# Standard behaviour for ftpd(8).
auth   required        pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed

# Note: vsftpd handles anonymous logins on its own. Do not enable pam_ftp.so.

# Standard pam includes
#@include common-account
#@include common-session
#@include common-auth
#auth   required        pam_shells.so

# Customized login using htpasswd file
auth    required pam_pwdfile.so pwdfile /etc/vsftpd/passwd
account required pam_permit.so

Keep the first line, comment out everything else and add the last two lines.

4. Add ftp users (virtual ones - no system users)

#first user (-c = create passwd file)
htpasswd -cd /etc/vsftpd/passwd test
#subsequent users
htpasswd -d /etc/vsftpd/passwd test2

#add user to allow list (easy way to deactivate users without the need to modify the passwd file)
nano /etc/vsftpd/allowed.userlist

#create folder for user "test"
sudo mkdir /var/www/test && chown ftp:www-data /var/www/test

5. Create vsftpd config

#save the old one
sudo mv /etc/vsftpd.conf /etc/vsftpd-sik.conf

#create a new one
nano /etc/vsftpd.conf

Content of vsftpd.conf

# Allow anonymous FTP?
anonymous_enable=NO
listen=YES
# Allow local logins are permitted or not - needed for virtual users too
local_enable=YES
# Mask for files
local_umask=022 #055 for web
# Allow change of file system
# Commands are: STOR, DELE, RNFR, RNTO, MKD, RMD, APPE and SITE
write_enable=YES
# Time out of idle session
idle_session_timeout=600
# Time out of data connection
data_connection_timeout=120
# User used to run service
nopriv_user=ftp
# Activate directory messages (.message files)
dirmessage_enable=YES
# File time stamps generated by server time
use_localtime=YES
# Enable transfer log
xferlog_enable=YES
# Transfer log file
xferlog_file=/var/log/xferlog
# YES writes to xferlog_file, NO writes to vsftpd_log_file,
xferlog_std_format=YES
# PORT transfer connections originate from port 20 (ftp-data)
connect_from_port_20=YES
# User used by vsftpd when it wants to be totally unprivileged
nopriv_user=ftp
# If enabled virtual users will use the same privileges as local users
virtual_use_local_privs=YES
# If enabled all non-anonymous logins are classed as "guest" logins
# = enable virtual users
guest_enable=YES
# the local user that virtual users will impersonate
guest_username=ftp
# Token for user name
user_sub_token=$USER
# User home directory. Needs to exist
local_root=/var/www/$USER
# Chroot user and lock down to their home directories
chroot_local_user=YES
# Directory used as a secure chroot() jail at times vsftpd does not require filesystem access
secure_chroot_dir=/var/run/vsftpd/empty
# Hide ids from user
hide_ids=YES
# Authentication service
pam_service_name=vsftpd
# Vsftpd will use userlist_file to determine if the user will be
# allowed or denied access before asking for a password.
userlist_enable=YES
# If YES users in the list will be denied access
# If NO users will be denied UNLESS they are in the list
userlist_deny=NO
# List of user names - whitelist is always better
userlist_file=/etc/vsftpd/allowed.userlist
# Do not allow FXP
# YES if you want to disable the PASV security check that ensures the data connection originates from the same IP address as the control connection
pasv_promiscuous=NO
# YES if you want to disable the PORT security check that ensures that outgoing data connections can only connect to the client
port_promiscuous=NO

# Enable passive ftp mode and set port ranges
pasv_enable=YES
pasv_min_port=49990
pasv_max_port=50000
# SSL for data and controll connections
ssl_enable=YES
# Force encrypted logins for non-anonymous
force_local_logins_ssl=YES
# Force encrypted data transfers for non-anonymous
force_local_data_ssl=YES
# Permit TLS v1 protocol connections. TLS v1 connections are preferred
ssl_tlsv1=YES
# Permit SSL v2 protocol connections. TLS v1 connections are preferred
ssl_sslv2=NO
# permit SSL v3 protocol connections. TLS v1 connections are preferred
ssl_sslv3=NO
# Newer versions of some clients don't accept the default ciphers
ssl_ciphers=HIGH
# RSA certificate to use for SSL encrypted connections
rsa_cert_file=/etc/vsftpd/vsftpd.pem
rsa_private_key_file=/etc/vsftpd/vsftpd.key

# welcome message
ftpd_banner=My ftp server

So we enabled ssl, disabled anonymous access, defined passive port range (for the iptable rules), enabled the userlist of active ftp users, switched to virtual users and defined the chroot path for ftp users:

# Token for user name
user_sub_token=$USER
# User home directory. Needs to exist
local_root=/var/www/$USER

The user "mylogin1" will have the home directory "/var/www/mylogin1".

If you want to add a message per folder you can add a ".message" file for each folder:

sudo nano /var/www/bloguser/.message

6. Restart service

service vsftpd restart

Fingerprint of vsftpd is small too.

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
 2713 ftp        20   0  4504  1632  1364 S  0.0  1.3  0:00.01 -- /usr/sbin/vsftpd

That's it.

Looking forward to additional input.