I use ProFTPd as my FTP server which I occasionally run externally to let friends grab files from my home server and to upload content to when I'm away from home. I opt to encrypt both the command and data channels using explicit FTP over TLS and posted about setting this up last year getting ProFTPd working with TLS / SSL. In trying to create a more limited user account with only read only access to a limited number of shared directories I hit a challenge in allowing the user to list the content of the directories when TLS was in place, receiving the error 534 Unwilling to accept security parameters. Here's my solution...I started off by creating the new directory share with more stringent limit controls as defined in the ProFTPd configuration file. The client I was using to access the ProFTPd server was Filezilla v3.5.0 running on Ubuntu 11.10. The shares were defined with the limits as follows:

<Limit READ DIRS> AllowUser TheReadOnlyLimitedUserAccount

</Limit><Limit ALL> DenyAll</Limit>

This config without TLS enabled achieved the desired result but as soon as TLS was enabled the user could authenticate with the server but could not list the content of the remote directory. With TLS enabled I received the following output on the Filezilla client from the server, I was hitting an issue with the TLS Data Channel Protection Level commands set out in RFC 2228:

Command: PROT PResponse: 534 Unwilling to accept security parameters

And eventually trying to list the directory contents using MLSD (an updated version of LIST) timed out:

When I set the limit to <Limit ALL> with TLS enabled the user was able to list the directory, this has the downside that it also granted the user far more commands than I wanted to permit. This guided me to an issue with the limit I had set up although the limits did seem to be the right limits for my needs and worked without TLS enabled. With limit set to ALL this was the response received by Filezilla before it listed the remote directory using MLSD:

Command: PROT PResponse: 200 Protection set to Private

A bit on TLS to explain the above...TLS can be set up to allow SSL/TLS if the user opts, or you can force the user to always use SSL/TLS, and not allow them to connect if they do not use it. I choose to always enforce TLS so I instantly know if the FTP session is not encrypted because the server rejects the connection.

TLS offers two forms of encryption one method is to encrypt the control commands sent to the server whereby only communication of the commands is encrypted this is known as PROT C.

The second option is to encrypt both the control commands and the data transfers this is known as PROT P. If PROT P isn't enforced, the client could send PROT C and transfer files unencrypted. If PROT P is enforced, PROT C is rejected. I enforce PROT P since I want the data transferred to be protected from eavesdroppers.

It appeared that PROT P was my issue and that the server required PROT P to be in place and the client was sending a PROT P command but the server with the Limits defined was rejecting the PROT P security parameter.

SolutionA quick Google and this bug report suggested that PROT could be defined as a limit, this kind of made sense. With a limit of All the user would have had access to the PROT command whilst with the limit of READ and DIRS the user would not have access to the PROT command. So time to update the directories limit:

<Limit READ DIRS PROT> AllowUser TheReadOnlyLimitedUserAccount

</Limit><Limit ALL> DenyAll</Limit>

Restart the server to pick up the configuration change and reconnect with Filezilla and voila:

Command: PROT PResponse: 200 Protection set to Private

And the file list for the directory was returned with both control and data communication encrypted over TLS. I hope this helps someone it took me a few hours to figure out and documentation appears to be a little scarce on this topic unless you want to read all of RFC 2228.