Go to jail

Jitesoft have a couple of servers, as of now, nothing heavy is running on them, hence I could take a customer in and let them run a development page on one of the main servers.
The server is a decent dedicated server in France, it has eight cores and about 16 gigs of ram. Right now its just running a few docker containers for the jitesoft page and some other minor stuff.

Adding new users to a server is not a big thing, but one might not feel to happy about giving access to the whole system, especially not other customers or internal stuff which you might want to keep private!
I thought of a few different possible ways of doing it for the customer in question, using a VM, using Docker or just go the old fashioned way and create a jail.
A “jail” enables user to ssh in to the server and access anything that is inside of their “jailed” environment, in this case their home directory.
The server itself does not have a lot of installed packages, I always try to keep this at the minimum in case I need to move all the stuff from the server or if I have to reinstall everything.
One of the things I install is Docker. All my current web services runs in docker (with some minor exceptions) and I use a proxy to easily set up and expose the web server to the public.

Set up the jail

note: I recommend checking the man-pages for all commands and make sure that you are doing the right thing instead of blindly following a walkthrough like this.

It’s not really necessary to install extra software to jail users, but to make it as easy as possible I decided to use the jailkit software. Jailkit is a set of scripts to set up and maintain a jail and jailed users, only exposing software and file system that one wish to expose.

Installation of jailkit is quite easy. The files are hosted on the jailkit site, easiest is to just fetch it with wget, curl or something similar. After untaring the file the binaries have to be built, this requires a few extra packages (build-essentials, autoconf, automake possibly others too, let me know in comments!).
When built, just install the deb file and its ready!

mkdir /tmp/jailkit && cd /tmp/jailkit
wget https://olivier.sessink.nl/jailkit/jailkit-2.19.tar.gz
tar -xzf jailkit-2.19.tar.gz
cd jailkit-2.19
sudo ./debian rules binary
sudo dpkg -i ../jailkit_2.19_am64.deb
cd /tmp && rm -r jailkit

Then the jail has to be set up!

# Create the directory and chown it to the root user.
mkdir /home/jail
sudo chown root:root /home/jail
# Letting the root own the jail is important, so that the users can't
# access stuff you do not wish them to access!
# Also make sure that the root foler is not write-able by users but root.
sudo chmod 0755 /home/jail

The users will most likely need a bunch of software, and the jailkit software enables a easy way to let them access a few applications right away. By using jk_init I decided to enable the following software:

sudo jk_init -j /home/jail basicshell editors extendedshell ssh sftp jk_lsh git
# -j Jail directory to use. 

After initialization of the apps the user/s are created the good ol’ linux way and jailed them with the jk_jailuser command:

sudo adduser customer
sudo jk_jailuser -m -j /home/jail customer
# -m Move users home directory inside the jail.
# -j Jail directory to use.

This moves the home folder of the user to the jailed environment.
Now, I personally feel that bash is quite a useful lil thing, so my users should be able to access it just as I would want.
In the /home/jail/etc/passwd file we should be able to find the jailed users pwd entry at the end somewhere, it will currently be set to use the /usr/sbin/jk_lsh shell, which is easily changed to bash by changing the end of the line from :/usr/bin/jk_lsh to /bin/bash.

None of my servers allow password login, so a public ssh key should be added to the /home/jail/home/customer/.ssh/authorized_keys file. This I will not go through cause if you do not know how to do this, I don’t think its a good idea to go on with this!

To make it possible to access git repositories and other stuff like that from the jail one can easily add the ssh-keygen command to the jail with the jk_cp command:

sudo jk_cp -j /home/jail ssh-keygen
# -j Jail directory to use.

The jk_cp command adds the ssh-keygen command to the jail and makes it possible for the user to use it, great!

Now the user will be able to access their home directory and create ssh keys, use basic console commands and stuff like that. But if they want to run a site on the server? Well, here is where docker comes in.

Set up the services

In this customers case, all they needed was a wordpress site, so I decided that a few docker containers running nginx, fpm and mysql would do the trick. It’s usually not recommended to run the database (especially not its file system) in a container, but in the case of a development site I feel that its good enough.
I use docker-compose to set up a simple structure for the containers and to easily start and stop them all.
The compose file looks something like this:

version: '2'
services:

  # Data container for the nginx and fpm services.
  data:
    image: busybox
    volumes:
      - "/home/jail/home/customer:/src"
      - "./nginx:/etc/nginx/conf.d:ro"

  nginx:
    image: nginx
    mem_limit: 512m
    volumes_from:
      - data

  fpm:
    image: jitesoft/php-fpm:7.1
    mem_limit: 256m
    working_dir: "/src"
    volumes_from:
      - data

  mysql:
    env_file: .env
    image: mysql
    mem_limit: 256m
    volumes:
      - "dbdata:/var/lib/mysql"

volumes:
  dbdata:
    driver: local

The mysql db uses a .env file for the environment variables, check the mysql docker container to know which are required!

Next on the list is to set up the nginx configuration, a simple conf is all that is needed, especially since a proxy is used which will set up all the extra needed stuff!

upstream phpfpm_backend {
    server fpm:9000;
}

server {
    listen      80;
    listen [::]:80;

    server_name customername.jitesoft.eu;

    root /src/public_html;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
      fastcgi_param HTTPS on;
      fastcgi_pass  phpfpm_backend;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      include       fastcgi_params;
    }
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        log_not_found off;
    }

    location ~ /\.(ht|svn|git) {
        deny all;
    }

    location ~ /\. {
        deny all;
    }

    location ~* /(?:uploads|files)/.*\.php$ {
        deny all;
    }
}

I set up the root dir for the nginx container to be in /src/public_html, that means that the only thing that the server will serve is the data inside the public_html directory in the users home directory, but the fpm container will still be able to access anything within the users “home” directory.

The containers are started with docker-compose up -d and everything is ready for use!

Last words

This is the first time I jail a user, I love testing new stuff when it comes to devops, but it’s always a lil bit scary!
Hopefully I succeeded in following the best practices for good security, but if you notice any issues, please let me know!

Updated: