How to Fix the vsftpd GnuTLS Error 15 with FileZilla on Ubuntu 12

by Nathaniel Morales

Like many of you around the interwebs, you have been upgrading your Ubuntu 10.04 LTS boxes to 12 because 10 is getting end-of-life’d. And, of course, it is not without headache. You upgrade your server, re-install vsftpd from apt, copy over your config files,  and it starts up just fine. Then you try to connect to vsftpd with your FileZilla FTP client, and the vsftpd GnuTLS Error 15 shows up in the FileZilla log. It worked before, but now it doesn’t. Here how I fixed it.

Here’s what I saw in my logs that prompted me to start this voyage:

Status:    Resolving address of yourserver.com
Status:    Connecting to 123.456.78.90:990...
Status:    Connection established, initializing TLS...
Status:    Verifying certificate...
Status:    TLS/SSL connection established, waiting for welcome message...
Response:    220 (vsFTPd 2.3.5)
Command:    USER michael
Response:    331 Please specify the password.
Command:    PASS ********
Error:    GnuTLS error -15: An unexpected TLS packet was received.
Error:    Could not connect to server

Well… that’s annoying.

What’s the cause of the vsftpd GnuTLS Error 15

When you upgrade from Ubuntu 10.04 to 12.04, it also upgrades vsftpd from version 2.2.2 to 2.3.5. Somewhere between 2.2.2 and 2.3.5, vsftpd became more secure, and it exposed a bug in FileZilla where FileZilla doesn’t present the client certificate properly or allow session reuse after certificate negotiation. (Source: https://security.appspot.com/vsftpd/Changelog.txt). The FileZilla people know about it because a bug is listed with the FileZilla, but “there is no general solution yet.”

Here’s how to fix it.

As an overview, here’s what we have to do to fix this problem:

  1. Revert to vsftpd 2.2.2 by removing the repo version and compiling from source.
  2. Fix the  vsf_findlibs.sh file, because it is looking for resources with hard-coded paths.
  3. Configure vsftpd to compile with ssl support
  4. Compile.
  5. Re-build init scripts / upstart jobs

Removing the Repo Version of vsftpd

It should be as easy as apt-get remove vsftpd. However, you may want to run the command below to see if there are any “straggler” files that might interfere.

 locate vsftpd | grep -v src

It’s ok if this shows results. We just want to make sure there are no results that contain a bin or sbin like:

/usr/bin/vsftpd

Getting the Proper “Working” Version of vsftpd

Download this version of vsftpd into /usr/src/, but changing directories to the /usr/src, and using wget to download it:

sudo su
cd /usr/src/
wget -r ftp://vsftpd.beasts.org/users/cevans/untar/vsftpd-2.2.2/

Fix  vsf_findlibs.sh

The file vsf_findlibs.sh in version 2.2.2 no longer works under Ubuntu 12 x64 because the file is (by its own admission in the comments) is very hackish. It looks to see if a file exists in a certain place, and if it does, it returns a configuration directive (like: -ssl -lpam, etc…).

The problem is: if it doesn’t ind those files, it doesn’t return the right configurations even though your system as all these resources. So, you have to fix it.

which you’re welcome to try. But, in case it doesn’t, here’s how to fix yours for yourself:

Throughout the file, you’ll see that there are directives / switches that are related to .so files. Each one of those directives / switches only needs to find those library files, to return that switch for the Makefile. So, all you have to do is use the locate command to find out where the file is in your installation, and add a line.

In the picture below, I have highlighted the switch “-lpam,” from the original file with red arrows. The line in the orange box shows the line I added to fix the file. All I did was execute the command below to find the library file, and added the line with the correct path.


vsf_findlibs.sh

Just repeat this process throughout the file. But there is one exception (shown below):

Because the results of this part of the script actually echo back a file location, you have to create symlinks. So, lets assume you find libcap.so.1 in /usr/lib/x86_x64-linux-gnu/libcap.so.1. You would create a symlink like this:

ln -s /usr/lib/x86_x64-linux-gnu/libcap.so.1 /lib/libcap.so.1

And then, repeat for the libcap.so.2 file as well. In my case, only libcap.so.2 was present on my system.

When you’re done, exit the editor, and run vsf_findlibs.sh manually. It should run with no errors, and return a series of configuration directives, as shown below:

 Configure SSL Support

Open the builddefs.h file, and modify it as shown below, or download the one I did here: builddefs.zip

Compile and Test vsftpd

First, you have to prepare the system by installing required dependencies:

apt-get build-dep vsftpd

Now, that we have that setup and a correctly modified source set, we can compile the source using:

make
make install

Now, use the which command to see where it has been installed:

which vsftpd

which will probably return this path: /usr/local/sbin/vsftpd.

Now run vsftpd -v, to double check to make sure the correct version (2.2.2) is displayed:

root@michael-desktop:/usr/src/vsftpd-2.2.2# vsftpd -v
vsftpd: version 2.2.2
root@michael-desktop:/usr/src/vsftpd-2.2.2#

Now, run vsftpd with the following command, which will start it stand-alone mode:

/usr/local/sbin/vsftpd&

Now, try to connect with your favorite FileZilla client. If it works, move to the next step. If it doesn’t, check your configs, re-read the instructions above, and try again.

Configuring the Upstart Job (Init Script)

It’s easiest to start with a working init script and upstart job, so you can download  Download vsftpd Upstart and Init Scripts. Download this file into your root directory, and then execute the following command to restore the two files to their respective positions:

tar -xvf vsftpdupstart.tar

At this point, most likely, it’s going to fail because the upstart job has the wrong exec path, so here’s how to fix that:

  1. Execute which vsftpd to double check the path. Mine is now in /usr/local/sbin/vsftpd
  2. Edit /etc/init/vsftpd, and find the last line where it says: exec /usr/sbin/vsftpd, and change it to reflect your binary location you found in step 1.
  3. Save the file, and exit

Now, that you have correctly setup the init script and upstart jobs, run start vsftpd, and you should get something like this:

root@michael-desktop:/# start vsftpd
vsftpd start/running, process 14189
root@michael-desktop:/#

If it’s not running, check all your paths. Otherwise, you should now have a working installation! Yay Downgrades!