Tuesday, August 28, 2012

New Website Launch and Job Hunting

In case you haven't noticed, the BlakeNet site has been down for quite a while. In it's place comes a much more serious website whose scope is beyond BlakeNet's original experimental sandbox and download repository purposes. My new site, Subnet ROOT (SNR), serves to bring professional contacts, as well as personal and casual ones, all the information they might want to know about me. All content previously provided by BlakeNet will still be available through SNR. If there are any articles here that still link to the defunct BlakeNet, please let me know and I will be happy to provide the working alternative.

In the meantime, did I mention I'm looking for employment opportunities? I just finished up my Bachelor's of Science in Engineering and Information Sciences (Game and Simulation Programming concentration). Now I'm looking to get my foot in the door in the video game industry or other computer programming careers. Find me on LinkedIn (professional inquiries only, please) or contact me through SNR (professional or personal inquiries).

Edit: I'm no longer actively seeking opportunities, though I am always open to professional networking. Feel free to continue reaching out to me!

Thursday, August 02, 2012

VSFTPD "refusing to run with writable root inside chroot" Work-around

Hey there, everyone! I've been very busy lately with a couple different projects, but I thought I'd take the time to share my latest challenge and how I worked around it. The other day, I updated my Ubuntu servers from 10.04 to 12.04. This update brings with it a new version of VSFTPD (Very Secure FTP Daemon) which boasts some security improvements. Unfortunately, one of these improvements is causing a lot of headaches for me and other server maintainers.

VSFTPD has buffed up security pertaining to chroot'ed users. The (brief) reasoning behind it is that users jailed to directories they have write access on may alter scripts in such a way that would allow them to "break out of" the jail. While I acknowledge this as something to take into consideration, I feel the compromise between security and usability currently being forced onto us is unacceptable. Many configurations that worked perfectly fine before the update now throw an error when a chroot'ed user logs in:

500 OOPS: vsftpd: refusing to run with writable root inside chroot ()

A quick Google search turns up some obvious solutions, like stripping write permissions from the user on their home directory, moving files you want the user to have access to into subfolders (where they can have write access), or using the local_root config directive to jail users to the parent directory instead. You can even replace VSFTPD with the vsftpd-ext package, which supports the allow_writeable_chroot config directive. But, these weren't viable solutions for me; I didn't want to remove write access from users on the one place on the system I feel they should be guaranteed full-run over, I didn't want to allow nosey users to see what other files and folders were outside of their own area, and I didn't want to install an alternative package just to fix one simplistic issue. So I came up with my own solution!

My configuration is set up to not jail users by default. This allows accounts like mine and my operating partners to navigate the entire system, while also allowing me to limit what is visible to specific users for simplicity or to keep them out of places they shouldn't be in.

$ nano /etc/vsftpd.conf
...
chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
user_config_dir=/etc/vsftpd_user_conf

$ nano /etc/vsftpd.chroot_list
# List of local users to chroot() jail in their home directory when FTPing
foo
bar
foobar

Above, we can see that my config file calls for local users to not be chroot jailed by default, but to jail specific users listed in /etc/vsftpd.chroot_list, and to also find user-specific config files in the /etc/vsftpd_user_conf directory. The list file is pretty straight-forward (one username per line). This next part is where the magic comes in. The objective is to jail the users in such a directory that the only thing they could possibly see in their FTP listing would be their home directory. This directory must not have write access, and it must preserve the existing directory structure. There is a great utility for this sort of thing: links! But therein lies a problem. Directories can only be symlinked/softlinked, and FTP clients typically can't follow symlinks.

Luckily, there is another, much more powerful way to create links to directories. If you are familiar with the mount command, you know that it's used to create links between the filesystem and physical data. Did you know it can also create links between one area of the filesystem and another? The magical command uses the syntax mount --bind originalfile linkname. Now let's put it to work!

This next part will require you to know the superuser password. If you don't know it, but your account is allowed to sudo, skip the su root command and preceed each of the other lines with sudo.

$ nano /etc/vsftpd_user_conf/foo
local_root=/srv/ftp/foo

$ su root
# mkdir /srv/ftp/foo
# chown foo:foo /srv/ftp/foo
# chmod ug-w /srv/ftp/foo
 
# mkdir /srv/ftp/foo/foohome
# mount --bind /home/foo /srv/ftp/foo/foohome

In the first part, we see that we change foo's local root directory to /srv/ftp/foo instead of his typical home directory (in this example, /home/foo, though it could be anywhere). I chose to use the /srv/ftp directory to house these jails, but you can use any directory you'd like as long as it has world read-execute permissions. In the second part, we run a couple commands to create the necessary directories, set the owner and access flags, and finally link the original home directory to the new area.

That's all there is to it! Simply repeat the above process for each jailed user, giving each one their own vsftpd_user_conf entry and /srv/ftp folder. Please note that you will have to execute the mount --bind command again for each user after every system reboot. To avoid this chore, I created a script and referenced it in my /etc/rc.local file. You can find more details about writing scripts and making them execute each time your system starts on plenty of other sites. I hope this has helped!