Closed ruipin closed 8 years ago
I am a bit hesitant to put a lot of effort into working around this design flaw in Docker. There are a lot of reason's why Docker isn't a perfect match for subuser, and I hope to someday say goodbye to Docker, and move to runc and some other image management system. I will think about your proposal, but be aware that anything that I do in this area will be intended as, and feel like, a temporary fix.
I don't mean to be argumentative, but have you considered that any application that has access to your real X11 server probably has the equivalent of root access? If you ever use sudo
or su
and type in your root password, than any program with X11 access can keylog that password and gain root access itself. OR, they can simply send key events to any terminal that happens to be logged in as root. If you are able to sudo in as the subuser user, what prevents the programs that you are trying to keep away from having root access, from sudoing in as the subuser user?
Thanks for the reply. And no problem, be argumentative all you want. That's what we're here for.
I understand that docker isn't very good and you want to transition away from it, but from what I've read here you still aren't sure exactly which substitute to pick, and when the transition will be done, so this is as you say a temporary fix until then, that adds an extra layer of protection.
You see, my plan is to use subuser to protect my personal data from the most obvious entry points (like the browser) without a huge loss of performance/user experience that a separate VM usually brings, and then have the root/normal user separation (through sudo) in order to protect system integrity (from rootkits and such). Other very untrustworthy code I usually run under a VM or (more simple, but less secure) under a nonpriv user.
Of course, if it ever comes to the point where that root separation matters, then my personal data isn't protected any more (that's what backups and encryption are for!), but at that point they do not yet have full (invisible) control over my system (nor any other dual-booted OS running on the same machine, for example).
Of course, if my main user is part of the docker group, this root separation basically disappears. My idea was to keep it by limiting subuser to a separate user, such that I could control access to the docker group, still keeping the sudo/kernel bug barrier for any attack to compromise my system integrity.
As you say, anything that gets access to my X11 server could keylog anything else. Subuser uses the Xpra bridge to fix that problem for stuff running under it, of course, but stuff running under my main user is free to keylog the sudo command and get sudo access.
I had actually considered that possibility. But you see, I setup my sudoers file in order to reduce to the maximum the number of times I might ever have to write my password. For example, I make "subuser run firefox" NOPASSWD as well as other harmless, frequently used commands (like "apt-get update"/"apt-get upgrade"). This effectively means that an attacker with X11 access would have to wait something like one month to actually find my own password.
Sure, it's not completely safe, but I feel like it's a relatively good compromise between safety and user experience, and better (more layers) than simply giving root equivalence to the main user by adding him to docker.
What do you think about running subuser as root? You could have a TTY open that would run as root (usually locked http://unix.stackexchange.com/questions/32351/is-there-a-way-to-lock-command-line ) and you could run subuser in that TTY as root. That would prevent any keylogging and would lead you to NEVER have to type your root password in through X11.
That is an interesting possibility, and I hadn't thought of that.
I don't think it matches my use case completely. I wish to be able to use my software almost as if I wasn't running it under a sandbox.
The way I have my VM set up right now (I've been using a VM to play around with subuser without modifying my normal install), I use the following shell script to run Firefox through subuser (firefox.sh):
#!/bin/bash
source /home/main_user/subuser/subuser_alias.sh
subuser_bgnd_firefox() {
xhost +SI:localuser:subuser
xauth -v -i extract /home/subuser/.Xauthority_subuser $DISPLAY
local subuser_cmd="sudo -u subuser XAUTHORITY=/home/subuser/.Xauthority_subuser DISPLAY=$DISPLAY -- $SUBUSER_PATH/subuser run firefox $@"
tmux has-session -t 'firefox' &> /dev/null
local tmux_firefox_session=$?
if [ $tmux_firefox_session -eq 0 ]
then
tmux new-window -a -t "firefox" -n "w`date +%s`" -d "$subuser_cmd"
else
tmux new-session -s "firefox" -n "w`date +%s`" -d "$subuser_cmd"
fi
}
subuser_bgnd_firefox > log.txt
Together with the sudoers lines:
Defaults env_keep+="SUBUSER_DEBUG_XPRA"
# Cmnd alias specification
Cmnd_Alias SUBUSER=/usr/local/bin/subuser run firefox, /usr/local/bin/subuser repair, /usr/local/bin/subuser update
# Allow normal user to run SUBUSER certain subuser commands without requiring password
main_user ALL=(subuser) NOPASSWD: SUBUSER
This makes it so that I can use firefox.sh to open Firefox without ever entering my password. I added this to a .desktop file in my taskbar, which basically runs firefox under the sandbox automatically with a hidden terminal session under tmux (this seems to be necessary, in order for the GUI to work). Basically, the only time you notice anything is different from a normal Firefox session is that you cannot save outside of the allowed directories, nor can you open downloaded files automatically from inside Firefox.
A solution like you mention, while possibly safer, has the annoyance of having to switch to the TTY session everytime you wish to launch an application (or a new window), which isn't exactly what I had in mind.
Please try out my new code. Hopefully, you can use your sudoers file trick with the root user as well. However, I haven't played with this much yet. Beware!
So, from what I understand, you can simply do "sudo subuser run firefox" and it'll run the subuser firefox as if I myself called it, with all the files (including the ./subuser folder) under my home directory, but without requiring me to be part of the docker group? Sounds perfect for my objectives.
I'll test it out later today or tomorrow. Thanks!
The .subuser
folder stays under /root/
(And owned by root, otherwise, "sudo subuser run firefox" wouldn't be safe, because the normal user could change firefox's permissions to give it root access.) but you can set the folder where your subuser's home directories will be, and that can be in your normal user's home dir.
Just tested it, and it seems to work fine. However, I've got this permission:
"user-dirs":["Downloads"]
It creates the /home/user/Userdirs/Downloads symlink, but it does not allow me to write to it (permissions denied), nor can I see any files I might place in my own Downloads folder. This, however, worked before when I was running everything under a separate "subuser" user (except it symlinked with user subuser's Download folder instead of my main user's).
Um, that would be a bug. Is it fixed now?
BTW: once I get this http://unix.stackexchange.com/questions/234326/change-ownership-of-file-from-a-user-to-another-user-which-the-first-user-contro figured out, than I should be able to support running subser as a normal user, and not just as root.
Haven't been able to figure out why it happens, no. So yes, there is a bug :)
And as for running under a normal user, that would be perfect!
Yes, but did my last commit fix that bug: https://github.com/subuser-security/subuser/commit/5acee088671dc02ef9ebb7169f92196ba2106092 ?
Yeah, everything is working fine now!
Oh, wait. You were still planning to add the possibility of running it under another user. Sorry, I'll re-open it then.
@ruipgpinheiro yep, as soon as you answer my stackexchange question :P
Could that not be solved by having both users share the same group? I mean, if user1 and user2 both belong to group1, and user1 gives group write permissions to the files, user2 can easily access the file, even if the file isn't owned by him. Why exactly do you want files to be owned by user2?
Anyway, I am relatively happy with the current implementation (running subuser under root). It's much better than "give yourself the docker group", since at least now your main user keeps some separation from root privileges, especially if you use the sudoers NOPASSWD functionality for your most used commands.
Well, the directories being created really should be owned by the EndUser
user. You can take a look here https://github.com/subuser-security/subuser/commit/6e899a05175a2dc483c897e483739966f734a728 . Pay attention to getEndUser().makedirs
and getEndUser().chown
. These are files and directories that should be owned by the end user, and not by the "proxy user".
There is an alternative, which is to require subuser to run once under root, a sort of setup, to prepare all those files and group permissions. If necessary, you could enforce subuser subuser add
under root, while allowing the subusers themselves to run with the other user.
Nah, here in the subuser project we eat user friendliness for breakfast lunch and dinner :) . That solution is way to complicated. If I don't get a solution on stack exchange in the next 24 hours, I'll do something uglier, but under the covers, so as to not disturb the user experience.
I mean, it wouldn't be THAT unfriendly. You could have (for example) subuser subuser add
call itself with sudo if it is configured to use a proxy user. The only thing most people would notice is a password prompt...
But I see the point.
Well, I'm considering making this a really truely first class feature of subuser, because I think it'll make the transition away from Docker and towards runc+some storage backend easier.
Unfortunately, I really like the current functionality of subuser, where simply copying my home directory to a new computer and running subuser repair
gets me all my subusers back, configured just as they were before. With this method, the .subuser
directory is in the proxy user's home dir, and that is messy when it comes to backups.
Instead of copying a single folder, you have to copy two folders... Is it really that bad?
If you're that worried, make a subuser backup
command that can tar both folders into a file (or the "homes" folder, together with the necessary configuration files for the repair), and also restore them (and auto-repair) from the file?
What I imagine a good solution looking like is that there would be a subuser
user account which subuser would run as. The .subuser
directory would reside in the end user's home directory and be owned by the end user. The end user would be able to lauch subuser with sudo and NOPASSWD
. However, the end user would not be allowed to run subusers which had the as-root
and sudo
permissions . In order to do that, they would have to enter the system's root password. The problem is, this bug here https://github.com/subuser-security/subuser/issues/229 . I think that bug is unresolvable without user namespaces, and it seems that Docker has some pretty fundamental problems with it's architecture in implementing user namespaces. This is going to be a difficult transition, but I think that the two features (moving away from docker, and making subuser be able to run as a proxy user) require eachother mutually.
I'm closing this issue for now. It has not been forgotten about, but the planned transition to runc completely changes the landscape for this sort of thing.
While subuser is pretty great, there is still a relatively large problem due to docker - you must run it under a user belonging to the docker group, which effectively means any application running under that user has root access.
That wouldn't be a huge problem if almost everything was run under subuser, but I don't have the patience to do so, and will only sandbox a few specific applications that serve as common entry points (for example, firefox). Therefore, I needed some way to keep my main user account outside the docker group (in order to not give anything I might ever run easy root privileges), but still be able to run subuser applications.
My idea was to create a second user, 'subuser', which belongs to the docker group, and use it to run the docker applications themselves. Thing is, subuser does not allow itself to be run with a different user. You can use 'sudo', but then you run into a few problems with X11.
This could very likely be fixed right into the code-base, such that a user could configure the user to use to access the docker daemon.
I managed to come up with this bash function as a workaround, which wraps around the 'subuser' command and calls it under a 'subuser' user:
Summed up, I add 'subuser' to the allowed users to access my X server, and then generate a new authority file for that user. Afterwards, I can just run subuser with the newly generated authority file and any given commands. I can then for example install firefox and whitelist "xauth -v generate :0 . trusted" as well as "subuser run firefox" under the 'subuser' user, in order to launch firefox without password prompts.
Alternatively, give your main user write permissions to the subuser's .Xauthority file, and then use this bash method:
For both of these, you'll probably also need to modify your sudo env_keep variable, or subuser will try your /home/main_user/.Xauthority file instead.
There's probably better ways of doing it. And, of course, it'd be better if the code supported something like this by default.