blu.org  wiki

Derek's Unix Sysadmin tip of the day

View: New views
3 Messages — Rating Filter:   Alert me  

Derek's Unix Sysadmin tip of the day

by Derek Martin-9 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm surrounded by smart people who know Unix/Linux very well, but from
time to time I still hear that people think what I'm about to describe
is impossible.  I typed most of this up for a reason that became
superfluous by the time I was done, so I figured I'd share it with you
all, and at least *someone* is bound to find this useful. :)

The problem is this:  How do you give write access to a file to one
group of users, and give read access to a second group of users, while
giving NO access to all the rest of the users on the system?  Unix
only allows for the owner, a named group, and everyone else...

I assure you, you don't need extended ACLs to solve this problem; Unix
is perfectly capable to handle it.  The answer is, you use directory
permissions.  You may still be unconvinced, so I will explain in
detail.  [Astute readers will note that the case I describe below can
be optimized a bit.  The method below is the most general and assumes
that neither group is a subset of the other, nor can it be treated
that way, due to access restrictions on other files not considered.]

You have two groups that need access.  You need THREE Unix groups to
put them in... each user in those two groups will be put in exactly
two of the three Unix groups.  In our example, we have some
accountants who need to create accounting documents, and need to be
able to change those documents.  We also have a group of auditors, who
need to be able to read the documents, but must not be allowed to
write to those documents.  We create the obvious two groups: accnting,
and auditors, and put the users in their respective Unix groups.  The
key is, we add a third Unix group, let's say finance, and put all of
the users in BOTH groups in the finance group:  

accnting:x:750:user1,user3
auditors:x:751:user2,user4
finance:x:752:user1,user2,user3,user4

Then, as root, you set up the directory structure you will need to make this
work:

[/tmp] $ sudo mkdir /tmp/finance
[/tmp] $ sudo chgrp finance /tmp/finance
[/tmp] $ sudo chmod 2770 /tmp/finance
[/tmp] $ ls -ld /tmp/finance
drwxrws--- 2 root finance 4096 2009-10-23 23:41 /tmp/finance/
[/tmp] $ sudo mkdir /tmp/finance/accounting
[/tmp] $ sudo chgrp accnting /tmp/finance/accounting
[/tmp] $ sudo chmod 2775 /tmp/finance/accounting
[/tmp] $ sudo ls -ld /tmp/finance/accounting
drwxrwsr-x 2 root accnting 4096 2009-10-23 23:44 /tmp/finance/accounting


But there's one last problem here.  An accountant goes in and creates
an accounting file.  He's always dealing with sensitive data, so his
umask is set to 027, so no one who isn't supposed to can mess with his
data.  All well and good.  Then he creates his file:

[/tmp] $ sudo su user1
[/tmp] $ id
uid=750(user1) gid=750(accnting) groups=750(accnting),752(finance)
[/tmp] $ cd /tmp/finance/accounting
[/tmp/finance/accounting] $ echo this is an accounting file > actfile1
[/tmp/finance/accounting] $ ls -l actfile1
-rw-r----- 1 user1 accnting 27 2009-10-24 00:05 actfile1

Now, at this point, only that user can write to the file.  He needs to
make it so that the other accountants can modify it, and the auditors
can read it (but NOT write to it)!  So he does this:

[/tmp/finance/accounting] $ chmod 664 actfile1
[/tmp/finance/accounting] $ ls -l actfile1
-rw-rw-r-- 1 user1 accnting 27 2009-10-24 00:05 actfile1

But wait, this file is world readable!  Doesn't that mean any user on
the system can read it?!?!?   NO, it doesn't.  Why not?  Because the
directory permissions leading to this file prevent that...  Remember
how we set up /tmp/finance?  Like this:

[/tmp] $ ls -ld /tmp/finance
drwxrws--- 2 root finance 4096 2009-10-23 23:41 /tmp/finance/

We needed that extra directory level to act as a gate, to keep out the
riff-raff.   So only users in the finance group can descend below
/tmp/finance, which includes everyone in the accnting group, and
everyone in the auditors group.  Then, /tmp/finance/accounting is at
least readable and cd-able (the execute bit) by everyone... so again,
both groups can cd to that directory, but all other users will be
prevented by the more strict permissions on /tmp/finance.  We can
confirm that this is true for our auditor (user2):

[/tmp/finance/accounting] $ exit
[/tmp] $ sudo su user2
[/tmp] $ id
uid=751(user2) gid=751(auditors) groups=751(auditors),752(finance)
[/tmp] $ cd /tmp/finance/accounting/
[/tmp/finance/accounting] $ cat actfile1
this is an accounting file
[/tmp/finance/accounting] $ echo foo > actfile1
sh: actfile1: Permission denied

Perfect: the auditor can read the file, but can not write to it, even
though it is writable by other accountants.  We can also show that
other users can not access this file:

[/tmp/finance/accounting] $ exit
[/tmp] $ sudo su user3
[/tmp] $ id
uid=752(user3) gid=600(staff) groups=600(staff)
[/tmp] $ cd /tmp/finance/accounting/  
sh: cd: /tmp/finance/accounting/: Not a directory
[/tmp] $ ls -l /tmp/finance
ls: cannot open directory /tmp/finance: Permission denied
[/tmp] $ cat /tmp/finance/accounting/actfile1
cat: /tmp/finance/accounting/actfile1: Permission denied

The shell gives us a weird error when we try to cd
(/tmp/finance/accounting/ most certainly is a directory), but
otherwise we get exactly what we expect: this user, who is not a
member of the finance group, nor accnting nor auditors, can access any
part of this tree from /tmp/finance down.  This is exactly what we
want.

So, think Unix suffers for not having extended ACLs?  Poppycock, I
say!  (Of course it has them, if you really really really want them,
but...)  You just need to think about how to organize your users and
data into groups that make sense.  There are some limitations on group
memberships, especially with NFS, but if you exceed them, it probably
means that either your data organization needs some more work, or
you've got some folks with WAY, WAY too many hats.  =8^)

--
Derek D. Martin    http://www.pizzashack.org/   GPG Key ID: 0xDFBEAD02
-=-=-=-=-
This message is posted from an invalid address.  Replying to it will result in
undeliverable mail due to spam prevention.  Sorry for the inconvenience.

_______________________________________________
Discuss mailing list
Discuss@...
http://lists.blu.org/mailman/listinfo/discuss

Re: Derek's Unix Sysadmin tip of the day

by Bill Bogstad :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Oct 24, 2009 at 3:27 AM, Derek Martin <invalid@...> wrote:
> I'm surrounded by smart people who know Unix/Linux very well, but from
> time to time I still hear that people think what I'm about to describe
> is impossible.  I typed most of this up for a reason that became
> superfluous by the time I was done, so I figured I'd share it with you
> all, and at least *someone* is bound to find this useful. :)

Great post.  I've done something like this, but never saw the idea of
using membership of a group used as a gateway in quite this way before
now.  Some comments/suggestions:

1. You seem to have complicated your example somewhat by having an
'auditors' group.  No file or directory in your example is ever placed
in that group.  The important thing is that the auditors' accounts are
not in the accnting group and are in the finance group.

2. If people have multiple roles (in a single account) you can't
always assume that their primary group is the one in
which you want files to be created.  (The primary group is the one
which is normally used to set group ownership on new files.)
Fortunately, there is a mechanism to 'force' group ownership of new
files into a specified group.  If you do a 'chmod g+s directoryname'
on a directory all new files/directories created underneath that
directory will be created with the same group
as directoryname.  Even better, it seems like any new directories that
you create will have g+s automatically set as well.   So once you
start a directory tree this way, all descendant directories/files will
have the same properties. (I'm not sure if this is peculiar to
specific versions of Linux or not as I only recently learned about it
myself.)  In your example, I would have done a

sudo chmod g+s /tmp/finance/accounting

to make sure that all files created from that point down in the tree
were in the accounting group.

3. A variant of this can be done which allows an unprivileged user to
share access to a directory tree to multiple users
without recourse to groups.  Unfortunately, it doesn't really allow
me to do more then yes/no access unlike the groups method.

Here is a an example:

mkdir /tmp/secretstuff
chmod 711 /tmp/secretstuff
mkdir /tmp/secretstuff/FunKyPassword
chmod 755 /tmp/secretstuff/FunKyPassword

In this case the gateway mechanism, isn't based on membership in a
particular group, but rather on knowledge of the directory name
'FunKyPassword'.  Anyone who knows the pathname
/tmp/secretstuff/FunKyPassword can get there, but without that
knowledge you would have to do a brute force attack by trying all
possible strings in that position.  'FunKyPassword' can leak if you
aren't careful via command line arguments (i.e. ps).  Environment
variables set by 'cd' macros/functions might be an issue was well, but
it seems like on most systems only the owner (or root) can view them
with ps.  Shell history files are another possible 'leakage' point if
you aren't careful.  (Which is already a privacy concern
if they are world readable.)

GOOD usage:

cd /tmp/secretstuff/FunKyPassword
vi boring.txt

'cd' doesn't show up in 'ps' commands and /proc/###/cwd isn't
accessible to non-privileged users.

BAD usage:

vi /tmp/secretstuff/FunKyPassword/boring.txt

'ps' will show full pathname.

Individual accessors of this restricted directory can make it more
user friendly with something like the following:

mkdir $HOME/secrets
chmod 700 $HOME/secrets
ln -s /tmp/secretstuff/FunKyPassword $HOME/secrets/funky

Now I can do "cd $HOME/secrets/funky" instead of "cd
/tmp/secretstuff/FunKyPassword".

The chmod 700 on secrets means that the easy to remember aliases for
the more complicated passwords
are only usable by the owner of the $HOME/secrets directory (me).
Shell completion of directory names will
work for cd $HOME/secrets as well.  Multiple users can share access to
different directory trees with me and I can put
all of the symbolic links in $HOME/secrets without compromising the
independence of their security.

Yes, $HOME/secrets is the equivalent of writing down the password.  As
I see it, if my account/the system has been compromised to the point
that setting permissions to 700 isn't enough then they could trojan
horse my account anyway and grab the password/directory name that way.
 (Or easier yet just read it from my .bash_history file.)

Historically, I first saw the idea of having a directory name be a
password used with anonymous ftp upload sites.
If you knew the name of the world writable directory you could cd
there and upload files.   Since all access was via
ftp; leakage via ps, etc. wasn't relevant.  Local shell accounts were
assumed to be trusted.  I still think it is useful even
if you assume local attackers, but you do have to be more careful.

Bill Bogstad

_______________________________________________
Discuss mailing list
Discuss@...
http://lists.blu.org/mailman/listinfo/discuss

Re: Derek's Unix Sysadmin tip of the day

by Derek Martin-9 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Oct 24, 2009 at 02:24:40PM -0400, Bill Bogstad wrote:
> Great post.  I've done something like this, but never saw the idea of
> using membership of a group used as a gateway in quite this way before
> now.

Glad you got something out of it... :)

> 1. You seem to have complicated your example somewhat by having an
> 'auditors' group.  No file or directory in your example is ever placed
> in that group.  The important thing is that the auditors' accounts are
> not in the accnting group and are in the finance group.

Right, I alluded to this:

> > [Astute readers will note that the case I describe below can be
> > optimized a bit.  The method below is the most general and assumes
> > that neither group is a subset of the other, nor can it be treated
> > that way, due to access restrictions on other files not
> > considered.]

I described it the way I did, because in most real environments, the
two groups will indeed have different roles, and the auditors will
need control over at least some files that the accountants should not
have access to, and vice versa.  In my simple example, it works to
reduce the number of groups, and put all the users in one group, and
only the accountants in their own group.  In practice, it's unlikely
to work out that way (though it very much depends on the size and
complexity of your organization).

[...]
> Fortunately, there is a mechanism to 'force' group ownership of new
> files into a specified group.  If you do a 'chmod g+s directoryname'
> on a directory all new files/directories created underneath that
> directory will be created with the same group as directoryname.
> Even better, it seems like any new directories that you create will
> have g+s automatically set as well.
[...]
> sudo chmod g+s /tmp/finance/accounting

Indeed, I did exactly that, though I didn't describe why, and the
commands I used were different than the ones you suggest:

> > [/tmp] $ sudo chmod 2770 /tmp/finance
> > [/tmp] $ ls -ld /tmp/finance
> > drwxrws--- 2 root finance 4096 2009-10-23 23:41 /tmp/finance/

The leading '2' in the chmod command is what does this (there's a
fourth set of bits, represented as the left-most digit, which controls
the SUID, SGID, and Sticky bits, in that order).  I usually use the
numeric representation of the permissions with chmod, because, if you
know them in advance, you can set them exactly with one command.
Though I sometimes find that modifying permissions is easier to think
about in terms of the symbolic method, e.g.:

 $ chmod a-w foo

...which removes the write bit from all three sets of bits.


> mkdir /tmp/secretstuff
> chmod 711 /tmp/secretstuff
> mkdir /tmp/secretstuff/FunKyPassword
> chmod 755 /tmp/secretstuff/FunKyPassword

The trouble with this is, if you know that the data exists, even if
you don't know *where*... it may not be all that hard to find out.  If
you know someone who works on that data, it's probably easy enough to
walk over to them, make a pretense as to why you're there, and then
scan their terminal window.  Chances are pretty good it'll be there
somewhere, if it's the sort of thing they work on a lot.  As you point
out, you can also scan ps output, as it may show up if someone is
working on a file there and specified the full path, or enough of the
relative path to reveal the location.  You might well use something
like this to secure love notes to your wife (which probably isn't
useful unless she has access to your system), but not your company's
trade secrets or financial documents... ;-)

It is a useful trick though.  It prevents users from having a shell
with that directory as its current working directory, may slow an
attacker down enough to give you a chance to catch them (security
through obscurity does have its uses, even if it can not be relied
upon solely), and may have other utility.

Now, for the bonus round:  Under certain circumstances, the method I
described fails.  When?

--
Derek D. Martin    http://www.pizzashack.org/   GPG Key ID: 0xDFBEAD02
-=-=-=-=-
This message is posted from an invalid address.  Replying to it will result in
undeliverable mail due to spam prevention.  Sorry for the inconvenience.


_______________________________________________
Discuss mailing list
Discuss@...
http://lists.blu.org/mailman/listinfo/discuss