How to limit user commands in Linux [closed]
Asked Answered
C

6

33

I have a user in a group: "demo".

I want to set the policy that this user can run only 10 commands, like vim, nano, cd, etc.

Or, set the policy to have access on all commands except ssh and cat commands.

Cinematography answered 1/2, 2014 at 13:32 Comment(6)
man rbash might be useful.Juta
you are root.ok.put all commands in /bin/bash . then set permissions for each user to specific commands by chowm and chmod...ok?Betterment
@MortezaLSC : this is not good action! I don't want to change bin files directory or permissions of them. it will make problem for system. I'm looking for correct way to restricting some users accesses.Cinematography
you could just write chown user:group /bin/ls || chown user2:group2 /bin/mv and so on...Betterment
I wanna set the policy that this users just can run 10 commands, like "vim","nano","cd" and etc. vim can be used to launch arbitrary commands. access.redhat.com/solutions/65822#comment-1221022Cronk
@MaxBarraclough If you are looking to restrict the commands of editors, there is a flag you can pass to the editor that prevents it from executing arbitrary commands. In the case of vim/vi that is vi -Z. It is part of my answer. You just need to make sure that the command alias is vi -Z and not just vi. For other editors look up their documentation for how to disable arbitrary command execution.Multimillionaire
M
32

There are lots of different ways that you could achieve this. I'm going to list one of several possible solutions.

I would propose using several different layers of protection to prevent users from running the commands that they shouldn't be allowed to access. All of the directions here assume that users have their own /home/[username] directory, that their shell is /bin/bash, and that you would like them to use the bash shell when they log in to the system.

  1. Change the user's bash to restricted bash mode so that they can't change directories (if you don't have a restricted bash mode on your system, this link will help and give you more information) chsh -s /bin/rbash [username]

  2. Change directory permissions so that only the user can edit the contents of their home directory

chmod 755 /home/[username]

  1. Remove the user's .bashrc file

rm /home/[username]/.bashrc This site has more information as to why it might be a good idea to delete the .bashrc in this situation.

  1. Create a .bash_profile and add "safe" aliases for all the commands that you would like to disable

./bash_profile file example

alias apt-get="printf ''"  
alias aptitude="printf ''"  
[...]  
alias vi="vi -Z" #this is vi's safe mode and shell commands won't be run from within vi
alias alias="printf ''"  

A please check the full list of bash commands for more information. You must make sure that the alias alias="printf ''" command is the last command on the list otherwise you lose your ability to alias all of those commands.

Note Running the commands below will search for almost all the commands available on your system and output a ready made file will almost all available commands pre-aliased. The [ command is the test command in bash. So if you see that in the file, it is not an error.

#search /bin and /usr/bin for any commands that exist on our system
ls /bin -1 > commands_on_system.txt && ls /usr/bin -1 >> commands_on_system.txt

#format and save this information to a bash variable
IFS=$'\n' GLOBIGNORE='*' command eval  'COMMANDS_ON_SYSTEM=($(cat ./commands_on_system.txt))'
IFS=$'\n' COMMANDS_ON_SYSTEM=($(sort <<<"${COMMANDS_ON_SYSTEM[*]}"))
unset IFS

#save these commands in aliased format for easy usage
for linux_command in "${COMMANDS_ON_SYSTEM[@]}"
do :
   #you can change how this works to automatically
   #setup the command file for you 
   echo "alias ${linux_command}=\"printf ''\"" >> ./startup_functions_for_beginners.sh
done
  1. Disable shell commands in vi by aliasing the vi command to restricted mode
    The syntax is alias vi="vi -Z", but please see this site for more information.

  2. Change the ownership of the user's .bash_profile to root
    chown root:root /home/[username]/.bash_profile

  3. Finally, remove write permissions on the user's .bash_profile
    chmod 755 /home/[username/.bash_profile]

Now when the users log in they won't be able to change directories, all of the commands that you don't want them to use will output the same information as if the user pressed the [ENTER] key with no command specified, and your /bin/bash functions stay intact.

Depending on what functions you choose to or not to alias this way, users may still be able to circumvent some of the controls that you implemented. However, since we implemented a few safety buffers, the user would really have to know about computer systems to do any dangerous.

On a related note and something that you might want to consider, if you directly place these aliases into each and every users' .bash_profile you would have difficulty maintaining which functions should and shouldn't be aliased, and if you need to change the alias on anything you would have to change all of them individually. Also, since users can use vim or vi to view files, they could see the contents of their .bash_profile and understand what restrictions they have and don't have.

To get around this I would suggest.

  1. Putting all of the aliases in a directory not accessible by the users (paste the contents of the .bash_profile here)

/[path_to_file]/startup_functions_for_beginners.sh

  1. Sourcing the aliases into their .bash_profile

improved ./bash_profile file example

if [[ -f /[path_to_file]/startup_functions_for_beginners.sh ]]; then
    . /[path_to_file]/startup_functions_for_beginners.sh
fi

This should put you on your way, but remember that there are almost always ways to circumvent restrictions.

Also, feel free to remix the information in this answer to suit your needs. These can most definitely be combined with a number of other restrictions as well.

Q: I need users to have access to fg and bg, but I don't want them to be able to access aptitude or bash

alias apt-get="printf ''"  #the user won't be able to run this  
alias aptitude="printf ''"  #the user won't be able to run this  
alias bash="printf ''"  #the user won't be able to run this  
#alias fg="printf ''" #this will run as a bash built-in  
#alias bg="printf ''" #you actually don't need to include these in your script  

List of common commands as per this Harvard Website (NOT EXHAUSTIVE)

As you install programs to Linux what you have available to you changes. I suggest that you run the commands listed above in step 4 to help find new commands after they have been installed.

caution should be taken care of with editors because some allow for the excution of shell commands from within the program

nano
emacs
pico
sed
vi
vim  

Everything Else

exit
logout
passwd
rlogin
ssh
slogin
yppasswd
mail
mesg
pine
talk
write
as
awk
bc
cc
csh
dbx
f77
gdb
gprof
kill
ld
lex
lint
make
maple
math
nice
nohup
pc
perl
prof
python
sh
yacc
xcalc
apropos
find
info
man
whatis
whereis
cd
chmod
chown
chgrp
cmp
comm
cp
crypt
diff
file
grep
gzip
ln
ls
lsof
mkdir
mv
pwd
quota
rm
rmdir
stat
sync
sort
tar
tee
tr
umask
uncompress
uniq
wc
cat
fold
head
lpq
lpr
lprm
more
less
page
pr
tail
zcat
xv
gv
xpdf
ftp
rsync
scp
alias
chquota
chsh
clear
echo
pbm
popd
pushd
script
setenv
stty
netstat
rsh
ssh
bg
fg
jobs
^y
^z
clock
date
df
du
env
finger
history
last
lpq
manpath
printenv
ps
pwd
set
spend
stty
time
top
uptime
w
who
whois
whoami
gimp
xfig
xv
xvscan
xpaint
kpaint
mplayer
realplay
timidity
xmms
abiword
addbib
col
diction
diffmk
dvips
explain
grap
hyphen
ispell
latex
pdfelatex
latex2html
lookbib
macref
ndx
neqn
nroff
pic
psdit
ptx
refer
roffbib
sortbib
spell
ispell
style
tbl
tex
tpic
wget
grabmode
import
xdpyinfo
xkill
xlock
xterm
xwininfo
html2ps
latex2html
lynx
netscape
sitecopy
weblint
Multimillionaire answered 8/2, 2014 at 17:33 Comment(11)
Is there any way to add just some commands accessible to user? for example a user who can access just 'cat' and 'vi' commands. with alias I should define all of commands. I need just add some commands accessible or not for some groups.Cinematography
You don't have to alias all the commands. You just need to alias the commands that you don't want users to use or the commands that need a safe mode. I'll add a small example list and add it to my answer for you so that you get an idea of what you could do.Multimillionaire
By the way, where is the list?Eared
I included a list of "common" commands.Multimillionaire
Apparently, I included a link to a list of commands in my original post. So posting the list was superfluous. The \bash problem is also answered in a link that I included in the original post Restricted Shell Reference.Multimillionaire
This is a terrible suggestion, for a bunch of reasons. First off, it's on the wrong site (should be on sec SE). Second, it's not a whitelisting approach. Third, it's passing everything the user types into a fully-featured Turing-complete and unrestricted interpreter which just begs for weird machines, but fourth (and mainly) because it's so damned easy to circumvent.Neurology
Just off the top of my head, a user could simply script sending a bunch of ^Z or ^C characters to the client right after entering the password to completely abridge any efforts made in the bashrc. Then, of course, they could spawn a subshell, which wouldn't have the aliases defined. Or they could give the full path to the executable they wanted to run. Et cetera. I came up with those three ideas in the thirty seconds it took me to read your post; imagine what someone with serious computer security knowledge who cared to take an interest could do.Neurology
This is worse than no security at all, because it gives the illusion of security; it makes the OP feel comfortable and complacent without protecting them at all. It's like they've asked you how to fight, and you've told them "close your eyes when you see someone's about to punch you in the face, and because you don't expect it, it's like you won't be punched at all".Neurology
@ParthianShot If the question is on the wrong site then it should be migrated. Next, just like the highest voted answer below, I also suggested using restricted shell. In fact, I suggested using all of the alias methods above IN ADDITION to using restricted shell. This is not just a list of aliases, it is aliases on top of rbash. Not just the .bashrc, but rbash. The user that was created has their default login shell set to rbash. I will setup an environment and see if the ^Z and ^C allow me to elevate rbash to regular bash.Multimillionaire
@ParthianShot I also made a suggestion to alias vim to a restricted version of VI. I include links to sources that state what is allowed from the restricted version of VI. That would restricted some of the commands in this pen-testing.sans.org/blog/2012/06/06/… link from being run. You should probably read the contents of an answer before jumping to conclusions.Multimillionaire
PLEASE DO NOT DO THIS. Aliases are a means of convenience, not security. You can circumvent an alias by simply using a forward slash. The restricted bash suggestion may be part of a solution, but the aliases won't be. They don't do what you want against an intelligent attacker. It only provides minor protection against someone accidentally making a mistake, not intentionally making one.Entomologize
R
29

@Dodzi Dzakuma solution is great if you only have a few commands that you wish to disable.

However if you only want to allow the user to run several commands, here is a better solution:

  1. Change the user shell to restricted bash

    chsh -s /bin/rbash <username>
    
  2. Create a bin directory under the user home directory

    sudo mkdir /home/<username>/bin
    sudo chmod 755 /home/<username>/bin
    
  3. Change the user's default PATH to the bin directory

    echo "PATH=$HOME/bin" >> /home/<username>/.bashrc
    echo "export PATH >> /home/<username>/.bashrc
    
  4. Create symlinks of the command(s) that the user require

    sudo ln -s /bin/<command> /home/<username>/bin/
    
  5. Restrict the user from modifying ~/.bashrc

    chattr +i /home/<username>/.bashrc
    

This is better IF you only want to allow the user to run several commands because instead of setting aliases of ALL commands to disable, you only set the symlink of the commands that you wish to allow.

Rashad answered 10/9, 2018 at 6:6 Comment(5)
Excellent option, as far as I see, the best solution and the safest of all with great control over which commands are allowed.Hughie
This too is a solid solution! A different way to do the same thing, but less ways to shoot yourself in the foot. I wasn't thinking about this at the time I answered.Multimillionaire
This did not work for me, since .bash_profile was read instead of .bashrc. If this is also the case for you, just change commands in step 3 accordingly.Liana
Beware of step 3 evaluating $HOME and missing quotesForsythe
this didn't work for me.Spanishamerican
C
17

I stumbled on a workaround for your situation just now. I had a user, let's call him "test1" that needed to have some commands restricted, like "su", but the rest should be available. To apply this restriction I just used ACL (assuming you have acls enabled on your FS) on the binary file behind the command itself like so:

setfacl -m u:test1:r /bin/su

The above command changes the permissions for that specific binary file, which is in fact the "su" command, to grant user "test1" only read access to that file. As such, when user "test1" tries to "execute" the "su" command he can't run the script behind it and gets "Permission denied".

Just run "which command_you_want_restricted" to see the file behind it.

I have tested this method on Red Hat 6.5 & 7 and it just affects user "test1", all the other users can continue running "su" at will.

As for you specific request:

Or, set the policy to have access on all commands except "ssh" and "cat" commands.

You can do the same thing with ACLs for the group "demo" on the command binaries you wish, but I HAVE NOT TESTED this with groups and I suggest you try it on a test VM or something beforehand.

Caponize answered 4/11, 2016 at 10:25 Comment(3)
Thanks a lot! Would you please give me an example for "set the policy to have access on all commands except ssh and cat commands".Cinematography
Well, that's actually a quote from you initial question...Caponize
You can use the "setfacl" command on all the command binaries except the ones you want the users to keep using.Caponize
A
17

I'm a bit surprised that nobody yet used the native SSH functionality in their answer... I know I'm 4 years late but it could still be handy :)

When using SSH you should use keys for logging in; as we are talking about securing a server, disabling password login should be one of the first things you should do. So, as you are using keys, you now have the ability to allow only one single command per key by adding this in the authorized_keys file:

command="only" ssh-rsa AAABBBCC....

The only command is a whitelisting feature which allows the user to run only those commands. You do not have to make exceptions on your system(s) by changing the default binary permissions (which is an admin hell..). Make sure you set the authorized_keys file to be non-writable for the user.

The only command is a script that must be installed in /usr/bin/ with 775 permissions.

Read all about it: The Only Way For SSH Forced Commands

Now you understand how it works, you can simply whitelist any command that you allow the user to execute:

command="only cal cowsay factor figlet fortune" ssh-rsa AAABBBCC....

Or use an .onlyrules file with the proper syntax, be careful not to use any greedy regex..

  ----------------------
  <   I'm restricted   >
  ----------------------
         \   ^__^ 
          \  (oo)\_______
             (__)\       )\/\
                 ||----w |
                 ||     ||
Adachi answered 27/4, 2018 at 16:51 Comment(1)
I also thought this should be the way to go. But just for completeness: Lets say your have several users, A,B,C... and you want do restrict the commands of C. Using the authorized_key file might help but: When you log in as root and change user to su C you end up beeing able to use all commands that C shouldn't be allowed to. Lets say C is able to exploit a program he is allowed to use in this authorized_key file and drop a shell, he will be able to execute all commands available - This is what I am afraid of and the question how to restrict a user remains the same?Ainslie
S
5

The standard answer would be to use a restricted shell, making this the last entry in the password file for users in that group. As you can run external commands from things like vim: http://web.physics.ucsb.edu/~pcs/apps/editors/vi/vi_unix.html

this does not seem like a great idea if you are trying to produce a restricted environment. The first thing a user could do is use the commands in the above link to run /bin/bash and he'd be outside the restricted environment.

A better idea would be to put each user's login into a chroot jail or perhaps a lightweight container (so if they break anything it's their own container). Have a look at Docker - http://docker.io .

Sleeping answered 1/2, 2014 at 13:38 Comment(0)
M
5

I have faced a similar situation at my organization where I had to restrict people to access only certain commands.

So far, I have found 2 different ways to do it.

  1. The only approach
  2. Having a different Shell altogether viz. rbash, lshell, dockersh

Here are my thoughts on the same.

  1. Take the only approach if you want the users to login and execute a certain command and then exit the shell entirely. Its better to you couple it with Rbash.

  2. Out of the 3 shells, I feel lshell would be the easiest to implement especially if you are on Ubuntu and its derivatives. You just have to install a package via apt and then edit the configuration. It is the simplest.

The rbash is good for basic stuff like blocking redirection and certain characters on the cli but to do the advanced stuff like whitelisting certain commands, you would need to go the extra mile.

Dockersh is a completely fresh and modern approach to restricting shells. Here you allow everything but you limit all the user's action to a container.

In my use-case, I had to limit my users to a single command with shell based redirection , piping etc. turned-off hence I chose lshell. Took hardly 5 minutes to configure. Find details here.

Manstopper answered 27/5, 2019 at 5:6 Comment(2)
Whitelisting commands with a dedicated restricted shell like lshell really seems like the way to go. The rbash approach seems dangerous, trying to cut down a full-featured shell and hoping you don't miss anything. RedHat describe rbash as 'just a hack', unsuitable for serious use - access.redhat.com/solutions/65822Cronk
Unfortunately none of these alternative shells are under development anymore!Ulrikeulster

© 2022 - 2024 — McMap. All rights reserved.