💾 Archived View for altesq.net › ~evenfire › posts › using-chroots.gmi captured on 2023-01-29 at 02:55:23. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

Using chroots

Alright, because I do not want to see anyone's server getting exploited or anything in that category, please run your scripts in chroot! I will use Josia's SSH notes as an example here, as my own version is not yet quite done, lots of improvements to make. This will be a step-by-step guide on how to fully securely deploy it in a chroot.

If a command is prefixed by "[root@altesq]" it means you must run it as root, if it prefixed by "[evenfire@altesq]" you must run it as a normal user. The root user is only used for representation purposes, you should run the root commands with sudo, doas or any alternative.

Making the user

First off, make a user that you can call whatever you want, I will use "pm" here, as in private message.

[root@altesq] useradd -m pm

Then we have to clear its password so people can SSH into it without having authorization.

[root@altesq] passwd -d pm

Configuring SSH

Now, in your SSH config, which most likely is in /etc/ssh/sshd_config, go to the bottom and add the following.

/etc/ssh/sshd_config
--------------------
[...]
Match User pm
    PasswordAuthentication yes
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no
    PermitEmptyPasswords yes
    ForceCommand bash ./bin/write-note
    ChrootDirectory %h

This sets various secure variables for our pm user, including restricting it to our to-be-made chroot, which will reside in the user's home folder.

Making our chroot

Now it is time to make the chroot itself. I assume you are on amd64.

[evenfire@altesq ~/] cd /home/pm
[root@altesq /home/pm] mkdir {bin,usr,usr/lib64,usr/lib}
[root@altesq /home/pm] ln -s ./usr/lib .
[root@altesq /home/pm] ln -s ./usr/lib64 .

This makes some rudimentary directories and symlinks them. Let me explain: our chroot, which is a "new root", is a fully separated file system from the host one. Devices, networking stack etc. are not separated. Now, what a program needs to run are the binary itself and various libraries, thus we need lib64 and lib. Playing around various times, I have discovered that without symlinking them, or just making lib64 and lib with no ./usr directory, bash did not work, this is why they must be symlinks.

Your to-be chroot should look like this, where lib and lib64 are symlinks:

[root@altesq /home/pm] ls
drwxr-xr-x 1 root root  0 Aug 20 07:28 bin
lrwxrwxrwx 1 root root  7 Aug 20 07:31 lib -> usr/lib
lrwxrwxrwx 1 root root  9 Aug 20 07:31 lib64 -> usr/lib64
drwxr-xr-x 1 root root 16 Aug 20 07:28 usr

Now that you have got the layout out of the way, you can start putting programs. We will start with Bash.

Programs in our chroot

[root@altesq /home/pm] cp /bin/bash bin/

Now we need to check what libraries Bash needs in order to run.

[evenfire@altesq /home/pm] ldd /bin/bash

linux-vdso.so.1 => linux-vdso.so.1
libreadline.so.8 => /usr/lib/libreadline.so.8
libdl.so.2 => /usr/lib/libdl.so.2
libc.so.6 => /usr/lib/libc.so.6
libncursesw.so.6 => /usr/lib/libncursesw.so.6
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2

These are all the libraries Bash needs in order to run. So let us go ahead and get them, putting them in their respective directories.

[root@altesq /home/pm] cp /usr/lib/libreadline.so.8 lib/
[root@altesq /home/pm] cp /usr/lib/libdl.so.2 lib/
[root@altesq /home/pm] cp /usr/lib/libc.so.6 lib/
[root@altesq /home/pm] cp /usr/lib/libncursesw.so.6 lib/
[root@altesq /home/pm] cp /usr/lib64/ld-linux-x86_64.so.2 lib64/

Now we have a fully functional Bash in our chroot, but we also need the "date" command, as it is present in the script.

[root@altesq /home/pm] cp /bin/date bin/
[evenfire@altesq /home/pm] ldd /bin/date

linux-vdso.so.1 => linux-vdso.so.1 (0x00007fff7e3fc000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f0c7e98d000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2

We can see that we already have date's libraries. Now we need to set up a few permissions.

Permissions

[evenfire@altesq /home/pm] cd /home/
[root@altesq /home] chown -R pm:pm /home/pm
[root@altesq /home] chown root:root /home/pm

What the above did is: change into your home directory, change recursively all the permissions in your chroot to be pm's, then change only the root directory's ownership to be root's. The root folder must be owned by root so SSH can deploy a chroot there.

Before you deploy it, try it yourself!

Trying out the chroot

[root@altesq /home] chroot /home/pm/

You should be dropped in a Bash shell. As you can see, there is no ls or any other command other than date. We must add our script to be here, exit the chroot now. We will copy the write-note script.

Chrooted script

[chroot@altesq /] exit
[root@altesq /home/pm] cp ~/Downloads/write-note.sh /home/pm/bin/write-note
[root@altesq /home/pm] chown pm:pm /home/pm/bin/write-note

Now enter the chroot again and you should be able to execute the write-note script. Et voila! This is it, a fully chrooted note environment. Because of the SSH configuration we set up earlier, you can now SSH, assuming you have port 22 forwarded, at pm@example.com

I highly suggest that if you plan to host SSH notes, or you are already hosting, to chroot the script. This will stop an eventual attacker on accessing your whole filesystem. Obviously, you can tailor a chroot for anything. Will give you added security benefits.

Troubleshooting

While testing out the guide, I encountered a few problems, the fixes are below.

If you encounter any problems, you can ask on The Camplog[1].

The Camplog

Home