amuck-landowner

Running your own small ftp server

wlanboy

Content Contributer
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

Code:
# 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.
 

sleddog

New Member
Awesome. FTP with secure login is excellent in my opinion. Way out-performs SFTP in transfer performance and memory usage.


# Force encrypted logins for non-anonymous
force_local_logins_ssl=YES
# Force encrypted data transfers for non-anonymous
force_local_data_ssl=YES
May want to explain those, and the pros/cons. I use the first, but not the latter. So logins are encrypted but data transfer happens in the clear for maximum performance. The choice depends on usage....
 

wlanboy

Content Contributer
Awesome. FTP with secure login is excellent in my opinion. Way out-performs SFTP in transfer performance and memory usage.


# Force encrypted logins for non-anonymous
force_local_logins_ssl=YES
# Force encrypted data transfers for non-anonymous
force_local_data_ssl=YES
May want to explain those, and the pros/cons. I use the first, but not the latter. So logins are encrypted but data transfer happens in the clear for maximum performance. The choice depends on usage....
Let's see what the manpage says:


force_local_logins_ssl
Only applies if ssl_enable is activated. If activated, all non-anonymous logins are
forced to use a secure SSL connection in order to send the password.

force_local_data_ssl
Only applies if ssl_enable is activated. If activated, all non-anonymous logins are
forced to use a secure SSL connection in order to send and receive data on data connections.

First is a must because you do not want to transfer passwords in plaintext. Second one depends on your needs.

The files I do transfer do contain a lot of sesitive data. Twitter logins, API keys, database logins, so I want the data streams encrypted too.

Performance is based on the cipher.

Just run:


openssl ciphers -v

To see what is available. Output is:


ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1
SRP-DSS-AES-256-CBC-SHA SSLv3 Kx=SRP Au=DSS Enc=AES(256) Mac=SHA1
SRP-RSA-AES-256-CBC-SHA SSLv3 Kx=SRP Au=RSA Enc=AES(256) Mac=SHA1
DHE-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256
DHE-DSS-AES256-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(256) Mac=SHA256
DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1
DHE-DSS-AES256-SHA SSLv3 Kx=DH Au=DSS Enc=AES(256) Mac=SHA1
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(256) Mac=SHA1
DHE-DSS-CAMELLIA256-SHA SSLv3 Kx=DH Au=DSS Enc=Camellia(256) Mac=SHA1
ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
ECDH-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA384
ECDH-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA384
ECDH-RSA-AES256-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA1
ECDH-ECDSA-AES256-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA1
AES256-GCM-SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD
AES256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA256
AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1
CAMELLIA256-SHA SSLv3 Kx=RSA Au=RSA Enc=Camellia(256) Mac=SHA1
PSK-AES256-CBC-SHA SSLv3 Kx=PSK Au=PSK Enc=AES(256) Mac=SHA1
ECDHE-RSA-DES-CBC3-SHA SSLv3 Kx=ECDH Au=RSA Enc=3DES(168) Mac=SHA1
ECDHE-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=3DES(168) Mac=SHA1
SRP-DSS-3DES-EDE-CBC-SHA SSLv3 Kx=SRP Au=DSS Enc=3DES(168) Mac=SHA1
SRP-RSA-3DES-EDE-CBC-SHA SSLv3 Kx=SRP Au=RSA Enc=3DES(168) Mac=SHA1
EDH-RSA-DES-CBC3-SHA SSLv3 Kx=DH Au=RSA Enc=3DES(168) Mac=SHA1
EDH-DSS-DES-CBC3-SHA SSLv3 Kx=DH Au=DSS Enc=3DES(168) Mac=SHA1
ECDH-RSA-DES-CBC3-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=3DES(168) Mac=SHA1
ECDH-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=3DES(168) Mac=SHA1
DES-CBC3-SHA SSLv3 Kx=RSA Au=RSA Enc=3DES(168) Mac=SHA1
PSK-3DES-EDE-CBC-SHA SSLv3 Kx=PSK Au=PSK Enc=3DES(168) Mac=SHA1
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-AES128-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1
ECDHE-ECDSA-AES128-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1
SRP-DSS-AES-128-CBC-SHA SSLv3 Kx=SRP Au=DSS Enc=AES(128) Mac=SHA1
SRP-RSA-AES-128-CBC-SHA SSLv3 Kx=SRP Au=RSA Enc=AES(128) Mac=SHA1
DHE-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256
DHE-DSS-AES128-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(128) Mac=SHA256
DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1
DHE-DSS-AES128-SHA SSLv3 Kx=DH Au=DSS Enc=AES(128) Mac=SHA1
DHE-RSA-SEED-SHA SSLv3 Kx=DH Au=RSA Enc=SEED(128) Mac=SHA1
DHE-DSS-SEED-SHA SSLv3 Kx=DH Au=DSS Enc=SEED(128) Mac=SHA1
DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(128) Mac=SHA1
DHE-DSS-CAMELLIA128-SHA SSLv3 Kx=DH Au=DSS Enc=Camellia(128) Mac=SHA1
ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
ECDH-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA256
ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA256
ECDH-RSA-AES128-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA1
ECDH-ECDSA-AES128-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA1
AES128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD
AES128-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA256
AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
SEED-SHA SSLv3 Kx=RSA Au=RSA Enc=SEED(128) Mac=SHA1
CAMELLIA128-SHA SSLv3 Kx=RSA Au=RSA Enc=Camellia(128) Mac=SHA1
PSK-AES128-CBC-SHA SSLv3 Kx=PSK Au=PSK Enc=AES(128) Mac=SHA1
ECDHE-RSA-RC4-SHA SSLv3 Kx=ECDH Au=RSA Enc=RC4(128) Mac=SHA1
ECDHE-ECDSA-RC4-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=RC4(128) Mac=SHA1
ECDH-RSA-RC4-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=RC4(128) Mac=SHA1
ECDH-ECDSA-RC4-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=RC4(128) Mac=SHA1
RC4-SHA SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=SHA1
RC4-MD5 SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=MD5
PSK-RC4-SHA SSLv3 Kx=PSK Au=PSK Enc=RC4(128) Mac=SHA1
EDH-RSA-DES-CBC-SHA SSLv3 Kx=DH Au=RSA Enc=DES(56) Mac=SHA1
EDH-DSS-DES-CBC-SHA SSLv3 Kx=DH Au=DSS Enc=DES(56) Mac=SHA1
DES-CBC-SHA SSLv3 Kx=RSA Au=RSA Enc=DES(56) Mac=SHA1
EXP-EDH-RSA-DES-CBC-SHA SSLv3 Kx=DH(512) Au=RSA Enc=DES(40) Mac=SHA1 export
EXP-EDH-DSS-DES-CBC-SHA SSLv3 Kx=DH(512) Au=DSS Enc=DES(40) Mac=SHA1 export
EXP-DES-CBC-SHA SSLv3 Kx=RSA(512) Au=RSA Enc=DES(40) Mac=SHA1 export
EXP-RC2-CBC-MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export
EXP-RC4-MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export

The vsftpd maintainers do have a parameter for that:


ssl_ciphers=HIGH

So what cipher should you use?

Depends on the system you are want to run a openssl encrypted connection. And what CPU is on the host side.

And there is a command for that too:


openssl speed

Compare the speeds and select a group of ciphers that are save and fast.

That can be done for Apache:


SSLHonorCipherOrder On
SSLCipherSuite "........................................."

And ngix too:


ssl_ciphers ".................................."

Recommended value?

Good question, there is a lot of discussion about it.

High security:


HIGH:!aNULL:!MD5

High performance:


RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5

I stick to the later value.
 

peterw

New Member
Needed to share a folder without ssh access. Searched vpsboard and found solution. Great tutorial.
 

MrBeReady

New Member
5. Create vsftpd config


# User used to run service
nopriv_user=ftp
# User used by vsftpd when it wants to be totally unprivileged
nopriv_user=ftp

Thanks for the tutorial.  nopriv_user=ftp is specified twice in your config file.

htpasswd -d only supports 8-character passwords.  Is there any way to support longer passwords?  I tried the other htpasswd encryption options, but it seems only -d is supported by the libpam-pwdfile module.
 

MrBeReady

New Member
htpasswd -d only supports 8-character passwords.  Is there any way to support longer passwords?  I tried the other htpasswd encryption options, but it seems only -d is supported by the libpam-pwdfile module.
I found at least one solution.  Openssl can generate password hashes for passwords longer than 8 characters that the libpam-pwdfile module can read:


openssl passwd -1

That's a number 1, not a lowercase letter L.  The downside of this method is it doesn't maintain the passwd file for you, like htpasswd does.  You'll have to edit the passwd file and manually add the username and password hash (or write a script to do it for you).
 

D. Strout

Resident IPv6 Proponent
Probably a dumb question, but why no local users? If I just adduser that has essentially no privileges except in their home directory, what harm can they do? Good tutorial overall, and SFTP is a nice addition.
 

wlanboy

Content Contributer
Probably a dumb question, but why no local users? If I just adduser that has essentially no privileges except in their home directory, what harm can they do? Good tutorial overall, and SFTP is a nice addition.
Local users do have (depends on the configuration) access to other services like terminal, mail, ssh, ... too.

If someone needs a tutorial to setup a ftp server he/she should not use local users.
 
Top
amuck-landowner