[ zurück ] [ Inhalt ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ H ] [ weiter ]
Dieses Kapitel handelt von einigen der anerkannten Vorgehensweisen, wenn
Entwickler Pakete für Debian erstellen. Wenn Sie sehr an sicherheitsbewusster
Programmierung interessiert sind, sollten Sie David Wheelers Secure Programming for Linux
and Unix HOWTO
und Secure Coding: Principles and
Practices
von Mark G. Graff und Kenneth R. van Wyk (O'Reilly,
2003) lesen.
Entwickler, die Software in Pakete packen, sollten größte Anstrengung darauf verwenden sicherzustellen, dass die Installation der Software und ihre Verwendung keine Sicherheitsrisiken für das System oder seine Benutzer eröffnet.
Dazu sollten sie vor der Veröffentlichung der Software oder einer neuen Version den Quellcode des Pakets nachprüfen, um Fehler zu finden, die zu Sicherheitslücken führen können. Bekanntermaßen ist der Aufwand für die Fehlerbehebung in verschiedenen Stadien der Entwicklung unterschiedlich. So ist es leichter (und billiger), Fehler während der Entwicklung auszubessern als später, wenn die Software schon herausgegeben wurde und nur noch gewartet wird (einige Studien behaupten, dass die Kosten in dieser Phase 60 Mal höher sind). Es gibt Hilfsmittel, die versuchen, Fehler automatisch zu entdecken. Entwickler sollten dennoch die verschiedenen Sicherheitsfehler kennen, damit sie sie verstehen und sie so in eigenen (oder fremden) Programmcode entdecken können.
Programmierfehler, die typischerweise zu Sicherheitsproblemen führen, sind
insbesondere: Pufferüberläufe,
,
Format-String-Überläufe, Heap-Überläufe und Integer-Überläufe (in
C/C++-Programmen), vorübergehende Symlink-Schwachstellen
(in Skripten), Directory
Traversal
, die Einschleusung von Befehlen (auf Servern) und Cross-Site
Scripting
sowie SQL-Injektionen
(bei web-orientierten Anwendungen). Eine ausführliche Liste von
Sicherheitsfehlern finden Sie in Fortifys Taxonomy of Software Security
Errors
.
Einige dieser Probleme können Sie nur erkennen, wenn Sie ein Experte in der
verwendeten Programmiersprache sind. Aber andere können leicht entdeckt und
behoben werden. Zum Beispiel kann eine Symlink-Schwachstelle auf Grund einer
falschen Verwendung von temporären Verzeichnissen ohne Weiteres entdeckt
werden, indem Sie grep -r "/tmp/" . ausführen. Diese
Verweise sollten überprüft werden und fest einprogrammierte Dateinamen in
temporären Verzeichnissen in Shell-Skripten mit mktemp
oder
tempfile
, in Perl-Skripten mit File::Temp(3perl)
und
in C/C++ mit tmpfile(3)
ersetzt werden.
Es stehen Ihnen einige Werkzeuge zur Verfügung, die Sie dabei unterstützen, den
Quellcode auf Sicherheitsprobleme hin zu überprüfen. Dazu zählen
rats
, flawfinder
und pscan
. Weitere
Informationen finden Sie in der Liste der Werkzeuge, die
vom Debian-Security-Audit-Team verwendet werden
.
Beim Paketieren von Software sollten Entwickler darauf achten, dass sie allgemein anerkannte Sicherheitsprinzipien einhalten. Dazu gehören:
Die Software sollte mit so geringen Rechten wie möglich laufen
Falls das Paket Binaries mit setuid oder setgid enthält, wird
Lintian
vor setuid
-,
setgid
-
und setuid und
setgid
-Binaries warnen.
Die Daemons, die in einem Paket enthalten sind, sollten mit den Rechten eines Benutzers laufen, der nur geringe Privilegien besitzt (vergleichen Sie dazu Benutzer und Gruppen für Daemons erstellen, Abschnitt 9.2).
Automatisierte Aufgaben (also mit cron
) sollten NICHT mit
Root-Rechten laufen. Zumindest sollten mit Root-Rechten keine komplizierten
Aufgaben erledigt werden.
Falls Sie diese Prinzipien nicht einhalten können, sollten Sie sichergehen,
dass das Programm, das mit umfangreicheren Rechten läuft, auf
Sicherheitsprobleme überprüft wurde. Wenn Sie sich nicht sicher sind oder
Hilfe benötigen, sollten Sie sich mit dem Sicherheits-Audit-Team von
Debian
in Verbindung setzen. Wenn Binaries setuid/setgid verwenden,
sollten Sie die Richtlinie von Debian zu Rechten und
Besitzern
beachten.
Für weitere Informationen, insbesondere hinsichtlich Sicherheitsfragen, sollten
Sie das Secure
Programming for Linux and Unix HOWTO
und das Build Security In
Portal lesen (oder den Programmautor darauf hinweisen).
Wenn Ihre Software als Daemon läuft, der keine Root-Rechte benötigt, müssen Sie
für ihn einen Benutzer erstellen. Es gibt zwei Arten von Benutzern in Debian,
die für Pakete verwendet werden können: statische UIDs (werden von
base-passwd
vergeben, eine Liste der statischen Benutzern in
Debian finden Sie bei Benutzer und
Gruppen des Betriebssystems, Abschnitt 12.1.12) und dynamisches UIDs, die
in einem zugewiesenen Bereich liegen.
Im ersten Fall müssen Sie mit base-passwd
eine Benutzer- oder
Gruppen-ID erstellen. Wenn der Benutzer verfügbar ist, muss das Paket, das Sie
anbieten möchten, eine Abhängigkeit vom Paket base-passwd
enthalten.
Im zweiten Fall müssen Sie den Systembenutzer entweder entweder preinst oder postinst erstellen und dafür sorgen, dass das Paket von adduser (>= 3.11) abhängt.
Im folgenden Programmbeispiel soll gezeigt werden, wie der Benutzer oder Gruppe, mit deren Rechten der Daemon laufen wird, bei der Installation oder Aktualisierung des Pakets erstellt wird.
[...] case "$1" in install|upgrade) # If the package has default file it could be sourced, so that # the local admin can overwrite the defaults [ -f "/etc/default/packagename" ] && . /etc/default/packagename # Sane defaults: [ -z "$SERVER_HOME" ] && SERVER_HOME=server_dir [ -z "$SERVER_USER" ] && SERVER_USER=server_user [ -z "$SERVER_NAME" ] && SERVER_NAME="Server description" [ -z "$SERVER_GROUP" ] && SERVER_GROUP=server_group # Groups that the user will be added to, if undefined, then none. ADDGROUP="" # create user to avoid running server as root # 1. create group if not existing if ! getent group | grep -q "^$SERVER_GROUP:" ; then echo -n "Adding group $SERVER_GROUP.." addgroup --quiet --system $SERVER_GROUP 2>/dev/null ||true echo "..done" fi # 2. create homedir if not existing test -d $SERVER_HOME || mkdir $SERVER_HOME # 3. create user if not existing if ! getent passwd | grep -q "^$SERVER_USER:"; then echo -n "Adding system user $SERVER_USER.." adduser --quiet \ --system \ --ingroup $SERVER_GROUP \ --no-create-home \ --disabled-password \ $SERVER_USER 2>/dev/null || true echo "..done" fi # 4. adjust passwd entry usermod -c "$SERVER_NAME" \ -d $SERVER_HOME \ -g $SERVER_GROUP \ $SERVER_USER # 5. adjust file and directory permissions if ! dpkg-statoverride --list $SERVER_HOME >/dev/null then chown -R $SERVER_USER:adm $SERVER_HOME chmod u=rwx,g=rxs,o= $SERVER_HOME fi # 6. Add the user to the ADDGROUP group if test -n $ADDGROUP then if ! groups $SERVER_USER | cut -d: -f2 | \ grep -qw $ADDGROUP; then adduser $SERVER_USER $ADDGROUP fi fi ;; configure) [...]
Außerdem müssen Sie für das Init.d-Skript sicherstellen,
dass der Daemon beim Starten seine Rechte ablegt: Wenn die Software nicht
selbst den setuid(2)
oder seteuid(2)
Aufruf absetzt,
sollten Sie die Option --chuid für start-stop-daemon
verwenden.
dass der Daemon nur angehalten wird, wenn die Benutzer-IDs übereinstimmen.
Dafür ist die Option --user von start-stop-daemon
hilfreich.
dass der Daemon nicht gestartet wird, wenn sein Benutzer oder Gruppe nicht existiert:
if ! getent passwd | grep -q "^server_user:"; then echo "Server user does not exist. Aborting" >&2 exit 1 fi if ! getent group | grep -q "^server_group:" ; then echo "Server group does not exist. Aborting" >&2 exit 1 fi
Wenn das Paket einen Systembenutzer erstellt, kann er wieder in postrm
entfernt werden, wenn das Paket vollständig gelöscht wird (purge). Dabei gibt
es allerdings einen Nachteil. Zum Beispiel werden Dateien, die von dem
Benutzer des Daemons erstellt wurden, benutzerlos und können später einem neuen
Benutzer gehören, dem die gleiche UID zugewiesen wurde [65]. Daher ist nicht zwingend
notwendig, dass Benutzer beim vollständigen Löschen eines Pakets entfernt
werden. Dies hängt vielmehr vom jeweiligen Paket ab. Im Zweifelsfall sollte
der Administrator gefragt werden (mit debconf
), was passieren
soll, wenn ein Paket gelöscht wird.
Sehen Sie sich folgenden Code an [66], der zuvor erstellte Benutzer und Gruppen entfernt. Dies geschieht aber nur dann, wenn die UID im Bereich der dynamisch zugewiesenen System-UIDs liegt und die GID einer Systemgruppe angehört:
case "$1" in purge) [...] # find first and last SYSTEM_UID numbers for LINE in `grep SYSTEM_UID /etc/adduser.conf \ | grep -v "^#"`; do case $LINE in FIRST_SYSTEM_UID*) FIST_SYSTEM_UID=`echo $LINE | cut -f2 -d '='` ;; LAST_SYSTEM_UID*) LAST_SYSTEM_UID=`echo $LINE | cut -f2 -d '='` ;; *) ;; esac done # Remove system account if necessary CREATEDUSER="server_user" if [ -n "$FIST_SYSTEM_UID" ] && [ -n "$LAST_SYSTEM_UID" ]; then if USERID=`getent passwd $CREATEDUSER | cut -f 3 -d ':'`; then if [ -n "$USERID" ]; then if [ "$FIST_SYSTEM_UID" -le "$USERID" ] && \ [ "$USERID" -le "$LAST_SYSTEM_UID" ]; then echo -n "Removing $CREATEDUSER system user.." deluser --quiet $CREATEDUSER || true echo "..done" fi fi fi fi # Remove system group if necessary CREATEDGROUP=server_group FIRST_USER_GID=`grep ^USERS_GID /etc/adduser.conf \ | cut -f2 -d '='` if [ -n "$FIST_USER_GID" ] then if GROUPGID=`getent group $CREATEDGROUP \ | cut -f 3 -d ':'`; then if [ -n "$GROUPGID" ]; then if [ "$FIST_USER_GID" -gt "$GROUPGID" ]; then echo -n "Removing $CREATEDGROUP group.." delgroup --only-if-empty $CREATEDGROUP || true echo "..done" fi fi fi fi [...]
Wenn ein Programm unter einem Benutzer mit beschränkten Rechten läuft, wird
sichergestellt, dass Sicherheitsprobleme nicht das gesamte System beschädigen
können. Dieses Vorgehen beachtet auch das Prinzip der geringst möglichen
Privilegien. Denken Sie daran, dass Sie die Rechte eines Programms auch
noch durch andere Methoden als beschränkte Benutzerrechte weiter einschränken
können [67]. Weitere
Informationen finden Sie im Abschnitt Minimize
Privileges
des Buchs Secure Programming for Linux and Unix
HOWTO.
[ zurück ] [ Inhalt ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ H ] [ weiter ]
Anleitung zum Absichern von Debian
Version: 3.11, Mon, 29 Oct 2012 03:47:21 +0000jfs@debian.org