Notes on installing an FTP server on a Digital Ocean virtual machine running Ubuntu 14


These are some quick notes/lessons related to vsftpd installation on Ubuntu 14. My reason for creating such a server was that I wanted to collect photos for an event (from the guests that came to the event). I had originally thought this was going to be easy with my 1 TB Dropbox account. What I didn’t realize was that in order for anyone to upload to a shared Dropbox folder, that person has to have an account on Dropbox.

So rather than hassle people about creating a Dropbox account, I figured that a temporary FTP server through Digital Ocean* would be easier. While I deployed the server and got it working for my needs I later realized that I was trading the ‘you need to create a Dropbox account’ hassle with ‘you need to upload using a FTP program’. I realized that this was a bad approach too since I was dealing with users that had a wide (wide) range of technical comfort and knowledge.

* Note that my Digital Ocean links in this post are referral links – they’re a great service which I really like and I definitely recommend.

Creating a virtual machine on Digital Ocean

Creating a virtual machine (i.e. a ‘Droplet’ per Digital Ocean’s jargon) on Digital Ocean (DO) literally takes 55 seconds (which is pretty amazing). DO’s support center ( walks you through clear instructions on doing this.

I went with Ubuntu 14,04 because it is an LTS version and was likely to be quite stable. Of course I didn’t need long term support for such a short-lived server but I figured the stability would be worth it.

Creating a virtual machine on Digital Ocean

SSH Keys

DO will email your root password or you can create SSH keys and put the public one on your instance for easy log-in.

I used the–2 instructions for ssh key association with my droplet. This line from the instructions did not work for me:

 cat ~/.ssh/ | ssh user@ "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

So I ended up destroying and re-creating my droplet and pre-associating the public key that I had just generated. Since it’s really fast, there was no big negative in doing it this way. Of course I could have used scp to the copy of the public key too if I didn’t want to re-create the droplet.

Installing and configuring the FTP server (vsftpd)

Installing vsftpd

I found pretty good instructions on for the initial installation.

The key is to install vsftpd and configure /etc/vsftp.conf:

 apt-get install vsftpd

When looking at vsftpd’s configuration – Vim drove me a bit batty with the built-in color syntax-ing (tons of dark shades of unreadable color) and I had to turn that off. The instrutions at explained how to do this (just put these at the end of the .vimrc):

 syntax off
 set nohlsearch
 set t_Co=0

550 error

My initial run of vsftpd per the tutorial that I found yielded a 550 error. This was one of a cavalcade of errors when testing different vsftpd configurations. The long and short of it is that the ftp server can be configured in different ways (anonymous download only, download and upload, etc…). Each of these possibilities yields different permutation of options in /etc/vsftpd.conf and the potential of other supporting files (for example – virtual users need more configuration files).

My configuration goal was a single user that could upload files to his home directory. This was going to be a shared user among different people that attended the above mentioned event. My assumption was that each would put their photos in a sub-directory that I created for them (see “Conclusion” section of this post for why this was a poor assumption).

So…I needed a chrooted ‘regular’ user for this configuration. Below is my final /etc/vsftpd.conf configuration and here are some useful sources of information.

550 error

Creating the ftp user – 1

I created the user using:

 useradd ftpuser

How-To Geek has a good article about useradd. Ubuntu also has an adduser command too. Both do the same thing but I found useradd to be easier to use.

After creating the ftpuser I decided to give my ftpuser a brilliantly simple password and it was ftpuser.

 passwd ftpuser

My intent was to make it easy on my users. This was a fatal (and dumb) security mistake. I am well versed in the stupidity of security by obscurity and I fell for it thinking that ‘no one is going to find the ip of this droplet’. I cover this lesson in the “Conclusion” section of this post.

Creating the ftp user – 2

One initial issue with my user and vsftpd was this error:

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

The problem was that ftpuser’s home directory didn’t have proper permissions for chroot to work correctly. Basically, the home directory of ftpuser cannot be writeable but sub-directories need to be writeable. So I did the following:

 As ftpuser within ftpuser's home directory:
 ftpuser@myawesomedroplet:~$ chmod 755 ../ftpuser/
 ftpuser@myawesomedroplet:~$ mkdir _test
 ftpuser@myawesomedroplet:~$ chmod 555 ../ftpuser/
 ftpuser@myawesomedroplet:~$ touch test
 touch: cannot touch ‘test’: Permission denied
 ftpuser@myawesomedroplet:~$ exit
 As root:
 root@myawesomedroplet:/home/ftpuser# service vsftpd restart

The _test directory is where I would have my logged-in user put their photos (well something better than _test)

For more info on this see:

Some insecurities

Everything looks good but…

After the above configuration for both vsftpd.conf and my local user I was all set. I tested logging-in via an ftp client, changing to _test and uploading a file and it all worked swimmingly. Then the next day I tested the exact same thing and I couldn’t log into the ftpuser account. I changed the password back to *ftpuser* and in 24 hours the exact same thing happened.

Well maybe it’s a security patch thing

I thought that perhaps my system wasn’t sufficiently patched (the magical thinking trap kicking in). So I went ahead and patched it. I also used the script from to make it easier on myself.

Chris Fido in his Servers for Hackers has an even better approach to get automatic security patches using cron and the specific Ubuntu distribution.

Nope it’s not a patch thing

My ftpuser kept being inaccessible after a few hours passed since changing its password to my brilliant password of ftpuser. So I decided to ask my question on

Nope it's not a patch thing

Vincent Flesouras rocks!

I got a fantastic answered from a gentleman named Vincent Flesouras.

The short answer: security by obscurity doesn’t work. I feel like Bart Simpson at the black board repeating this sentence over and over again.

Vincent Flesouras rocks!

Next action

The next step would be to throw away my Digital Ocean droplet and re-create it with something like Ansible. Since Digital Ocean charges me based on an the existence of an instance (whether it’s online or shut off it still costs), this would also save my some money and create a repeatable virtual machine.

I stopped here because I realized that the FTP server approach was the wrong approach for my audience. I think a better solution would be a webserver approach for easy upload of files (perhaps Caddy with some Golang goodness) but this will have to wait for another time because I’m out of time.


I learned the following lessons:

  1. Before diving into something, make absolutely sure you know how your least technical user will use your product/creation/monstrocity. I had assumed the built-in pervasiveness of ftp clients within all web browsers. The problem is that this is true but in the wrong direction for my use case. Most web browsers can connect to an anonymous ftp server to download files not upload them. Of course there are plenty of web based ftp clients, but then I’m giving a third party access to this ftp server with personal items (i.e. photos) on there. So…an ftp server was the wrong solution for this problem to begin with.
  2. Never ever ever use a super simplistic password relying on the obscurity of your server (i.e. ‘just’ an IP without an associated domain). Rationally, I knew this to be the case but there’s nothing like your brand spanking new user account on a brand spanking new virtual machine changing passwords ‘by itself’ every day.
  3. I should have used Ansible or some such orchestration software for the creation of the server. It would have allowed me to quickly and cleanly destroy/create server instances. This would have helped with testing of my server’s configuration (security and otherwise).

This was definitely a learning experience both about vsftpd and security.