Ubuntu 9.10: Virtual FTP Users

by Mike on October 23, 2009 · 6 comments

in Ubuntu Servers

Virtual Users
If you create user accounts on a server, and then allow people to log on to the ftp server under those accounts, there’s a chance that some  hacker could find a way out of the chroot jail.   That would allow him to access areas of the file system where he has no authorization, and possibly to plant Trojans or other malicious programs.  You can increase your security using FTP by creating virtual users.  These users can use FTP but they are limited in access to the system as a whole.

Ubuntu chroot Jail for VSFTPD

FTP and Active or Passive Connections

The goal here is to create a directory which will contain all of the virtual user home files and also add the users to a MySQL database for management.

ftp_virtual

Install MySQL

sudo apt-get install mysql-server

When you install, part of the process of installation is requiring you to create a password for the MySQL root user during install.   Be sure to remember that password as you will need it to create the database.

Login and create the database.

mysql -p -u root

CREATE DATABASE vsftpd;

Whatever you choose to call the database does not matter except that you need to be consistent in all of the settings.

USE vsftpd;

This command will select the vsftpd database, or whatever you called it, so that the rest of the commands are executed on the database of choice.

This next series of commands will set up permissions for the user vsftpd and set a password for that user so that you can authenticate.

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON vsftpd.* TO ‘vsftpd’@'localhost’ IDENTIFIED BY ‘ftpuserpass’;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON vsftpd.* TO ‘vsftpd’@'localhost.localdomain’ IDENTIFIED BY ‘ftpuserpass’;
FLUSH PRIVILEGES;

This next command sets up the accounts table with a username and password, note the command goes all the way to the semi-colon.

CREATE TABLE `accounts` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 30 ) NOT NULL ,
`pass` VARCHAR( 50 ) NOT NULL ,
UNIQUE (
`username`
)
) ENGINE = MYISAM ;

quit;

The quit command will end your MySQL session.

Next you will need to configure VSFTPD so the first thing to do is make a backup of  the default /etc/vsftpd.conf and then create a new one with these settings.  Note that initially the connections will be on port 21 with no SSL so that you can get a basic system working.  Later you can add SSL and change ports if you want.  Just to keep everything consistent the guest user for the /home directory is vsftpd and then inside that directory will be the virtual FTP clients.

listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
nopriv_user=vsftpd
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd
pam_service_name=vsftpd
guest_enable=YES
guest_username=vsftpd
local_root=/home/vsftpd/$USER
user_sub_token=$USER
virtual_use_local_privs=YES
ftpd_banner=Welcome to Secure FTP.

Modify PAM Settings
cd /etc/pam.d
vi vsftpd
Add these lines to /etc/pam.d/vsftp.  Note the user is vsftpd and the password is ftpuserpass, change those to reflect what you created with the database.

auth required pam_mysql.so user=vsftpd passwd=ftpuserpass host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=2
account required pam_mysql.so user=vsftpd passwd=ftpuserpass host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=2

Save the file as /etc/pam.d/vsftpd

Now create a virtual user.
mysql -p -u root

USE vsftpd;

INSERT INTO accounts (username, pass) VALUES(‘tom’, PASSWORD(‘tomspassword’));
The next step will involve use of the Pluggable Authentication Module (PAM).

Now check to see if it created the user and password.

SHOW TABLES;
+——————+
| Tables_in_vsftpd |
+——————+
| accounts         |
+——————+
1 row in set (0.00 sec)

mysql> select * from accounts;
+—-+———-+——————————————-+
| id | username | pass                                      |
+—-+———-+——————————————-+
|  1 | tom      | *1B8F8905CDA6675FA316A5D50D1B7EC4FBE838B9 |
+—-+———-+——————————————-+
1row in set (0.00 sec)

This confirms the user has been created.

One frustrating aspect of the virtual accounts is that you must also create a directory in the /home/vsftpd and change the permissions for each user  you create.  Here is a script that will help with that process.

#!/bin/bash
# Create Virtual User homes
echo “Enter User to be Created”
read NAME

mkdir /home/vsftpd/$NAME
echo “Home Directory Created”

chown -R vsftpd:nogroup /home/vsftpd
echo “Permissions Changed”
echo “Now you need to create the user and password in mysql”
exit 0

Make the script executable with chmod 755 vsftpd.sh and then run the script.

sh vsftpd.sh
Enter User to be Created
joe
Home Directory Created
Permissions Changed
ls -la /home/vsftpd
total 32
drwxr-xr-x 2 vsftpd nogroup 4096 2009-10-16 06:47 joe
drwxr-xr-x 2 vsftpd nogroup 4096 2009-10-16 06:39 tom

Virtual Account Options
One of the virtual account options you may want to consider is to use SSL for connecting to FTP so it is more secure.  Here are the three lines you need to add.

force_local_data_ssl=YES
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

Most of the settings in this file are either self-explanatory, or they’ve already been covered.

chroot_local_user=YES

This chroot_local_user setting keeps the user confined to only one directory on the server.

guest_enable=YES
guest_username=vsftpd

These two lines allow VSFTPD to use the user “vsftpd” that we just created.

You can also change the port that FTP listens on.
listen=YES
listen_port=10021

This means that VSFTPD will run in daemon mode, and that we’ll be making use of port 10021, instead of ftp’s normal port 21.

pasv_min_port=30000
pasv_max_port=30999

You will also need to comment out the option allowing the client to connect on port 20.

#connect_from_port_20=YES

When running ftp in passive mode, these lines will limit the range of ports that it will use for incoming passive requests from the client.   This will help make it easier to configure a firewall.   You will need to add these ports to your UFW firewall.

sudo ufw allow proto tcp from any to any port 30000:30999

You’ll now want to restart VSFTPD to re-read the configuration file any time you make changes.

sudo /etc/init.d/vsftpd restart

You can test your setup from the server command-line, like so:

ftp localhost 10021

The one disadvantage to this configuration is that each user must log on to a common home directory, instead of having his own private home directory.  This may be fine for your purposes, but, if not, it’s possible to set up other configurations that feature the added security of virtual users.

{ 4 comments }

luctor812 December 8, 2009 at 3:59 am

Nice turt,but there are some errors in it,first in your syntaxis for mysql the ‘ in accounts and the field starts and end with a ‘,second your script to add virtual users create some errors invalid user ‘vsftpd:nogroup’,i guess that a vsftp user must by added? And after all it isn’nt possible to connect to vsftpd,after i use this turtual.

asd January 6, 2010 at 11:03 am

Yes, ensure you apt-get install libpam-mysql to provide the pam module for using mysql

cshark January 26, 2010 at 12:12 pm

I also did the tutorial and it seems that i can’t connect with any of the virtual users I created :(

John Crenshaw August 13, 2010 at 11:49 am

When did you create the VSFTPD system user? I see you added it to mysql, but you have to create the system user or else you’re going to end up with the same errors as luctor812. So how should this be setup?

If I remember correctly most VSFTPD installs use “FTP” as the user.

{ 2 trackbacks }

Previous post:

Next post: