How to restrict the users' shell allowing to execute shell programs
Solution 1:
Your question should be:
I don't trust my users. The dumb ones see something on the internet and try it out without understanding what it does. The devious ones like to snoop around and look at other peoples files and steal their ideas. And the lazy, don't get me started on the lazy ones.
How do I protect my system and my users from my users?
First, unix has very a very comprehensive filesystem permissions system. This seems to be a decent tutorial on unix filesystem permissions. The gist of this is that directories can be set such that a user can go into a directory and can run programs out of that directory but can't view the contents of that directory. If you do this, for example, on /home, if the user runs ls on /home, they get a permission denied error.
If you're really scared of your users and want to stick them in a supermax type of restricted environment, use something like freebsd's jails or solaris's zones -- each user gets their own tailor made environment. For added points use ZFS so you can take a snapshot of the environment when they log in so if they delete their files you can just pull them out of the snapshot.
Solution 2:
There are three things that need to be in place to fully do what you're asking for:
- A custom shell that lacks the commands you're interested in. This is a hard thing to get, but if you really truly don't want users to have access to some shell primitives, this is the only way to remove them.
- Correctly set file permissions. Don't want users to damage the system? Set the permissions so they can't damage the system even if they have the right tools. Of these three steps, this is the easiest step.
- Use a mandatory access control technoloy like AppArmor. MACs like AppArmor and SELinux embed permissions in the kernel. These prevent users from running the right tools even if they find them somewhere (and like file permissions, prevent them from using them outside of the restricted box).
Belt, suspenders, and a staple-gun for good measure. Hard to go wrong there.
AppArmor is interesting since the MAC for a specific executable is inherited by all of its children. Set a user's login to be /bin/bash-bob
, set the AppArmor profile for that specific binary right, and the only way they're getting out of that permission jail is through kernel exploits. If some lazy install script left /var/opt/vendor/tmp
global-writeable for some stupid reason, the user using /bin/bash-bob
as their shell won't be able to write there. Set the bash-bob profile to only allow writing to their home directory and /tmp
, and such permission mistakes can't be leveraged. Even if they somehow find the root password, the AppArmor profile for /bin/bash-bob
will still apply even after they su
up since su
and the bash
process it spawns are children of /bin/bash-bob
.
The hard part is building that AppArmor profile.
- Create an AppArmor profile for /bin/bash-bob and set it to audit mode
- Set Bob's login-shell to /bin/bash-bob
- Login as Bob. Do everything you want Bob to be able to do.
- Use the auditlog to build the AppArmor profile (SUSE has tools for this, not sure about other Linux distros). This is monstrously tedious, but needs to happen if you need this level of security.
- You'll be doing things like:
- Approving read access to most of the system libraries
- Approving read and execute rights to the selected few allowed system commands
- Approving write access to temp spaces
- Approving socket creation, if needed
- You'll be doing things like:
- Set the policy to enforce.
- Log in as Bob, do things.
- Make adjustments.
In my opinion, you only need steps 2 and 3, since in combination they both prevent the ability to do anything harmful outside of the carefully constructed box you set up in both those steps.
Solution 3:
Well, you can set the user's shell to a program you've written that only lets them run certain shell scripts.
Of course this would only be as secure as the program and shell scripts; in practice, this kind of restricted shell typically isn't secure against a smart attacker.
Solution 4:
Don't try and limit commands, limit file permissions. You can't practically limit people's access to syscalls, so all someone needs to do is provide their own copy of whatever "dangerous" commands you don't want them to execute, and you're stuffed.
Solution 5:
If you want the user to only be able to execute certain scripts/binaries, you can use a restricted shell. This (as the Wikipedia article mentions) isn't completely secure, but if you can guarantee that no application allowed to run is able to execute a new shell then it is a good alternative.
To setup a users restricted shell, set /bin/rbash
(or similar, most shells enter restricted mode when the binary is named r***name*) as the users shell.
Then, edit **.bashrc (or equivalent) and set $PATH
to a directory where all allowed binaries/scripts are stored.