chroot jails ring-fence users, files and processes. While the theory – privilege isolation for damage limitation – is singular, the practice has many techniques and uses.
Let's employ OpenSSH's advanced functionality to limit an SFTP area that can be used to share files, for example to offer a developer safe access to our web files, complete with logging, and allowing us to disable the now-redundant FTP service and close its port.
chroot is explained in the Kernel level chroot hardening section of wpCop's Setup grsecurity for Kernel Hardening.
If you're wondering why we're using SFTP, not FTP, then read the Lock Down WordPress Connections tutorials, where we also generated the authentication keys used with this method.
Assuming root …
… we swap the export value for a username, create a group to fence in this and other such SFTP users, add the user with a regular home directory (which he'll never see but which will contain a public authentication key) and add the user to both his group and the sftpusers groups. We'll also neuter the user's functionality with the /bin/false shell. If you don't want the user to use authentication keys, which is inadvisable, then create a password too:
Now for the jail and permissions. The chroot – what the user sees as / – is the chroot-sftp directory and inside we have the dev folder that we need for logging and the home directory to contain the SFTP users and their respective folders:
We need to enable logging in the isolated chroot, restart the logging service and add a logrotate entry to keep the logs at a reasonable size:
Now for the safer alternative to a password, authentication keys. We must create the folders, set some rights and add the public key – which we created in Setup SSH for Secure Server Login – into a new file:
… Add the key and save the file.
Finally, open the OpenSSH configuration file:
Look for Subsystem sftp /usr/lib/openssh/sftp-server, #comment it out and replace with Subsystem sftp internal-sftp -l VERBOSE. The edit looks like this:
Below that, add a match block to apply to all new members of the sftpusers group:
And restart the SSH service:
SFTP users need their private key, which you should provide to them to hook up with its corresponding public key, linking it with their SFTP client. To test the jail, you can also enter it, using a terminal, like this:
Or if you're using a non-standard SSH port – so not the regular port 22 – then instead swap the port with a command like this:
Bin the FTP service and firewall the port
Neither the service nor the open port are needed now. In fact they remain a liability. (Remain? Yes, FTP always was a liability which of course is why we're using SFTP. Be happy!) You could use a tool such as sysv-rc-conf to disable the FTP daemon. Then again, you'd do better to uninstall the program entirely. Neither will you want its port, 21, to remain open so add a rule to your firewall.
Providing a secure workspace
One good use for this system is to provide a user with a secure mount of some files or other. Take a WordPress developer who needs access purely to the wp-content/themes folder. Edit the value of the path to share in this export value and paste the other commands:
This ensures Apache's group ownership of the source files. Swap the group as needed:
Now create a SHARE directory in the user's file path and mount the web files there:
The user can only read the content of the share. Make an exception, a development folder owned by the user yet which the Apache group, in this scenario, can also work with:
To save you from a heart attack down the road I'm going to repeat that:
With our newly created, super-duper system, the user can download the original web files, edit them locally before uploading them to the development folder from where, due to the mount, they can be directly tested. For theme files, for example, you could use a plugin such as Theme Test Drive to swap to the development theme without affecting the live theme.
Deleting users safely
If you've mounted anything then, as is highlighted above, you must unmount before deleting the user, else it is deleted. You can check your mounts with mount -l. Then swap the user and path here:
Now you tell me, WordPress developers, if that isn't just so totally darned fine … and secure.