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:
- SVN/Git pushing is done on a per-user basis, which means giving out those credentials limits a 3rd-parties access to one directory/virtual-host
- Easy to provide ftp-access to people who want to simply upload files
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.
VSFTP Configuration
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:
- Uncomment `write_enable=YES`
- Uncomment `local_umask=022`
- Add `virtual_use_local_privs=YES`
- Switch `pam_service_name` to `vsftpd.virtual`
- Add `guest_enable=YES`
- Add `guest_username=ubuntu`
- Add `user_sub_token=$USER`
- Add `local_root=/var/www/$USER`
- Add `listen_port=PORT1`
- Uncomment `chroot_local_user=YES`
- Add `hide_ids=YES`
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:
- pasv_min_port=PORT2
- pasv_max_port=PORT2
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.
ftp-restart
Virtual User Setup
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>
For example:
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:
ftp-restart
And boom. We've created a set of virtual-users which can access only their associated /var/www directory.
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.
Update
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 entries like:
Wed Aug3 00:38:04 2011 [pid 2] CONNECT: Client "174.116.180.121"
Wed Aug3 00:38:04 2011 [pid 1] [prod.djkstyles.com] FAIL LOGIN: Client "174.116.180.121"
...
This didn't help all that much, so I went back into my VSFTPD config file, and did the following:
- Uncomment `xferlog_std_format=YES`
- Changed `xferlog_std_format=YES` to `xferlog_std_format=NO`
- Add `log_ftp_protocol=YES`
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 :)
Comments (add comment)
lonely post 5 seconds from now