Managing Users and Groups
One of the easier non-trivial aspects of the RHCSA objectives
is the setup of users and groups. They have an entire section for this, putting this
on an equal footing with all of the common command line (sed, grep, su, chmod) access
items. I would recommend starting with info coreutils user
to get the docs for id
, logname
, whoami
, who
, groups
, and users
.
man usermod
shows
these in “SEE ALSO”:
- chfn(1)
- chsh(1)
- passwd(1)
- crypt(3)
- gpasswd(8)
- groupadd(8)
- groupdel(8)
- groupmod(8)
- login.defs(5)
- useradd(8)
- userdel(8)
From RedHat’s page, we see (as of today) the following items listed under “Manage users and groups”:
- Create, delete, and modify local user accounts
- Change passwords and adjust password aging for local user accounts
- Create, delete, and modify local groups and group membership
- Configure a system to use an existing authentication service for user and group information
Creating and deleting and groups accounts is straightforward (useradd, groupadd, userdel, groupdel), but modifying accounts is non-trivial. Using an ‘authentication service’ implies probably ldap or kerberos. LDAP is a larger topic than goes here. I’ll talk about the other information in this post. Setting passwords with passwd is straightforward, but managing the lifespan and expiration dates was new to me. As a home user, I typically set passwords to not expire (I assume most people do this). At work, we reset passwords on all machines randomly whenever we have a user leave the company, with every machine account set uniquely and randomly. If we ever had a time without any turnover, the passwords would possibly stay the same indefinitely.
As a system administrator, I see group membership changed
incorrectly at least once a month among my peers, in an environment where
most of the decisions have already been taken. cPanel systems tend to restrict
access to several systems based on group membership. We have an internal hardening
that assigns wget and curl to the get-users
group, and only users in this group
can access those commands. Similarly, cPanel supports an equivalent compiler
group
that can access the gcc toolchain on the system. Ubiquitous in Unix is the group wheel
that is often the only set allowed su access, or can be given automatic sudo privileges.
The video course from Sander van Gudt does go over this pretty exhaustively. The setgid and sticky bits on directories are explained, and methods for allowing read-write access to, but not allowing deletion of, files in common directories is covered. The permissions model (user/group ownership and permissions, and ACL’s) needs to be understood as well.
usermod
The most common pitfall I see is with the usermod
command, where the -G
or -g
options are confused.
The capital G sets the list of supplementary groups this user belongs to.
The lower case g sets the initial group, which in RedHat and CentOS was a group with
the same name as the user, and a single member. That is:
useradd newbie
id newbie
outputs this:
uid=1001(newbie) gid=1001(newbie) groups=1001(newbie)
We can add this user to a new set of groups as the secondary list:
groupadd new-users
usermod -G new-users newbie
id newbie
And we see the new situation showing two groups.
uid=1001(newbie) gid=1001(newbie) groups=1001(newbie),1002(new-users)
Why the initial group matters
The users primary group will be the group ownership assigned to any uploaded, created, or copied files. This can be very important in the context of shared content, and setting this incorrectly can lead to some security problems.
Let’s take a simple example. We have four users sam
, tim
, mark
, and brian
.
Each are members of the blue-team
group, and now a fifth person is added to
the blue-team. That is we have a situation like this:
id sam
uid=1003(sam) gid=1005(sam) groups=1005(sam),1003(blue-team)
Sam’s home directory has files set sam:sam
(user sam, group sam)
and permissions 751 on the directory.
This allows group members to access files in /home/sam/blue-team, where files are set
group blue-team. Then Dave joins the team. Sam su
’s to root, and creates an account
for Dave, incorrectly:
useradd dave
usermod -g blue-team dave
Now dave only belongs to the group blue-team
, and all his files are accessible
to the team, including his mail directory, where he plans with the boss to get Sam
fired. Bad days for Dave.
However, for the user’s home directories, that’s actually less of an issue. The default
behavior is to set /home/$USERNAME
to permissions 700, and that means Sam can’t access
/home/dave/secrets.
cat /home/dave/secrets
cat: /home/dave/secrets: Permission denied
In cPanel environments, the home directory has broader permissions, 711, to allow
the access of these files by the nobody
user, since the document roots in cPanel shared
hosting are under /home/$USERNAME/public_html/
,
rather than in a location like /var/www/
that’s more common under stock Linux installations.
This would allow the users in blue-team to access the content in the directory.
On my debian systems at home, the permissions on user homes are broader still, set to
755 (others can list the directory content, while in cPanel they can cd
but not ls
).
Overwriting the current secondary groups
Apart from confusing the -g
and -G
options, there’s also the destructive update
behavior of the -G
option. For example, Tim needs access to the system compiler,
and the gcc binary is set 750 root:compiler. Sam now wants to add Tim to the compiler
group to accomplish this. Reading the man page for usermod
, he find -G
, remembers
his bad experience with Dave last week, and issues the following:
usermod -G compiler tim
Sam should check his work, since this removed Tim from the team (and Tim will not be getting that report done this weekend!):
id tim
uid=1004(tim) gid=1006(tim) groups=1006(tim),1009(compiler)
There is a -a
append option that needs to be used, and setting this straight requires
one of the following two commands:
usermod -G blue-team,compiler tim
usermod -a -G blue-team tim
Either should give the end state as desired:
id tim
uid=1004(tim) gid=1006(tim) groups=1006(tim),1003(blue-team),1009(compiler)