SelfLinux Sicherheit Grundlagen Sicherheit Abschnitt 7 | SelfLinux-0.13.0

| Grundlagen Sicherheit | Autoren Formatierung GFDL

#### 7 Sicherheit im Dateisystem

#### 7.1 Dateiattribute

Grundlage für die folgenden Unterabschnitte sind die Dateiattribute LESEN, SCHREIBEN, AUSFÜHREN und damit verbunden die Berechtigungsklasen USER, GROUP, OTHER. Diese wurden ausführlich im Abschnitt 4 und 5 des Kapitels Benutzer- und Berechtigungskonzepte unter Linux erläutert.

#### 7.2 t-Bit (sticky Bit), SGID, SUID

Das sticky-Bit hat historischen Ursprung und wird heute nur noch auf Verzeichnisse angewendet (Früher blieben mit dem t-Bit versehene Programme auch nach Beendigung im Hauptspeicher).

Ist das Sticky Bit auf einem Verzeichnis z.B. /tmp gesetzt, dann dürfen Dateien nur noch von dessen Besitzer und vom Verzeichnisbesitzer gelöscht werden.

root@linux # chmod 1777 public_tmp root@linux # ls -la public_tmp drwxrwxrwt 7 root root 4096 2003-07-06 19:17 .

SUID und SGID sind nur für Programme sinnvoll. Diese werden mit der Benutzerkennung
(SUID - Set User ID) bzw mit der Gruppenkennung
(SGID - Set Group ID) der Programmdatei ausgeführt.

Anwendung findet dies beisielsweise beim Programm passwd, welches ja Schreibrechte auf die Datei /etc/shadow benötigt um das Passwort zu ändern. Das Programm wird also von einem realen Nutzer aufgerufen, läuft aber unter root-Rechten ab:

root@linux # ls -la /usr/bin/passwd -rwsr-xr-x 1 root root 24248 2003-04-26 21:50 /usr/bin/passwd

# User ID bei Ausführung des apache setzen
chmod 4755 /usr/bin/passwd

#Gruppen ID bei Ausführung von my_script setzen
chmod 2755 /usr/bin/my_script

Bit-Maske | Bedeutung
--- | ---
4000 | User ID setzen (bei Programmen)
2000 | Gruppen ID setzen (bei Programmen)
1000 | Lösch- und Überschreibschutz aktivieren (Verzeichnisse)
400 | Eigentümer lesen
200 | Eigentümer schreiben / modifizieren
100 | Eigentümer ausführen /Verzeichnis wechseln
40 | Gruppe lesen
20 | Gruppe schreiben / modifizieren
10 | Gruppe ausführen /Verzeichnis wechseln
4 | alle lesen
2 | alle schreiben / modifizieren
1 | alle ausführen /Verzeichnis wechseln

#### 7.3 Erweiterte ext2-Dateiattribute

Seit dem Linux-Kernel 2.2 ist es möglich, für Dateien und Verzeichnisse erweiterte (Sicherheits-)Funktionen durch die Vergabe von Flags (Attributen) zu aktivieren. Diese betreffen auch den Superuser root.

a (Append Only)

> Das System erlaubt das Öffnen dieser Datei nur zum Zwecke der Erweiterung und verbietet explizit allen Prozessen das Überschreiben bzw. Löschen bereits gespeicherter Daten (sinnvoll bei log-Dateien). Ebenfalls untersagt ist das Löschen, Umbenennen, Verschieben und "hartes" Linken der Datei. Wird das Flag auf einem Verzeichnis angewendet, dürfen darin keine Dateien angelegt oder gelöscht werden.

i (Immutable)

> Das System verbietet jegliche Änderungen an der Datei. Im Falle eines Verzeichnisses können Dateien, die in diesem Verzeichnis bereits existieren, verändert werden. Weder das Löschen noch das Anlegen von Dateien ist möglich.

d (No Dump)

> Das dump Programm soll diese Datei beim Backup ignorieren.

c (Compress)

> Das System soll diese Datei "transparent" komprimieren. Beim Schreiben in die Datei wird deren Inhalt komprimiert und erst danach auf dem physischen Datenträger abgelegt, beim Lesen der Datei werden jedoch stets dekomprimierte Daten zurückgegeben. Diese Funktion ist derzeit noch nicht implementiert.

s (Secure Delete)

> Wenn das System diese Datei löscht, werden alle Datenblöcke auf dem Datenträger zufällig überschrieben.

u (Undelete)

> Wenn eine Anwendung das Löschen der Datei fordert, soll das System die Datenblöcke so "konservieren", dass das Löschen der Datei auch wieder rückgängig gemacht werden kann. Diese Funktion ist derzeit noch nicht impementiert.

A (Atime)

> Das System soll die "atime" (access time) dieser Datei nicht aktualisieren.

S (Sync)

> Wenn eine Anwendung gerade den Schreibprozess durchführt, soll das System alle Änderungen sofort und ungepuffert auf dem physischen Datenträger abspeichern.

root@linux # chattr +a test.log root@linux # chattr +i test.conf root@linux # ls -al test* -rw-rw-r-- 1 gwe users 0 Nov 22 22:22 test.conf root@linux # lsattr -a test* ---i-------- test.conf ----a------- test.log root@linux # chattr -i test.conf lsattr -a test.conf ------------ test.conf

In vielen Fällen ist der Schutz der folgenden Dateien/Verzeichnisse sinnvoll:

root@linux # chattr -R +i /etc /bin /sbin /boot /lib root@linux # chattr -R +i /usr/bin /usr/sbin /usr/lib /usr/src /usr/include root@linux # chattr +a /var/log/messages /var/log/secure root@linux # (...)

Der Schutz folgender Verzeichnissen kann zu unerwünschten Nebeneffekten führen:

Verzeichnis | Problemursache
--- | ---
/ | syslog
/dev | Syslog will beim Start den Socket /dev/log anlegen
/tmp | versteht sich von selbst
/var | logrotate, sendmail

Mithilfe der oben beschriebenen Capabilities kann das Rücksetzen der Sicherheitsattribute unterbunden werden. Die damit realisierten Restriktionen gelten für alle Benutzer (inkl. root) und werden nur bei Systemsneustart aufgehoben.

#### 7.4 Partitionen

Das Einbinden von Partitionen kann sehr viel zur Sicherheit beitragen. Als Beispiel soll der folgende Eintrag in der /etc/fstab dienen:

/etc/fstab

    /dev/hda9    /tmp    ext2    defaults,nosuid,noexec,nodev    0    2

Aufgrund der Mount-Optionen werden gesetzte SUID- und GUID-Attribute komplett ignoriert. Weiterhin verbietet noexec das Ausführen von Programmen auf dieser Partition und nodev verhindert character und block-Devices.

Die folgenden Einträge geben Überblick über eine mögliche Konfiguration:

/etc/fstab

    /dev/sda5   /usr         ext3    defaults,ro,nodev                              0   2
    /dev/sda7   /usr/share   ext3    defaults,ro,nodev,nosuid                       0   2
    /dev/sda8   /var         ext3    defaults,nodev,usrquota,grpquota               0   2
    /dev/sda9   /tmp         ext3    defaults,nodev,nosuid,noexec,usrquota,grpquota 0   2
    /dev/sda10  /home        ext3    nosuid,nodev,auto,nouser,usrquota,grpquota     0   2
    /dev/hda1   /mnt/hda1    vfat    rw,nosuid,nodev,umask=000,uid=1000,gid=1000    0   0
    /dev/fd0    /mnt/fd0     ext2    defaults,users,nodev,nosuid,noexec             0   0
    /dev/hdd    /mnt/cdrom   iso9660 ro,users,nodev,nosuid,noexec                   0   0

Die Optionen sind im Einzelnen in den man-Pages (man 8 mount) nachzulesen, deshalb gibt es hier nur eine kleine Auswahl:

defaults | Entspricht den voreingestellten Optionen rw, suid, dev, exec, auto, nouser, und async.
rw | Einhängen des Dateisystems zum Lesen und Schreiben.
ro | Einhängen des Dateisystems ausschließlich zum Lesen, Schreiboperationen werden ignoriert.
user | Ein Normaluser darf das Dateisystem einhängen. Ansonsten darf dies nur root.
nouser | Nur root darf das Dateisystem einhängen.
dev / nodev | Das Nutzen von Gerätedateien auf der Partition ist (nicht) erlaubt.
exec / noexec | Auf der Partition gespeicherte Programme können (nicht) ausgeführt werden.
auto / noauto | Partition wird beim Booten (nicht) automatisch eingehängt.
atime / noatime | Sie Zugriffszeit (atime) wird bei jedem Zugriff (nicht) gesetzt.
suid / nosuid | SUID und SGID Bits werden (nicht) interpretiert.
sync / async | Ein- und Ausgabeoperationen werden (a)synchron durchgeführt

Jedes Dateisystem stellt selbst noch einige Optionen zur Verfügung (z. B. usrquota, gid, uid, umask). Die Dokumentation dieser speziellen Optionen kann ebenfalls in den Manpages von mount nachgelesen werden.

#### 7.5 Festplattenkontingente mit Quota

Jeder Computernutzer weiß, dass eine Festplatte, egal wie groß sie auch sein mag, immer zu klein ist. Auf Systemen, die von mehreren Personen genutzt werden, wird dies sehr oft zum Problem. Damit es gar nicht erst zu einem Streit kommt, kann der Administrator mit root-Rechten für jeden Nutzer bzw. für jede Nutzergruppe ein Kontingent (engl. Quota) an Speicherplatz zur Verfügung stellen. Dazu benötigt man Quota.

Die Kontingente werden nicht global für das ganze System, sondern für jede Partition separat vergeben. Wenn ein Nutzer Schreibrechte auf mehreren Partitionen besitzt, muss man auch mehrere Quota für diesen Benutzer setzen.

Man kann sowohl Quotas auf Benutzerebene als auch auf Gruppenebene festlegen. Bei der Kombination von Benutzerebene und Gruppenebene haben Quotas auf Benutzerebene eine höhere Priorität.

Mit den folgenden drei Parametern lassen sich Quotas einstellen:

Softlimit | Der Benutzer darf diese Grenze nur kurz überschreiten und wird extra gewarnt.
Grace Period | Dieser Parameter legt den Zeitraum fest, den ein Benutzer das Softlimit überschreiten darf.
Hardlimit | Diese Grenze darf nicht überschritten werden.

Bevor man Quotas festlegen kann, muss der Kernel mit der Option Quota Support kompilert werden. Weiterhin ist es erforderlich, die Dateisysteme darauf vorzubereiten (mount Option). Dazu wird die Datei /etc/fstab angepasst:

/etc/fstab

    ...
    /dev/sda7   /home  ext3    nosuid,nodev,auto,nouser,usrquota,grpquota  0   2
    ...

Nun müssen die Änderungen übernommen werden. Dazu ist nicht unbedingt ein reboot erforderlich es reicht durchaus, die Partition aus- und wieder einzuhängen.

root@linux # mount -a -o remount

Weiterhin müssen die Dateien aquota.user und aquota.group im Wurzelverzeichnis der jeweiligen Partition erstellt werden. Dies übernimmt auch der erstmalige Aufruf des Programmes quotacheck. Damit die Benutzer auch den aktuellen Stand ihres Kontingentes erfragen können, ist der Lesezugriff auf diese quota-Dateien notwendig.

root@linux # quotacheck -avugm root@linux # chmod 644 /home/aquota.* root@linux # chmod 644 /moutpoint/aquota.*

Das Starten und Beenden der Kontingentüberwachung übernehmen die Programme quotaon und quotaoff, die nach jedem Systemstart neu aufgerufen werden müssen. Wenn bei der Distribution ein entsprechendes SysV-Initskript fehlt, kann man folgendes benutzen:

/etc/init.d/quota

    #! /bin/sh

    case "$1" in
        start)
            echo "Starte Quotaüberwachung:"
            /sbin/quotaon -avug
            ;;
        stop)
            echo "Stoppe Quotaüberwachung:"
            /sbin/quotaoff -avug
            ;;
        *)
            echo "Aufruf: $0 {start|stop}"
            exit 1
    esac
    exit 0

root@linux # cd /etc/init.d
root@linux # chmod +x quota
root@linux # ln -s ../init.d/quota /etc/rc0.d/K85quota
root@linux # ln -s ../init.d/quota /etc/rc1.d/K85quota
root@linux # ln -s ../init.d/quota /etc/rc2.d/S20quota
root@linux # ln -s ../init.d/quota /etc/rc3.d/S20quota
root@linux # ln -s ../init.d/quota /etc/rc4.d/S20quota
root@linux # ln -s ../init.d/quota /etc/rc5.d/S20quota
root@linux # ln -s ../init.d/quota /etc/rc6.d/K85quota

Zur Festlegung und Verwaltung der Kontingente existiert das Programm edquota.

root@linux # /edquota -u user007

Dieser Aufruf öffnet den Standardeditor (i.d.R. vi), mit Hilfe dessen man die Änderungen an den Parametern vornehmen kann.

/tmp/EdP.auS8yzc

    Disk quotas for user user007 (uid 1000):
    Filesystem    blocks     soft    hard   inodes   soft    hard
    /dev/hda7      80579   100000  120000     3841  10000   12000

Detaillierte Informationen findet man in den man-Pages, deshalb seien hier nur in Kurzform die wichtigsten Kommandos aufgezählt:

# Ändern der Quota für Benutzergruppe users
root@linux # edquota -g users
# Ändern der Grace Period (Zeitraum/Frist für Softlimit)
root@linux # edquota -t
# Übernahme der Quotaeinstellungen von Benutzer user007
# für alle User mit UID > 1000
root@linux # edquota -p user007 `awk -F: '$3 > 1000 {print $1}' /etc/passwd`
# Erzeugen eines Reportes
root@linux # repquota -avug
Report for user quotas on device /dev/hda2
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
root -- 69841 0 0 9226 0 0
postgres -- 1 0 0 1 0 0
ai114 -- 80154 60000* 90000 6days 3841* 3840 7000 3days
user007 -- 80579 100000 120000 3841 10000 12000
# Statusabfrage für einen Benutzer
root@linux # su user007
user@linux $ quota
Disk quotas for user user007 (uid 1000):
Filesystem blocks quota limit grace files quota limit grace
/dev/hda7 80579 100000 120000 3841 10000 12000

Es sei darauf hingewiesen, dass nicht bei allen Dateisystemen Quotas unterstützt werden. Auf den FAQ-Seiten des ReiserFS findet man weitere Informationen.

#### 7.6 Verschlüsselte Dateien

Im Kapitel "GnuPG Handbuch" wurde bereits detailliert auf das Verschlüsseln von Dokumenten eingegangen. Deshalb soll an dieser Stelle nicht näher darauf eingegangen werden. Das folgende Kapitel beschäftigt sich deshalb mit der Einrichtung verschlüsselter Dateisysteme, die an jede beliebige Stelle im Verzeichnissbaum eingehängt werden können. Alle Dateien in einem solchen Verzeichnis werden automatisch ver- und entschlüsselt.

#### 7.7 Verschlüsselte Dateisysteme

Es gibt zwei Möglichkeiten, Dateisysteme zu verschlüsseln:

1. Das Filesystem residiert in einer verschlüsselten Datei
2. Das Filesystem residiert auf einer verschlüsselten Partition

Für beide Varianten sind Modifikationen am Kernel erforderlich, bei Kernel 2.6.XX werden alle passenden Module mitgliefert (Menü "Cryptographic Options"). Für den Fall a) ist zusätzlich der "Loopback Device Support / Cryptoloop Support" im Menü "Block Devices" zu aktivieren. Bei älteren Kerneln ist ein spezieller Patch einzuspielen.

Weiterhin ist es (noch) notwendig, einige wichtige Programme wie mount und losetup linux-utils zu modifizieren. Keine Probleme gab es mit dem Patch von http://therapy.endorphin.org/patches/ .

root@linux # tar zxvpf util-linux-2.11y.tar.gz root@linux # patch -p0 < util-linux-2.11y.losetup.diff root@linux # cd util-linux-2.11y root@linux # make && make install

Die Verschlüsselung wird durch ein virtuelles Laufwerk (Loop-Device) realsiert. Dieses wird, wie jedes andere Laufwerk auch, in den Verzeichnisbaum eingehängt, z.B. an /mnt/crypted. Alle nach /mnt/crypted kopierten Dateien werden nun automatisch verschlüsselt. Natürlich muss dieses virtuelle Laufwerk mit einer real existierenden Datei oder Partition verbunden sein, die verschlüsselten Daten sollen ja schließlich nicht verloren gehen.

# Fall a) Erzeugen einer Datei (Größe 8MB)
root@linux # dd if=/dev/zero of=/home/user/crypedFile.dat bs=4096 count=2048
# Erzeugen eines leeren Verzeichnisses, welches
# sensible Daten aufnehmen soll
root@linux # mkdir /mnt/crypted
# mit AES verschlüsseltes loop-Device mit dieser Datei verbinden
root@linux # losetup -e aes /dev/loop0 /home/user/crypedFile.dat
# oder Partition mit loop-Device verbinden
root@linux # losetup -e aes /dev/loop0 /dev/hda7
# auf dem virtuellen Laufwerk ein Dateisystem anlegen
root@linux # mkfs -t ext2 /dev/loop0
# virtuelles Laufwerk mounten
root@linux # mount /dev/loop0 /mnt/crypted
# nun kann normal gearbeitet werden:
root@linux # cp datei /mnt/crypted
# am Ende: unmount
root@linux # umount /dev/crypted
# virtuelles Laufwerk (loop-Device) trennen
root@linux # losetup -d /dev/loop0

Um das Einhängen der Laufwerke zu automatisieren, kann die Datei /etc/fstab angepasst werden (letzte Zeile).

/etc/fstab

    # <Dateisystem>           <Mountpunkt>  <Typ>  <Optionen>                  <dump>  <pass>
    /dev/hda2                 /             ext3    defaults,errors=remount-ro    0       1
    proc                      /proc         proc    defaults                      0       0
    /dev/fd0                  /floppy       auto    defaults,user,noauto          0       0
    /dev/cdrom                /cdrom        iso9660 defaults,ro,user,noauto       0       0
    /home/user/crypedFile.dat /mnt/crypted  ext2    defaults,loop,encryption=aes  0       0

Natürlich gibt es auch Alternativen zu der hier vorgestellten Vorgehensweise, beispielsweise findet man auf pro-linux eine Anleitung zu Loop-AES.

Für die Zukunft bleibt zu hoffen, dass die Einrichtung von verschlüsselten Dateisystemen sich um Größenordnungen vereinfacht.