34

I was thinking that it might be advantageous to have a user with permissions higher than the root user.

You see, I would like to keep all of the activities and almost all existing root user privileges exactly as they are now.

However, I would like the ability to deny privileges to root on an extremely isolated case by case basis.

One of the advantages of this would allow me to prevent certain unwanted files from being installed during updates. This is just an example of one possible advantage.

Because apt-get updates are run by root or with sudo privileges, apt-get has the ability to replace certain unwanted files during updates.

If I could deny these privileges to these individual particular files, I could set them as a simlink to /dev/null or possibly have a blank placeholder file that could have permissions that would deny the file from being replaced during the update.

Additionally, I can't help but be reminded about a line which was said in an interview with one of the Ubuntu creators when the guy said something about how users better trust "us" (referring to the Ubuntu devs) "because we have root" which was a reference to how system updates are performed with root permission.

Simply altering the installation procedure to say work around this problem is absolutely not what I am interested here. Now that my mind has a taste for the idea of having the power to deny root access, I would like to figure out a way to make this happen just for the sake of doing it.

I just thought about this and have not spent any time on the idea so far and I'm fairly confident that this could be figured out. However, I am curious to know if this has already been done or if this is possibly not a new idea or concept.

Basically, it seems like there should be some way to have a super super-user which would have permission beyond that of the system by only one degree.


Note: Although I feel the accepted answer fits the criteria the most, I really like the answer by @CR. also.

I would like to create an actual user higher on the tree (me) but I guess I'll just have to sit down one day when I have the time to figure it out.

Additionally, I'm not trying to pick on Ubuntu here; I wouldn't use it as my main distro if I felt negative about it.

  • 4
    What sort of files are you talking about and why? "prevent certain unwanted files from being installed _" suggests the files don't (normally) exist, and you want to stop them doing so; but "_hat would deny the file from being replaced during the update." suggests the files already exist (with, presumably desirable content) and you don't want new versions. – TripeHound Sep 4 '17 at 7:18
  • 6
    Be aware that any method that prevents apt from (over)writing files might lead to an error, aborting the update process. apt will then refuse to do any updates or installations until the "problem" is solved. – Dubu Sep 4 '17 at 7:29
  • 6
    "Simply altering the installation procedure to say work around this problem is absolutely not what I am interested here." Maybe so, but it is generally the correct way to solve the problem as stated. Limiting root can be done (formally, root-in-userland is not the same level of access as kernel mode), and there are systems for accomplishing it, but it goes against the Unix philosophy and basic security principles. In general, once somebody has "partial" root, it is exceptionally difficult to blacklist off everything they might use to get "full" root. Prefer only giving root to trusted code. – Kevin Sep 4 '17 at 19:37
  • 8
    @mchid: root is full control. That's the whole point of it. In order to make it not have full control, you have to deny so many things that it no longer looks like root (e.g. no installing kernel modules, no mounting arbitrary devices, and so on). If you don't want to run things as root, then don't run them as root. Instead, hand out capabilities (except for all the root-equivalent ones, don't bother with those) or run a daemon like polkitd that performs root operations on behalf of non-root processes. – Kevin Sep 6 '17 at 6:09
  • 4
    @mchid: That's the problem: There are a large number of ways for programs to circumvent your restrictions. Unless you blacklist all of those ways, any program you run as "restricted root" can still become full root whenever it wants. So your whole scheme is nothing more than a charade of security theater. – Kevin Sep 6 '17 at 6:26

13 Answers 13

83

The "user" you want is called LSM: Linux security module. The most well known are SELinux and AppArmor.

By this you can prevent certain binaries (and their child processes) from doing certain stuff (even if their UID is root). But you may allow these operations to getty and its child processes so that you can do it manually.

  • 2
    But if their UID is root can't they change the selinux permissions that prevent them access in the first place? – curious_cat Sep 4 '17 at 3:27
  • 11
    @curious_cat: Yes, of course you need to deny a "limited root" process the ability to change / raise its own permission! The people that wrote SELinux thought of that already... – Peter Cordes Sep 4 '17 at 5:12
  • 8
    @curious_cat You can configure the LSMs so that it is completely impossible to change their configuration at run time. You have to reboot and give a kernel parameter in order to to that then. – Hauke Laging Sep 4 '17 at 7:17
  • 5
    @Joshua If your copy of apt-get is using Rowhammer then you have bigger problems to worry about. – Draconis Sep 4 '17 at 17:58
  • 3
    @corsiKa First, you want to restrict the people who can boot the machine to people who are actually at the machine, because systems are vulnerable while they're booting. Triggering a reboot over the net is fine, but allowing control as it boots is not. Second, a rule of computer security is that you cannot do anything once an attacker has physical access, because then they may as well dunk everything in LN2/rewire the hardware/etc. So, yes, someone who can alter the booting of a machine is generally assumed to have "won" the machine. – HTNW Sep 5 '17 at 1:20
51

You're misunderstanding the concept of the root user.

In plain English, root is at the "top of the tree".

What if you decide one day to have a "super super user", and then next month, a "super super super user"(!). How far "up" the tree would you want to go? How would you shuffle all the permissions and hierarchy to make that work? Who is always at the top? Someone has to be at the top, and it's root. End of story.

The solutions given here - including AppArmor and SELinux - don't really change this. They simply allow finer grain control over root permissions and processes.

It sounds to me like your update process isn't suitable for the desired outcome. But that's not a fault of the root user, at all. Instead of overcomplicating things, think of root as the highest level permission user, and then everything else, you have to work downwards.

I know some people will mark this down, but there is no level higher in the user hierarchy, and all the other solutions simply give slightly different control to how root permissions work. But they do not create a new user, with higher permissions.

You can't have a user with "more permissions" than root because root represents the highest level of permissions possible. Using a phrase like "more control than root" is a contradiction - root has full control and all possible permissions, so there is nothing that can be done above it.

  • I would be at the top not root, end of story. Because there is no level higher in the user hierarchy is the exact reason I would like to create a higher user. – mchid Sep 6 '17 at 1:45
  • Although, that is kind of what I want: control over root permissions and processes so I can deny permission to root. If I can somehow deny permission to root without creating a new user with SELinux or AppArmor then I guess I don't need a new user. I want full control, more control than root. – mchid Sep 6 '17 at 5:11
  • 16
    You can't have a user that has "more permissions" than root. That's the whole problem. The user you are looking to create is essentially the root user. You need to approach this the other way, such as creating a user with root privileges, and then deny certain ones where you want finer control. What you're asking ("more control than root") isn't possible, or even a thing! – Andy Sep 6 '17 at 8:39
  • @mchid So what you actually want to do is rename the current root user to mchid, create a new user called root and make apt-get et al use your new, non-root user? – Odalrick Sep 6 '17 at 8:39
  • On some systems, root doesn't have permission to access hardware directly. If you disable the loading of kernel modules, you can keep root locked out of total control over the hardware (/dev/mem, and stuff like that). Not really relevant for filesystem permissions, since you wouldn't use an apt-get that talked to your SATA or NVMe controller directly... But technically, there is a "more permissions than root" state, and it's called kernel mode. :P – Peter Cordes Sep 8 '17 at 8:58
26

If you just want to prevent files or directories from being changed/deleted then just set the immutable flag on them.

chattr +i <file>

Not even root will be able to do anything to them unless the flag is removed. It's also possible to use the container/namespace system to prevent root access but that seems like overkill for what you need.

  • 11
    But root can remove the flag. – sebasth Sep 3 '17 at 21:21
  • 10
    apt, like almost everything, will not use chattr to remove that flag. – CR. Sep 3 '17 at 21:23
  • 13
    @sebasth: Correct, but Apt, dpkg and per-package installation scripts won't (normally) alter file attributes. Instead they will just fail and complain when they try to alter files with the immutable flag. – David Foerster Sep 3 '17 at 21:25
  • 4
    @TripeHound So the OP wants apt-get to succeed in replacing the file, yet having that file intact? That's somewhat contradictory I dare say. – Dmitry Grigoryev Sep 4 '17 at 10:51
  • 3
    @DmitryGrigoryev It sounds like they want apt-get to think it succeeded but leaving one or more files unchanged. They don't say which files or why, but as you say, somewhat contradictory -- and prone to "odd behaviour" in the future. – TripeHound Sep 4 '17 at 11:01
9
  • Instead of having a super-super-user, you can limit root. see What are the different ways to set file permissions etc on gnu/linux

  • There is also AppArmor and SELinux.

  • And/Or configure sudo, so that you do not give away full root privileges. You can set it up so that a user can only run pre-agreed commands, with pre-agreed arguments.

  • You can also use virtualisation to restrict root:

    • cgroups, namespaces, chroot etc (docker does this)
    • Xen
    • Virtualbox
  • See also etckeeper: this tool revision controls the /etc directory, and synchronises with apt. By default it is not secure, a malicious install could sabotage it, but you could also get it to push changes to a fire-walled backup repository.

  • Use of revision control in general, with a fire-walled backup repository. This help with accidental, intentional corruption and hardware failure.


Firewalled backup repositories could be on a different machine, on the internet, or a different virtual machine (or host of virtual machine).

8

For software like APT, which in normal operation require access to almost all of the system, restricting is problematic. Even if you prevent it from accessing certain parts of the system, there most likely are more than enough possibilities for malicious distributor to work around. For example by replacing a library or just a binary or adding a malicious configuration change, which unrestricted root is going to use eventually.

Depending on how much you would place restrictions, some install scripts can be expected to break.

For ways to restrict applications and users, you can write an AppArmor or a SELinux policy. Such policy would Which is more supported depends on your distribution: Debian based have better support for AppArmor while Fedora/RHEL based distributions enable SELinux by default.

Both AppArmor and SELinux work on white list policies, which contain rules to allow (or deny) specific actions. Policies are applied to a process at exec, similarly users can be restricted when a policy is applied to their processes at log-in. A well thought policy can not be circumvented (if kernel bugs are not considered). Confined process running as root (uid 0) is restricted by the configured policy and cannot change it unless explicitly allowed in the policy.

AppArmor policy language defines a deny rule, which can be used to build a blacklist policy. A good place to begin with AppArmor is AppArmor man pages, wiki and looking the existing configuration on your distribution in /etc/apparmor.d/.

Plenty SELinux administration and development material is provided in SELinux wiki. SELinux reference policy is hosted on github.

7

I can't believe no one has mentioned apt pinning...

A couple years ago, Microsoft released a patch that broke Windows 10 machines from talking to our old Samba NT4 Domain Controllers. When the issue was found, we pinned the Samba package to stay at the current version, and apt still functioned correctly.

A full Debian Walkthrough explains the process well:

In /etc/apt/preferences (or a new file under /etc/apt/preferences.d/), add some text to specify which package and version:

Package: samba
Pin: release v=3.6.6-6+deb7u7
Pin-Priority: 900

Check the documentation for the exact syntax, but this is the quick and dirty way we pinned a package version. Root could bypass it, as root can always do, but this solves the problem of package managers trying to automatically upgrade packages on you.

NOTE: This answer is assuming you have an XY problem

  • I have answered a number of XY problems myself on askubuntu. However, apt is just an example and is what lead me to the idea. I'm more interested in the "power-corrupts-and-absolute-power-corrupts-absolutely" aspect of the whole thing. Complete and absolute power over my own system is what lead me to linux in the first place. Realizing that my power is not always absolute over root is kind of unsettling; the idea of absolute power is enticing. – mchid Sep 6 '17 at 5:21
  • Also, I guess it is a bit of an XY problem but Y here is "how do I deny permission to root when root is the superuser?" – mchid Sep 6 '17 at 5:47
  • 1
    @mchid it's not about denying permissions to root, but denying something to a program running as root. – John Keates Sep 6 '17 at 9:54
6

It's actually quite simple.

Root is your "super super user"

Create an account called "admin" and give him all of root's permissions except the one's you don't want.

Then create a user called bob, and let him "become admin". By using su or even sudo.

Now you have a normal user (bob) a super user that can do admin stuff (admin) and a super super user (root).

If you want to change the name "root" to something else you can even do that. Technially only the user id (0) matters.

  • If I had a normal user (bob), a super user that can do admin stuff (admin), and a super super user (root), wouldn't root still be doing all the admin stuff with the background processes, cronjobs, and other stuff as user id (0)? – mchid Sep 6 '17 at 3:56
  • not if you don't want them to. Most services let you choose what user does the work. You could set it up so the admin user is the one running the processes. There are a few exceptions, but not many. – coteyr Sep 6 '17 at 4:06
  • Wouldn't I have to go through and set all of those process individually? – mchid Sep 6 '17 at 4:13
  • 3
    That's what happens when you try to break the standard conventions. I think you need to better understand the hows and whys of the permissions systems in a *nix environment. – Shauna Sep 6 '17 at 14:32
  • 2
    I agree with Shauna, you seem to lack a fundamental understanding of the *nix permission system. It's very powerful, but it's nothing like windows. – coteyr Sep 6 '17 at 16:02
3

If what you want is simply to prevent specific files from being installed, then restricting root permissions is not the way to go about doing this. It is worth noting also that the conventional answers (immutable files or LSM's) will not work for your particular use case, as APT (and most other package managers), will bail out if they can't install files.

The real question you want to be asking is:

Is there a way to prevent APT from installing specific files?

That is something completely different from what you're asking on multiple levels.

Now, as to that question, I'm not 100% certain myself, but I do know a number of other package managers have options to prevent specific files from being installed (for example, Gentoo's Portage system has the option INSTALL_MASK=, which actually accepts shell-style matching patterns of things to not install). I'd be more than willing to bet that such an option exists for APT ( or possibly dpkg itself).

  • Really, "Is there a way to prevent APT from installing specific files?" is not my question; this is just an example and what brought the question to my mind. The new firefox ships with addons and installs these files even after the user deletes them with new updates. This is not actually the problem; this is what made me realize that I want even more control over my system. I do, however, appreciate your logic here as I have answered a few questions this way myself so thanks for the input. – mchid Sep 6 '17 at 2:40
  • dpkg-divert does this: unix.stackexchange.com/a/157896/70847 – mchid Sep 6 '17 at 6:01
1

Put a backup copy in a safe place. After any install/update, immediately replace the specific files from that back-up. Thus, no errors to screw up the install but you still get back the file(s) you wanted to keep.

1

Work from a mounted drive

Note that this mostly a conceptual answer, but I think it should work and be in spirit with what you want to achieve.

Let system X be your working system, and system Y an other system which you control

  1. Mount a directory from Y as a drive in X
  2. Set up the rights in such a way that the root user of X has rights on everything in this mounted drive, with a few exceptions

Now you have your 'working root' which can do nearly everything, and you have your 'super root', the actual root account of system Y, which can truely do everything.

  • I like the idea, although, I would like to do this on a running system. – mchid Sep 6 '17 at 2:03
1

You could run a type-1 hypervisor like Xen hypervisor & have that hosting your regular OS as a virtualized guest. The hypervisor controls the virtual guest OS at a level "deeper" than root because it has control over the (virtual) hardware on which the guest OS runs.

You could program the hypervisor to manipulate the guest OS in various ways, including changing permissions, creating & applying backups, hooking certain changes or instructions in the guest OS to inject additional functionality, validation, etc. That would be a valid, potentially useful way to implement a unix type system with a "user" (actually a function of the hypervisor) for "doing things even root cannot do"

My sense that this approach is probably overkill though

  • How does a hypervisor prevent a user with root permission from doing anything they wish to do in a guest VM? – fpmurphy Sep 4 '17 at 4:54
  • This answer starts ok, but then grammatically goes astray (it is then reading the wrong way around, or at least ambigues). I did a fix. – ctrl-alt-delor Sep 4 '17 at 8:30
  • 1
    @fpmurphy1 a hypervisor can hook system calls, apply policies, etc. to enforce arbitrary restrictions on root user or any other part of the guest OS. Maybe my answer isn't good because this is way too much work unless you've got some real enterprise use case or something though... – Nathan Smith Sep 4 '17 at 20:33
  • @ctrl-alt-delor Thanks for your fix, but I don't think grammar was the problem. I clarified what I meant to say though, & I appreciate the feedback that my thoughts weren't clear at first – Nathan Smith Sep 4 '17 at 20:37
  • 1
    @fpmurphy1 within the guest you have full root. However it is not the same root as root on the host. Therefore it is a lesser root than the host root. Docker will allow things to be more integrated, but still put restrictions on root. – ctrl-alt-delor Sep 6 '17 at 8:47
1

Take a look at cgroups and Linux namespaces as an alternative method of achieving this type of goal, as well as tools based on them like Docker and lxd.

These tools allow you to, among other things, limit what parts of the file system a process running as "root" can see, limit which processes are visible to it, and provide only certain capabilities to the "root" user.

0

UNINSTALL sudo

How about uninstalling sudo and symlink /bin/su to /bin/false? Couple that with making sure that root cannot login via ssh and you have locked down the system.

That makes root the Super*Super User, and everyone else is subordinate to that.

For files replaced during updates, simply do not do any updates. More realistically, change the permissions of the files to 440 or 444 so they can't be written. Or put them in a git repository so if they do get overwritten, it can be reverted.

  • You see, I still want to do updates and I still want root doing pretty much all the stuff that root normally does. However, I want to be able to say to root "hey don't do that" or "no, you can't do that" like a parental authority would be able to do to an offspring. As it is now, Root is like the parental authority on my system and all the little children say "mother may I?" when they use sudo. This is fine. However, almost every person on this planet is an offspring of somebody. It seems like some answers here are like a toddler would be at before self awareness when they don't realize – mchid Sep 7 '17 at 10:54
  • . . . that grandma and grandpa are the mothers and fathers of mom and dad. I would like to ask grandpa to come live in my system because, right now, root is the Dad of the house and Grandpa can tell Dad what to do because Grandpa is Dad's father :) – mchid Sep 7 '17 at 10:56
  • It sounds like you have added too many people with sudo powers. Adjust the sudoers file so only selected users can sudo to pre-selected commands. – user176717 Sep 7 '17 at 21:11
  • I only have two users in the sudoers file including root. I was trying to use a simile to explain how some people seem to not understand my question and what I would like to achieve. – mchid Sep 9 '17 at 0:24
  • It seems like people feel like there can not be any user higher than root in the same way that a very young child feels that their mom and dad can have no parent. Also, I did not downvote. – mchid Sep 9 '17 at 0:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.