Root privileges allow you to do many things on a virtual private or dedicate server. However, there are times when you want to grant access to some users you don’t trust. Then it makes sense to create chroot-ed environment. Another reason for making chroot environment is selling off resources on dedicated servers, effectively turning it into “shared”. Chroot can be achieved by using special utilities like Jailkit. Another approach to do the same is via virtualization.
Install JailKit
JailKit is not available with standard repositories. You have to install it manually.
Fetch the source files from download page. Then refer to our tutorial on compiling software in Linux to install it.
Alternatively, use these sample commands to install the latest version as of this writing:
cd /usr/local/src
wget http://olivier.sessink.nl/jailkit/jailkit-2.19.tar.gz
tar zxvf jailkit-2.19.tar.gz
cd jailkit-2.19
./configure && make && make install
rm -rf /usr/local/src/jailkit-2.19.tar.gz
Jailkit Chroot
This is variation of the tutorial available at JailKit website with a few changes:
# create and initialize jail
mkdir -p /opt/jails/username
chown root:root /opt/jails/username
jk_init -v -j /opt/jails/username basicshell editors extendedshell netutils ssh sftp scp jk_lsh
# make tmp directory inside jail
mkdir /opt/jails/username/tmp
chmod a+rwx /opt/jails/username/tmp
Setup current SSH user into jail
Stop all the processes that are owned by user that will be jailed, i.e. stop PHP-FPM pools owned by jailed user.
jk_jailuser -m -j /opt/jails/username username
Edit /opt/jails/username/etc/passwd and adjust the shell to be /bin/bash, like so:
username:x:1016:1016::/home/username:/bin/bash
Now we need to allow the user to execute the scp and sftp programs. Edit the /opt/jails/username/etc/jailkit/jk_lsh.ini file and add in some lines like so:
[username]
paths= /usr/bin, /usr/lib/
executables= /usr/bin/scp, /usr/lib/sftp-server, /usr/lib/openssh/sftp-server, /usr/libexec/sftp-server
Copy programs into jail
The created jail environment is limited to a few basic programs that we specificed during initialization. You can copy binaries into the jail environment using jk_cp command. Let’s demonstrate how to use it. We will copy groups program into the jail.
sudo jk_cp /opt/jails/username /usr/bin/groups
This will also solve a warning that you might get when SSH login with the jailed user.
Copy PHP inside jail
Often times user wants to SSH into their account and run some PHP scripts. We have to add all the binaries into their environment by making a copy.
This command will copy currently installed PHP into a jail:
sudo jk_cp /opt/jails/username /usr/bin/php
If you need, copy all other wanted binaries via similar command:
sudo jk_cp /opt/jails/username /path/to/command
Make all PHP extensions available in jail environment
These are example commands for Ubuntu. You have to copy all the .ini files and all library files where extensions are located:
sudo jk_cp /opt/jails/username /etc/php5
jk_cp /opt/jails/username /usr/lib/php5
Put MySQL socket file into Jail
Finally, you may want to add MySQL socket file over to the jail. Since it is created dynamically, you have to make use of rc.local startup file and wait for MySQL server to start:
nano /etc/rc.local
put the following lines:
sleep 60
mkdir -p /opt/jails/username/var/run/mysqld
mount --bind /var/run/mysqld /opt/jails/username/var/run/mysqld
Save the file and make sure rc.local is executable by running chmod +x /etc/rc.local
Make timezone definitions available to PHP inside chroot
This will create symlinks to timezone definitions inside jails:
jk_cp -k -j /opt/jails/username /usr/share/zoneinfo
Update PHP in jail environment
jk_update -j /opt/jails/username
Make ps and expr available inside chroot
sudo jk_cp /opt/jails/username /bin/ps
sudo jk_cp /opt/jails/username /usr/bin/expr
mkdir /opt/jails/username/proc
mount -t proc proc /opt/jails/username/proc
Give the jailed user access to some site files
Suppose that we are running a site with proper setup: it has a dedicated site user on the system, Apache (or Nginx) is member of the site user’s group. Thus the web server can read the site files. Everything is perfect.
Now we want to share the access to the site but we don’t want to do it directly for some reason, or we want them to access just a single directory of the site. Common example here would be having a WordPress site, and we want to grant a developer access to edit theme files only.
For that, we can use our jailed user and bind the site directory into jail. The jailed user will be able to see the site directory and it will be mounted as if they are the owner of the files. Let’s do it.
sudo apt-get install bindfs # this will install required kernel modules
mkdir /opt/jails/username/home/username/themename # create the directory inside jailed user's home
sudo bindfs -u username -g username --create-for-user=siteuser --create-for-group=siteuser --create-with-perms=777 /var/www/html/wp-content/themes/themename /opt/jails/username/home/username/themename
Now the jailed user can connect via SFTP and edit the live site theme files. They will not be able to edit anything else on the site.