Solution for homebrew user without admin privileges in /urs/local?


(André) #1

Hello - I just got a new Mac with Sierra. For future virus-readiness, I am setting up my Mac with and admin account (that I will only use when necessary - rarely) and a user account withOUT admin privileges that I will regularly use - so viruses can’t get into my system files at all (I at least believe this will provide some level of protection provided my user files are all regularly backed up). As well documented, this causes issues installing homebrew. I have come up with what seems to be a viable fix, and would like feedback from experienced users whether this will cause me problems in the future.

As admin, I installed homebrew. I then used sudo to do the following (as admin) - make a new group local that I added myself and admin to, and change the group of /usr/local to local

Mac-Pro:~ admin$ sudo dseditgroup -o create -r "local group for using /usr/local" local
Password:
Mac-Pro:~ admin$ sudo dseditgroup -o edit -a admin -t user local
Mac-Pro:~ admin $ sudo dseditgroup -o edit -a walkloud -t user local
Mac-Pro:~ admin $ sudo chgrp local /usr/local/
Mac-Pro:~ admin $ sudo chmod g+w /usr/local/
Mac-Pro:~ admin $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
==> This script will install:
....
Press RETURN to continue or any other key to abort
==> Downloading and installing Homebrew...
...
==> Next steps:
- Run `brew help` to get started
- Further documentation:
    http://docs.brew.sh

Mac-Pro:~ admin$ cd /usr/local/
Mac-Pro:~ admin$ for d in $(ls); do echo $d; chgrp -R local $d; chmod -R ug+rwX $d; done

I then logged out of my admin account and was able as my non-admin user to

Mac-Pro:~ walkloud$ brew doctor
Your system is ready to brew.
Mac-Pro:~ walkloud$ brew install python
==> Installing dependencies for python: pkg-config, readline, sqlite, gdbm, openssl
...

for example, and then also

Mac-Pro:~ walkloud$ pip install numpy

So this solution seems to be working so far, I have installed the entire “scipy stack” through nose (nose makes a new dir in /usr/local and this worked). This works for me as I am the only user on my Mac, so I do not have to worry about different users doing stuff to my brew-land that I do not want.

I am worried I am fooling myself on how well this will work, and wondering if there is a better way. Also, if someone knows how to extend such a setup to allow multiple users following these seemingly simple steps, that would be cool and seem to solve others problems.


(Mike McQuaid) #2

Viruses are pretty much unheard of on macOS, particularly if you keep yourself on the latest version. Additionally, even the root user cannot modify system files on macOS, let alone admin users (who would need sudo elevation anyway). In short, you’re creating unnecessary work for yourself and not actually making your system any more secure.

Rather than trying what you’re doing I strongly recommend just using an admin user as your main user or at least as the user that always runs brew. If not, use one of our alternative installs to install in a different location (which will mean you won’t get many binary packages so your experience will be worse): https://github.com/Homebrew/brew/blob/master/docs/Installation.md#installation


(André) #3

Hi Mike,
Thanks for the comments. I agree that today, viruses for macOS are very rare, but I expect this will change sooner rather than later. One of the high performance computing centers I remotely use has recently required us to install anti-virus software on our remote computers, including macOS, even though we already use passwd+token login.

If someone has virused their way onto my computer, that also means they have my password, and so if my account has admin privileges, they can sudo all they like. In this case, by keeping my admin account with a different password, I would argue my computer is more secure, in the rare event I get a virus.

I admit that I do not expect this is a likely problem. I am trying to be future ready and also assume that even though I pay attention, it is possible I could get a virus.

And - this is not very much extra work. The idea came to me in a moment of inspiration (rare these days, but still happens now and then), and then it takes less than 10 lines in a terminal to set it all up. If I run into some problem, then this is a failed solution. So far, I can not foresee any problems I will cause myself. Based on your reply, my guess is you do not know of a specific problem, but if I did encounter one, you would not be surprised.

Regards,
Andre


(Mike McQuaid) #4

I just think you’re creating extra work for yourself and things are likely to go wrong in weird, hard-to-debug ways. You may well be a security researcher but unless you are: I have done work in security-critical environments and I would like to delicately suggest that you’ve quite a few erroneous assumptions there (but that’s a longer conversation for another day). In short, I don’t think it’s worth it but obviously it’s up to you.


(Franklin Yu) #5

How can they have your password in the first place? If they can have the password of your unprivileged account, they can also get the password of your administrator account. In addition, how can “someone has virused their way onto my computer” given that macOS doesn’t have insecure AutoPlay like Windows?


(Todd Gamblin) #6

I’ll just chime in to say that I work at a national lab and we’re required to use a non-admin account as the primary user, so using homebrew for me is painful sometimes as well. I don’t think it’s the greatest setup, but it’s what I have to do. I’ve been able to get around this, mostly, by chowning and chmod’ing judiciously from the admin account, but it sure would be nice if Homebrew supported it better. I am pretty sure we’re not the only site that requires this, for good reasons or not.


(André) #7

Hi Todd,
I think I have one extra line to add to my setup that will make it work for you on a clean install - and also, a fix to get it to work with your existing installation. I have brewed lots of stuff now, including gcc. I am getting to mpi and openmpi next, but so far, I have only run into one glitch, and that was with a caskbrew/cask formula - I had to install as admin cause the last step moves an application (meld) into the /Applications folder, and I can’t find a workaround without having admin privileges.

Here is my less-than 10-line terminal setup to get homebrew to work in /usr/local with a user that is not admin (provided and admin can do the admin setup, or you also have admin access but aren’t supposed to use it regularly).
all as admin:
L1-3, create new group that admin and non-admin will join
L4, change the group oh /usr/local to your new “local” group
L5, give /usr/local g+ws permissions - the “s” will cause all subsequent files/folders made in /usr/local to inherit the parent permissions
L6, install homebrew

$ sudo dseditgroup -o create -r "local group for using /usr/local" local
$ sudo dseditgroup -o edit -a <admin-user> -t user local
$ sudo dseditgroup -o edit -a <non-admin-user. -t user local
$ sudo chgrp local /usr/local
$ sudo chmod g+ws /usr/local
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

If the permissions in subsequent folders/files created in the brew installation are not created properly, or if you have a pre-existing homebrew installation you want to make friendly to a non-admin user, the following should fix it (also as admin)

$ cd /usr/local/
$ for d in $(ls); do echo $d; chgrp -R local $d; chmod -R ug+rwX $d; done
$ find /usr/local -type d -print0 | sudo xargs -0 chmod ug+s

I am still curious to hear comments on the method of accomplishing this non-admin brew installation, not just commentary on the why someone would be interested.


(Mike McQuaid) #8

We will never “support” it because that implies we will help you with issues when there’s an existing workaround: use an administrator user. I appreciate that solution may not work for you but, for instance, if Homebrew flat-out didn’t work as a non-administrator at all your lab would likely find a solution.

As pointed out before but more specifically: “untar anywhere” (https://github.com/Homebrew/brew/blob/master/docs/Installation.md#untar-anywhere) is the alternate method that allows you to install Homebrew in any location. Not all binary packages will work but that’s probably a better trade-off than monkeying around with permission issues that do cause hard-to-reproduce bugs.


(André) #9

Hi Mike - you have mentioned this twice. I would like to understand why you think it is better (I am trying to learn, not be obstinate). The solution I have does not require many permission changes. It simply works by creating a new group, “local” in my case, which both users are members of, and provides “g+rws” to the entire /usr/local dir. Generally, this will maintain permissions for the non-admin (and admin user) user and simply work. I use this method with colleagues in shared volatile folders we write to for work, and we almost never run into permission problems that need fixing - and when they do, it is simple to fix (usually arising from a failed process doesn’t set permissions properly cause it aborts early).


(Mike McQuaid) #10

I think it’s better because you’re relying on group permissions being set correctly and consistently by Homebrew and upstream software and I wouldn’t rely on either. This is not a configuration tested by Homebrew’s CI or our maintainers whereas the defaults and the “extract anywhere” are.


(André) #11

Hi Mike - I hope you guys will look into this solution. The use of

chmod g+s /usr/local

assuming the group of /usr/local is local or something else chosen by the admin user means that anyone in the group local who uses files in /usr/local or it’s subdirectories, will inherit the permissions of local. So, if you create new files there, they will automatically pick up the same permissions and group as defined for /usr/local. Similarly, if you execute binaries in /usr/local, you will execute them as group local. My colleagues and I use this behavior on a shared filesystem, owned by me, to build software, write and delete files, directories, etc. With rare exceptions, I believe this should work for homebrew also. And when the exceptions occur, they will be easy to fix - the first diagnostic to run will be an inspection of the permissions of the compiled brew code.


(Mike McQuaid) #12

As you’ve noticed there are exceptions that require manual intervention (and therefore detection/debugging also). This is not the case with the other methods which is why we do not recommend it.


(André) #13

Yes, but the exceptions have known causes and known symptoms. The symptoms will always be the non-admin user does not have sufficient permissions. For example, my installation of meld with caskbrew/casks has a step at the end where the application is copied to the Applications folder - which only an admin can do. The fix was simple. A homebrew configuration fix would be to trigger asking for an admin username and password. When we install software as a non-admin users, there is a GUI that always pops up asking for such permissions. Something simple like this could easily fix this problem. Also, a very short bash script could be developed to recursively fix the group and permissions of all files in the homebrew distribution, in case a corrupt install of some software happens. Another one could be written to set up the group structure in the first place. I would be happy to write these bash scripts and provide them for anyone who wants to try it out.

I guess what confuses me is this fix takes advantage of known and easy to use permission structures in a linux/unix file system, yet the pushback I am getting seems to come from the idea that I am doing something very out of the ordinary and/or not standardly supported with a linux/unix file system. I just want to stress this is not the case. It is a very simple permission/group change that is allowing this to work.

Regards,
Andre


(Joshua McKinney) #14

Perhaps I’m missing something here. It seems like you’re concerned that a virus would be able to write to your system files, but you’re not concerned that they could write to your files in /usr/local/ which you later blindly execute. Your instructions don’t seem to have set the setgid flag on any files, only directories, so you’re not running anything as the local group.

I can see the utility of what you’re doing. You’re looking to apply a least privilege isolation from your main user. I think it’s the same as how I’d go about this if I was in a similar position as you.

  1. Create your admin user, and a non-admin user
  2. Install homebrew as the admin user su admin curl ...
  3. Ensure the admin user and admin group owns /usr/local, and all users can read and execute as appropriate (644 / 755 are the appropriate permissions).
  4. When running Homebrew commands use su to run commands as the admin user. E.g.: su admin brew install

This is similar to the permissions you’ll see in/bin, but with admin:admin rather than root:wheel, to indicate a user managed set of software rather than root managed. I think this is the suggestion that @MikeMcQuaid had above about using an admin user.


(André) #15

Greetings @jsohka,

Let us ignore the virus or no virus, as this was just a motivation to have a non-admin user being able to use Homebrew in the standard location. @tgamblin provided another reason outside the users control: work requires you to use a non-admin account (but you can still work as <admin> now and then when necessary).

I do not agree that your description of how it will work is necessary - precisely, the use of su admin brew install <package> is NOT required. Verified: these steps

$ sudo dseditgroup -o create -r "local group for using /usr/local" local
$ sudo dseditgroup -o edit -a <admin-user> -t user local
$ sudo dseditgroup -o edit -a <non-admin-user> -t user local
$ sudo chgrp local /usr/local
$ sudo chmod g+ws /usr/local
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

allow any user in the group local to use Homebrew in the standard fashion. For example, as the non-admin user, I can now brew install <package> without issue, e.g.

<non-admin>$ brew install wget
<non-admin>$ ls -l /usr/local/bin/ | grep wget
lrwxr-xr-x  1 <non-admin>  local     32 May 18 19:25 wget -> ../Cellar/wget/1.19.1_1/bin/wget
<non-admin>$ ls -l /usr/local/Cellar/wget
drwxr-xr-x  12 <non-admin>  local  408 May 18 19:38 1.19.1_1

You will notice the installed package did NOT inherit the group write permissions, but it is in the group local, so any user in local can use it, importantly, the <non-admin> user. To get the g+w inheritance to work, one must ensure BOTH <admin> and <non-admin> have their default permissions set to umask u=rwx,g=rwx,o=rx, in the .bash_profile for example. I expect this is only an issue if one needs to run as <admin> to clean up something, as you would not want multiple users using the same Homebrew stack. This is verified also: set umask u=rwx,g=rwx,o=rx in both <admin> and <non-admin> .bash_profile, then

<non-admin>$ brew install python3
<non-admin>$ ls -l /usr/local/Cellar/python3
drwxrwxr-x  13 <non-admin>  local  442 May 30 09:48 3.6.1

I believe, with few exceptions that have known symptoms and fixes, this is a viable working means of having a <non-admin> user use Homebrew in the standard location.

Regards,
André


(Joshua McKinney) #16

Hi @walkloud

I understand that you need non-admin accounts. I’d be very confused if the requirement to run as a non-admin user was compatible with the practice of arbitrarily installing binarires from the internet as the non-admin user to a shared location. What is your threat model?


(André) #17

Hi @joshka,

If possible, I would like to focus first on whether the method works before discussing why I am motivated. I don’t believe there is something I have missed that will prevent this solution from working, defined at this time as having a personal computer in which I have 2 accounts, admin and non-admin, and the non-admin is the main account used, with the non-admin having (near) full ability to use Homebrew, including installing new packages. The one exception encountered so far is the caskbrew/casks installation of meld includes copying the binary to the /Applications folder, which requires admin privileges. Are there other known, or suspected exceptions that will require an admin account?


(JKMiller) #18

Excellent approach so far. Using an admin account is the main reason I have been avoiding homebrew on my current machine. I’ll give André’s approach a shot, and I’ll let you guys know if I run into any difficulties.


(André) #19

Hi JKMiller,

I have been using this solution since my initial message still without any problem or difficulty. If you have any trouble setting it up, let me know, I would be happy to help.

Just as a reminder - the one exception I have run into is the installation of meld which is now installed through cask. The reason it fails (as non admin user) is that at the very end of the installation, it copies the executable into /Applications which only an admin can do.

I have wondered (but not investigated) if this can be fixed in the ruby script. When you install software as a non-admin, you are simply prompted to have an admin provide permissions. I suspect there is some way to have the ruby script generate this prompt. Alternatively, you simply have to login as admin to install this type of software.

Regards,
Andre


(Joshua McKinney) #20

brew cask install meld --appdir=~/Applications