Block Particular Command in Linux for Specific user

I don't know how to do it with bash, but I know of another shell that restricts the user environment: lshell (limited shell).

A quick overview of configuration

Lshell is configured via an INI file. By default, it holds a whitelist of allowed commands, but it can be easily configured to prohibit user from using a specific command.

This configuration (default conf /etc/lshell.conf) prohibits user foo from using mkdir:

[foo]
allowed = 'all' - ['mkdir', 'bash', 'sh', 'csh', 'dash', 'env']

In order to configure a user account to use lshell by default, you must:

 chsh -s /usr/bin/lshell foo

Lshell can do more, like:

  • 3 levels of granularity: user, group, all.
  • Can restrict access to certain paths in the system.
  • Can restrict the use of certain characters (like |).
  • Can restrict the use of certain commands only over SSH.

And more.

Update 1# Added Test Result :

rahul:~$ which bash
/bin/bash
rahul:~$ dd if=$(which bash) of=my_bash
*** forbidden syntax: dd if=$(which bash) of=my_bash
rahul:~$ bash
*** forbidden command: bash
rahul:~$ cp /bin/bash my_bash
*** forbidden path: /bin/bash
rahul:~$ /bin/bash
*** forbidden command: /bin/bash
rahul:~$ sh
*** forbidden command: sh
rahul:~$ dash
*** forbidden command: dash
rahul:~$ env bash
*** forbidden command: env
rahul:~$ cp /bin/mkdir mycreatedir
*** forbidden path: /bin/mkdir

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 wheel group, the only one authorized to use su (enforced via PAM).
  • The user is given a properly secured rbash with a read-only PATH pointing to a private ~/bin, this ~/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 LESSSECURE, TMOUT, HISTFILE variables).

  • the user is mapped to the SELinux user staff_u and given rights to execute commands as other user as required via sudo.
  • the user's /home, /tmp and possibly /var/tmp are polyinstantiated via /etc/security/namespace.conf:

    /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
    

    Also, /etc/security/namespace.init makes all skeletal files readonly for the user and owned by root.

This way you can choose whether $USER can execute mkdir 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.


Add a dummy group, add the user to that group, chown root:somegroup /bin/mkdir, chmod g-x /bin/mkdir. Note that this relies on the user not being able to modify their groups. IIRC this is true in GNU/Linux but not in some other Unices.