Rechteverwaltung mit POSIX-ACLs Holger Jakobs holger@jakobs.com 2017-05-12 Inhaltsverzeichnis 1 Grundlagen zu Rechten 1 1.1 Die klassischen Unix-Rechte.......................... 1 1.2 Eigentümer und Gruppe............................ 2 1.3 voreingestellte Rechte.............................. 2 2 Erweiterte Rechte mit ACLs 3 2.1 Hilfsprogramme................................. 4 2.2 Rechte für weitere Benutzer.......................... 4 2.3 Rechte für weitere Gruppen.......................... 5 2.4 Ändern der Maske............................... 6 2.5 ACL-Einträge löschen.............................. 7 2.6 Rechte für neue Dateien............................ 7 3 Probleme und Grenzen 9 Die klassischen Unix-Rechte bei Verzeichnissen und Dateien gestatten nur die Vergabe von Lese-, Schreib- und Ausführungsrecht an den Eigentümer, die Gruppe und den Rest der Welt, was als zu grob angesehen wird. Oft möchte man Rechte an Teile einer Gruppe, an weitere einzelne Benutzer oder weitere Gruppen vergeben. Genau dies und sogar etwas mehr erlauben die Access Control Lists (ACLs), die mittlerweile von vielen Dateisystemen unter Unix und Linux angeboten werden und auch über das Netz (NFS) funktionieren. Hinweis zu Windows: Da Windows zwar auch sogenannte Access Control Lists verwendet, die dort verwendeten Rechte und Einstellungen aber völlig andere Bedeutungen haben, wird bei vielen Samba-Servern die Anzeige und Einstellung von Rechten durch Windows-Rechner nicht unterstützt, d. h. im Eigenschaften-Dialog von Dateien und Verzeichnissen der Freigaben von den Linux-Servern gibt es keine Registerkarte Sicherheitseinstellungen oder ein mit eingeschränkter Funktionalität. Die Rechte können dann nur direkt auf dem Linux-System eingestellt werden. 1
1 Grundlagen zu Rechten 1.1 Die klassischen Unix-Rechte Unter Unix bzw. Linux gibt es folgende Rechte: Lesen: Bei einer gewöhnlichen Datei bedeutet es, dass man den Inhalt der Datei lesen darf. Bei Verzeichnissen bedeutet es, dass man die Verzeichniseinträge lesen darf (Directorylisting). Schreiben: Bei einer gewöhnlichen Datei bedeutet es, dass man den Dateiinhalt verändern darf sowohl durch Anhängen als auch durch Ersetzen bzw. Überschreiben. Bei Verzeichnissen bedeutet es, dass man neue Verzeichniseinträge erzeugen (also neue Dateien bzw. neue Unterverzeichnisse anlegen) und bestehende Verzeichniseinträge entfernen (also Dateien bzw. Unterverzeichnisse löschen) darf. Ausführen: Bei einer gewöhnlichen Datei bedeutet es, dass man die Datei als Kommando ausführen darf. Das funktioniert natürlich nur, wenn es sich tatsächlich um eine ausführbare Datei, d. h. ein binäres Programm oder ein Script handelt. Bei Verzeichnissen bedeutet es, dass man das Verzeichnis betreten darf; daher ist dieses Recht bei Verzeichnissen die Grundvoraussetzung dafür, dass man mit dem Verzeichnis überhaupt arbeiten darf. Diese Rechte können vergeben werden an den Eigentümer der Datei, an die Gruppe, der die Datei zugeordnet ist, und an den Rest der Welt, d. h. alle übrigen Benutzer des Rechners. Die Zuweisung der Rechte geschieht mit dem Kommando chmod (change mode), das nur der Datei-Eigentümer aufrufen darf (und natürlich der Systemverwalter). Der Eigentümer kann sich zwar auch selbst Rechte nehmen, sich aber nicht aussperren, weil er sich die Rechte jederzeit wieder geben kann. Näheres zur Rechtevergabe mit chmod sollte bereits bekannt sein, ggf. rufen Sie zur Erinnerung man chmod oder chmod --help auf. 1.2 Eigentümer und Gruppe Jede neue Datei gehört demjenigen, der sie erzeugt hat. Sie ist auch automatisch der Gruppe zugeordnet, der der Erzeuger angehört. Üblicherweise ist das die sogenannte primäre Gruppe des Erzeugers, denn in der befindet er sich nach der Anmeldung. Mit Hilfe des Kommandos newgrp kann man aber in eine andere Gruppe wechseln, deren Mitglied man ist. Um herauszufinden, in welchen Gruppen man Mitglied ist, d. h. in welche Gruppen man wechseln kann, gibt man groups ein oder schaut in der Datei /etc/group bzw. in der Ausgabe von ypcat group nach. Bereits bestehende Dateien kann man mit dem Kommando chgrp einer anderen Gruppe zuordnen, deren Mitglied man ist. Fremden Gruppen kann man Dateien nicht zuordnen. Ebenso wenig kann man eine Datei einem anderen Benutzer schenken. Durch diese Restriktionen ist gesichert, dass man immer nachvollziehen kann, wer eine Datei angelegt 2
hat und dass der Plattenplatz immer auf die Platzbeschränkung (Quota) des Erzeugers angerechnet wird. 1.3 voreingestellte Rechte Jede neue Datei bekommt bestimmte Rechte. Die Rechte werden zunächst vorgegeben vom Programm, das die Datei erzeugt. Das Programm verwendet zum Erzeugen der Datei ein der Systemaufrufe open() oder creat() 1. Das von Ihnen in Ihren C-Programmen vielleicht benutzte fopen() verwendet intern wiederum einen der oben genannten Systemaufrufe. Bei fopen() kann man als Programmierer nicht festlegen, welche Rechte eine neue Datei bekommen soll bei direkter Verwendung von open() geht das dagegen schon: int open(const char *pathname, int flags, mode_t mode); Im dritten Parameter (mode) gibt man die gewünschten Rechte in Form einer Oktalzahl an. Bei fopen() wird immer 0666 verwendet, d. h. Lesen und Schreiben für alle, Ausführen für niemanden. Der Linker, der aus übersetzen Programmodulen (.o-dateien) und Bibliotheken ein ausführbares, binäres Programm macht, gibt diesem die Rechtemaske 0777 mit. Die open() übermittelten Rechte werden dann durch die umask gefiltert, deren Einstellung man mit dem Kommando umask anzeigen und ändern kann. Die umask ist eine Eigenschaft, die jeder Prozess hat. Sie wird von der Shell an alle Kindprozesse weiter vererbt, ähnlich wie die Umgebungsvariablen. Der Filtervorgang bewirkt, dass alle Bits, die in der umask gesetzt sind, in der Rechtemaske ausgeknipst werden. Es ist also eine bitweise Minus-Operation. Ein gängiger Wert für die umask ist 022, der bewirkt, dass die Gruppe und der Rest der Benutzer kein Schreibrecht an Dateien bekommen können. So funktioniert es: rw- rw- rw- 6 6 6 dritter Parameter von open() minus --- -w- -w- 0 2 2 umask-wert rw- r-- r-- 6 4 4 Rechtemaske der neuen Datei Wenn Sie umask mit einem neuen Wert als Parameter aufrufen, ändern Sie den umask- Wert. Um dies dauerhaft zu tun, schreiben Sie ihn in die Datei $HOME/.profile. 2 Erweiterte Rechte mit ACLs Nun kommen wir (endlich) zu den erweiterten Rechten, die nur mit Hilfe von ACLs eingestellt werden können. Diese ACLs sind ein POSIX 2 -Standard und bei den gängigen Linux- Dateisystemen umgesetzt. Auch wenn man nicht lokal, sondern über das Netz (NFS) auf das Dateisystem zugreift, funktionieren die ACLs mittlerweile. Auch Samba-Server, die Freigaben für Window-Systeme bereitstellen, können mit den ACLs umgehen, wenn auch 1 siehe ~>man creat 2 Portable Operating System Interface for Unix, http://de.wikipedia.org/wiki/posix 3
die Zuordnung zwischen den POSIX-ACLs von Unix/Linux und den Windows-eigenen ACLs nur teilweise funktioniert und daher nicht in allen Installationen aktiviert ist. Folgene ACL-Eintragsarten gibt es: ACL_USER_OBJ Dieser Eintrag gibt die Rechte für den Datei-Eigentümer an. Er enthält keine Namensangabe. ACL_USER Diese Einträge geben die Rechte für weitere Benutzer an und enthalten die Namen oder die User-IDs der betreffenden Benutzer. ACL_GROUP_OBJ Dieser Eintrag gibt die Rechte für die Gruppe an, der die Datei zugeordnet ist. Er enthält keine Namensangabe. ACL_GROUP Diese Einträge geben die Rechte für weitere Gruppen an und enthalten die Namen oder die Group-IDs der betreffenden Gruppen. ACL_MASK Dieser Eintrag gibt die maximal wirksamen Rechte der Einträge ACL_USER, ACL_GROUP_OBJ und ACL_GROUP an. Durch sie werden also diese Rechte gefiltert. ACL_OTHER Dieser Eintrag gibt die Rechte für alle anderen Benutzer an. Die Standard-Unix-Rechte entsprechen den Einträgen ACL_USER_OBJ, ACL_GROUP_OBJ und ACL_OTHER. Beim Ermitteln, ob ein Zugriff erfolgen darf oder nicht, wird die effektive User-ID mit ACL_USER_OBJ- und ACL_USER-Einträgen verglichen. Die effektive Group-ID und die IDs aller Gruppen, bei denen der Benutzer sekundäres Mitglied ist (Eintrag in /etc/group), werden mit ACL_GROUP_OBJ- und ACL_GROUP-Einträgen verglichen. 2.1 Hilfsprogramme Zwei kleine Hilfsprogramme dienen dazu, mit ACLs zu arbeiten: getfacl dient dazu, die ACL einer Datei anzuzeigen, denn das geläufige ls kann das nicht. Hat eine Datei eine ACL, so zeigt ls aber immerhin ein +-Zeichen neben der Rechteliste an, so dass man weiß, dass noch mehr Rechte vergeben wurden. setfacl wird dazu benutzt, um eine ACL einzustellen und zu verändern (Option -m). Natürlich kann man eine ACL auch wieder entfernen und die einfachen Standardrechte wieder herstellen (Option -x). 2.2 Rechte für weitere Benutzer Zeigt man die Rechte einer Datei ohne eine ACL an, so sehen die Ausgaben von ls -l und getfacl so aus: 4
mueller@ux-01:~> ls -l uebung_unix.odt -rw-r--r-- 1 mueller verwaltung 6044 2004-12-03 11:51 uebung_unix.odt mueller@ux-01:~> getfacl uebung_unix.sodt # file: uebung_unix.odt user::rw- group::r-- other::r-- Die angezeigte Information ist in diesem Fall identisch, auch wenn die Formatierung sehr unterschiedlich ist. Fügen wir jetzt Rechte für einen zusätzlichen Benutzer hinzu, so sieht es so aus: mueller@ux-01:~> setfacl -m u:guest:rw- uebung_unix.odt mueller@ux-01:~> ls -l uebung_unix.odt -rw-rw-r--+ 1 mueller verwaltung 6044 2004-12-03 11:51 uebung_unix.odt mueller@ux-01:~> getfacl uebung_unix.odt # file: uebung_unix.odt user::rwuser:guest:rwgroup::r-- mask::rw- other::r-- Die Option -m (modify) gibt an, dass wir einen ACL-Eintrag modifizieren bzw. neu erstellen wollen. Es handelt sich um einen u-eintrag (User), denn es soll ein Benutzer keine Gruppe Rechte bekommen. Der Benutzer heißt guest und bekommt die Rechte rw-; wahlweise kann man natürlich alle Rechtemasken von --- bis rwx zuweisen, wobei man die Striche auch weglassen kann, also nur rx statt r-x. Die Lang-Ausgabe von ls gibt uns mit dem +-Zeichen einen Hinweis auf die bestehende ACL der Datei. Die Ausgabe von getfacl zeigt zunächst alle benutzerspezifischen Einträge, d. h. erst den des Eigentümers (ohne Name), dann den von guest. Danach folgen die Einträge für die Gruppe, d. h. derzeit nur die der Datei zugeordnete Gruppe (ohne Name). Vor den Rechten für alle anderen (other) kommt noch eine Maske mask, die immer dann existieren muss, wenn es Rechte über die Standardrechte hinaus gibt. Sie wird zunächst automatisch als Vereinigungsmenge aller Rechte ermittelt, die benannte Benutzer, die Gruppe und die benannten Gruppen haben. Deren Rechte werden durch die Maske begrenzt. Wenn man die Maske manuell verändert, kann man deren Rechte auf einen Schlag eingrenzen und auch wieder freigeben, ohne alle Einzeleinträge ändern zu müssen. 5
2.3 Rechte für weitere Gruppen Fügen wir jetzt Rechte für eine zusätzliche Gruppe hinzu, so sieht es so aus: mueller@ux-01:~> setfacl -m g:users:rw- uebung_unix.odt mueller@ux-01:~> getfacl uebung_unix.odt # file: uebung_unix.odt user::rwuser:guest:rwgroup::r-- group:users:rwmask::rwother::r-- Neben der der Datei zugeordneten Gruppe gibt es jetzt einen Eintrag einer benannten Gruppe. Alle Benutzer, die (primäres oder sekundäres) Mitglied dieser Gruppe sind, haben nun Lese- und Schreibrecht, d. h. sogar mehr Rechte als die Benutzer der Gruppe verwaltung. 2.4 Ändern der Maske Ändern wir manuell die Maske, deren Wert bislang automatisch bestimmt wurde, so unterscheiden sich die eingestellten und die effektiven Rechte: mueller@ux-01:~> setfacl -m m::r-- uebung_unix.odt mueller@ux-01:~> getfacl uebung_unix.odt # file: uebung_unix.odt user::rwuser:guest:rw- group::r-- group:users:rw- mask::r-- other::r-- Die ACL-Einträge bei den Benutzern und Gruppen bleiben von der Änderung der Maske zwar unverändert, aber die tatsächlichen, effektiven Rechte werden beeinflusst. Das zeigt getfacl dann daneben übersichtlich an. Da bei group::r-- ohnehin keine über r-- hinausgehenden Rechte vergeben wurden, weichen die effektiven Rechte nicht ab. Andernfalls würde auch in dieser Zeile ein Hinweis auf die effektiven Rechte stehen: 6
mueller@ux-01:~> getfacl uebung_unix.odt # file: uebung_unix.odt user::rwuser:guest:rw- group::rw- group:users:rw- mask::r-- other::rw- 2.5 ACL-Einträge löschen Möchte man ACL-Einträge löschen, so schreibt man statt -m die Option -x davor. Die Standardeinträge für den Eigentümer, die Gruppe und die anderen Benutzer kann man natürlich nicht löschen. Um alle ACL-Einträge zu entfernen und zu den Standard-Unix- Rechten zurückzukehren, verwendet man die Option -b ohne sonstige Angaben. 2.6 Rechte für neue Dateien Möchte man ein Verzeichnis für andere Benutzer oder Gruppen freigeben, z. B. um in einem Projektteam zusammen zu arbeiten, dann würde man den Projektteilnehmern auch Schreibrechte dort einräumen. Was passiert nun, wenn dort eine neue Datei erzeugt wird? Sie hat natürlich die Rechte wie im Abschnitt 1.3 auf Seite 2 beschrieben. Das bedeutet, dass die anderen Projektteilnehmer nicht die notwendigen Rechte besitzen. Man könnte diese mit Hilfe eines kleinen Scripts entsprechend anpassen, aber das kann leicht vergessen werden. Viel praktischer ist es, dem Verzeichnis sogenannte default-rechte für neue Dateien mitzugeben. Alle neu erzeugten Dateien bekommen dann diese automatisch lediglich die umask des erzeugenden Prozesses hat noch einen filternden Einfluss auf sie. Um die default-rechte zu vergeben, schreibt man vor die Angaben, wie sie im vorigen Abschnitt gezeigt wurden, noch d: davor. Wenn die Mitglieder der Gruppe einkauf und der Benutzer guest3 gemeinsam mit dem aktuellen Benutzer (mueller der Gruppe verwaltung) selbst in einem Projektteam das Verzeichnis projekt1 bearbeiten sollen, dann könnte man die Rechte so vergeben: mueller@ux-01:~> mkdir projekt1 mueller@ux-01:~> setfacl -m g:einkauf:rwx -m u:guest3:rwx projekt1 mueller@ux-01:~> setfacl -m d:g:einkauf:rw- -m d:u:guest3:rw- -m d:u:$user:rw- projekt1 mueller@ux-01:~> setfacl -m d:g::--- -m d:o::--- -m d:u::rw- projekt1 mueller@ux-01:~> getfacl projekt1 # file: projekt1 7
Es wird das Verzeichnis projekt1 erzeugt. Anschließend werden der Gruppe einkauf und dem Benutzer guest3 alle Rechte an diesem Verzeichnis eingeräumt. Anschließend werden Lese- und Schreibrechte auch als default-rechte für neue Dateien eingerichtet. Zusätzlich muss man aber auch sich selbst ($USER) die Rechte geben (hier: mueller), weil man sie sonst nur an den Dateien hat, die man selbst erzeugt hat nicht aber an Dateien, die andere Teammitglieder angelegt haben. Im zweiten setfacl werden die default-rechte für neue Dateien für die Gruppe einkauf auf rw gesetzt, ebenso für den Benutzer guest3 und für den aktuellen Benutzer. Im dritten setfacl werden die default-rechte für die zugeordnete Gruppe auf nichts gesetzt, ebenso die für alle übrigen Benutzer und die für den Eigentümer auf rw. Nun legen wir selbst eine Datei plan.txt mit einem Editor an. Haben jetzt alle Benutzer alle Rechte? Mal sehen: user::rwx user:guest3:rwx group::r-x group:einkauf:rwx mask::rwx other::r-x default:user::rwdefault:user:guest3:rwdefault:user:mueller:rwdefault:group::--- default:group:einkauf:rwdefault:mask::rwdefault:other::--- mueller@ux-01:~/projekt1> getfacl plan.txt # file: plan.txt user::rwuser:guest3:rw- user:mueller:rw- group::--- group:einkauf:rw- mask::r-- other::r-- Nein, denn unsere umask hat uns da einen Streich gespielt und die effektiven Rechte für die anderen bis auf das Leserecht verhindert. Wir müssen also die Maske anpassen: 8
mueller@ux-01:~/projekt1> setfacl -m m::rwx plan.txt mueller@ux-01:~/projekt1> getfacl plan.txt # file: plan.txt # group: einkauf user::rwuser:guest3:rwuser:mueller:rwgroup::--- group:einkauf:rwmask::rwx other::r-- Jetzt sehen die Rechte aus wie gewünscht. Die default-rechte kann man alle gemeinsam mit -k löschen. Einzelne Einträge werden wie bei den anderen Rechten auch mit -x gelöscht. Man könnte auch die umask ändern, evtl. sogar in der Datei $HOME/.profile. Beim Erzeugen von Dateien und Verzeichnissen innerhalb von anderen Verzeichnissen als dem Projektverzeichnis würden dann aber sehr wahrscheinlich mehr Rechte freigegeben als gewünscht. Daher sollte man die umask möglichst nur temporär ändern. 3 Probleme und Grenzen Die mit Hilfe von ACLs eingestellten Rechte sind für alle Anwendungen wirksam, denn die Rechteüberprüfung wird nicht von den Programmen, sondern vom Dateisystem durchgeführt. Also brauchten die Programme hierfür auch gar nicht angepasst zu werden. Es können nicht beliebig viele ACL-Einträge pro Datei gemacht werden. In Abhängigkeit vom verwendeten Dateisystem sind es aber mindestens 25. Probleme kann es geben, wenn Dateien von einem Rechner auf einen anderen übertragen oder auch nur auf einen anderen Datenträger kopiert oder verschoben werden sollen. Die hierzu verwendeten Programme müssen die ACLs mitkopieren und das auf dem Zieldatenträger verwendete Dateisystem muss ACLs kennen. Hilfsprogramme wie cp und mv mussten also erweitert werden. Und ob der von Ihnen vielleicht so geschätzte Dateimanager beim Kopieren oder Verschieben alles richtig macht? Könnte auch sein, dass beim Verschieben auf demselben Datenträger noch alles in Ordnung ist, beim Verschieben über Datenträgergrenzen aber nicht. Also bitte vorher nachschlagen und zur Sicherheit auch ausprobieren. Ein weiteres Problem kann die Datensicherung sein. Auch Datensicherungsprogramme müssen die ACLs beim Sichern mitschreiben und beim Zurückspielen auch wieder einrichten. Das Standard GNU tar-programm tut das nicht, wohl aber das Programm star 3, wenn man die notwendigen Optionen angibt. 3 http://sourceforge.net/projects/s-tar/ 9
Eine gangbare Alternative ist das Sichern von ACLs in einer Textdatei mittels getfacl -R verzeichnis > acldatei.txt. Diese Datei wird nach Zurückspielen der Daten dann an setfacl übergeben, um die ACLs wieder herzustellen: setfacl --restore=acldatei. txt. Das Programm rsync 4 aus dem Samba-Projekt, mit dessen Hilfe Dateien und auch ganze Verzeichnisbäume von einem Rechner zu einem anderen überspielt und synchronisiert werden können, beherrscht ACLs. Es dient auch als Grundlage für die Backuplösung rsnapshot 5 Siehe auch http://www.linux-user.de/ausgabe/2003/12/066-acl. Access-Control-Lists.tex 3bbfc6c9a2 2017-05-12 4 http://rsync.samba.org/ 5 http://www.rsnapshot.org/ 10