💾 Archived View for altesq.net › ~evenfire › posts › using-chroots.gmi captured on 2023-07-10 at 13:25:36. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
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.
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
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.
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.
[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.
[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!
[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.
[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.
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].