Server-Administration

Benutzerverwaltung unter Linux

18.02.2011 von Thomas Steudten
Linux ist ein Multi-Tasking- und Multi-User-Betriebssystem. Somit können mehrere Benutzer die vorhandenen Ressourcen wie Prozessoren, Netzwerk, Arbeitsspeicher und Festplatten parallel nutzen. Wir zeigen Ihnen, wie Sie Benutzer mit Gruppen und Verzeichnisdiensten verwalten.

Spätestens beim sogenannten Login von Linux wird der Benutzer aufgefordert, seinen Benutzernamen und sein Passwort zur Authentifizierung einzugeben. Der Linux-Kernel verifiziert mit diesen Angaben, welche Rechte ein vom Benutzer gestarteter Prozess im System und auf Dateisystemebene hat (Autorisierung).

Linux verwendet, wie jedes andere Unix-Betriebssystem auch, Benutzer- (User-) und Gruppen-Identifikationen für die Rechtekontrolle. Jede Datei und jedes Verzeichnis im Dateisystem verfügt über Besitz- und Zugriffsrechte. Letztere bestimmen, welche Rechte ein Systembenutzer für das Objekt hat. Einfache Zugriffsrechte sind Lesen, Schreiben und Ausführen. Diese werden drei Klassen von Nutzern zugeordnet:

Jede Klasse kann unterschiedliche Zugriffsrechte besitzen; beispielsweise kann der Besitzer einer Datei diese lesen und schreiben, die Dateigruppe kann nur lesen, und alle anderen Prozesse haben keinen Zugriff darauf. Zuständig für das Setzen der Zugriffsrechte sind die Systemaufrufe "chmod" oder "fchmod" und der Kommandozeilenaufruf "chmod". Beispielsweise setzt "chmod u=rw,g=r,o-a myfile" oder octal "chmod 640 myfile" genau diese Rechte. Access Control Lists (ACL) sind weitergehende Zugriffsrechte und erlauben eine feiner granulierte Rechtesteuerung.

Der Kernel markiert jeden auszuführenden Prozess mit der numerisch eindeutigen ID des Benutzers (UID) und seiner Gruppen (GIDs). Lediglich die UID und die GID mit dem Wert null werden vom Kernel besonders behandelt, denn diese beiden Werte sind dem Systemadministrator - besser bekannt als "root" - vorbehalten. Der root-User ist im klassischen System meist im Besitz aller Rechte. Als bedingte Abfrage in der Programmiersprache C lässt sich dies als "if (uid ==0) .." oder kürzer "if (!uid) .." implementieren.

Nummerische ID zu Namen

Während der Kernel effektiver mit den numerischen IDs agiert, haben wir Menschen es lieber mit Namen zu tun. Die Übersetzung zwischen beiden erfolgt traditionell über die für jeden Benutzer lesbaren Dateien "/etc/passwd" für die UID und "/etc/group" für die GID.

> ls -l /etc/passwd /etc/group

-rw-r--r-- 1 root root 1067 2011-02-01 15:00 /etc/group

-rw-r--r-- 1 root root 2248 2011-02-01 15:00 /etc/passwd

> grep ^thomas /etc/passwd /etc/group

/etc/passwd:thomas:x:1000:1000:thomas,,,:/home/thomas:/bin/bash

/etc/group:thomas:x:1000:

Der Benutzer "thomas" hat also die UID 1000 und auch die gleiche Default-Gruppen-ID 1000.

Welche Referenz für das Mapping verwendet wird, entscheidet der "Name Service Switch" (NSS) mit der Konfigurationsdatei "/etc/nsswitch.conf", die optional ist. Fehlt sie, werden Standardeinstellungen verwendet:

/etc/nsswitch.conf: Name Service Switch

passwd: compat

group: compat

shadow: compat

Mögliche vier Werte sind "files" für lokale Dateien, "db" für eine Datenbank, "nis" für das Network-Informationssystem (=YellowPages) oder "nisplus" für NIS+. "compat" bezeichnet eine spezielle Methode, die die lokalen Dateien konsultiert, aber dort NIS für einen Eintrag verwendet, wenn dieser mit einem Pluszeichen beginnt.

Gruppen

Die maximale Anzahl an Gruppen im System wird in der Kernel-Header-Datei "limits.h" auf 65536 definiert. Ein Benutzer kann per Default Mitglied in bis zu 32 Gruppen sein. Über die Gruppenmitgliedschaft ist es beispielsweise möglich, verschiedenen Benutzern Schreib- oder Leserechte auf Objekte im Dateisystem zu vergeben, die sonst für alle Systembenutzer nicht zugreifbar wären.

include/linux/cred.h:

#define NGROUPS_SMALL 32

include/linux/limits.h

#define NGROUPS_MAX 65536

Verzeichnisdienste

Ab einer bestimmten Anzahl von Nutzern ist es nicht mehr effektiv, die personifizierten Angaben lokal auf jedem System zu verwalten. Hier setzt man besser ein zentrales Verzeichnis ein, und die lokalen Angaben beinhalten oft nur noch systemrelevante Benutzer- und Gruppendaten (root, adm, ..).

Zu den verbreiteten Verzeichnisdiensten, die meist auf LDAP basieren, und den notwendigen Netzwerkzugriffsprotokollen zählen:

Linux zeigt mithilfe des Befehls oder Programms "id" aus dem coreutils-Paket die User-, Default-Gruppen- und weitere Gruppenmitgliedschaften-IDs namentlich und numerisch aus den bereits genannten beiden Dateien an:

> id

uid=1000(thomas) gid=1000(thomas) groups=1000(thomas),0(root),4(adm),20(dialout),24(cdrom),46(plugdev),105(lpadmin),119(admin),122(sambashare)

> id -u oder id -g

1000

> id -un oder id -gn

thomas

> id -Gn

thomas root adm dialout cdrom plugdev lpadmin admin sambashare

Eine neu angelegte Datei erhält als Gruppen-ID die aktuelle GID. Mittels "newgrp <group>" kann man ohne Passwort die aktuelle Gruppe wechseln, sofern man auch in der neuen Gruppe eingetragen ist. Eine neue Datei erhält ab dann die neue GID. "newgrp" ohne Argument weist die Default-Gruppe zu.

> id -un; id -gn

thomas

thomas

> touch myfile1; ls -l myfile1

-rw-r--r-- 1 thomas thomas .. myfile1

> id -Gn

thomas root adm dialout cdrom plugdev lpadmin admin sambashare

> newgrp adm

> id -gn

adm

> touch myfile2; ls -l myfile2

-rw-r--r-- 1 thomas adm .. myfile2

> newgrp

> id -gn

thomas

Passwörter für Authentifizierung

Mittlerweile sind die Passwörter für die UID- und GID-Authentifizierung nicht mehr in "/etc/passwd" und "/etc/group" abgelegt. Das Shadow-System legt diese Angaben nun in "/etc/shadow" und "/etc/gshadow" les- und schreibar nur für "root" und lesbar für die Gruppe "shadow" ab.

Eine Gruppe im Linux-System besteht optional aus dem Gruppenadministrator, einem Passwort und den Mitgliedern der Gruppe. Zur Gruppenverwaltung kann man die Befehle

für die Gruppe selbst und "gpasswd" für die Gruppenbenutzerverwaltung verwenden. Ein direktes Editieren der Dateien ist möglich, kann aber zu Problemen führen, wenn ein gleichzeitiger Zugriff darauf erfolgt. "vipw" oder "vigr" ermöglichen ein direktes Editieren und sperren die Datei für die Dauer der Bearbeitung.

Für die Benutzerverwaltung gelten analog die Befehle

und "passwd".

Gibt man keine UID oder GID bei "useradd" oder "groupadd" vor, so wird gemäß den Vorgaben (je nach Derivat) in der Datei "/etc/login.defs" eine passende gewählt. Die Vorgaben vom System (Defaults) für "useradd" kann man mittels "useradd -D" ermitteln oder in der Datei "/etc/defaults/useradd" nachsehen.

> useradd -D

GROUP=100

HOME=/home

INACTIVE=-1

EXPIRE=

SHELL=/bin/sh

SKEL=/etc/skel

CREATE_MAIL_SPOOL=no

Neuen Benutzer anlegen

Einen neuen Benutzer richtet man per "useradd <username>" ein, löscht diesen wieder mit "userdel <username>" oder modifiziert Einstellungen mit "usermod .. <username>".

Einen Nutzer mit dem Login "alen", der gleichen Default-Gruppe, der Gruppenzugehörigkeit "cdrom", der Shell "/bin/bash", einem Kommentarfeld, einem eigenen (Home-)Verzeichnis unter "/home" und einem zeitlichen Login-Ablauf auf den 1. März 2011 legen wir so an:

# useradd -c "Alfred E. Neumann" -m -e 2011-03-01 -U -G cdrom -s /bin/bash alen # Neu

> id alen

uid=1001(alen) gid=1001(alen) groups=1001(alen),24(cdrom)

> ls -ld /home/alen

drwxr-xr-x 2 alen alen 4096 2011-02-03 12:17 /home/alen

> ls -A /home/alen

.bash_logout .bashrc examples.desktop .profile

Die Dateien im neu erstellen Home-Verzeichnis des Users werden per Default von "/etc/skel" kopiert. Der Account des neuen Nutzers ist noch gesperrt ("L" bei Ausgabe "passwd -S .."), und es muss noch ein Passwort vergeben werden:

# passwd -S alen

alen L 02/14/2011 0 99999 7 -1

# passwd alen

..

passwd: password updated successfully

# passwd -S alen

alen P 02/14/2011 0 99999 7 -1

Wir geben dem Nutzer "alen" noch eine weitere Gruppenzugehörigkeit:

# usermod -a -G admin alen

> id alen

uid=1001(alen) gid=1001(alen) groups=1001(alen),24(cdrom),119(admin)

Möchte man einen Account einschließlich des Home-Verzeichnisses und der lokalen Mailbox löschen, dann lässt sich dies per "userdel" bewerkstelligen:

# userdel -r alen

Eine vorhandene crontab-Datei bleibt bestehen, wird aber aufgrund des fehlenden Shell-Eintrags in /etc/passwd nicht ausgeführt. Wir haben den Account so angelegt, dass dieser zu einem definierten Datum deaktiviert wird. Ein Passwort sollte nach einer bestimmten Zeit geändert werden, und die Zeitspanne in Tagen kann man per "chage" setzen:

# chage -l alen

Last password change : Feb 14, 2011

Password expires : never

Password inactive : never

Account expires : Mar 01, 2011

Minimum number of days between password change : 0

Maximum number of days between password change : 99999

Number of days of warning before password expires : 7

# chage -M 30 alen

Last password change : Feb 14, 2011

Password expires : Mar 16, 2011

Password inactive : never

Account expires : Mar 01, 2011

Minimum number of days between password change : 0

Maximum number of days between password change : 30

Number of days of warning before password expires : 7

Mehrfache Einträge

Mit dem Befehl "useradd" kann ein anderer Nutzeraccount, aber mit gleicher UID angelegt werden:

# useradd -c "Alfred E. Neumann" -m -e 2011-03-01 -U -G cdrom -s /bin/bash -o -u 1001 alen1

> id alen1

uid=1001(alen) gid=1003(alen1) groups=1001(alen),24(cdrom)

Die Zuordnung von UID zu Namen erfolgt dabei so, dass der erste gefundene Eintrag für die UID (in /etc/passwd) benutzt wird.

Benutzer wechseln

Switch-User (su) ermöglicht das Ausführen von Prozessen unter einer anderen Benutzer-ID. Root darf dies ohne Authorisierung, alle anderen Benutzer benötigen das Passwort für den Account. "su - alen" startet eine neue Shell inklusive der Login-Dateien für den Benutzer "alen" unter Verwendung der zugehörigen Login-Shell. Nachteil hierbei ist, dass stets das Passwort eingegeben werden muss.

"sudo" bietet als Zusatzpaket mehr Möglichkeiten und merkt sich auch eine erfolgreiche Autorisierung für eine bestimmte Zeit. Die Konfigurationsdateien liegen unter "/etc/sudoers*". Per "visudo -f /etc/sudoers.d/mysudoers" kann die Datei bearbeitet werden.

"sudo <cmd>" führt <cmd> als Root aus, und "sudo -s" startet eine Shell. Mit "sudo -i -u alen" wird eine Login-Shell für den Benutzer "alen" aufgerufen.

Im Kernel

Damit der Kernel die Zugriffsrechte überwachen kann, sind Strukturen erfordeerlich, in denen die notwendigen Angaben mitgeführt werden. Beim Anmelden am System erhält die Login-Shell die UID und GIDs des Nutzers und vererbt diese an neu generierte Prozesse weiter. Für jeden Befehl auf der Kommandozeile generiert die Shell über die Systemaufrufe fork() oder exec() einen neuen Prozess. Threads nach POSIX.1 vererben die UID und GUIDs vom ausführenden Prozess.

Schauen wir uns die Strukturen in den Linux-Quellen etwas näher an:

include/linux/sched.h:

struct task_struct {

volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */

..

/* process credentials */

const struct cred __rcu *real_cred;

const struct cred __rcu *cred;

..

}

Die Struktur "task_struct" wird vom Kernel mit allen notwendigen Angaben versehen, um einen Prozess zu managen. Dort enthalten ist auch eine Referenz auf die Struktur "cred", die Informationen über die UID und die GIDs des Prozesses liefert.

Es sind vier Paare für Prozess- und Gruppen-ID im Linux-Kernel definiert:

struct cred {

..

uid_t uid; /* real UID of the task */

gid_t gid; /* real GID of the task */

uid_t suid; /* saved UID of the task */

gid_t sgid; /* saved GID of the task */

uid_t euid; /* effective UID of the task */

gid_t egid; /* effective GID of the task */

uid_t fsuid; /* UID for VFS ops */

gid_t fsgid; /* GID for VFS ops */

struct group_info *group_info;

..

}

Hier noch ein Beispiel für ein setuid-Programm:

> cp /usr/bin/id myid

> ./myid

uid=1000(thomas) gid=1000(thomas) groups=1000 ..

# chown root myid; chmod 4750 myid; ls -l myid

-rwsr-x--- 1 root thomas 26152 2011-02-14 16:43 myid

> ./myid

uid=1000(thomas) gid=1000(thomas) euid=0(root) ..

Fazit

Auf Mehrbenutzersystemen können eine gezielte Rechtevergabe und die Gruppenzugehörigkeit die Systemsicherheit erhöhen, ohne dass aus Bequemlichkeit allen Nutzern der volle Zugriff ermöglicht wird.

Praktischerweise lässt sich unter Linux zwischen unterschiedlichen Gruppen eine Zugriffstrennung konfigurieren. Dabei kann auch ein nicht privilegierter Benutzer per sudo bei Bedarf einen privilegierten Zugriff ohne Authorisierung erhalten.

Die Steuerungsmöglichkeiten der Benutzerverwaltung sind unter Linux sehr vielfältig. Allerdings ist die Konfiguration nicht immer selbsterklärend, wenn man mit den Zugriffsmechanismen des Linux-Kernels nicht vertraut ist. (cvi)