Following in the footsteps of my post AWS EC2 Micro Instance Setup, I wanted to devote a full-post to how I've setup my box's FTP server/service/daemon to allow for a pretty secure, decentralized, login system. Worth noting is that some commands are based on the post above being followed (eg. aliases were created to restart the ftp server, etc.), and this post is directly targeting some intricacies of AWS and how it manages it's firewall.
The premise behind my configuration is that each-and-every VirtualHost gets it's own virtual user with it's own unique password. The benefit behind this is two fold:
Although the purpose behind this is to create virtual-host-based users, one can
simple create ftp-only accounts that are found in the
/var/www directory, but
don't correlate directly to a virtual-host.
While a public/private key system is also a solid option (and easy to coordinate with AWS), I didn't like the idea of a 3rd-party service having access to my entire filesystem, so I've opted for the process outlined in this guide.
The first step in this process is to configure the previously installed vsftp program.
sudo vi /etc/vsftpd.conf
The following needs to now happen:
One of the things that stands out here is the custom port that should be configured for listening. I change this just to mix things up, but if you do this, you'll need to open that port up in the AWS Security Group/firewall. Keep that in mind.
However in addition to this, AWS (versus some other providers like Slicehost) requires you to add in the following two directives:
In this case, PORT2 is a different port than what was setup earlier, and will also need to be opened up in the AWS security group/firewall.
While my understanding of passive vs. active mode is limited, I believe that in passive mode, setting a range (in this case equal to the same exact port; security issue?) instructs the ftp-server's data-port to fall somewhere in that range. At that point, AWS's firewall isn't an issue since it's already been instructed to open that port up specifically.
The article Active FTP vs. Passive FTP, a Definitive Explanation gives a pretty solid explanation. The VSFTPD Configuration Manual is also worth it's weight in gold.
Oh, and I can't forget about the tutorial Set up an FTP Server on Amazon EC2. Solid walkthrough, although the IP tables bit wasn't a requirement.
Now, let's complete the configuration setup by rebooting the server.
Now comes the "fun" part. We get to create and manage the virtual users for this box.
sudo apt-get -y install db4.8-util cd sudo vi vusers.txt
This opens up an empty txt file which should be filled in in the following format:
<directory in /var/www> <password>
prod.olivernassar.com kittens dev.olivernassar.com kittens
Although this file will temporarily contain plain-text passwords, it gets compiled and encrypted shortly, so don't be concerned about that. The next step is to compile this information down to a format that the ftp-daemon can understand/process:
sudo db4.8_load -T -t hash -f vusers.txt /etc/vsftpd.vusers.db sudo chmod 600 /etc/vsftpd.vusers.db sudo vi /etc/pam.d/vsftpd.virtual
In the file that opens, copy and paste the following:
#%PAM-1.0 auth required pam_userdb.so db=/etc/vsftpd.vusers account required pam_userdb.so db=/etc/vsftpd.vusers session required pam_loginuid.so
Now we just restart:
And boom. We've created a set of virtual-users which can access only their
To make changes (eg. add, remove, change) to the list of virtual-users, the process is a little long-winded. You need to recreate a vusers.txt file with all the logins and passwords, and then run the following:
cd sudo vi vusers.txt sudo db4.8_load -T -t hash -f vusers.txt /etc/vsftpd.vusers.db sudo chmod 600 /etc/vsftpd.vusers.db sudo rm vusers.txt ftp-restart
Hopefully at some point I'll find a way to automate that. There we have it. Hope that helps.
Ha, after all that, I couldn't get my FTP server working. And while I don't know why yet (Update: see passive port opening above), I found a pretty helpful logging snippet.
The log file located at
/var/log/vsftpd.log is pretty sparse, showing basic
Wed Aug3 00:38:04 2011 [pid 2] CONNECT: Client "18.104.22.168" Wed Aug3 00:38:04 2011 [pid 1] [prod.djkstyles.com] FAIL LOGIN: Client "22.214.171.124" ...
This didn't help all that much, so I went back into my VSFTPD config file, and did the following:
Now, thanks to http://www.linuxquestions.org/questions/linux-newbie-8/vsftpd-and-log-files-can-i-up-the-log-level-to-see-login-attempts-632999/, the log file is a little more helpful :)