Is it possible to prevent any user to not use commands like ls, rm and other system commands which could harm the system. But the users should be able to execute shell programs.
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.
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
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.
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.
Yes, it's possible, but in practice it would take a lot of work and planning. You can create scripts and have them run as a privileged use, then remove all privileges from the user in question. Or, you can set the user's shell to something of your own making that lets them do only what you explicitly allow.
However, standard permissions in linux make it nearly impossible for a normal user to "harm the system". What sort of harm are you trying to prevent? It's trivial to prevent users from being able to install software or run programs outside of their home directory, and you can use chroot to lock down the system even further.
You may want to try [lshell] (limited shell).
lshell is a shell coded in Python, that lets you restrict a user's environment to limited sets of commands, choose to enable/disable any command over SSH (e.g. SCP, SFTP, rsync, etc.), log user's commands, implement timing restriction, and more.
: http://lshell.ghantoos.org/Overview lshell
The way I usually implement this kind of restrictions requires that several conditions are met, otherwise the restriction can be easily circumvented:
- The user does not belong to the
wheelgroup, the only one authorized to use
su(enforced via PAM).
The user is given a properly secured
rbashwith a read-only
PATHpointing to a private
~/bin/directory contains links to simple utilities:
$ ll ~/bin total 0 lrwxrwxrwx. 1 root dawud 14 Sep 17 08:58 clear -> /usr/bin/clear* lrwxrwxrwx. 1 root dawud 7 Sep 17 08:58 df -> /bin/df* lrwxrwxrwx. 1 root dawud 10 Sep 17 08:58 egrep -> /bin/egrep* lrwxrwxrwx. 1 root dawud 8 Sep 17 08:58 env -> /bin/env* lrwxrwxrwx. 1 root dawud 10 Sep 17 08:58 fgrep -> /bin/fgrep* lrwxrwxrwx. 1 root dawud 9 Sep 17 08:58 grep -> /bin/grep* lrwxrwxrwx. 1 root dawud 10 Sep 17 08:58 rview -> /bin/rview* lrwxrwxrwx. 1 root dawud 13 Sep 17 08:58 rvim -> /usr/bin/rvim* lrwxrwxrwx. 1 root dawud 13 Sep 17 08:58 sudo -> /usr/bin/sudo* lrwxrwxrwx. 1 root dawud 17 Sep 17 08:58 sudoedit -> /usr/bin/sudoedit* lrwxrwxrwx. 1 root dawud 13 Sep 17 08:58 tail -> /usr/bin/tail* lrwxrwxrwx. 1 root dawud 11 Sep 17 08:58 wc -> /usr/bin/wc*
the user is given a restricted, read-only environment (think of stuff like
- the user is mapped to the SELinux user
staff_uand given rights to execute commands as other user as required via
/var/tmpare polyinstantiated via
/tmp /tmp/.inst/tmp.inst-$USER- tmpdir:create root /var/tmp /tmp/.inst/var-tmp.inst-$USER- tmpdir:create root $HOME $HOME/$USER.inst/ tmpdir:create root
/etc/security/namespace.initmakes all skeletal files readonly for the user and owned by
This way you can choose whether
$USER can execute any command on his/her own behalf (via a link in the private
~/bin directory, provisioned via
/etc/skel, as explained above), on behalf of other user (via
sudo) or none at all.