VSFTPD1) means "very secure ftp server", Devil-Linux2) was a hardened linux distribution for firewalls and servers with security in mind, it was run from CD, keept its configuration on floppy or otherwise write-protectable media and didn't need a hard drive - if large storage capacity is not needed.
Devil-Linux is discontinued since 2017, but the vsftpd part might still work on an other linux distribution.
The ftp server in our case should follow following requirements:
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:
db_load
5). Any normal Linux-Distro probably will dosetup
, create floppy with proper network settings) 6)/root/.ssh/authorized_keys
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
insserv -d vsftpd
/etc/init.d/vsftpd start
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 ..
This work is licensed under the Creative Commons Attribution-ShareAlike 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.5/
Alternative Licence: If you want to include my document to a project, where the GNU licences are neccessary, you might use it under the GNU Free Documentation Licence or General Public Licence (GPL)
db_load
is not contained in the default devil-linux, and if the clear-text-password file never touches the ftp-server, it doesn't hurt either. On Suse db_load
is part of the db-utils package (Command Line tools for Managing Berkeley DB Databases) /home/myuser/.ssh/id_dsa.dmz