vsftpd1) means “very secure ftp server”, devil-linux2) is a hardened linux distribution for firewalls and servers with security in mind, it runs from CD, keeps its configuration on floppy or otherwise write-protectable media and doesn’t need a hard drive - if large storage capacity is not needed.
The ftp server in our case should follow following requirements:
large up- and download capacity
with a relative small number of known external users via Internet
anonymous access is not necessary
3)
secure as possible
easy to maintain
a basic log: why and for whom which ftp user was created
This is a configuration example with virtual users. Virtual users are only known by the ftp program, we try to rule out other possibilities of doing harm with user name + password4).
Transferred data is quite large in this case, that’s why we use the hard disk as storage.
We used:
the ftp-server: a computer with CD-drive, floppy-drive and hard disk
devil-linux 1.2.9 CD
an other (unixoid) computer for creating pw-database with
db_load5). Any normal Linux-Distro probably will do
create a normal devil-linux installation (burn CD, boot from CD, configure with
setup, create floppy with proper network settings)
6)
put your ssh-key
7) to the devil linux root users
/root/.ssh/authorized_keys
create partitions or logical volumes on your hard disk
8)
my ftp-servers /etc/fstab
# location mount point fs-type options
/dev/fd0 /floppy auto noauto 0 0
/dev/data/home /home ext3 auto 1 2
/dev/data/mountpoint /opt ext2 auto 1 2
/dev/data/log /opt/data/log ext3 auto 1 2
/dev/data/ftp /opt/data/ftp ext3 auto 1 2
Mount /home and /opt, create mount points /opt/data/log and /opt/data/ftp, and mount all.
Hint: Mount points outside of the devil-linux scheme won’t survive a reboot, if they don’t live on a hard disk.
We just create one real unix user “virtual”, which does the ftp service for all virtual users.
create this groups ( /etc/group )
ftp:x:40:vsftpd
ftpvirtual:x:613:
and this users ( /etc/passwd )
vsftpd:x:41:40:nopriv user for ftp:/var/empty:/bin/false
virtual:x:1000:613:used for all virtual ftp users:/opt/data/ftp/virtual/$USER:/bin/false
The trick is the string $USER in the home directory of the user virtual. Each virtual user will get its own home directory below the virtual user home directory.
The ftp-server config file /etc/vsftpd.conf
### tcp/ip
listen=yes
background=YES
pasv_min_port=30000
pasv_max_port=30999
connect_from_port_20=YES
idle_session_timeout=600
data_connection_timeout=120
#### log
xferlog_enable=YES
vsftpd_log_file=/opt/data/log/vsftpd.log
# enable only for debugging (large log file ...)
#log_ftp_protocol=YES
### users for privilege separation
### and for virtual users
nopriv_user=vsftpd
pam_service_name=vsftpd
guest_username=virtual
user_sub_token=$USER
### user privileges
anonymous_enable=NO
local_enable=YES
write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
chroot_local_user=YES
guest_enable=YES
ls_recurse_enable=YES
local_umask=002
anon_umask=000
dirmessage_enable=YES
### security settings
secure_chroot_dir=/var/empty
check_shell=NO
### misc
ftpd_banner=Welcome to the XYZ FTP service.
# banner_file=/etc/vsftpd.banner
local_umask=002
anon_umask=002
dirmessage_enable=YES
#not working ??
#text_userdb_names=YES
# alternative:
hide_ids=YES
/etc/pam.d/vsftpd
auth required /lib/security/pam_userdb.so db=/etc/vsftpd_login
account required /lib/security/pam_userdb.so db=/etc/vsftpd_login
Our virtual users live only in vsftpd, have no entry in /etc/passwd but their own user database. The creation of this user database happens on an other machine with this small script and the tool db_load.
#!/bin/bash
# ftpuseradd
# ftp user generator for ftp server ftp.xxx.yy
# (runs with vsftpd)
# create userdb for virtual ftp users,
# transfer it to the ftp server
# create homedir for these users on the remote ftp server
FTPSRV=name.or.ip.of.your.ftp.server.xx
# these paths are local on *this* machine
# -> here we save the user list locally
# (since the passwords are clear text, one should protect this directory
# e.g. don't keep it in a NFS directory)
PATH=/etc/vsftpd # local path - use something reasonable for your side
USERFILE=ftp.vsftpd_login.txt
USERDB=ftp.vsftpd_login.db
LOG=ftp.userlog # sort of log: which users for which project
# that's where the user-database is moved to on the ftp server:
USERDB="/etc/vsftpd_login.db"
FTPDIR="/opt/data/ftp/virtual/"
# this is the real ftp user, we create virtual ftp users
# which all work with this user id ..
FTPUSER="virtual"
FTPGROUP="ftpvirtual"
# command to create the berkley db userdatabase
DB=/usr/bin/db_load
DBCREATE="$DB -T -t hash -f $PATH/$USERFILE $PATH/$USERDB"
# transport method: ssh and necessary ssh-key
# (the matching public key should be on the ftp server in
# roots .ssh/authorized_keys)
SSH=/usr/bin/ssh
SCP=/usr/bin/scp
SSHID=/home/myuser/.ssh/id_dsa.dmz
TIME=`/bin/date +%F--%H%M`
GREP=/usr/bin/grep
# first: save old files
/bin/cp $PATH/$USERFILE $PATH/$USERFILE.$TIME
# query for user name
echo "Please enter name and Password of the new ftp user name"
echo -n "Username: "
read USERNAME
# exit, if we have this user already
if [ `$GREP "^$USERNAME$" $PATH/$USERFILE` ]; then
echo "FTP-User $USERNAME already configured? Found entry in $PATH/$USERFILE"
exit 1
fi
## small bug: if we have a password, which is the same name as the new user,
## this won't work
# query for password and contact info
echo -n "Password: "
read PASSWORD
echo "Who is the local contact for this ftp user (remote contact, project, remarks)?"
echo -n "Contact: "
read CONTACTINFO
# put the queried values to the log-file and to the user+pw textfile
echo "$USERNAME:$PASSWORD:$TIME:$CONTACTINFO" >> $PATH/$LOG
echo $USERNAME >> $PATH/$USERFILE
echo $PASSWORD >> $PATH/$USERFILE
# create the binary (berkley-db) user database from the user+pw textfile
$DBCREATE
# transfer user database to server
echo "transfer new user-database to server $SERVER"
$SCP -i $SSHID $PATH/$USERDB root@$FTPSRV:/$USERDB
# create a home directory for the ftp user
# + add a textfile text.txt
# ->for debugging: "can you see +download test.txt?"
echo "create home directory on $FTPSRV for ftp-user $USERNAME"
$SSH $FTPSRV -i $SSHID "/bin/mkdir -p $FTPDIR/$USERNAME"
$SSH $FTPSRV -i $SSHID "/usr/bin/ex -s $FTPDIR/$USERNAME/test.txt << _eof_
a
Welcome on our ftp-server, $USERNAME
This life is a test. It is only a test. Had this been an actual life
you would have received further instructions as to what to do and where to go
.
w
_eof_
"
# set ownership of directory + files
$SSH $FTPSRV -i $SSHID "/bin/chown -R $FTPUSER:$FTPGROUP $FTPDIR/$USERNAME"
$SSH $FTPSRV -i $SSHID "/bin/chmod g+w -R $FTPDIR/$USERNAME"
$SSH $FTPSRV -i $SSHID "/bin/chmod g+s $FTPDIR/$USERNAME"
echo "if there were no error messages, the user was probably created"
echo "please check the user homedir $FTPDIR on $FTPSRV "
echo "and DONT FORGET: save-config !!!"
# the end
create a new ftp-user with ./ftpuseradd and answer the questions - take a critical look at the output and check on the ftp-server the existence of the user-directory and the time of the ftp-password-database.
connect with the ftp-program of your choice to your new ftp server and try to show the directory (you should see the created test.txt), up- and download a file ..