Best practice for WordPress, direct auto updates and SFTP access for users

I'm trying to set up a secure WordPress site on a Debian 8 system with the following requirements:

  • automatic core updates (FS_method "direct")
  • chrooted SFTP access to /wp-content (for a single user)

I'm sure this a pretty standard setup. Still, I can't find a tutorial how this fits together.

First, to make automatic core updates with FS_method "direct" work, mostly all of WordPress has to be owned by www-data, i.e.:

chown -R www-data.www-data /var/www/wordpress

Furthermore, I have a local account "sftp-wordpress" which I put into the group "www-data".

I made wp-content and everything inside group-writable (group is www-data, see above), so sftp-wordpress is able to write, and - to be on the safe side- I made "wp-content" and its subdirectories setgid:

chmod -R g+w /var/www/wordpress/wp-content
find /var/www/wordpress/wp-content -type d -exec chmod g+s {} \;

First problem: To setup the chroot, I put the following in /etc/ssh/sshd_config:

Match User sftp_wordpress
    ChrootDirectory /var/www/wordpress/wp-content
    ForceCommand internal-sftp -u 0002
    AllowTcpForwarding no

This won't work, since OpenSSH doesn't like the permissions and the owner of the ChrootDirectory:

fatal: bad ownership or modes for chroot directory "/var/www/wordpress/wp-content"

So I took out the chroot requirement for now, by disabling the ChrootDirectory directive.

At this point, I'm able to upload files into wp-content. The files will show up with owner "sftp-wordpress" (that might be a problem for the WordPress update?) and group "www-data".

What is definitely another problem is that uploaded files and directories are not group-writable, so that the Apache process won't be able to modify them. And this is a problem if WordPress wants to modify them.

The "umask 0002" won't help, since (unlike other questions here say) it won't enforce group-write permission.

In fact uploaded files will be group-writable on the server, if they were group-writable on the client - that's far from a solution, since you can't expect that SFTP will fix this on their side.

I'd like to hear if there is a consistent solution for this setup of WordPress.


Solution 1:

The chroot directory needs to be owned by root in order for openssh to accept it, it's for security purposes.

For further explanation see: bad ownership or modes for chroot directory component

ChrootDirectory
Specifies the pathname of a directory to chroot(2) to after authentication. All components of the pathname must be root-owned directories that are not writable by any other user or group. After the chroot, sshd(8) changes the working directory to the user's home directory.

I think a solution could be to separate the upload location from where it will be viewable by wordpress.

You could create kind of a staging area where the user can upload files through the openssh sftp server in a chrooted location. Then your system has a cronjob which runs a script at regular intervals which will check the upload location and does whatever is appropriate with the uploaded files.

It could just send an email asking for human intervention, or it does some automated file checking, virus scans, whatever you think may be worthwhile. Then copy or move the file to the location where wordpress can handle it.

I think there is not really a consistent solution as many situations are quite unique. But using a staging area for uploaded files is not uncommon for many purposes. And it adds a level of security.