vsftpd with chroot_local_user requires client certificate

When setting up my FTPS server I want to enable chroot_local_user. When disabled everything works fine. If I enable this however, WinSCP fails to connect and claims I need a client certificate to connect. Filezilla fails outright.

If I explicitly set require_cert to NO (even if it is default), this issue still persists.

How can I solve this?

An alternative solution that limits users to their home folder would also be acceptable.

Thanks


Solution 1:

The WinSCP error message is probably wrong (or mere speculation). When I tried to set up vsftpd with chroot_local_user a while ago I found out that vsftpd will reject logins (for security reasons) if the user has write permissions in the chroot directory. This is a little hidden in the vsftpd FAQ:

Q) Help! I'm getting the error message "refusing to run with writable root".

A) vsftpd is protecting against dangerous configurations. The cause of this message is usually dodgy ownership of the ftp home directory. The home directory should NOT be owned by the ftp user itself. Neither should it be writable by the ftp user. A way to fix this is:

chown root ~ftp; chmod -w ~ftp

Another cause might be an attempt to use chroot_local_user without setting up the directory ownership properly.

To debug this, add log_die=YES to your vsftpd.conf. The log will then show something like this:

Nov 29 16:08:55 yourhost vsftpd[2866]: pam_userdb(vsftpd:auth): user 'testuser' granted access
Nov 29 16:08:55 yourhost vsftpd[2872]: ERROR: vsftpd: refusing to run with writable root inside chroot()

This is not a problem for read-only access, but if your users should be able to upload files, you have to create a folder in the chroot dir which is owned by the respective user. If you want to provide ftps access to your users' home directories, it gets a little cumbersome. You probably have to insert an additional hierarchy level, i.e. /home/someuser becomes /home/someuser/someuser.

For quick testing, I found that curl is quite handy, e.g. to test an upload:

curl -T /tmp/blub -u testuser:testpass ftps://yourserver.example.com/in/