I have many hobbies I dabble in, one of them is vintage computers, and the other is vintage phones. I have an Asterisk server with a special card that connect to some of my vintage phone gear. I also have vintage computers that I could use to play with modems and act as a phone company of sorts. Of course Asterisk is digital and that introduces some problems, but that’s another story for another article far far away. I have a server set up as a dial-in server (as in I can dial the server’s modem extension as it is connected to one of the ports of that special card mentioned earlier). I wanted to make a dial in server that can serve DOS and CP/M files, but not in a BBS form as I didn’t want or need the complexity of a full BBS system. Sure, there are a few downsides like someone could hang on the line forever if they wanted to. Being that this sort of thing is becoming more and more obscure, I’m not too worried about that. I am however worried about making it public and having someone come in and mess with and break the system. After some research I found some interesting software called jailkit. This does exactly what I needed. This is also useful for creating very restricted users on servers for other projects.

For example, my dial in user only has access to the XMODEM and ZMODEM commands that you can install in Linux, and CD to change directories. The jailed user can’t do anything else except change directories around in the jail itself, and transfer files the old fashioned way. Now, my usage case is pretty extreme (and probably a bit weird), but it’s a good example of how locked down you can get.

Before I begin, a huge thanks goes out to “gs69azza” and his forum post here. Most instructions I found on Google don’t work for the newer versions of Ubuntu. There was always something weird that would stop me in my tracks.

cd /tmp
wget http://olivier.sessink.nl/jailkit/jailkit-2.17.tar.gz
tar xvfz jailkit-2.17.tar.gz
cd jailkit-2.17

Now, compile and install:

./configure
sudo make
sudo make install


Next, make a jail. You can really put it anywhere you would like but do not put it in /home. This will confuse yourself and jailkit.

sudo jk_init -v -j /jail ssh

Next create the new home directory environment for users:

sudo mkdir /jail/home


Create a group in the jail to link the users that will be made to a “users” group. Create /jail/etc/group and add this line:

users:x:100:

After that, we need to create a jail user in etc/password so we can define the shell to log in to. This example uses “jailuser”, but of course you can name it whatever you would like. This is the first place you must edit when creating a new user for the jail. Edit /etc/password and add the user as below:

jailuser:x:2000:100::/jail/./home/jailuser:/usr/sbin/jk_chrootsh

Now, create the same user you created above in the jail itself. Create /jail/etc/passwd and add the following:

jailuser:x:2000:100::/home/jailuser:/bin/bash

Now that that is done, we need to edit the shadow to include the new user. Edit /etc/shadow and add:

jailuser::11302:0:99999:7:::

Of course, change jailuser to whatever user name you would like.

Next is to change the password of the new user:

sudo passwd jailuser

Now that the shadow file has been updated, copy the shadow files so that the jail is synced with the system:

sudo jk_cp -v -f /jail /etc/shadow
sudo jk_cp -v -f /jail /etc/shadow-

Next create the new user’s home directory:

sudo mkdir jailuser
sudo chown 2000:100 jailuser

Now we will need to copy over commands that you will want your users to use in this jail. The post linked above has a much bigger list, but here are some examples for some basics:

sudo jk_cp -v -f /jail /bin/bash
sudo jk_cp -v -f /jail /bin/ls

Note: bash is required, but don’t worry, they can’t use the chroot trick to break out of the jail with the bash command. ls is optional.

Keep issuing similar commands to copy over the software you want the jailed user to run. For example, If you want them to edit files, you have to copy over an editor. The jk_cp script also copies over the libraries needed to run the programs. There are a couple special cases:

(optional) Create /proc in jail for ps to work:

cd /jail/
sudo mkdir proc
sudo mount -t proc none /jail/proc

(optional) Set permissions for sudo to work:

sudo chown root:root /jail/usr/bin/sudo
sudo chmod 4755 /jail/usr/bin/sudo
sudo chmod u+s /jail/usr/bin/passwd


That’s it! Now log in as that user and make sure everything works. Check out /var/log/auth.log if you are having any issues. For example, I had an extra space character after the shell path in /etc/passwd which was preventing log in.

There are many things you can do with this setup. For example, I created a .bashrc for my user (as root so that the user couldn’t edit it), and added the following lines to hide more of the system, and enable a “help” command which is a very simple script I created that just tells the user what they actually can do. It also customizes the command prompt they get.

shopt -s checkwinsize
shopt -u mailwarn
unset MAILCHECK
alias help='/bin/help'
PS1="\u@\W> "

Note: The “help” script is actually in /jail/bin/help. For things that are sitting inside the jail, the paths are as if /jail was the root. The help script also overrides the standard “help” command.

Also, to remove more system identification (and for other reasons), I completely disabled the standard MOTD system wide.

If you don’t want to do it system wide however, and want to disable the messages for the user, create .hushlogin in their home directory:

sudo touch .hushlogin

Finally, my last requirement was to be able to serve DOS and CP/M files so that it is possible to xmodem them over (great for recovering an old system). Of course, it would be silly to duplicate the files over just for the jailed user. However, you can’t directly mount an NFS share to the user jail either, but you CAN do a bind mount! I use autofs to automatically mount my NFS file server to a directory in /mnt on the dial in server. Then I use a bind mount in fstab to make the directories I want available to the jailed user. Here is an example of an entry in fstab that makes this possible:

/mnt/fileserv/data/Software/CPM /jail/home/jailuser/cpm     none    bind,_netdev    0       0

Note: _netdev is super important in this line, don’t forget it! If you don’t have fstab wait for the network to become available, and you reboot the machine, it will hang trying to mount those directories (ask me how I know!).

Note 2: Don’t forget to make the directories to mount to (e.x. /jail/home/jailuser/cpm).

You can go pretty far down the jailed user rabbit hole. The jailkit homepage has lots of great documentation for doing more with it.