9

I understand the concept of managing permissions on Linux with chmod using the first digit as the user, the second as the group and the third as other users as described on this answer in Understanding UNIX permissions and file types.

Let's say I have a Linux system with 5 users: admin, usera, userb, userc and guest. By default, the users usera, userb and userc will have execution permission on all files inside /usr/bin, so these users can use the command line of the system executing the files in there as those files have 755 permission. So far it's completely ok. However, I'd like to forbid the user guest from executing files on the folder /usr/bin, I know I could achieve that by changing the permission of all files inside this folder to something like 750 with chmod, but if I do that I'll mess up the permissions of the users usera, userb and userc because they will be also forbidden to execute files.

On my computer, all the files in /usr/bin belong to the group root, so I know I could create a newgroup, change the group of all those files to it and add usera, userb and userc to newgroup. But doing that sounds like way too much modification on the system's default settings. Does anyone know a smarter way of solving this problem?

How can I forbid a single user from using the command line (or executing any file on PATH) without an overcomplicated solution that requires changing the permissions of too many files?

Paulo Tomé
  • 3,782
  • Use group permissions and have that user not be in that group – planetmaker Mar 05 '20 at 06:53
  • 1
    @planetmaker no! You'll either break the entire system or else break distribution upgrades. – Chris Davies Mar 05 '20 at 07:49
  • 4
    That implies user guest won't even have a shell to start, because /usr/bin and /bin are identical in many modern distros. (My gut feeling would be to try and put them in a chroot jail; it's possible that systemd even gives you nice automatisms for that, like it does for services.) – Ulrich Schwarz Mar 05 '20 at 08:42
  • @UlrichSchwarz You're right but for my case of use, it works fine... I'm giving ssh access to the user guest just so he can port forward the system to have access to specific web applications. Even with the terminal dead for running the shell, applications running on ports by other users on the system will still work fine after port forwarding. – Rafael Muynarsk Mar 05 '20 at 17:00
  • 3
    I'd implement this with a PAM module that does a bind mount of /var/empty over /usr/bin in a private filesystem namespace during login for the relevant user. Why do something that modifies the filesystem for everyone, when you can modify the filesystem only for the one user? – Charles Duffy Mar 05 '20 at 17:38
  • 1
    See https://www.ibm.com/developerworks/library/l-mount-namespaces/index.html discussing a (different) private-namespace PAM module's implementation. – Charles Duffy Mar 05 '20 at 17:40
  • @CharlesDuffy seems to have become something ubiquitous: https://manpages.debian.org/stable/libpam-modules/pam_namespace.8.en.html . Are you over with this? I might write an alternate answer – A.B Mar 05 '20 at 19:28
  • My instincts would be to set the user's login shell to something very restricted - and then make sure that the SSH settings don't allow "ssh hostname ls /" to bypass that. Don't know off the top of my head if that's actually possible and if so what the exact sshd_config settings would be. – Daniel Schepler Mar 05 '20 at 19:41
  • 3
    Just a heads up, but permissions are defined with 4 octal digits, not 3. You might be thinking that all your files are 755, but I have many that are 4755, 2755, 6755, etc. 750 is the same as 0750, so by changing them all to 750, you might be breaking quite a few executables (like sudo) by clearing their suid, sgid, and sticky bits. – JoL Mar 05 '20 at 20:02
  • @A.B, by all means do write it up yourself. – Charles Duffy Mar 05 '20 at 20:29
  • 1
    @CharlesDuffy on 2nd thought, I drop this. This would go far from the initial question. Just to tell you that what you wrote works fine with pam_namespace. Documentation isn't that great but present (man pam_namespace + man namespace.conf) – A.B Mar 05 '20 at 20:34
  • @JoL Good Point. Just as a curiosity, would you know a way of changing the permission of the last three octal digits of files while keeping the first octal as it is? Instead of just replacing it with 0? – Rafael Muynarsk Mar 05 '20 at 23:04
  • 1
    @RafaelMuynarsk, you can always specify chmod o= ...files... to clear only the "other" field and leave u/g and the other bits like temp and set[ug]id alone. But to be very, very clear, doing that with /usr/bin is a horrible idea. I really do recommend the bind-mount approach to leave the rest of the system alone while changing a single user's view of it. – Charles Duffy Mar 06 '20 at 00:58

2 Answers2

14

Use ACLs to remove the permissions. In this case, you don't need to modify the permissions of all the executables; just remove the execute permission from /usr/bin/ to disallow traversal of that directory and therefore access of any files within.

setfacl -m u:guest:r /usr/bin

This sets the permissions of user guest to just read for the directory /usr/bin, so they can ls that directory but not access anything within.

You could also just remove all permissions:

setfacl -m u:guest:- /usr/bin
muru
  • 72,889
2

What are you trying to do? Forbidding use of the system's standard commands to some user is just incivil behavior in the extreme... commands that could put the system in jeopardy are far in between, and have been carefully vetted for security. The permissions on files should stop most attempts at mischief.

  • Consider giving them a restricted shell (check the manuals, it is probably named something like rbash; careful though, rsh is a different kind of animal!). They cage the user rather effectively (but watch out, it is possible to break out!)
  • If this is a pseudo-user in charge of owning some service, the common way out is to give the "user" a shell that does nothing, like /bin/true (check your system's manual for any recommendations in this line, there might be a special program for this; if /bin/true is a shell script don't use it for this). That way, if somebody manages to log in to that account, their session finishes immediately.
  • Create a chrootfor them (again, there are ways to break out), or use Linux' containers of BSD's jails to confine them, and just expose exactly what you want them to see. Most control, but messy to set up and keep up to date.
vonbrand
  • 18,253
  • Forbidding use of the system's standard commands to users is not uncivil behavior, everything depends on the context of how it's being used, even the act of deleting a user could be seen as uncivil behavior if used by the wrong person. But as I wrote in the comments of my question, I'm giving ssh access to the user guest just so he can port forward the system to have access to specific web applications. A "caged" shell wouldn't be the ideal solution to my case because it'd still allow the user to use RAM memory and CPU power with scripts. But thanks for bringing a different perspective. – Rafael Muynarsk Mar 05 '20 at 22:28
  • 3
    @RafaelMuynarsk if you want to limit the user to port forwarding and nothing else, you may want an SSH "Forced Command", see this question and/or google for "ssh forced command" (you may not even need a separate user!) – Josh Mar 05 '20 at 22:31
  • 1
    @Josh That's actually exactly what I needed. I haven't thought I could create these restrictions directly on my SSH configuration. Thanks! – Rafael Muynarsk Mar 05 '20 at 22:40
  • Sure thing! Yeah I didn't know about forced commands for years, they're an amazing feature (especially for running specific commands remotely as root or other privileged users) – Josh Mar 05 '20 at 22:45