---
title: Kapitel 13. Sicherheit
part: Teil III. Systemadministration
prev: books/handbook/boot
next: books/handbook/jails
showBookMenu: true
weight: 17
params:
  path: "/books/handbook/security/"
---

[[security]]
= Sicherheit
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 13
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/security/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[security-synopsis]]
== Übersicht

Sicherheit, ob nun physisch oder virtuell, ist ein so breit gefächertes Thema, dass sich eine ganze Industrie darum gebildet hat. Es wurden bereits hunderte Verfahren zur Sicherung von Systemen und Netzwerken verfasst, und als Benutzer von FreeBSD ist es unumgänglich zu verstehen, wie Sie sich gegen Angreifer und Eindringlinge schützen können.

In diesem Kapitel werden einige Grundlagen und Techniken diskutiert. Ein FreeBSD-System implementiert Sicherheit in mehreren Schichten, und viele weitere Programme von Drittanbietern können zur Verbesserung der Sicherheit beitragen.

Nachdem Sie dieses Kapitel gelesen haben, werden Sie:

* Grundlegende auf FreeBSD bezogene Sicherheitsaspekte kennen.
* Die verschiedenen Verschlüsselungsmechanismen von FreeBSD kennen.
* Wissen, wie Sie ein Einmalpasswörter zur Authentifizierung verwenden.
* TCP Wrapper für man:inetd[8] einrichten können.
* Wissen, wie Sie Kerberos unter FreeBSD einrichten.
* Wissen, wie Sie IPsec konfigurieren und ein VPN einrichten.
* Wissen, wie Sie OpenSSH unter FreeBSD konfigurieren und benutzen.
* Wissen, wie Sie ACLs für Dateisysteme benutzen.
* pkg anwenden können, um Softwarepakete aus der Ports-Sammlung auf bekannte Sicherheitslücken hin zu überprüfen.
* Mit FreeBSD-Sicherheitshinweisen umgehen können.
* Eine Vorstellung davon haben, was Prozessüberwachung (Process Accounting) ist und wie Sie diese Funktion unter FreeBSD aktivieren können.
* Wissen, wie Sie Login-Klassen oder die Ressourcen-Datenbank benutzen, um die Ressourcen für Benutzer zu steuern.

Bevor Sie dieses Kapitel lesen, sollten Sie

* Grundlegende Konzepte von FreeBSD und dem Internet verstehen.

Dieses Buch behandelt weitere Sicherheitsthemen. Beispielsweise werden verbindliche Zugriffskontrollen im crossref:mac[mac,Verbindliche Zugriffskontrolle] und Firewalls im crossref:firewalls[firewalls,Firewalls] besprochen.

[[security-intro]]
== Einführung

Sicherheit ist die Verantwortung eines jeden Einzelnen. Ein schwacher Einstiegspunkt in einem System kann einem Eindringling Zugriff auf wichtige Informationen verschaffen, was sich verheerend auf das gesamte Netzwerk auswirken kann. Eines der Grundprinzipien der Informationssicherheit sind die Vertraulichkeit, Integrität und Verfügbarkeit von Informationssystemen.

Diese Grundprinzipien sind ein fundamentales Konzept der Computer-Sicherheit, da Kunden und Benutzer erwarten, dass ihre Daten geschützt sind. Zum Beispiel erwartet ein Kunde, dass seine Kreditkarteninformationen sicher gespeichert werden (Vertraulichkeit), dass seine Aufträge nicht hinter den Kulissen geändert werden (Integrität) und dass er zu jeder Zeit Zugang zu seinen Informationen hat (Verfügbarkeit).

Um diese Grundprinzipien zu implementieren, wenden Sicherheitsexperten das sogenannte Defense-in-Depth-Konzept an. Die Idee dahinter ist, mehrere Sicherheitsschichten zu addieren, so dass nicht die gesamte Systemsicherheit gefährdet ist, wenn eine einzelne Sicherheitsschicht kompromittiert wird. Beispielsweise ist es nicht ausreichend, ein Netzwerk oder ein System nur mit einer Firewall zu sichern. Der Systemadministrator muss auch Benutzerkonten überwachen, die Integrität von Binärdateien prüfen und sicherstellen, dass keine bösartigen Programme installiert sind. Um eine effektive Sicherheitsstrategie zu implementieren, muss man Bedrohungen verstehen und wissen, wie man sich dagegen verteidigen kann.

Was ist eine Bedrohung, wenn es um Computer-Sicherheit geht? Bedrohungen beschränken sich nicht nur auf entfernte Angreifer, die sich unerlaubten Zugriff auf ein System verschaffen wollen. Zu den Bedrohungen zählen auch Mitarbeiter, bösartige Software, nicht autorisierte Netzwerkgeräte, Naturkatastrophen, Sicherheitslücken und sogar konkurrierende Unternehmen.

Der Zugriff auf Netzwerke und Systeme erfolgt ohne Erlaubnis, manchmal durch Zufall, oder von entfernten Angreifern, und in einigen Fällen durch Industriespionage oder ehemalige Mitarbeiter. Als Anwender müssen Sie vorbereitet sein und auch zugeben, wenn ein Fehler zu einer Sicherheitsverletzung geführt hat. Melden Sie Probleme umgehend dem verantwortlichen Sicherheitspersonal. Als Administrator ist es wichtig, Bedrohungen zu kennen und darauf vorbereitet zu sein, mögliche Schäden zu mildern.

Wenn Sicherheit auf Systeme angewendet wird, empfiehlt es sich mit der Sicherung der Benutzerkonten zu beginnen und dann die Netzwerkschicht zu sichern. Dabei ist zu beachten, dass die Sicherheitsrichtlinien des Systems und des Unternehmens eingehalten werden. Viele Unternehmen haben bereits eine Sicherheitsrichtlinie, welche die Konfiguration von technischen Geräten abdeckt. Die Richtlinie sollte die Konfiguration von Arbeitsplatzrechnern, Desktops, mobilen Geräten, Mobiltelefonen, Produktions- und Entwicklungsservern umfassen. In einigen Fällen ist bereits eine Standardvorgehensweise vorhanden. Fragen Sie im Zweifelsfall das Sicherheitspersonal.

Der übrige Teil dieser Einführung beschreibt, wie einige grundlegende Sicherheitskonfigurationen auf einem FreeBSD-System durchgeführt werden. Der Rest des Kapitels zeigt einige spezifische Werkzeuge, die verwendet werden können, um eine Sicherheitsrichtlinie auf einem FreeBSD-System zu implementieren.

[[security-accounts]]
=== Anmeldungen am System verhindern

Ein guter Ausgangspunkt für die Absicherung des Systems ist die Prüfung der Benutzerkonten. Stellen Sie sicher, dass `root` ein starkes Passwort besitzt und dass dieses Passwort nicht weitergegeben wird. Deaktivieren Sie alle Konten, die keinen Zugang zum System benötigen.

Es existieren zwei Methoden, um die Anmeldung über ein Benutzerkonto zu verweigern. Die erste Methode ist, das Konto zu sperren. Dieses Beispiel sperrt das Benutzerkonto `toor`:

[source,shell]
....
# pw lock toor
....

Bei der zweiten Methode wird der Anmeldevorgang verhindert, indem die Shell auf [.filename]#/usr/sbin/nologin# gesetzt wird. Nur der Superuser kann die Shell für andere Benutzer ändern:

[source,shell]
....
# chsh -s /usr/sbin/nologin toor
....

Die Shell [.filename]#/usr/sbin/nologin# verhindert, dass dem Benutzer bei der Anmeldung am System eine Shell zugeordnet wird.

[[security-accountmgmt]]
=== Gemeinsame Nutzung von Benutzerkonten

In manchen Fällen wird die Systemadministration auf mehrere Benutzer aufgeteilt. FreeBSD bietet zwei Methoden, um solche Situationen zu handhaben. Bei der ersten und nicht empfohlenen Methode wird ein gemeinsames root Passwort der Mitglieder der Gruppe `wheel` verwendet. Hier gibt der Benutzer `su` und das Passwort für `wheel` ein, wenn er die Rechte des Superusers benötigt. Der Benutzer sollte dann nach der Beendigung der administrativen Aufgaben `exit` eingeben. Um einen Benutzer zu dieser Gruppe hinzuzufügen, bearbeiten Sie [.filename]#/etc/group# und fügen Sie den Benutzer an das Ende des Eintrags `wheel` hinzu. Die Benutzer müssen durch Komma und ohne Leerzeichen getrennt werden.

Die zweite und empfohlene Methode ein Benutzerkonto zu teilen wird über den Port oder das Paket package:security/sudo[] realisiert. Dieses Programm bietet zusätzliche Prüfungen, bessere Benutzerkontrolle und es kann auch konfiguriert werden, einzelnen Benutzern Zugriff auf bestimme, privilegierte Befehle zu gestatten.

Benutzen Sie nach der Installation `visudo`, um [.filename]#/usr/local/etc/sudoers# zu bearbeiten. Dieses Beispiel erstellt eine neue Gruppe `webadmin` und fügt das Benutzerkonto `trhodes` dieser Gruppe hinzu. Anschließend wird die Gruppe so konfiguriert, dass es Gruppenmitgliedern gestattet wird package:apache24[] neu zu starten:

[source,shell]
....
# pw groupadd webadmin -M trhodes -g 6000
# visudo
%webadmin ALL=(ALL) /usr/sbin/service apache24 *
....

[[security-passwords]]
=== Passwort-Hashes

Passwörter sind ein notwendiges Übel. Wenn sie verwendet werden müssen, sollten sie sehr komplex sein und dazu sollte eine leistungsfähige Hash-Funktion gewählt werden, um die Version des Passworts zu verschlüsseln, die in der Passwortdatenbank gespeichert wird. FreeBSD unterstützt die Hash-Funktionen DES, MD5, SHA256, SHA512, sowie Blowfish Hash-Funktionen in seiner `crypt()`-Bibliothek. Das in der Voreinstellung verwendete SHA512 sollte nicht durch eine weniger sichere Hash-Funktion getauscht werden. Es kann jedoch durch den besseren Blowfish-Algorithmus ersetzt werden.

[NOTE]
====
Blowfish ist nicht Bestandteil von AES und ist nicht kompatibel mit allen Federal Information Processing Standards (FIPS). Die Verwendung wird in einigen Umgebungen vielleicht nicht gestattet.
====

Um zu bestimmen, welche Hash-Funktion das Passwort eines Benutzers verschlüsselt, kann der Superuser den Hash für den Benutzer in der Passwortdatenbank von FreeBSD nachsehen. Jeder Hash beginnt mit einem Zeichen, mit dem die verwendete Hash-Funktion identifiziert werden kann. Bei DES gibt es allerdings kein führendes Zeichen. MD5 benutzt das Zeichen `$`. SHA256 und SHA512 verwenden das Zeichen `$6$`. Blowfish benutzt das Zeichen `$2a$`. In diesem Beispiel wird das Passwort von `dru` mit dem Hash-Algorithmus SHA512 verschlüsselt, da der Hash mit `$6$` beginnt. Beachten Sie, dass der verschlüsselte Hash und nicht das Passwort selbst, in der Passwortdatenbank gespeichert wird:

[source,shell]
....
# grep dru /etc/master.passwd
dru:$6$pzIjSvCAn.PBYQBA$PXpSeWPx3g5kscj3IMiM7tUEUSPmGexxta.8Lt9TGSi2lNQqYGKszsBPuGME0:1001:1001::0:0:dru:/usr/home/dru:/bin/csh
....

Der Hash-Mechanismus wird in der Login-Klasse des Benutzers festgelegt. In diesem Beispiel wird die voreingestellte Login-Klasse für den Benutzer verwendet. Der Hash-Algorithmus wird mit dieser Zeile in [.filename]#/etc/login.conf# gesetzt:

[.programlisting]
....
        :passwd_format=sha512:\
....

Um den Algorithmus auf Blowfish zu ändern, passen Sie die Zeile wie folgt an:

[.programlisting]
....
        :passwd_format=blf:\
....

Führen Sie anschließend `cap_mkdb /etc/login.conf` aus, wie in <<users-limiting>> beschrieben. Beachten Sie, dass vorhandene Passwort-Hashes durch diese Änderung nicht beeinträchtigt werden. Das bedeutet, dass alle Passwörter neu gehasht werden sollten, indem die Benutzer mit `passwd` ihr Passwort ändern.

Für die Anmeldung auf entfernten Rechnern sollte eine Zwei-Faktor-Authentifizierung verwendet werden. Ein Beispiel für eine Zwei-Faktor-Authentifizierung ist "etwas, was Sie besitzen" (bspw. einen Schlüssel) und "etwas, was Sie wissen" (bspw. das Passwort für diesen Schlüssel). Da OpenSSH Teil des FreeBSD-Basissystems ist, sollten alle Anmeldungen über das Netzwerk über eine verschlüsselte Verbindung mit einer schlüsselbasierten Authentifizierung stattfinden. Passwörter sollten hier nicht verwendet werden. Weitere Informationen finden Sie in <<openssh>>. Kerberos-Benutzer müssen eventuell zusätzliche Änderungen vornehmen, um OpenSSH in Ihrem Netzwerk zu implementieren. Diese Änderungen sind in <<kerberos5>> beschrieben.

[[security-pwpolicy]]
=== Durchsetzung einer Passwort-Richtlinie

Die Durchsetzung einer starken Passwort-Richtlinie für lokale Benutzerkonten ist ein wesentlicher Aspekt der Systemsicherheit. In FreeBSD kann die Länge, Stärke und Komplexität des Passworts mit den Pluggable Authentication Modules (PAM) implementiert werden.

In diesem Abschnitt wird gezeigt, wie Sie die minimale und maximale Passwortlänge und die Durchsetzung von gemischten Zeichen mit dem Modul [.filename]#pam_passwdqc.so# konfigurieren. Dieses Modul wird aufgerufen, wenn ein Benutzer sein Passwort ändert.

Um dieses Modul zu konfigurieren, müssen Sie als Superuser die Zeile mit `pam_passwdqc.so` in [.filename]#/etc/pam.d/passwd# auskommentieren. Anschließend bearbeiten Sie die Zeile, so dass sie den vorliegenden Passwort-Richtlinien entspricht:

[.programlisting]
....
password        requisite       pam_passwdqc.so min=disabled,disabled,disabled,12,10 similar=deny retry=3 enforce=users
....

Dieses Beispiel legt gleich mehrere Anforderungen für neue Passwörter fest. Die Einstellung `min` kontrolliert die Passwortlänge. Es verfügt über fünf Werte, weil dieses Modul fünf verschiedene Arten von Passwörtern definiert, basierend auf der Komplexität. Die Komplexität wird durch die Art von Zeichen definiert, die in einem Passwort vorhanden sind, wie zum Beispiel Buchstaben, Zahlen und Sonderzeichen. Die verschiedenen Arten von Passwörtern werden in man:pam_passwdqc[8] beschrieben. In diesem Beispiel sind die ersten drei Arten von Passwörtern deaktiviert, was bedeutet, dass Passwörter, die dieser Komplexitätsstufe entsprechen, nicht akzeptiert werden, unabhängig von der Länge des Passworts. Die `12` legt eine Richtlinie von mindestens zwölf Zeichen fest, wenn das Passwort auch drei Arten von Komplexität aufweist. Die `10` legt eine Richtlinie fest, die auch Passwörter mit mindestens zehn Zeichen zulassen, wenn das Passwort Zeichen mit vier Arten von Komplexität aufweist.

Die Einstellung `similar` verbietet Passwörter, die dem vorherigen Passwort des Benutzers ähnlich sind. Die Einstellung `retry` bietet dem Benutzer drei Möglichkeiten, ein neues Passwort einzugeben.

Sobald diese Datei gespeichert wird, sehen Benutzer bei der Änderung ihres Passworts die folgende Meldung:

[source,shell]
....
% passwd
Changing local password for trhodes
Old Password:

You can now choose the new password.
A valid password should be a mix of upper and lower case letters,
digits and other characters.  You can use a 12 character long
password with characters from at least 3 of these 4 classes, or
a 10 character long password containing characters from all the
classes.  Characters that form a common pattern are discarded by
the check.
Alternatively, if noone else can see your terminal now, you can
pick this as your password: "trait-useful&knob".
Enter new password:
....

Wenn ein Passwort nicht den Richtlinien entspricht, wird es mit einer Warnung abgelehnt und der Benutzer bekommt die Möglichkeit, es erneut zu versuchen, bis die Anzahl an Wiederholungen erreicht ist.

Die meisten Passwort-Richtlinien erzwingen, dass Passwörter nach einer bestimmten Anzahl von Tagen ablaufen. Um dieses Limit in FreeBSD zu konfigurieren, setzen Sie es für die Login-Klasse des Benutzers in [.filename]#/etc/login.conf#. Die voreingestellte Login-Klasse enthält dazu ein Beispiel:

[.programlisting]
....
#       :passwordtime=90d:\
....

Um für diese Login-Klasse das Passwort nach 90 Tagen ablaufen zu lassen, entfernen Sie das Kommentarzeichen (`#`), speichern Sie die Änderungen und führen Sie `cap_mkdb /etc/login.conf` aus.

Um das Passwort für einzelne Benutzer ablaufen zu lassen, geben Sie `pw` ein Ablaufdatum oder die Anzahl von Tagen, zusammen mit dem Benutzer an:

[source,shell]
....
# pw usermod -p 30-apr-2015 -n trhodes
....

Wie zu sehen ist, wird das Ablaufdatum in der Form von Tag, Monat und Jahr angegeben. Weitere Informationen finden Sie in man:pw[8].

[[security-rkhunter]]
=== Erkennen von Rootkits

Ein _Rootkit_ ist eine nicht autorisierte Software die versucht, Root-Zugriff auf ein System zu erlangen. Einmal installiert, wird diese bösartige Software normalerweise eine Hintertür für den Angreifer installieren. Realistisch betrachtet sollte ein durch ein Rootkit kompromittiertes System nach der Untersuchung von Grund auf neu installiert werden. Es besteht jedoch die enorme Gefahr, dass sogar das Sicherheitspersonal oder Systemingenieure etwas übersehen, was ein Angreifer dort platziert hat.

Wird ein Rootkit erkannt, ist dies bereits ein Zeichen dafür, dass das System an einem bestimmten Zeitpunkt kompromittiert wurde. Meist neigen diese Art von Anwendungen dazu, sehr gut versteckt zu sein. Dieser Abschnitt zeigt das Werkzeug package:security/rkhunter[], mit dem Rootkits erkannt werden können.

Nach der Installation dieses Ports oder Pakets kann das System mit dem folgenden Kommando überprüft werden. Das Programm generiert eine ganze Menge Informationen und Sie werden diverse Male kbd:[ENTER] drücken müssen:

[source,shell]
....
# rkhunter -c
....

Nachdem der Prozess abgeschlossen ist, wird eine Statusmeldung auf dem Bildschirm ausgegeben. Die Meldung enthält die Anzahl der überprüften Dateien, verdächtige Dateien, mögliche Rootkits und weitere Informationen. Während der Überprüfung erscheinen allgemeine Sicherheitswarnungen, zum Beispiel über versteckte Dateien, die Auswahl von OpenSSH-Protokollen und bekannte, anfällige Versionen installierter Anwendungen. Diese können nun direkt, oder nach detaillierter Analyse untersucht werden.

Jeder Administrator sollte wissen, was auf den Systemen läuft, für die er verantwortlich ist. Werkzeuge von Drittanbietern, wie rkhunter oder package:sysutils/lsof[], sowie native Befehle wie `netstat` oder `ps`, können eine große Menge an Informationen über das System anzeigen. Machen Sie sich Notizen darüber, was "normal" ist, und fragen Sie nach, wenn Ihnen etwas suspekt erscheint. Eine Beeinträchtigung zu verhindern ist ideal, aber die Erkennung einer Beeinträchtigung ist ein Muss.

[[security-ids]]
=== Überprüfung von Binärdateien

Die Überprüfung von System- und Binärdateien ist wichtig, da sie Systemadministratoren Informationen über Systemänderungen zur Verfügung stellt. Eine Software, die das System auf Änderungen überwacht wird Intrustion Detection System (IDS) genannt.

FreeBSD bietet native Unterstützung für ein einfaches IDS-System. Obwohl die täglichen Sicherheits-E-Mails den Administrator über Änderungen in Kenntnis setzen, werden diese Informationen lokal gespeichert und es besteht die Möglichkeit, dass ein Angreifer diese Informationen manipulieren kann, um Änderungen am System zu verbergen. Daher ist es empfehlenswert, einen eigenen Satz an Signaturen zu erstellen und diese dann in einem schreibgeschützten Verzeichnis, oder vorzugsweise auf einem USB-Stick oder auf einem entfernten Server zu speichern.

Das im Basissystem enthaltene Werkzeug mtree kann verwendet werden, um eine Spezifikation des Inhalts eines Verzeichnisses zu erzeugen. Hierbei wird ein Startwert (Seed) oder eine numerische Konstante benutzt, um die Spezifikation zu erstellen und um sicherzustellen, dass sich die Spezifikation nicht geändert hat. Dadurch kann festgestellt werden, ob eine Datei oder eine Binärdatei verändert wurde. Da ein Angreifer den Seed nicht kennt, ist es ihm fast unmöglich die Prüfsummen von Dateien zu manipulieren. Das folgende Beispiel generiert einen Satz mit SHA256-Prüfsummen für jede Binärdatei unterhalb von [.filename]#/bin# und speichert diese Werte in einer versteckten Datei im Heimatverzeichnis von `root` unter dem Namen [.filename]#/root/.bin_chksum_mtree#:

[source,shell]
....
# mtree -s 3483151339707503 -c -K cksum,sha256digest -p /bin > /root/.bin_chksum_mtree
# mtree: /bin checksum: 3427012225
....

_3483151339707503_ stellt den Seed dar. Diesen Wert sollten Sie sich merken, aber nicht mit anderen Personen teilen.

Die Ausgabe von [.filename]#/root/.bin_chksum_mtree# sollte ähnlich der folgenden sein:

[.programlisting]
....
#          user: root
#       machine: dreadnaught
#          tree: /bin
#          date: Mon Feb  3 10:19:53 2014

# .
/set type=file uid=0 gid=0 mode=0555 nlink=1 flags=none
.               type=dir mode=0755 nlink=2 size=1024 \
                time=1380277977.000000000
    \133        nlink=2 size=1170 time=1380277977.000000000 \
                cksum=484492447 \
                sha256digest=6207490fbdb5ed1904441fbfa941279055c3e24d3a4049aeb45094596400662a
    cat         size=12096 time=1380277975.000000000 cksum=3909216944 \
                sha256digest=65ea347b9418760b247ab10244f47a7ca2a569c9836d77f074e7a306900c1e69
    chflags     size=8168 time=1380277975.000000000 cksum=3949425175 \
                sha256digest=c99eb6fc1c92cac335c08be004a0a5b4c24a0c0ef3712017b12c89a978b2dac3
    chio        size=18520 time=1380277975.000000000 cksum=2208263309 \
                sha256digest=ddf7c8cb92a58750a675328345560d8cc7fe14fb3ccd3690c34954cbe69fc964
    chmod       size=8640 time=1380277975.000000000 cksum=2214429708 \
                sha256digest=a435972263bf814ad8df082c0752aa2a7bdd8b74ff01431ccbd52ed1e490bbe7
....

Der Report enthält den Rechnernamen, das Datum und die Uhrzeit der Spezifikation, sowie den Namen des Benutzers, der die Spezifikation erstellt hat. Für jede Binärdatei im Verzeichnis gibt es eine Prüfsumme, Größe, Uhrzeit und einen SHA256-Hashwert.

Um sicherzustellen, dass die binären Signaturen nicht verändert wurden, vergleichen Sie den Inhalt des aktuellen Verzeichnisses mit der zuvor erstellen Spezifikation. Speichern Sie die Ergebnisse in einer Datei. Dieses Kommando benötigt den Seed, der verwendet wurde um die ursprüngliche Spezifikation zu erstellen:

[source,shell]
....
# mtree -s 3483151339707503 -p /bin < /root/.bin_chksum_mtree >> /root/.bin_chksum_output
# mtree: /bin checksum: 3427012225
....

Dies sollte die gleiche Prüfsumme für [.filename]#/bin# produzieren, wie die ursprüngliche Spezifikation. Wenn keine Änderungen an den Binärdateien in diesem Verzeichnis aufgetreten sind, wird die Ausgabedatei [.filename]#/root/.bin_chksum_output# leer sein. Um eine Änderung zu simulieren, ändern Sie mit `touch` das Datum von [.filename]#/bin/cat# und führen Sie die Verifikation erneut aus:

[source,shell]
....
# touch /bin/cat
# mtree -s 3483151339707503 -p /bin < /root/.bin_chksum_mtree >> /root/.bin_chksum_output
# more /root/.bin_chksum_output
cat changed
	modification time expected Fri Sep 27 06:32:55 2013 found Mon Feb  3 10:28:43 2014
....

Es wird empfohlen, Spezifikationen für Verzeichnisse zu erstellen, welche Binärdateien, Konfigurationsdateien und sensible Daten enthalten. In der Regel werden Spezifikationen für [.filename]#/bin#, [.filename]#/sbin#, [.filename]#/usr/bin#, [.filename]#/usr/sbin#, [.filename]#/usr/local/bin#, [.filename]#/usr/local/sbin#, [.filename]#/etc# und [.filename]#/usr/local/etc# erstellt.

Mit package:security/aide[] steht ein fortgeschrittenes IDS-System zur Verfügung, aber in den meisten Fällen bietet `mtree` die Funktionalität, die von Administratoren benötigt wird. Es ist jedoch sehr wichtig den Seed und die Prüfsummen in der Ausgabe vor böswilligen Benutzern verborgen zu halten. Weitere Informationen zu `mtree` finden Sie in man:mtree[8].

[[security-tuning]]
=== System-Tuning für Sicherheit

Unter FreeBSD können viele Systemfunktionen mit `sysctl` konfiguriert werden. Dieser Abschnitt behandelt ein paar Sicherheitsmerkmale mit denen Denial of Service (DoS) verhindert werden sollen. Weitere Informationen über die Benutzung von `sysctl` und wie Werte vorübergehend oder auch permanent geändert werden können, finden Sie in crossref:config[configtuning-sysctl,“Einstellungen mit sysctl(8)”].

[NOTE]
====
Jedes Mal wenn eine Einstellung mit `sysctl` geändert wird, vergrößert sich die Wahrscheinlichkeit eines unerwünschten Schadens, was die Verfügbarkeit des Systems beeinflusst. Alle Änderungen sollten überwacht und wenn möglich, vorher auf einem Testsystem ausprobiert werden, bevor sie auf einem Produktivsystem verwendet werden.
====

In der Voreinstellung startet FreeBSD in der Sicherheitsstufe (Securelevel) `-1`. Dieser Modus wird "unsicherer Modus" genannt, da die unveränderlichen Datei-Flags ausgeschaltet werden können und dadurch von allen Geräten gelesen und geschrieben werden kann. Solange die Einstellung nicht über `sysctl` oder in den Startskripten geändert wird, verbleibt die Sicherheitsstufe auf `-1`. Die Sicherheitsstufe kann während des Systemstarts erhöht werden. Dazu muss in [.filename]#/etc/rc.conf#`kern_securelevel_enable` auf `YES` und `kern_securelevel` auf den gewünschten Wert gesetzt werden. Weitere Informationen zu diesen Einstellungen und den verfügbaren Sicherheitsstufen finden Sie in man:security[7] und man:init[8].

[WARNING]
====

Das Erhöhen der Sicherheitsstufe kann zu Problemen mit Xorg führen.
====

Die Einstellungen `net.inet.tcp.blackhole` und `net.inet.udp.blackhole` können benutzt werden, um eingehende SYN-Pakete an geschlossenen Ports zu blockieren, ohne ein RST-Paket als Antwort zu senden. Standardmäßig wird jedoch ein RST-Paket gesendet, um zu zeigen, dass der Port geschlossen ist. Das ändern dieser Voreinstellung bietet einen gewissen Schutz gegen Portscans. Diese Portscans versuchen herauszufinden, welche Anwendungen auf einem System ausgeführt werden. Setzen Sie `net.inet.tcp.blackhole` auf `2` und `net.inet.udp.blackhole` auf `1`. Weitere Informationen zu diesen Einstellungen finden Sie in man:blackhole[4].

Die Einstellung `net.inet.icmp.drop_redirect` hilft dabei, sogenannte Redirect-Angriffe zu verhindern. Ein Redirect-Angriff ist eine Art von DoS, die massenhaft ICMP-Pakete Typ 5 versendet. Da solche Pakete nicht benötigt werden, setzen Sie `net.inet.icmp.drop_redirect` auf `1` und `net.inet.ip.redirect` auf `0`.

Source Routing zur Erfassung und zum Zugriff auf nicht-routbare Adressen im internen Netzwerk. Dies sollte deaktiviert werden, da nicht-routbare Adressen in der Regel nicht absichtlich geroutet werden. Um diese Funktion zu deaktivieren, setzen Sie `net.inet.ip.sourceroute` und `net.inet.accept_sourceroute` auf `0`.

Wenn ein Netzwerkgerät Nachrichten an alle Rechner in einem Subnetz senden muss, wird eine ICMP-Echo-Request Nachricht an die Broadcast-Adresse gesendet. Allerdings gibt es keinen guten Grund für externe Rechner, solche Nachrichten zu verschicken. Um alle externen Broadcast-Anfragen abzulehnen, setzen Sie `net.inet.icmp.bmcastecho` auf `0`.

Einige zusätzliche Einstellungen sind in man:security[7] dokumentiert.

[[one-time-passwords]]
== Einmalpasswörter

In der Voreinstellung unterstützt FreeBSD One-time Passwords in Everything (OPIE). OPIE wurde konzipiert um Replay-Angriffe zu verhindern, bei dem ein Angreifer das Passwort eines Benutzers ausspäht und es benutzt, um Zugriff auf ein System zu erlangen. Da ein Passwort unter OPIE nur einmal benutzt wird, ist ein ausgespähtes Passwort für einen Angreifer nur von geringem Nutzen. OPIE verwendet eine sichere Hash-Funktion und ein Challenge/Response-System, um Passwörter zu verwalten. Die FreeBSD-Implementation verwendet in der Voreinstellung die MD5-Hash-Funktion.

OPIE verwendet drei verschiedene Arten von Passwörtern. Das erste ist das normale UNIX(R)- oder Kerberos-Passwort. Das zweite ist das Einmalpasswort, das von `opiekey` generiert wird. Das dritte Passwort ist das "geheime Passwort", das zum Erstellen der Einmalpasswörter verwendet wird. Das geheime Passwort steht in keiner Beziehung zum UNIX(R)-Passwort und beide Passwörter sollten unterschiedlich sein.

Es gibt noch zwei weitere Werte, die für OPIE wichtig sind. Der erste ist der "Initialwert" (engl. seed oder key), der aus zwei Buchstaben und fünf Ziffern besteht. Der zweite Wert ist der "Iterationszähler", eine Zahl zwischen 1 und 100. OPIE generiert das Einmalpasswort, indem es den Initialwert und das geheime Passwort aneinander hängt und dann die MD5-Hash-Funktion so oft, wie durch den Iterationszähler gegeben, anwendet. Das Ergebnis wird in sechs englische Wörter umgewandelt, die das Einmalpasswort ergeben. Das Authentifizierungssystem (meistens PAM) merkt sich das zuletzt benutzte Einmalpasswort und der Benutzer ist authentifiziert, wenn die Hash-Funktion des Passworts dem vorigen Passwort entspricht. Da nicht umkehrbare Hash-Funktionen benutzt werden, ist es unmöglich, aus einem bekannten Passwort weitere gültige Einmalpasswörter zu berechnen. Der Iterationszähler wird nach jeder erfolgreichen Anmeldung um eins verringert und stellt so die Synchronisation zwischen Benutzer und Login-Programm sicher. Wenn der Iterationszähler den Wert `1` erreicht, muss OPIE neu initialisiert werden.

Es gibt ein paar Programme, die in diesen Prozess einbezogen werden. Ein Einmalpasswort oder eine Liste von Einmalpasswörtern, die von man:opiekey[1] durch Angabe eines Iterationszählers, eines Initalwertes und einem geheimen Passwort generiert wird. man:opiepasswd[1] wird benutzt, um Passwörter, Iterationszähler oder Initialwerte zu ändern. man:opieinfo[1] hingegen gibt den momentanen Iterationszähler und Initialwert eines Benutzers aus, den es aus [.filename]#/etc/opiekeys# ermittelt.

Dieser Abschnitt beschreibt vier verschiedene Arten von Tätigkeiten. Zuerst wird erläutert, wie Einmalpasswörter über eine gesicherte Verbindung konfiguriert werden. Als nächstes wird erklärt, wie `opiepasswd` über eine nicht gesicherte Verbindung eingesetzt wird. Als drittes wird beschrieben, wie man sich über eine nicht gesicherte Verbindung anmeldet. Die vierte Tätigkeit beschreibt, wie man eine Reihe von Schlüsseln generiert, die man sich aufschreiben oder ausdrucken kann, um sich von Orten anzumelden, die über keine gesicherten Verbindungen verfügen.

=== OPIE initialisieren

Um OPIE erstmals zu initialisieren, rufen Sie man:opiepasswd[1] über eine gesicherte Verbindung auf:

[source,shell]
....
% opiepasswd -c
[grimreaper] ~ $ opiepasswd -f -c
Adding unfurl:
Only use this method from the console; NEVER from remote. If you are using
telnet, xterm, or a dial-in, type ^C now or exit with no password.
Then run opiepasswd without the -c parameter.
Using MD5 to compute responses.
Enter new secret pass phrase:
Again new secret pass phrase:

ID unfurl OTP key is 499 to4268
MOS MALL GOAT ARM AVID COED
....

Die Option `-c` startet den Konsolen-Modus, der davon ausgeht, dass der Befehl von einem sicherem Ort ausgeführt wird. Dies kann beispielsweise der eigene Rechner sein, oder über eine mit SSH gesicherte Verbindung zum eigenen Rechner.

Geben Sie das geheime Passwort ein, wenn Sie danach gefragt werden. Damit werden die Einmalpasswörter generiert. Dieses Passwort sollte schwer zu erraten sein und sich ebenfalls vom Passwort des Bentuzerkontos unterscheiden. Es muss zwischen 10 und 127 Zeichen lang sein. Prägen Sie sich dieses Passwort gut ein!

Die Zeile, die mit "ID" beginnt, enthält den Login-Namen (`unfrul`), den voreingestellten Iterationszähler (`499`) und den Initialwert (`to4268`). Das System erinnert sich an diese Parameter und wird sie bei einem Anmeldeversuch anzeigen. Sie brauchen sich diese Dinge also nicht merken. Die letzte Zeile enthält das generierte Einmalpasswort, das aus den Parametern und dem geheimen Passwort ermittelt wurde. Bei der nächsten Anmeldung muss dann diese Einmalpasswort benutzt werden.

=== Initialisierung über eine nicht gesicherte Verbindung

Um Einmalpasswörter über eine nicht gesicherte Verbindung zu initialisieren, oder das geheime Passwort zu ändern, müssen Sie über eine gesicherte Verbindung zu einer Stelle verfügen, an der Sie `opiekey` ausführen können. Dies kann etwa die Eingabeaufforderung auf einer Maschine sein, der Sie vertrauen. Zudem müssen Sie einen Iterationszähler vorgeben (100 ist ein guter Wert) und einen Initialwert wählen, wobei Sie auch einen zufällig generierten benutzen können. Benutzen Sie man:opiepasswd[1] über die ungesicherte Verbindung zu der Maschine, die Sie einrichten wollen:

[source,shell]
....
% opiepasswd

Updating unfurl:
You need the response from an OTP generator.
Old secret pass phrase:
        otp-md5 498 to4268 ext
        Response: GAME GAG WELT OUT DOWN CHAT
New secret pass phrase:
        otp-md5 499 to4269
        Response: LINE PAP MILK NELL BUOY TROY

ID mark OTP key is 499 gr4269
LINE PAP MILK NELL BUOY TROY
....

Drücken Sie kbd:[Return], um die Vorgabe für den Initialwert zu akzeptieren. Bevor Sie nun das Zugriffspasswort (engl. access password) eingeben, rufen Sie über die gesicherte Verbindung `opikey` mit denselben Parametern auf:

[source,shell]
....
% opiekey 498 to4268
Using the MD5 algorithm to compute response.
Reminder: Don not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase:
GAME GAG WELT OUT DOWN CHAT
....

Gehen Sie zurück zu der nicht gesicherten Verbindung und geben dort das eben generierte Einmalpasswort ein.

=== Erzeugen eines einzelnen Einmalpasswortes

Nachdem Sie OPIE eingerichtet haben, werden Sie beim nächsten Anmelden wie folgt begrüßt:

[source,shell]
....
% telnet example.com
Trying 10.0.0.1...
Connected to example.com
Escape character is '^]'.

FreeBSD/i386 (example.com) (ttypa)

login: <username>
otp-md5 498 gr4269 ext
Password: 
....

OPIE besitzt eine nützliche Eigenschaft. Wenn Sie an der Eingabeaufforderung kbd:[Return] drücken, wird die echo-Funktion eingeschaltet, das heißt Sie sehen, was Sie tippen. Dies ist besonders nützlich, wenn Sie ein generiertes Passwort von einem Ausdruck abtippen müssen.

Jetzt müssen Sie das Einmalpasswort generieren, um der Anmeldeaufforderung nachzukommen. Dies muss auf einem gesicherten System geschehen, auf dem Sie man:opiekey[1] ausführen können. Dieses Programm gibt es auch für Windows(R), Mac OS(R) und FreeBSD. Es benötigt den Iterationszähler sowie den Initialwert als Parameter, die Sie mittels "cut-and-paste" direkt von der Login-Aufforderung nehmen können.

Auf dem sicheren System:

[source,shell]
....
% opiekey 498 to4268
Using the MD5 algorithm to compute response.
Reminder: Do not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase:
GAME GAG WELT OUT DOWN CHAT
....

Sobald das Einmalpasswort generiert wurde, können Sie die Anmeldeprozedur fortsetzen.

=== Erzeugen von mehreren Einmalpasswörtern

Manchmal haben Sie keinen Zugriff auf eine sichere Maschine oder eine sichere Verbindung. In diesem Fall können Sie vorher mit man:opiekey[1] einige Einmalpasswörter generieren. Zum Beispiel:

[source,shell]
....
% opiekey -n 5 30 zz99999
Using the MD5 algorithm to compute response.
Reminder: Do not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase: <secret password>
26: JOAN BORE FOSS DES NAY QUIT
27: LATE BIAS SLAY FOLK MUCH TRIG
28: SALT TIN ANTI LOON NEAL USE
29: RIO ODIN GO BYE FURY TIC
30: GREW JIVE SAN GIRD BOIL PHI
....

Mit `-n 5` fordern Sie fünf Passwörter der Reihe nach an. Der letzte Iterationszähler wird durch `30` gegeben. Beachten Sie bitte, dass die Passwörter in der _umgekehrten_ Reihenfolge, in der sie zu benutzen sind, ausgeben werden. Wirklich paranoide Benutzer können sich jetzt die Passwörter aufschreiben oder ausdrucken. Sie sollten die Passwörter nach Gebrauch durchstreichen.

=== Einschränken der Benutzung von System-Passwörtern

OPIE kann die Verwendung von UNIX(R)-Passwörtern abhängig von der IP-Adresse einschränken. Die dazu nötigen Einstellungen werden in [.filename]#/etc/opieaccess# vorgenommen, die bei der Installation des Systems automatisch erzeugt wird. Weitere Informationen über diese Datei und Sicherheitshinweise zu ihrer Verwendung finden Sie in man:opieaccess[5].

[.filename]#opieaccess# könnte beispielsweise die folgende Zeile enthalten:

[.programlisting]
....
permit 192.168.0.0 255.255.0.0
....

Diese Zeile erlaubt es Benutzern, die sich von einer der angegebenen IP-Adressen anmelden, ihr UNIX(R)-Passwort zu verwenden. Beachten Sie bitte, dass eine IP-Adresse leicht gefälscht werden kann.

Findet sich in [.filename]#opieaccess# kein passender Eintrag, muss die Anmeldung mit OPIE erfolgen.

[[tcpwrappers]]
== TCP Wrapper

TCP Wrapper ist ein rechnerbasiertes Zugriffskontrollsystem, das die Fähigkeiten von crossref:network-servers[network-inetd,“Der inetd Super-Server”] erweitert. Beispielsweise können Verbindungen protokolliert, Nachrichten zurückgesandt oder nur interne Verbindungen angenommen werden. Weitere Informationen über TCP Wrapper und dessen Funktionen finden Sie in man:tcpd[8].

TCP Wrapper sollten nicht als Ersatz für eine ordentlich konfigurierte Firewall angesehen werden. Stattdessen sollten TCP Wrapper in Verbindung mit einer Firewall und anderen Sicherheitsmechanismen eingesetzt werden, um bei der Umsetzung einer Sicherheitsrichtlinie eine weitere Sicherheitsschicht zu bieten.

=== Konfiguration

Um TCP Wrapper unter FreeBSD zu aktivieren, fügen Sie die folgenden Zeilen in [.filename]#/etc/rc.conf# ein:

[.programlisting]
....
inetd_enable="YES"
inetd_flags="-Ww"
....

Anschließend muss [.filename]#/etc/hosts.allow# richtig konfiguriert werden.

[NOTE]
====
Im Gegensatz zu anderen Implementierungen der TCP Wrapper wird unter FreeBSD vom Gebrauch der Datei [.filename]#hosts.deny# abgeraten. Die Konfiguration sollte sich vollständig in [.filename]#/etc/hosts.allow# befinden.
====

In der einfachsten Konfiguration werden Dienste abhängig von den Optionen in [.filename]#/etc/hosts.allow# erlaubt oder gesperrt. Unter FreeBSD wird in der Voreinstellung jeder von inetd gestartete Dienst erlaubt.

Eine Konfigurationszeile ist wie folgt aufgebaut: `Dienst : Adresse : Aktion`. `Dienst` ist der von inetd gestartete Dienst (auch Daemon genannt). Die `Adresse` ist ein gültiger Rechnername, eine IP-Adresse oder eine IPv6-Adresse in Klammern (`[ ]`). Der Wert `allow` im Feld `Aktion` erlaubt Zugriffe, der Wert `deny` verbietet Zugriffe. Die Zeilen in [.filename]#hosts.allow# werden für jede Verbindung der Reihe nach abgearbeitet. Trifft eine Zeile auf eine Verbindung zu, wird die entsprechende Aktion ausgeführt und die Abarbeitung ist beendet.

Um beispielsweise einkommende POP3-Verbindungen für den Dienst package:mail/qpopper[] zu erlauben, sollte [.filename]#hosts.allow# um die nachstehende Zeile erweitert werden:

[.programlisting]
....
# This line is required for POP3 connections:
qpopper : ALL : allow
....

Jedes Mal, wenn diese Datei bearbeitet wird, muss inetd neu gestartet werden:

[source,shell]
....
# service inetd restart
....

=== Erweiterte Konfiguration

TCP Wrapper besitzen weitere Optionen, die bestimmen, wie Verbindungen behandelt werden. In einigen Fällen ist es gut, wenn bestimmten Rechnern oder Diensten eine Nachricht geschickt wird. In anderen Fällen soll vielleicht der Verbindungsaufbau protokolliert oder eine E-Mail an einen Administrator versandt werden. Oder ein Dienst soll nur für das lokale Netz bereitstehen. Dies alles ist mit so genannten Wildcards, Metazeichen und der Ausführung externer Programme möglich.

Stellen Sie sich vor, eine Verbindung soll verhindert werden und gleichzeitig soll dem Rechner, der die Verbindung aufgebaut hat, eine Nachricht geschickt werden. Solch eine Aktion ist mit `twist` möglich. `twist` führt beim Verbindungsaufbau ein Kommando oder ein Skript aus. Ein Beispiel ist in [.filename]#hosts.allow# enthalten:

[.programlisting]
....
# Alle anderen Dienste sind geschützt
ALL : ALL \
        : severity auth.info \
        : twist /bin/echo "You are not welcome to use %d from %h."
....

Für jeden Dienst, der nicht vorher in [.filename]#hosts.allow# konfiguriert wurde, wird die Meldung "You are not allowed to use _daemon name_ from _hostname_." zurückgegeben. Dies ist nützlich, wenn die Gegenstelle sofort benachrichtigt werden soll, nachdem die Verbindung getrennt wurde. Der Text der Meldung _muss_ in Anführungszeichen (`"`) stehen.

[WARNING]
====

Ein so konfigurierter Server ist anfällig für Denial-of-Service-Angriffe. Ein Angreifer kann die gesperrten Dienste mit Verbindungsanfragen überfluten.
====

Eine weitere Möglichkeit bietet `spawn`. Wie `twist` verbietet `spawn` die Verbindung und führt externe Kommandos aus. Allerdings sendet `spawn` dem Rechner keine Rückmeldung. Sehen Sie sich die nachstehende Konfigurationsdatei an:

[.programlisting]
....
# Verbindungen von example.com sind gesperrt:
ALL : .example.com \
	: spawn (/bin/echo %a from %h attempted to access %d >> \
	  /var/log/connections.log) \
	: deny
....

Damit sind Verbindungen von der Domain `*.example.com` gesperrt. Jeder Verbindungsaufbau wird zudem in [.filename]#/var/log/connections.log# protokolliert. Das Protokoll enthält den Rechnernamen, die IP-Adresse und den Dienst, der angesprochen wurde. In diesem Beispiel wurden die Metazeichen `%a` und `%h` verwendet. Eine vollständige Liste der Metazeichen finden Sie in man:hosts_access[5].

Die Wildcard `ALL` passt auf jeden Dienst, jede Domain oder jede IP-Adresse. Eine andere Wildcard ist `PARANOID`. Sie passt auf jeden Rechner, dessen IP-Adresse möglicherweise gefälscht ist. Dies ist beispielsweise der Fall, wenn der Verbindungsaufbau von einer IP-Adresse erfolgt, die nicht zu dem übermittelten Rechnernamen passt. In diesem Beispiel werden alle Verbindungsanfragen zu Sendmail abgelehnt, wenn die IP-Adresse nicht zum Rechnernamen passt:

[.programlisting]
....
# Block possibly spoofed requests to sendmail:
sendmail : PARANOID : deny
....

[CAUTION]
====

Die Wildcard `PARANOID` wird Verbindungen ablehnen, wenn der Client oder der Server eine fehlerhafte DNS-Konfiguration besitzt.
====

Weitere Informationen über Wildcards und deren Funktion finden Sie in man:hosts_access[5].

[NOTE]
====
Wenn Sie neue Einträge zur Konfiguration hinzufügen, sollten Sie sicherstellen, dass nicht benötigte Einträge in [.filename]#hosts.allow# auskommentiert werden.
====

[[kerberos5]]
== Kerberos

Kerberos ist ein Netzwerk-Authentifizierungsprotokoll, das ursprünglich am Massachusetts Institute of Technology (MIT) entwickelt wurde. Es bietet die Möglichkeit zur sicheren Authentifizierung über ein potentiell unsicheres Netzwerk. Das Kerberos-Protokoll benutzt eine starke Kryptographie, um die Identität von Clients und Servern nachweisen zu können. Dabei werden keine unverschlüsselten Daten über das Netzewrk gesendet. Kerberos kann als eine Art Proxy zur Identitätsprüfung, oder als vertrauenswürdiges Authentifizierungssystem betrachtet werden.

Kerberos hat nur eine Aufgabe: Die sichere Prüfung der Identität eines Benutzers (Authentifizierung) über das Netzwerk. Das System überprüft weder die Berechtigungen der Benutzer (Autorisierung), noch verfolgt es die durchgeführten Aktionen (Audit). Daher sollte Kerberos zusammen mit anderen Sicherheits-Systemen eingesetzt werden, die diese Funktionen bereitstellen.

Die aktuelle Version des Protokolls ist Version 5, die in RFC 4120 beschrieben ist. Es existieren mehrere freie Implementierungen dieses Protokolls für eine Reihe von Betriebssystemen. Das MIT entwickelt auch weiterhin seine Kerberos-Version weiter. Es wird in den vereinigten Staaten als Kryptographie-Produkt eingesetzt und unterlag in der Vergangenheit US-Exportbeschränkungen. In FreeBSD ist MIT-Kerberos als Port oder Paket package:security/krb5[] verfügbar. Die Kerberos-Implementation von Heimdal wurde außerhalb der USA entwickelt und unterliegt daher keinen Export-Beschränkungen. Heimdal-Kerberos ist im Basissystem von FreeBSD enthalten. Mit package:security/heimdal[] aus der Ports-Sammlung steht eine weitere Distribution, mit mehr konfigurierbaren Optionen zur Verfügung.

Unter Kerberos werden Benutzer und Dienste als "Prinzipale" bezeichnet, die innerhalb einer administrativen Domäne, dem sogenannten "Realm" enthalten sind. Ein typisches Benutzer-Prinzipal hätte das Format `_user_@_REALM_` (Realms sind traditionell in Großbuchstaben).

Die folgenden Anweisungen beschreiben, wie Sie das mit FreeBSD gelieferte Heimdal-Kerberos einrichten.

Die Beschreibung der Kerberos-Installation benutzt folgende Namensräume:

* Die DNS-Domain ("Zone") heißt `example.org`.
* Das Kerberos-Realm heißt `EXAMPLE.ORG`.

[NOTE]
====
Benutzen Sie echte Domain-Namen, wenn Sie Kerberos einrichten. Damit vermeiden Sie DNS-Probleme und stellen die Zusammenarbeit mit anderen Kerberos-Realms sicher.
====

=== Das Heimdal KDC einrichten

Kerberos authentifiziert Benutzer an einer zentralen Stelle: dem Key Distribution Center (KDC). Das KDC verteilt _Tickets_, mit denen ein Dienst die Identität eines Benutzers feststellen kann. Weil alle Mitglieder eines Kerberos-Realms dem KDC vertrauen, gelten für das KDC erhöhte Sicherheitsanforderungen. Der direkte Zugriff auf das KDC sollte daher eingeschränkt sein.

Obwohl der Kerberos-Server wenig Ressourcen benötigt, sollte das KDC wegen der Sicherheitsanforderungen auf einem separaten Rechner installiert werden.

Installieren Sie zunächst das Paket package:security/heimdal[] wie folgt:

[source,shell]
....
# pkg install heimdal
....

Als nächstes aktualisieren Sie [.filename]#/etc/rc.conf# mittels `sysrc`:

[source,shell]
....
# sysrc kdc_enable=yes
# sysrc kadmind_enable=yes
....

Danach wird [.filename]#/etc/krb5.conf# wie folgt bearbeitet:

[.programlisting]
....
[libdefaults]
    default_realm = EXAMPLE.ORG
[realms]
    EXAMPLE.ORG = {
	kdc = kerberos.example.org
	admin_server = kerberos.example.org
    }
[domain_realm]
    .example.org = EXAMPLE.ORG
....

Diese Einstellungen setzen voraus, dass der voll qualifizierte Name des KDCs `kerberos.example.org` ist. Der Rechnername des KDC muss im DNS auflösbar sein.

In großen Netzwerken mit einem ordentlich konfigurierten DNS-Server kann die Datei aus dem obigen Beispiel verkürzt werden:

[.programlisting]
....
[libdefaults]
      default_realm = EXAMPLE.ORG
[domain_realm]
    .example.org = EXAMPLE.ORG
....

Die Zonendatei von `example.org` muss dann die folgenden Zeilen enthalten:

[.programlisting]
....
_kerberos._udp      IN  SRV     01 00 88 kerberos.example.org.
_kerberos._tcp      IN  SRV     01 00 88 kerberos.example.org.
_kpasswd._udp       IN  SRV     01 00 464 kerberos.example.org.
_kerberos-adm._tcp  IN  SRV     01 00 749 kerberos.example.org.
_kerberos           IN  TXT     EXAMPLE.ORG
....

[NOTE]
====
Damit die Clients die Kerberos-Dienste benutzen können, _muss_ sie entweder eine vollständig konfigurierte [.filename]#/etc/krb5.conf# enthalten, oder eine minimale Konfiguration _und_ zusätzlich ein richtig konfigurierter DNS-Server.
====

Im nächsten Schritt wird die Kerberos-Datenbank eingerichtet. Die Datenbank enthält die Schlüssel aller Prinzipale und ist mit einem Passwort geschützt. Dieses Passwort brauchen Sie sich nicht merken, da ein davon abgeleiteter Schlüssel in [.filename]#/var/heimdal/m-key# gespeichert wird. Es wäre durchaus sinnvoll, ein 45-stelliges Zufallspasswort für diesen Zweck zu benutzten. Um den Schlüssel zu erstellen, rufen Sie `kstash` auf und geben Sie ein Passwort ein:

[source,shell]
....
# kstash
Master key: xxxxxxxxxxxxxxxxxxxxxxx
Verifying password - Master key: xxxxxxxxxxxxxxxxxxxxxxx
....

Nachdem der Schlüssel erstellt wurde, sollte die Datenbank initialisiert werden. Das Kerberos-Werkzeug man:kadmin[8] kann die Datenbank mit `kadmin -l` direkt bearbeiten, ohne dabei den Netzwerkdienst man:kadmind[8] zu benutzen. An der Eingabeaufforderung von `kadmin` kann mit `init` die Datenbank des Realms initialisiert werden:

[source,shell]
....
# kadmin -l
kadmin> init EXAMPLE.ORG
Realm max ticket life [unlimited]:
....

Zuletzt wird in `kadmin` mit `add` das erste Prinzipal erstellt. Benutzen Sie vorerst die voreingestellten Optionen für das Prinzipal. Die Optionen können später mit `modify` verändert werden. An der Eingabeaufforderung von man:kadmin[8] zeigt `?` die verfügbaren Optionen an.

[source,shell]
....
kadmin> add tillman
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
Password: xxxxxxxx
Verifying password - Password: xxxxxxxx
....

Jetzt können die KDC-Dienste wie folgt gestartet werden:

[source,shell]
....
# service kdc start
# service kadmind start
....

Obwohl zu diesem Zeitpunkt noch keine kerberisierten Dienste laufen, kann die Funktion des KDC schon überprüft werden, indem Sie für den eben angelegten Benutzer ein Ticket anfordern:

[source,shell]
....
% kinit tillman
tillman@EXAMPLE.ORG's Password:
....

Überprüfen Sie, ob das Ticket erfolgreich ausgestellt wurde:

[source,shell]
....
% klist
Credentials cache: FILE: /tmp/krb5cc_1001
        Principal: tillman@EXAMPLE.ORG

  Issued                Expires               Principal
Aug 27 15:37:58 2013  Aug 28 01:37:58 2013  krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
....

Nachdem der Test abgeschlossen ist, kann das temporäre Ticket zurückgezogen werden:

[source,shell]
....
% kdestroy
....

=== Kerberos-Dienste auf dem Server einrichten

Bei der Konfiguration eines Servers für die Kerberos-Authentifizierung muss zuerst sichergestellt werden, dass [.filename]#/etc/krb5.conf# richtig konfiguriert ist. Die Datei kann entweder vom KDC kopiert, oder auf dem neuen System generiert werden.

Als nächstes muss auf dem Server die [.filename]#/etc/krb5.keytab# erzeugt werden. Dies ist der Hauptbestandteil um Dienste zu "kerberisieren" und entspricht der Erzeugung eines geheimen Schlüssels zwischen dem Dienst und dem KDC. Das Geheimnis ist ein kryptographischer Schlüssel, der in einem [.filename]#keytab#> abgelegt wird. Diese Datei enthält den Schlüssel des Servers, mit dem sich der Server und das KDC gegenseitig authentifizieren können. Sie muss in einer sicheren Art und Weise an den Server übertragen werden, da ansonsten die Sicherheit des Servers gefährdet ist, wenn z.B. die Schlüssel öffentlich werden. In der Regel wird die [.filename]#keytab# auf einem vertrauenswürdigen Rechner mit `kadmin` erzeugt und anschließend sicher auf den Server übertragen, beispielsweise mit man:scp[1]. Wenn die Sicherheitsrichtlinien es erlauben, kann die Datei auch direkt auf dem Server erzeugt werden. Es ist sehr wichtig, dass die [.filename]#keytab# auf sichere Weise auf den Server übertragen wird. Wenn der Schlüssel einer anderen Partei bekannt wird, kann sich diese Partei den Benutzern als Server ausgeben! Da der Eintrag für das Host-Prinzipal für die KDC-Datenbank auch mit `kadmin` erstellt wird, ist es praktisch, `kadmin` direkt auf dem Server zu benutzen.

Natürlich ist auch `kadmin` ein kerberisierter Dienst: ein Kerberos-Ticket ist erforderlich, um sich gegenüber dem Netzwerkdienst zu authentifizieren und um sicherzustellen, dass der Benutzer, der `kadmin` ausführt, tatsächlich vorhanden ist. `kadmin` wird nach dem Passwort fragen, um ein neues Ticket zu generieren. Das Prinzipal, das sich mit dem kadmin-Dienst authentifiziert, muss über die Zugriffskontrollliste [.filename]#/var/heimdal/kadmin.acl# dazu berechtigt sein. Weitere Informationen über Zugriffskontrolllisten finden Sie in den Heimdal-Info-Seiten (`info heimdal`) im Abschnitt "Remote administration". Wenn der Zugriff auf `kadmin` von entfernten Rechnern verboten ist, kann sich der Administrator entweder über die lokale Konsole oder über man:ssh[1] mit dem KDC verbinden, um die lokale Administration mit `kadmin -l` durchzuführen.

Nach der Installation von [.filename]#/etc/krb5.conf#, können Sie das Kommando `add --random-key` in `kadmin` ausführen, um das Host-Prinzipal in die Datenbank zu schreiben. Das Kommando `ext` extrahiert den Schlüssel des Prinzipals in eine eigene keytab:

[source,shell]
....
# kadmin
kadmin> add --random-key host/myserver.example.org
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin> ext_keytab host/myserver.example.org
kadmin> exit
....

Beachten Sie, dass `ext_keytab` den extrahierten Schlüssel standardmäßig in [.filename]#/etc/krb5.keytab# speichert. Das ist gut, wenn das Kommando auf dem kerberisierten Server ausgeführt wird, ansonsten sollte das Argument `--keytab _pfad/zur/datei_` benutzt werden, wenn die keytab an einen anderen Ort extrahiert wird:

[source,shell]
....
# kadmin
kadmin> ext_keytab --keytab=/tmp/example.keytab host/myserver.example.org
kadmin> exit
....

Anschließend kann die erzeugte keytab sicher mit man:scp[1] auf Server oder auf einen Wechseldatenträger kopiert werden. Geben Sie auf jeden Fall einen anderen Namen für die keytab an, um unnötige Schlüssel in der keytab des Systems zu vermeiden.

Mit Hilfe der Datei [.filename]#krb5.conf# kann der Server nun mit dem KDC kommunizieren und seine Identität mithilfe der Datei [.filename]#krb5.keytab# nachweisen. Jetzt können die kerberisierten Dienste aktiviert werden. Einer der gebräuchlichsten Dienste ist man:sshd[8], der Kerberos über GSS-API unterstützt. Fügen Sie folgende Zeile in [.filename]#/etc/ssh/sshd_config# ein:

[.programlisting]
....
GSSAPIAuthentication yes
....

Nach dieser Änderung muss man:sshd[8] mit `service sshd restart` neu gestartet werden, damit die neue Konfiguration wirksam wird.

=== Kerberos auf dem Client einrichten

Genau wie der Server, benötigt auch der Client eine Konfiguration in [.filename]#/etc/krb5.conf#. Kopien Sie die Datei (sicher) vom KDC auf den Client, oder schreiben Sie die Datei bei Bedarf einfach neu.

Testen Sie den Client, indem Sie mit `kinit` Tickets anfordern, mit `klist` Tickets anzeigen und mit `kdestroy` Tickets löschen. Kerberos-Anwendungen sollten auch kerberisierte Server ansprechen können. Wenn das nicht funktioniert, Sie aber Tickets anfordern können, hat wahrscheinlich der kerberisierte Server ein Problem und nicht der Client oder das KDC. Im Falle eines kerberisierten man:ssh[1] ist GSS-API in der Voreinstellung deaktiviert. Testen Sie daher mit `ssh -o GSSAPIAuthentication=yes _hostname_`.

Wenn Sie die kerberisierten Anwendungen testen, können Sie einen Paket-Sniffer wie `tcpdump` benutzen, um sicherzustellen, dass keine sensiblen Informationen im Klartext übertragen werden.

Es stehen verschiedene Kerberos-Anwendungen zur Verfügung. Die Anwendungen, die SASL benutzen, können dann auch GSS-API benutzen. Viele Arten von Anwendungen können Kerberos zur Authentifizierung verwenden, vom Jabber-Client bis zum IMAP-Client.

Normalerweise wird ein Kerberos-Prinzipal auf ein lokales Benutzerkonto abgebildet. Manchmal wird aber Zugriff auf ein lokales Benutzerkonto benötigt, zu dem es keinen passenden Kerberos-Prinzipal gibt. Der Prinzipal `tillman@EXAMPLE.ORG` bräuchte beispielsweise Zugriff auf das Konto `webdevelopers`. Ebenso könnten andere Prinzipale auf dieses Konto zugreifen wollen.

Die Dateien [.filename]#.k5login# und [.filename]#.k5users# im Heimatverzeichnis eines Benutzers können verwendet werden, um dieses Problem zu lösen. Mit der folgenden [.filename]#.k5login# im Heimatverzeichnis des Benutzers `webdevelopers` haben beide Prinzipale auch ohne das gemeinsame Passwort Zugriff auf das Konto:

[.programlisting]
....
tillmann@example.org
jdoe@example.org
....

Weitere Informationen zu [.filename]#.k5users# finden Sie in man:ksu[1].

=== Unterschiede zur MIT-Implementation

Der Hauptunterschied zwischen der MIT- und der Heimdal-Implementation ist das Kommando `kadmin`. Die Befehlssätze des Kommandos (obwohl funktional gleichwertig) und das verwendete Protokoll unterscheiden sich in beiden Varianten. Das KDC lässt sich nur mit dem `kadmin` Kommando der passenden Kerberos-Variante verwalten.

Für dieselbe Funktion können auch die Client-Anwendungen leicht geänderte Kommandozeilenoptionen besitzen. Folgen Sie der Anleitung auf http://web.mit.edu/Kerberos/www/[ http://web.mit.edu/Kerberos/www/]. Achten Sie besonders auf den Suchpfad für Anwendungen. Der MIT-Port wird unter FreeBSD standardmäßig in [.filename]#/usr/local/# installiert. Wenn die Umgebungsvariable `PATH` zuerst die Systemverzeichnisse enthält, werden die Systemprogramme anstelle der MIT-Programme ausgeführt.

Wenn Sie MIT-Kerberos verwenden, sollten Sie außerdem folgende Änderungen an [.filename]#/etc/rc.conf# vornehmen:

[.programlisting]
....
kdc_program="/usr/local/sbin/kdc"
kadmind_program="/usr/local/sbin/kadmind"
kdc_flags=""
kdc_enable="YES"
kadmind_enable="YES"
....

=== Tipps und Fehlersuche

Während der Konfiguration und bei der Fehlersuche sollten die folgenden Punkte beachtet werden:

* Wenn Sie Heimdal- oder MIT-Kerberos benutzen, muss in der Umgebungsvariable `PATH` der Pfad zu den Kerberos-Programmen vor dem Pfad zu den Programmen des Systems stehen.
* Wenn die Clients im Realm ihre Uhrzeit nicht synchronisieren, schlägt vielleicht die Authentifizierung fehl. crossref:network-servers[network-ntp,“Die Uhrzeit mit NTP synchronisieren”] beschreibt, wie Sie mithilfe von NTP die Uhrzeiten synchronisieren.
* Wenn Sie den Namen eines Rechners ändern, müssen Sie auch den `host/`-Prinzipal ändern und die keytab aktualisieren. Dies betrifft auch spezielle Einträge wie den `HTTP/`-Prinzipal für Apaches package:www/mod_auth_kerb[].
* Alle Rechner in einem Realm müssen vor- und rückwärts aufgelöst werden können. Entweder über DNS, zumindest aber über [.filename]#/etc/hosts#. CNAME-Einträge im DNS funktionieren, aber die entsprechenden A- und PTR-Einträge müssen vorhanden und richtig sein. Wenn sich Namen nicht auflösen lassen, ist die Fehlermeldung nicht gerade selbstsprechend: `Kerberos5 refuses authentication because Read req failed: Key table entry not found`.
* Einige Betriebssysteme installieren `ksu` mit falschen Zugriffsrechten; es fehlt das Set-UID-Bit für `root`. Das hat zur Folge, dass `ksu` nicht funktioniert. Dies ist ein Fehler in den Zugriffsrechten und kein Fehler des KDCs.
* Wenn Sie für einen Prinzipal unter MIT-Kerberos Tickets mit einer längeren Gültigkeit als der vorgegebenen zehn Stunden einrichten wollen, müssen Sie zwei Sachen ändern. Benutzen Sie `modify_principal` am Prompt von man:kadmin[8], um die maximale Gültigkeitsdauer für den Prinzipal selbst und den Prinzipal `krbtgt` zu erhöhen. Das Prinzipal kann dann mit `kinit -l` ein Ticket mit einer längeren Gültigkeit beantragen.
* Mit einem Packet-Sniffer können Sie feststellen, dass Sie sofort nach dem Aufruf von `kinit` eine Antwort vom KDC bekommen - noch bevor Sie überhaupt ein Passwort eingegeben haben! Das ist in Ordnung: Das KDC händigt ein Ticket-Granting-Ticket (TGT) auf Anfrage aus, da es durch einen vom Passwort des Benutzers abgeleiteten Schlüssel geschützt ist. Wenn das Passwort eingegeben wird, wird es nicht zum KDC gesendet, sondern zum Entschlüsseln der Antwort des KDCs benutzt, die `kinit` schon erhalten hat. Wird die Antwort erfolgreich entschlüsselt, erhält der Benutzer einen Sitzungs-Schlüssel für die künftige verschlüsselte Kommunikation mit dem KDC und das TGT. Das TGT wiederum ist mit dem Schlüssel des KDCs verschlüsselt. Diese Verschlüsselung ist für den Benutzer völlig transparent und erlaubt dem KDC, die Echtheit jedes einzelnen TGT zu prüfen.
* Host-Prinzipale können Tickets mit längerer Gültigkeit besitzen. Wenn der Prinzipal eines Benutzers über ein Ticket verfügt, das eine Woche gültig ist, das Ticket des Host-Prinzipals aber nur neun Stunden gültig ist, funktioniert der Ticket-Cache nicht wie erwartet. Im Cache befindet sich dann ein abgelaufenes Ticket des Host-Prinzipals.
* Wenn Sie mit [.filename]#krb5.dict# die Verwendung schlechter Passwörter verhindern wollen, wie in man:kadmin[8] beschrieben, geht das nur mit Prinzipalen, denen eine Passwort-Policy zugewiesen wurde. Das Format von [.filename]#krb5.dict# enthält pro Zeile ein Wort. Sie können daher einen symbolischen Link auf [.filename]#/usr/shared/dict/words# erstellen.

=== Beschränkungen von Kerberos

Kerberos muss ganzheitlich verwendet werden. Jeder über das Netzwerk angebotene Dienst muss mit Kerberos zusammenarbeiten oder auf anderen Wegen gegen Angriffe aus dem Netzwerk geschützt sein. Andernfalls können Berechtigungen gestohlen und wiederverwendet werden. Es ist beispielsweise nicht sinnvoll, für Remote-Shells Kerberos zu benutzen, dagegen aber POP3-Zugriff auf einem Mail-Server zu erlauben, da POP3 Passwörter im Klartext versendet.

Das KDC ist verwundbar und muss daher genauso abgesichert werden, wie die auf ihm befindliche Passwort-Datenbank. Auf dem KDC sollten absolut keine anderen Dienste laufen und der Rechner sollte physikalisch gesichert sein. Die Gefahr ist groß, da Kerberos alle Passwörter mit einem Schlüssel, dem Haupt-Schlüssel, verschlüsselt. Der Haupt-Schlüssel wiederum wird in einer Datei auf dem KDC gespeichert.

Ein kompromittierter Haupt-Schlüssel ist nicht ganz so schlimm wie allgemein angenommen. Der Haupt-Schlüssel wird nur zum Verschlüsseln der Passwort-Datenbank und zum Initialisieren des Zufallsgenerators verwendet. Solange der Zugriff auf das KDC abgesichert ist, kann ein Angreifer wenig mit dem Haupt-Schlüssel anfangen.

Wenn das KDC nicht zur Verfügung steht, sind auch die Netzwerkdienste nicht benutzbar, da eine Authentifizierung nicht durchgeführt werden kann. Das KDC ist also ein optimales Ziel für einen Denial-of-Service Angriff. Sie können diesem Angriff entgegenwirken, indem Sie einen KDC-Master und einen oder mehrere Slaves verwenden. Der Rückfall auf ein sekundäres KDC mittels PAM-Authentifizierung muss sorgfältig eingerichtet werden.

Mit Kerberos können sich Benutzer, Rechner und Dienste gegenseitig authentifizieren. Allerdings existiert kein Mechanismus, der das KDC gegenüber Benutzern, Rechnern oder Diensten authentifiziert. Ein verändertes `kinit` könnte beispielsweise alle Benutzernamen und Passwörter abfangen. Die von veränderten Programmen ausgehende Gefahr können Sie lindern, indem Sie die Integrität von Dateien mit Werkzeugen wie package:security/tripwire[] prüfen.

=== Weiterführende Dokumentation

* http://www.faqs.org/faqs/Kerberos-faq/general/preamble.html[The Kerberos FAQ]
* http://web.mit.edu/Kerberos/www/dialogue.html[Designing an Authentication System: a Dialogue in Four Scenes]
* https://www.ietf.org/rfc/rfc4120.txt[RFC 4120, The Kerberos Network Authentication Service (V5)]
* http://web.mit.edu/Kerberos/www/[MIT Kerberos-Seite]
* https://github.com/heimdal/heimdal/wiki[Heimdal Kerberos-Wiki]

[[openssl]]
== OpenSSL

OpenSSL ist eine Open Source Implementierung der SSL und TLS-Protokolle. Es bietet eine verschlüsselte Transportschicht oberhalb der normalen Kommunikationsschicht und kann daher zusammen mit vielen Netzdiensten benutzt werden.

Das in FreeBSD integrierte OpenSSL stellt die Protokolle Secure Sockets Layer 3.0 (SSLv3) und Transport Layer Security 1.0/1.1/1.2 (TLSv1/TLSv1.1/TLSv1.2) zur Verfügung. Die OpenSSL-Bibliotheken stellen kryptographische Funktionen bereit. FreeBSD 12.0-RELEASE und neuere Versionen enthalten OpenSSL mit Unterstützung für Transport Layer Security 1.3 (TLSv1.3).

Anwendungsbeispiele für OpenSSL sind die verschlüsselte Authentifizierung von E-Mail-Clients oder Web-Transaktionen wie das Bezahlen mit Kreditkarte. Einige Ports, wie package:www/apache24[] und package:databases/postgresql11-server[], haben eine Option für den Bau mit OpenSSL. Bei Auswahl dieser Option, wird OpenSSL aus dem Basissystem benutzt. Wenn Sie für den Bau der Anwendung stattdessen OpenSSL aus dem Port package:security/openssl[] benutzten wollen, fügen Sie folgende Zeile in [.filename]#/etc/make.conf# ein:

[.programlisting]
....
DEFAULT_VERSIONS+= ssl=openssl
....

OpenSSL wird auch eingesetzt, um Zertifikate für Anwendungen bereitzustellen. Die Zertifikate stellen die Identität einer Firma oder eines Einzelnen sicher. Wenn ein Zertifikat nicht von einer Zertifizierungsstelle (Certificate Authority, CA) gegengezeichnet wurde, erhalten Sie normalerweise eine Warnung. Eine Zertifizierungsstelle ist eine Firma wie http://www.verisign.com/[VeriSign], die Zertifikate von Personen oder Firmen gegenzeichnet und damit die Korrektheit der Zertifikate bestätigt. Diese Prozedur kostet Geld, ist aber keine Voraussetzung für den Einsatz von Zertifikaten, beruhigt aber sicherheitsbewusste Benutzer.

Dieser Abschnitt beschreibt, wie Sie auf einem FreeBSD-System Zertifikate erstellen und benutzen. crossref:network-servers[ldap-config,“Konfiguration eines LDAP-Servers”] beschreibt, wie Sie eine CA erstellen um die eigenen Zertifikate zu signieren.

Weitere Informationen über SSL finden Sie im kostenlosen https://www.feistyduck.com/books/openssl-cookbook/[OpenSSL Cookbook].

=== Zertifikate erzeugen

Um ein Zertifikat zu erzeugen, das von einer externen CA signiert werden soll, geben Sie folgenden Befehl und die angeforderten Informationen ein. Diese Informationen werden in das Zertifikat geschrieben. Für `Common Name` geben Sie den vollqualifizierten Namen des Systems ein, auf dem das Zertifikat später installiert wird. Wenn der Name nicht übereinstimmt, wird die Anwendung, die das Zertifikat überprüft, dem Benuzter eine Warnung anzeigen. Die Überprüfung würde fehlschlagen und das Zertifikat damit unbrauchbar machen.

[source,shell]
....
# openssl req -new -nodes -out req.pem -keyout cert.key -sha256 -newkey rsa:2048
Generating a 2048 bit RSA private key
..................+++
.............................................................+++
writing new private key to 'cert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:PA
Locality Name (eg, city) []:Pittsburgh
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (eg, YOUR name) []:localhost.example.org
Email Address []:trhodes@FreeBSD.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:Another Name
....

Bei der Erzeugung des Zertifikates können noch weitere Optionen, wie die Gültigkeitsdauer und alternative Verschlüsselungsalgorithmen, angegeben werden. man:openssl[1] beschreibt die zur Verfügung stehenden Optionen.

Das folgende Kommando erstellt zwei Dateien im aktuellen Verzeichnis: Die Anforderung für ein neues Zertifikat wird in [.filename]#req.pem# gespeichert. Diese Datei können Sie an eine CA senden, wo die Angaben geprüft werden. Nach erfolgreicher Prüfung wird das Zertifikat signiert und an Sie zurückgesandt. [.filename]#cert.key#, enthält den privaten Schlüssel für das Zertifikat und darf auch keine Fall in fremde Hände geraten, da ein Angreifer sonst in der Lage ist, anderen Personen oder Rechnern vorzugaukeln, dass es sich bei ihm um Sie handelt.

Wenn Sie keine Signatur einer Zertifizierungsstelle benötigen, können Sie ein selbst signiertes Zertifikat erstellen. Erzeugen Sie dazu zuerst einen RSA-Schlüssel:

[source,shell]
....
# openssl genrsa -rand -genkey -out cert.key 2048
0 semi-random bytes loaded
Generating RSA private key, 2048 bit long modulus
.............................................+++
.................................................................................................................+++
e is 65537 (0x10001)
....

Benutzen Sie diesen Schlüssel, um ein selbst signiertes Zertifikat zu erzeugen. Folgen Sie wieder den Anweisungen am Prompt:

[source,shell]
....
# openssl req -new -x509 -days 365 -key cert.key -out cert.crt -sha256
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:PA
Locality Name (eg, city) []:Pittsburgh
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (e.g. server FQDN or YOUR name) []:localhost.example.org
Email Address []:trhodes@FreeBSD.org
....

Dieses Kommando erstellt zwei neue Dateien im aktuellen Verzeichnis: Der Schlüssel der Zertifizierungsstelle [.filename]#cert.key# und das Zertifikat selbst, [.filename]#cert.crt#. Sie sollten in einem Verzeichnis, vorzugsweise unterhalb von [.filename]#/etc/ssl/# abgelegt werden, das nur von `root` lesbar ist. Die Zugriffsrechte der Dateien können mit `chmod` auf `0700` gesetzt werden.

=== Zertifikate benutzen

Mit einem Zertifikat können beispielsweise die Verbindungen zu Sendmail verschlüsselt werden, um eine Klartext-Authentifizierung zu verhindern.

[NOTE]
====
Einige E-Mail-Programme geben Warnungen aus, wenn ein Zertifikat nicht lokal installiert ist. Weitere Informationen zur Installation von Zertifikaten finden Sie in der Dokumentation der entsprechenden Software.
====

Unter FreeBSD 10.0-RELEASE und neueren Versionen ist es möglich, ein selbst signiertes Zertifikat für Sendmail automatisch erzeugen zu lassen. Um diese Funktionalität zu aktivieren, fügen Sie die folgenden Zeilen in [.filename]#/etc/rc.conf# ein:

[.programlisting]
....
sendmail_enable="YES"
sendmail_cert_enable="YES"
sendmail_cert_cn="localhost.example.org"
....

Dadurch wird automatisch ein selbst signiertes Zertifikat ([.filename]#/etc/mail/certs/host.cert#), der Schlüssel für die CA ([.filename]#/etc/mail/certs/host.key# und das Zertifikat der CA ([.filename]#/etc/mail/certs/cacert.pem# erzeugt. Das Zertifikat wird den in `sendmail_cert_cn` festgelegten `Common Name` verwenden. Nachdem Sie die Änderungen gespeichert haben, starten Sie Sendmail neu:

[source,shell]
....
# service sendmail restart
....

Wenn alles gut ging, erscheinen keine Fehlermeldungen in [.filename]#/var/log/maillog#. Für einen einfachen Test, bauen Sie mit Hilfe von `telnet` eine Verbindung zum Mailserver auf:

[source,shell]
....
# telnet example.com 25
Trying 192.0.34.166...
Connected to example.com.
Escape character is '^]'.
220 example.com ESMTP Sendmail 8.14.7/8.14.7; Fri, 18 Apr 2014 11:50:32 -0400 (EDT)
ehlo example.com
250-example.com Hello example.com [192.0.34.166], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH LOGIN PLAIN
250-STARTTLS
250-DELIVERBY
250 HELP
quit
221 2.0.0 example.com closing connection
Connection closed by foreign host.
....

Wenn die Zeile `STARTTLS` erscheint, hat alles funktioniert.

[[ipsec]]
== VPN mit IPsec

Internet Protocol Security (IPsec) ist ein Satz von Protokollen, die auf dem Internet-Protokoll (IP) aufbauen. Durch Authentifizierung und Verschlüsselung jedes einzelnen IP-Pakets, können mehrere Systeme geschützt miteinander kommunizieren. FreeBSDs IPSsec Netzwerk-Stack basiert auf der http://www.kame.net[http://www.kame.net] Implementierung und unterstützt sowohl IPv4 als auch IPv6.

IPsec besteht aus den folgenden Protokollen:

* _Encapsulated Security Payload (ESP)_: dieses Protokoll verschlüsselt IP-Pakete mit einem symmetrischen Verfahren wie Blowfish oder 3DES. Damit werden die Pakete vor Manipulationen Dritter geschützt.
* _Authentication Header (AH)_: dieses Protokoll enthält eine kryptographische Prüfsumme, die sicher stellt, dass ein IP-Paket nicht verändert wurde. Der Authentication-Header folgt nach dem normalen IP-Header und erlaubt dem Empfänger eines IP-Paketes, dessen Integrität zu prüfen.
* _IP Payload Compression Protocol (IPComp)_: dieses Protokoll versucht durch Komprimierung der IP-Nutzdaten die Menge der gesendeten Daten zu reduzieren und somit die Kommunikationsleistung zu verbessern.

Diese Protokolle können, je nach Situation, zusammen oder einzeln verwendet werden.

IPsec unterstützt zwei Modi: Der _Transport-Modus_ verschlüsselt die Daten zwischen zwei Systemen. Der _Tunnel-Modus_ verbindet zwei Subnetze miteinander. Durch einen Tunnel können dann verschlüsselte Daten übertragen werden. Ein Tunnel wird auch als Virtual-Private-Network (VPN) bezeichnet. Detaillierte Informationen über das IPsec-Subsystem von FreeBSD finden Sie in man:ipsec[4].

Seit FreeBSD 11 ist IPsec in der Voreinstellung aktiviert. Um die Unterstützung für IPsec in älteren Versionen zu aktivieren, fügen Sie folgenden Optionen in die Kernelkonfigurationsdatei ein und erstellen Sie einen neuen Kernel, wie in crossref:kernelconfig[kernelconfig,Konfiguration des FreeBSD-Kernels] beschrieben.

[source,shell]
....
options   IPSEC        IP security
device    crypto
....

Wenn Sie zur Fehlersuche im IPsec-Subsystem Unterstützung wünschen, sollten Sie die folgende Option ebenfalls aktivieren:

[source,shell]
....
options   IPSEC_DEBUG  debug for IP security
....

Der Rest dieses Kapitels beschreibt die Einrichtung eines IPsec-VPN zwischen einem Heimnetzwerk und einem Firmennetzwerk. Für das folgende Beispiel gilt:

* Beide Netzwerke sind über ein FreeBSD-Gateway mit dem Internet verbunden.
* Der Gateway jedes Netzwerks besitzt mindestens eine externe IP-Adresse. In diesem Beispiel ist die externe IP-Adresse des Firmennetzwerks (LAN) `172.16.5.4` und das Heimnetzwerk (LAN) hat die externe IP-Adresse `192.168.1.12`.
* Die intern verwendeten IP-Adressen können private oder öffentliche Adressen sein. Sie dürfen sich jedoch nicht überschneiden. Zum Beispiel sollten nicht beide Netze `192.168.1.x` benutzen. In diesem Beispiel ist die interne IP-Adresse des Firmennetzwerks (LAN) `10.246.38.1` und das Heimnetzwerk (LAN) hat die interne IP-Adresse `10.0.0.5`.

=== Konfiguration eines VPN unter FreeBSD

Als erstes muss package:security/ipsec-tools[] aus der Ports-Sammlung installiert werden. Diese Software enthält einige Anwendungen, die bei der Konfiguration von IPsec hilfreich sind.

Als nächstes müssen zwei man:gif[4]-Pseudogeräte angelegt werden, um die Pakete zu tunneln und dafür zu sorgen, dass beide Netzwerke richtig miteinander kommunizieren können. Geben Sie als `root` die folgenden Befehle ein, wobei Sie _intern_ und _extern_ durch die realen internen und externen IP-Adressen der Gateways ersetzen müssen:

[source,shell]
....
# ifconfig gif0 create
# ifconfig gif0 intern1 intern2
# ifconfig gif0 tunnel extern1 extern2
....

Überprüfen Sie mit `ifconfig` die Konfiguration auf beiden Gateways. Hier folgt die Ausgabe von Gateway 1:

[.programlisting]
....
gif0: flags=8051 mtu 1280
tunnel inet 172.16.5.4 --> 192.168.1.12
inet6 fe80::2e0:81ff:fe02:5881%gif0 prefixlen 64 scopeid 0x6
inet 10.246.38.1 --> 10.0.0.5 netmask 0xffffff00
....

Hier folgt die Ausgabe von Gateway 2:

[.programlisting]
....
gif0: flags=8051 mtu 1280
tunnel inet 192.168.1.12 --> 172.16.5.4
inet 10.0.0.5 --> 10.246.38.1 netmask 0xffffff00
inet6 fe80::250:bfff:fe3a:c1f%gif0 prefixlen 64 scopeid 0x4
....

Wenn Sie fertig sind, sollten beide internen Adressen über man:ping[8] erreichbar sein:

[.programlisting]
....
priv-net# ping 10.0.0.5
PING 10.0.0.5 (10.0.0.5): 56 data bytes
64 bytes from 10.0.0.5: icmp_seq=0 ttl=64 time=42.786 ms
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=19.255 ms
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=20.440 ms
64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=21.036 ms
--- 10.0.0.5 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 19.255/25.879/42.786/9.782 ms

corp-net# ping 10.246.38.1
PING 10.246.38.1 (10.246.38.1): 56 data bytes
64 bytes from 10.246.38.1: icmp_seq=0 ttl=64 time=28.106 ms
64 bytes from 10.246.38.1: icmp_seq=1 ttl=64 time=42.917 ms
64 bytes from 10.246.38.1: icmp_seq=2 ttl=64 time=127.525 ms
64 bytes from 10.246.38.1: icmp_seq=3 ttl=64 time=119.896 ms
64 bytes from 10.246.38.1: icmp_seq=4 ttl=64 time=154.524 ms
--- 10.246.38.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 28.106/94.594/154.524/49.814 ms
....

Wie erwartet, können nun beiden Seiten ICMP-Pakete von ihren privaten Adressen senden und empfangen. Als nächstes müssen beide Gateways so konfiguriert werden, dass sie die Pakete des anderen Netzwerkes richtig routen. Dazu werden folgende Befehle verwendet:

[source,shell]
....
corp-net# route add 10.0.0.0 10.0.0.5 255.255.255.0
corp-net# route add net 10.0.0.0: gateway 10.0.0.5
priv-net# route add 10.246.38.0 10.246.38.1 255.255.255.0
priv-net# route add host 10.246.38.0: gateway 10.246.38.1
....

Ab jetzt sollten die Rechner von den Gateways sowie von den Rechnern hinter den Gateways erreichbar sein. Dies können Sie wieder mit man:ping[8] überprüfen:

[.programlisting]
....
corp-net# ping 10.0.0.8
PING 10.0.0.8 (10.0.0.8): 56 data bytes
64 bytes from 10.0.0.8: icmp_seq=0 ttl=63 time=92.391 ms
64 bytes from 10.0.0.8: icmp_seq=1 ttl=63 time=21.870 ms
64 bytes from 10.0.0.8: icmp_seq=2 ttl=63 time=198.022 ms
64 bytes from 10.0.0.8: icmp_seq=3 ttl=63 time=22.241 ms
64 bytes from 10.0.0.8: icmp_seq=4 ttl=63 time=174.705 ms
--- 10.0.0.8 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.870/101.846/198.022/74.001 ms

priv-net# ping 10.246.38.107
PING 10.246.38.1 (10.246.38.107): 56 data bytes
64 bytes from 10.246.38.107: icmp_seq=0 ttl=64 time=53.491 ms
64 bytes from 10.246.38.107: icmp_seq=1 ttl=64 time=23.395 ms
64 bytes from 10.246.38.107: icmp_seq=2 ttl=64 time=23.865 ms
64 bytes from 10.246.38.107: icmp_seq=3 ttl=64 time=21.145 ms
64 bytes from 10.246.38.107: icmp_seq=4 ttl=64 time=36.708 ms
--- 10.246.38.107 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.145/31.721/53.491/12.179 ms
....

Das Konfigurieren der Tunnel ist der einfache Teil. Die Konfiguration einer sicheren Verbindung geht viel mehr in die Tiefe. Die folgende Konfiguration benutzt pre-shared (PSK) RSA-Schlüssel. Abgesehen von den IP-Adressen, sind beide [.filename]#/usr/local/etc/racoon/racoon.conf# identisch und sehen ähnlich aus:

[.programlisting]
....
path    pre_shared_key  "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file
log     debug;  #log verbosity setting: set to 'notify' when testing and debugging is complete

padding # options are not to be changed
{
        maximum_length  20;
        randomize       off;
        strict_check    off;
        exclusive_tail  off;
}

timer   # timing options. change as needed
{
        counter         5;
        interval        20 sec;
        persend         1;
#       natt_keepalive  15 sec;
        phase1          30 sec;
        phase2          15 sec;
}

listen  # address [port] that racoon will listen on
{
        isakmp          172.16.5.4 [500];
        isakmp_natt     172.16.5.4 [4500];
}

remote  192.168.1.12 [500]
{
        exchange_mode   main,aggressive;
        doi             ipsec_doi;
        situation       identity_only;
        my_identifier   address 172.16.5.4;
        peers_identifier        address 192.168.1.12;
        lifetime        time 8 hour;
        passive         off;
        proposal_check  obey;
#       nat_traversal   off;
        generate_policy off;

                        proposal {
                                encryption_algorithm    blowfish;
                                hash_algorithm          md5;
                                authentication_method   pre_shared_key;
                                lifetime time           30 sec;
                                dh_group                1;
                        }
}

sainfo  (address 10.246.38.0/24 any address 10.0.0.0/24 any)    # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp)
{                                                               # $network must be the two internal networks you are joining.
        pfs_group       1;
        lifetime        time    36000 sec;
        encryption_algorithm    blowfish,3des;
        authentication_algorithm        hmac_md5,hmac_sha1;
        compression_algorithm   deflate;
}
....

Eine Beschreibung der verfügbaren Optionen finden Sie in der Manualpage von [.filename]#racoon.conf#.

Die Security Policy Database (SPD) muss noch konfiguriert werden, so dass FreeBSD und racoon in der Lage sind den Netzwerkverkehr zwischen den Hosts zu ver- und entschlüsseln.

Dies wird durch ein Shellskript ähnlich wie das folgende, das auf dem Firmennetzwerk-Gateway liegt, ausgeführt. Diese Datei wird während der Systeminitialisierung ausgeführt und sollte unter [.filename]#/usr/local/etc/racoon/setkey.conf# gespeichert werden.

[.programlisting]
....
flush;
spdflush;

# To the home network
spdadd 10.246.38.0/24 10.0.0.0/24 any -P out ipsec esp/tunnel/172.16.5.4-192.168.1.12/use;
spdadd 10.0.0.0/24 10.246.38.0/24 any -P in ipsec esp/tunnel/192.168.1.12-172.16.5.4/use;
....

Nachdem die Datei gespeichert wurde, kann racoon durch das folgende Kommando auf beiden Gateways gestartet werden:

[source,shell]
....
# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
....

Die Ausgabe sollte so ähnlich aussehen:

[.programlisting]
....
corp-net# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf
Foreground mode.
2006-01-30 01:35:47: INFO: begin Identity Protection mode.
2006-01-30 01:35:48: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:35:55: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:36:04: INFO: ISAKMP-SA established 172.16.5.4[500]-192.168.1.12[500] spi:623b9b3bd2492452:7deab82d54ff704a
2006-01-30 01:36:05: INFO: initiate new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=28496098(0x1b2d0e2)
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=47784998(0x2d92426)
2006-01-30 01:36:13: INFO: respond new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=124397467(0x76a279b)
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=175852902(0xa7b4d66)
....

Um sicherzustellen, dass der Tunnel richtig funktioniert, wechseln Sie auf eine andere Konsole und benutzen Sie man:tcpdump[1] mit dem folgenden Befehl, um sich den Netzwerkverkehr anzusehen. Tauschen Sie `em0` durch die richtige Netzwerkkarte aus:

[source,shell]
....
# tcpdump -i em0 host 172.16.5.4 and dst 192.168.1.12
....

Die Ausgabe der Konsole sollte dem hier ähneln. Wenn nicht, gibt es ein Problem und ein Debuggen der ausgegebenen Daten ist notwendig.

[.programlisting]
....
01:47:32.021683 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xa)
01:47:33.022442 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xb)
01:47:34.024218 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xc)
....

An diesem Punkt sollten beide Netzwerke verfügbar sein und den Anschein haben, dass sie zum selben Netzwerk gehören. Meistens sind beide Netzwerke durch eine Firewall geschützt. Um den Netzwerkverkehr zwischen den beiden Netzwerken zu erlauben, ist es notwendig Regeln zu erstellen. Für die man:ipfw[8] Firewall fügen Sie folgende Zeilen in die Firewall-Konfigurationsdatei ein:

[.programlisting]
....
ipfw add 00201 allow log esp from any to any
ipfw add 00202 allow log ah from any to any
ipfw add 00203 allow log ipencap from any to any
ipfw add 00204 allow log udp from any 500 to any
....

[NOTE]
====
Die Regelnummern müssen eventuell, je nach Hostkonfiguration, angepasst werden.
====

Für Benutzer der man:pf[4]- oder man:ipf[8]-Firewall sollte folgendes funktionieren:

[.programlisting]
....
pass in quick proto esp from any to any
pass in quick proto ah from any to any
pass in quick proto ipencap from any to any
pass in quick proto udp from any port = 500 to any port = 500
pass in quick on gif0 from any to any
pass out quick proto esp from any to any
pass out quick proto ah from any to any
pass out quick proto ipencap from any to any
pass out quick proto udp from any port = 500 to any port = 500
pass out quick on gif0 from any to any
....

Zum Ende, um dem Computer den Start vom VPN während der Systeminitialisierung zu erlauben, fügen Sie folgende Zeilen in ihre [.filename]#/etc/rc.conf#: ein

[.programlisting]
....
ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot
racoon_enable="yes"
....

[[openssh]]
== OpenSSH

OpenSSH stellt Werkzeuge bereit, um sicher auf entfernte Maschinen zuzugreifen. Zusätzlich können TCP/IP-Verbindungen sicher durch SSH getunnelt oder weitergeleitet werden. OpenSSH verschlüsselt alle Verbindungen. Dadurch wird beispielsweise verhindert, dass die Verbindung abgehört oder übernommen (Hijacking) werden kann. Weitere Informationen zu OpenSSH finden Sie auf http://www.openssh.com/[ http://www.openssh.com/].

Dieser Abschnitt enthält einen Überblick über die integrierten Client-Werkzeuge, mit denen Sie sicher auf entfernte Systeme zugreifen können, oder mit denen Sie sicher Dateien austauschen können. Der Abschnitt beschreibt auch die Konfiguration eines SSH-Servers auf einem FreeBSD-System. Weitere Informationen finden Sie in den hier erwähnten Manualpages.

=== Die SSH Client-Werkzeuge benutzen

Benutzen Sie `ssh` zusammen mit einem Benutzernamen und einer IP-Adresse oder dem Hostnamen, um sich an einem SSH-Server anzumelden. Ist dies das erste Mal, dass eine Verbindung mit dem angegebenen Server hergestellt wird, wird der Benutzer aufgefordert, zuerst den Fingerabdruck des Servers zu prüfen:

[source,shell]
....
# ssh user@example.com
The authenticity of host 'example.com (10.0.0.1)' can't be established.
ECDSA key fingerprint is 25:cc:73:b5:b3:96:75:3d:56:19:49:d2:5c:1f:91:3b.
Are you sure you want to continue connecting (yes/no)? yes
Permanently added 'example.com' (ECDSA) to the list of known hosts.
Password for user@example.com: user_password
....

SSH speichert einen Fingerabdruck des Serverschlüssels um die Echtheit des Servers zu überprüfen, wenn der Client eine Verbindung herstellt. Wenn der Benutzer den Fingerabdruck mit `yes` bestätigt, wird eine Kopie des Schlüssels in [.filename]#.ssh/known_hosts# im Heimatverzeichnis des Benutzers gespeichert. Zukünftige Verbindungen zu dem Server werden gegen den gespeicherten Fingerabdruck des Schlüssels geprüft und der Client gibt eine Warnung aus, wenn sich der empfangene Fingerabdruck von dem gespeicherten unterscheidet. Wenn dies passiert, sollte zunächst geprüft werden, ob sich der Schlüssel geändert hat, bevor die Verbindung hergestellt wird.

In der Voreinstellung akzeptieren aktuelle Versionen von OpenSSH nur SSHv2 Verbindungen. Wenn möglich, wird der Client versuchen Version 2 zu verwenden, ist dies nicht möglich, fällt er auf Version 1 zurück. Der Client kann gezwungen werden, nur eine der beiden Versionen zu verwenden, indem die Option `-1` oder `-2` übergeben wird. Weitere Optionen sind in man:ssh[1] beschrieben.

Mit man:scp[1] lassen sich Dateien in einer sicheren Weise auf entfernte Maschinen übertragen. Dieses Beispiel kopiert die Datei [.filename]#COPYRIGHT# von einem entfernten System in eine Datei mit dem gleichen Namen auf das lokale System:

[source,shell]
....
#  scp user@example.com:/COPYRIGHT COPYRIGHT
Password for user@example.com: *******
COPYRIGHT            100% |*****************************|  4735
00:00
#
....

Da der Fingerabdruck für diesen Rechner bereits bestätigt wurde, wird er automatisch überprüft, bevor der Benutzer zur Eingabe des Passworts aufgefordert wird.

Die Argumente, die `scp` übergeben werden, gleichen denen von `cp` in der Beziehung, dass die ersten Argumente die zu kopierenden Dateien sind und das letzte Argument den Bestimmungsort angibt. Da die Dateien über das Netzwerk kopiert werden, können ein oder mehrere Argumente die Form `user@host:<path_to_remote_file>` besitzen. Beachten Sie, das `scp` die Option `-r` verwendet um Dateien rekursiv zu kopieren, während `cp -R` benutzt.

Mit `sftp` können Dateien über eine interaktive Sitzung kopiert werden. man:sftp[1] beschreibt die verfügbaren Befehle, die während einer `sftp`-Sitzung zur Verfügung stehen.

[[security-ssh-keygen]]
==== Schlüsselbasierte Authentifizierung

Ein Client kann bei der Verbindung auch Schlüssel anstelle von Passwörtern verwenden. Benutzen Sie `ssh-keygen` um RSA-Schlüssel erzeugen. Geben Sie das entsprechende Protokoll an, wenn Sie einen öffentlichen und einen privaten Schlüssel erzeugen. Folgen Sie anschließend den Anweisungen des Programms. Es wird empfohlen, die Schlüssel mit einer einprägsamen, aber schwer zu erratenen Passphrase zu schützen.

[source,shell]
....
% ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):  <.>
Enter same passphrase again:                 <.>
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:54Xm9Uvtv6H4NOo6yjP/YCfODryvUU7yWHzMqeXwhq8 user@host.example.com
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|        . o..    |
|       .S*+*o    |
|      . O=Oo . . |
|       = Oo= oo..|
|      .oB.* +.oo.|
|       =OE**.o..=|
+----[SHA256]-----+
....

<.> Geben Sie hier die Passphrase ein. Diese darf auch Leer- und Sonderzeichen enthalten.
<.> Geben Sie die Passphrase zur Überprüfung erneut ein.

Der private Schlüssel wird in [.filename]#~/.ssh/id_rsa# und der öffentliche Schlüssel in [.filename]#~/.ssh/id_rsa.pub# gespeichert. Der _öffentliche_ Schlüssel muss zuerst auf den entfernten Rechner nach [.filename]#~/.ssh/authorized_keys# kopiert werden, damit die schlüsselbasierte Authentifizierung funktioniert.

[WARNING]
====

Viele Benutzer denken, dass die Verwendung von Schlüsseln generell sicher ist. Sie verwenden dann einen Schlüssel ohne eine Passphrase. Dies ist jedoch sehr _gefährlich_. Ein Administrator kann überprüfen, ob ein Schlüsselpaar mit einer Passphrase geschützt ist. Wenn die Datei mit dem privaten Schlüssel den Text `ENCRYPTED` enthält, dann hat der Benutzer eine Passphrase verwendet. Um die Benutzer zusätzlich zu schützen, kann ein `from`-Feld in der Datei des öffentlichen Schlüssels hinzugefügt werden. Zum Beispiel würde das Hinzufügen von `from="192.168.10.5"` vor dem `ssh-rsa`-Präfix dafür sorgen, dass sich ein bestimmter Benutzer nur noch von dieser IP-Adresse anmelden darf.
====

Die Optionen und Dateinamen sind abhängig von der eingesetzten Version von OpenSSH. Die für das System gültigen Optionen finden Sie in man:ssh-keygen[1].

Wenn bei der Erzeugung des Schlüssels eine Passphrase angegeben wurde, wird der Benutzer bei jeder Anmeldung am Server zur Eingabe der Passphrase aufgefordert. Mit man:ssh-agent[1] und man:ssh-add[1] ist es möglich, SSH-Schlüssel in den Speicher zu laden, damit die Passphrase nicht jedes Mal eingegeben werden muss.

`ssh-agent` übernimmt die Authentifizierung mit den geladenen privaten Schlüsseln. `ssh-agent` kann dazu verwendet werden, ein anderes Programm zu starten, beispielsweise eine Shell oder einen Window-Manager.

Um `ssh-agent` in einer Shell zu verwenden, muss es mit einer Shell als Argument aufgerufen werden. Die zu verwaltende Identität muss mit `ssh-add` sowie der Passphrase für den privaten Schlüssel übergeben werden. Danach kann sich der Benutzer mit `ssh` auf jedem Rechner anmelden, der einen entsprechenden öffentlichen Schlüssel besitzt. Dazu ein Beispiel:

[source,shell]
....
% ssh-agent csh
% ssh-add
Enter passphrase for /usr/home/user/.ssh/id_rsa:  <.>
Identity added: /usr/home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)
%
....

<.> Geben Sie hier die Passphrase für den Schlüssel ein.

Um `ssh-agent` unter Xorg zu verwenden, muss ein Eintrag für das Programm in [.filename]#~/.xinitrc# aufgenommen werden. Dadurch können alle unter Xorg gestarteten Programme die Dienste von `ssh-agent` nutzen. [.filename]#~/.xinitrc# könnte etwa so aussehen:

[.programlisting]
....
exec ssh-agent startxfce4
....

Dadurch wird bei jedem Start von Xorg zuerst `ssh-agent` aufgerufen, das wiederum XFCE startet. Nachdem diese Änderung durchgeführt wurde, muss Xorg neu gestartet werden. Danach können Sie mit `ssh-add` die SSH-Schlüssel laden.

[[security-ssh-tunneling]]
==== SSH-Tunnel

Mit OpenSSH ist es möglich, einen Tunnel zu erstellen, in dem ein anderes Protokoll verschlüsselt übertragen wird.

Im folgenden Kommando erzeugt `ssh` einen Tunnel für `telnet`:

[source,shell]
....
% ssh -2 -N -f -L 5023:localhost:23 user@foo.example.com
%
....

Dieses Beispiel verwendet die folgenden Optionen:

`-2`::
Zwingt `ssh` dazu, die Version 2 des Protokolls zu verwenden, um sich mit dem Server zu verbinden.

`-N`::
Zeigt an, dass ein Tunnel erstellt werden soll. Ohne diese Option würde `ssh` eine normale Sitzung öffnen.

`-f`::
Zwingt `ssh` im Hintergrund zu laufen.

`-L`::
Ein lokaler Tunnel wird in der Form _localport:remotehost:remoteport_ angegeben. Die Verbindung wird dabei von dem lokalen Port _localport_ auf einen entfernten Rechner weitergeleitet.

`user@foo.example.com`::
Gibt den Anmeldenamen auf dem entfernten SSH-Server an.

Ein SSH-Tunnel erzeugt einen Socket auf `localhost` und dem angegebenen lokalen Port. Jede Verbindung, die auf dem angegebenen Socket aufgemacht wird, wird dann auf den spezifizierten entfernten Rechner und Port weitergeleitet. Im Beispiel wird der lokale Port `5023` an die entfernte Maschine auf Port `23` weitergeleitet. Da der Port 23 für `telnet` reserviert ist, erzeugt das eine sichere man:telnet[1]-Verbindung durch einen SSH-Tunnel.

Wie in den folgenden Beispielen zu sehen ist, kann diese Vorgehensweise genutzt werden, um jedes unsichere TCP-Protokoll, wie SMTP, POP3 und FTP, weiterzuleiten.

.Einen sicheren Tunnel für SMTP erstellen
[example]
====

[source,shell]
....
% ssh -2 -N -f -L 5025:localhost:25 user@mailserver.example.com
user@mailserver.example.com's password: *****
% telnet localhost 5025
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mailserver.example.com ESMTP
....
Zusammen mit `ssh-keygen` und zusätzlichen Benutzer-Accounts können leicht benutzbare SSH-Tunnel aufgebaut werden. Anstelle von Passwörtern können Schlüssel benutzt werden und jeder Tunnel kann unter einem eigenen Benutzer laufen.
====

.Sicherer Zugriff auf einen POP3-Server
[example]
====
In diesem Beispiel gibt es einen SSH-Server, der Verbindungen von außen akzeptiert. Im selben Netzwerk befindet sich zudem noch ein Mail-Server, der POP3 spricht. Um E-Mails auf sichere Weise abzurufen, bauen Sie eine SSH-Verbindung zu dem SSH-Server im Netzwerk auf und tunneln von dort zum Mail-Server weiter.

[source,shell]
....
% ssh -2 -N -f -L 2110:mail.example.com:110 user@ssh-server.example.com
user@ssh-server.example.com's password: ******
....

Wenn Sie den Tunnel eingerichtet haben, konfigurieren Sie den Mail-Client so, dass er POP3 Anfragen zu `localhost` auf Port 2110 sendet. Diese Verbindung wird dann über den gesicherten Tunnel zu `mail.example.com` weitergeleitet.
====

.Umgehen einer Firewall
[example]
====
Einige Firewalls filtern sowohl eingehende als auch ausgehende Verbindungen. Zum Beispiel könnte eine Firewall den Zugriff auf entfernte Rechner auf die Ports 22 und 80 beschränken, um lediglich SSH und Web-Inhalte zu erlauben. Dies würde den Zugriff auf Dienste verhindern, die nicht die Ports 22 oder 80 benutzen.

Die Lösung hier ist es, eine SSH-Verbindung zu einer Maschine außerhalb der Firewall aufzumachen und durch diese zum gewünschten Dienst zu tunneln:

[source,shell]
....
% ssh -2 -N -f -L 8888:music.example.com:8000 user@unfirewalled-system.example.org
user@unfirewalled-system.example.org's password: *******
....

In diesem Beispiel benutzt ein Ogg Vorbis Client `localhost` und Port 8888. Die Verbindung wird dann zu `music.example.com` Port 8000 weitergeleitet. Die Firewall wurde somit erfolgreich umgangen.
====

=== Den SSH-Server aktivieren

Neben den integrierten SSH Client-Werkzeugen, die zur Verfügung stehen, kann ein FreeBSD-System auch als SSH-Server konfiguriert werden, um Verbindungen von anderen SSH-Clients zu akzeptieren.

Benutzen Sie den Kommando man:service[8], um zu prüfen ob der sshd ausgeführt wird:

[source,shell]
....
# service sshd status
....

Wenn der Dienst nicht ausgeführt wird, fügen Sie folgende Zeile in [.filename]#/etc/rc.conf# ein:

[.programlisting]
....
sshd_enable="YES"
....

Diese Zeile startet `sshd`, den OpenSSH-Daemon, beim nächsten Systemstart. Geben Sie folgendes ein, um den Dienst jetzt zu starten:

[source,shell]
....
# service sshd start
....

Wenn `sshd` erstmalig gestartet wird, werden die Host-Schlüssel des Systems erzeugt und der Fingerabdruck wird auf der Konsole angezeigt. Stellen Sie den Fingerabdruck den Benutzern zur Verfügung, sodass sie ihn überprüfen können, wenn sie das erste Mal eine Verbindung mit dem Server herstellen.

man:sshd[8] enthält die verfügbaren Optionen für den Start von `sshd` und weitere Informationen zur Authentifizierung, den Anmeldeprozess und die verschiedenen Konfigurationsdateien.

Ab jetzt sollte sshd für alle Benutzer mit einem Benutzernamen und Kennwort zur Verfügung stehen.

=== SSH Server Sicherheit

Obwohl sshd das am weitesten verbreitete Remote-Administrations-Werkzeug ist, sind Brute-Force- und Drive-by-Angriffe auf öffentliche Netzwerke weit verbreitet. Daher stehen mehrere Optionen zur Verfügung, um diese Art von Angriffen zu verhindern. Diese Optionen werden in diesem Abschnitt beschrieben.

Es ist in der Regel ein gute Idee, festzulegen, welche Benutzer sich von welchem Rechner aus anmelden können. Dies lässt sich beispielsweise über die Option `AllowUsers` festlegen. Soll sich etwa nur `root` vom Rechner mit der IP-Adresse `192.168.1.32` aus einwählen dürfen, würden Sie folgenden Eintrag in [.filename]#/etc/ssh/sshd_config# aufnehmen:

[.programlisting]
....
AllowUsers root@192.168.1.32
....

Damit sich `admin` von jedem Rechner aus anmelden kann, geben Sie nur den Benutzernamen an:

[.programlisting]
....
AllowUsers admin
....

Sie können auch mehrere Benutzer in einer Zeile aufführen:

[.programlisting]
....
AllowUsers root@192.168.1.32 admin
....

Nachdem Sie [.filename]#/etc/ssh/sshd_config# angepasst haben, muss `sshd` seine Konfigurationsdateien neu einlesen. Dazu geben Sie Folgendes ein:

[source,shell]
....
# /etc/rc.d/sshd reload
....

[NOTE]
====
Wenn die Option `AllowUsers` verwendet wird, ist es wichtig, jeden Benutzer aufzulisten, der sich an diesem Rechner anmelden muss. Benutzer, die nicht in dieser Liste aufgeführt sind, dürfen sich nicht anmelden. Die Optionen für die Konfigurationsdatei von OpenSSH unterscheiden zwischen Groß- und Kleinschreibung. Wenn Sie eine Option falsch schreiben, so wird sie ingnoriert. Testen Sie immer die Änderungen, um sicherzustellen, dass sie wie erwartet funktionieren. Weitere Informationen zu den verfügbaren Optionen finden Sie in man:sshd_config[5].
====

Darüber hinaus können Benutzer gezwungen werden, eine Zwei-Faktor-Authentifizierung mit einem öffentlichen und einem privaten Schlüssel zu benutzen. Bei Bedarf kann der Benutzer ein Schlüsselpaar mit man:ssh-keygen[1] erzeugen und dem Administrator den öffentlichen Schlüssel zukommen lassen. Der Schlüssel wird, wie weiter oben beschrieben, in [.filename]#authorized_keys# platziert. Um den Benutzer zu zwingen, ausschließlich Schlüssel zu benutzen, kann die folgende Option konfiguriert werden:

[.programlisting]
....
AuthenticationMethods publickey
....

[TIP]
====

Verwechseln Sie nicht [.filename]#/etc/ssh/sshd_config# mit [.filename]#/etc/ssh/ssh_config# (beachten Sie das zusätzliche `d` im ersten Dateinamen). Die erste Datei konfiguriert den Server und die zweite Datei konfiguriert den Client. man:ssh_config[5] enthält eine Auflistung der verfügbaren Client-Einstellungen.
====

[[fs-acl]]
== Zugriffskontrolllisten für Dateisysteme (ACL)

_Zugriffskontrolllisten_ (Access Control Lists, ACL) erweitern die normalen Zugriffsrechte von UNIX(R) Systemen auf eine kompatible (POSIX(R).1e) Weise und bieten feiner granulierte Sicherheitsmechanismen.

Der [.filename]#GENERIC#-Kernel von FreeBSD bietet ACL-Unterstützung für UFS-Dateisysteme. Benutzer, die es vorziehen einen eigenen Kernel zu übersetzen, müssen die folgende Option in die Kernelkonfigurationsdatei aufnehmen:

[.programlisting]
....
options UFS_ACL
....

Das System gibt eine Warnung aus, wenn ein Dateisystem mit ACLs eingehangen werden soll und die Unterstützung für ACLs nicht im Kernel aktiviert ist. ACLs bauen auf den erweiterten Attributen auf, die von UFS2 standardmäßig unterstützt werden.

Dieses Kapitel beschreibt, wie ACL-Unterstützung aktiviert wird. Zudem werden einige Anwendungsbeispiele vorgestellt.

=== ACL-Unterstützung aktivieren

Die Option `acl` in [.filename]#/etc/fstab# aktiviert Zugriffskontrolllisten für ein Dateisystem. Die bevorzugte Möglichkeit ist die Verwendung von Zugriffskontrolllisten mit man:tunefs[8] (Option `-a`), im Superblock des Dateisystems festzuschreiben. Diese Möglichkeit hat mehrere Vorteile:

* Nochmaliges Einhängen eines Dateisystems (Option `-u` von man:mount[8]) verändert den Status der Zugriffskontrolllisten nicht. Die Verwendung von Zugriffskontrolllisten kann nur durch Abhängen und erneutes Einhängen eines Dateisystems verändert werden. Das heißt auch, dass Zugriffskontrolllisten nicht nachträglich auf dem Root-Dateisystem aktiviert werden können.
* Die Zugriffskontrolllisten auf den Dateisystemen sind, unabhängig von den Optionen in [.filename]#/etc/fstab# oder Namensänderungen der Geräte, immer aktiv. Dies verhindert auch, dass Zugriffskontrolllisten aus Versehen auf Dateisystemen ohne Zugriffskontrolllisten aktiviert werden.

[NOTE]
====
Es kann sein, dass sich der Status von Zugriffskontrolllisten später durch nochmaliges Einhängen des Dateisystems (Option `-u` von man:mount[8]) ändern lässt. Die momentane Variante ist aber sicherer, da der Status der Zugriffskontrolllisten nicht versehentlich geändert werden kann. Allgemein sollten Zugriffskontrolllisten auf einem Dateisystem, auf dem sie einmal verwendet wurden, nicht deaktiviert werden, da danach die Zugriffsrechte falsch sein können. Werden Zugriffskontrolllisten auf einem solchen Dateisystem wieder aktiviert, werden die Zugriffsrechte von Dateien, die sich zwischenzeitlich geändert haben, überschrieben, was zu erneuten Problemen führt.
====

Die Zugriffsrechte einer Datei werden durch ein `+` (Plus) gekennzeichnet, wenn die Datei durch Zugriffskontrolllisten geschützt ist:

[.programlisting]
....
drwx------  2 robert  robert  512 Dec 27 11:54 private
drwxrwx---+ 2 robert  robert  512 Dec 23 10:57 directory1
drwxrwx---+ 2 robert  robert  512 Dec 22 10:20 directory2
drwxrwx---+ 2 robert  robert  512 Dec 27 11:57 directory3
drwxr-xr-x  2 robert  robert  512 Nov 10 11:54 public_html
....

In diesem Beispiel sind die Verzeichnisse [.filename]#directory1#, [.filename]#directory2# und [.filename]#directory3# durch Zugriffskontrolllisten geschützt, wohingegen das Verzeichnis [.filename]#public_html# nicht geschützt ist.

=== Zugriffskontrolllisten benutzen

`getfacl` zeigt Zugriffskontrolllisten an. Das folgende Kommando zeigt die ACLs auf der Datei [.filename]#test#:

[source,shell]
....
% getfacl test
	#file:test
	#owner:1001
	#group:1001
	user::rw-
	group::r--
	other::r--
....

`setfacl` ändert oder entfernt ACLs auf Dateien. Um alle ACLs einer Datei zu entfernen, können Sie die Option `-k` benutzen. Es ist jedoch empfehlenswert die Option `-b` zu verwenden, da sie die erforderlichen Felder, die für ACLs benötigt werden, beibehält.

[source,shell]
....
# setfacl -k test
....

Benutzen Sie `-m` um die Einträge der ACL zu verändern:

[source,shell]
....
% setfacl -m u:trhodes:rwx,g:web:r--,o::--- test
....

In diesem Beispiel gab es keine vordefinierten Einträge, da sie durch den vorhergehenden Befehl entfernt wurden. Mit diesem Kommando werden die eben entfernten Zugriffskontrolllisten wiederhergestellt. Der Befehl gibt die Fehlermeldung `Invalid argument` aus, wenn Sie nicht existierende Benutzer oder Gruppen als Parameter angeben.

Weitere Informationen zu den Optionen dieser Kommandos finden Sie in man:getfacl[1] und man:setfacl[1].

[[security-pkg]]
== Sicherheitsprobleme in Software von Drittanbietern überwachen

In den letzten Jahren wurden zahlreiche Verbesserungen in der Einschätzung und dem Umgang mit Sicherheitsproblemen erzielt. Die Gefahr von Einbrüchen in ein System wird aber immer größer, da Softwarepakete von Dritten auf nahezu jedem Betriebssystem installiert und konfiguriert werden.

Die Einschätzung der Verletzlichkeit eines Systems ist ein Schlüsselfaktor für dessen Sicherheit. FreeBSD veröffentlicht zwar Sicherheitshinweise (security advisories) für das Basissystem, das Projekt ist allerdings nicht dazu in der Lage, dies auch für die zahlreichen Softwarepakete von Dritten zu tun. Dennoch gibt es einen Weg, auch diese Programmpakete zu überwachen. Das FreeBSD Dienstprogramm pkg enthält Optionen für genau diesen Anwendungsfall.

pkg fragt dazu eine Datenbank auf bekannte Sicherheitsprobleme ab. Diese Datenbank wird vom FreeBSD Security Team sowie den Ports-Entwicklern aktualisiert und gewartet.

Anweisungen zur Installation von pkg finden Sie im crossref:ports[pkgng-intro,Benutzen von pkg zur Verwaltung von Binärpaketen].

Die Installation enthält Konfigurationsdateien für man:periodic[8], welche die Datenbank von pkg verwaltet und aktualisiert. Diese Funktionalität wird aktiviert, wenn in man:periodic.conf[5] die Variable `daily_status_security_pkgaudit_enable` auf `YES` gesetzt wird. Stellen Sie auf jeden Fall sicher, dass diese (an das E-Mail-Konto von `root` gesendeten) Sicherheitsberichte auch gelesen werden.

Nach der Installation kann ein Administrator mit dem folgenden Kommando die Datenbank aktualisieren und sich die Sicherheitslücken in installierten Paketen anzeigen lassen:

[source,shell]
....
# pkg audit -F
....

pkg zeigt dann die Schwachstellen in installierten Pakete an:

[.programlisting]
....
Affected package: cups-base-1.1.22.0_1
Type of problem: cups-base -- HPGL buffer overflow vulnerability.
Reference: <https://www.FreeBSD.org/ports/portaudit/40a3bca2-6809-11d9-a9e7-0001020eed82.html>

1 problem(s) in your installed packages found.

You are advised to update or deinstall the affected package(s) immediately.
....

Wenn Sie die angegebene URL über einen Internetbrowser aufrufen, erhalten Sie weitere Informationen über die bestehende Sicherheitslücke, wie die betroffenen Versionen, die Version des FreeBSD-Ports sowie Hinweise auf weitere Seiten, die ebenfalls Sicherheitshinweise zu diesem Problem bieten.

pkg ist ein mächtiges Werkzeug und insbesondere in Zusammenarbeit mit package:ports-mgmt/portmaster[] äußerst hilfreich.

[[security-advisories]]
== FreeBSD Sicherheitshinweise

Wie viele andere Hersteller von hochwertigen Betriebssystemen, hat auch das FreeBSD-Projekt ein Sicherheitsteam, das für die Bestimmung des End-of-Life (EoL) Datum verantwortlich ist. Das Sicherheitsteam stellt zudem sicher, dass Sicherheitsupdates für unterstützte Versionen, welche noch nicht ihr EoL erreicht haben, zur Verfügung gestellt werden. Weitere Informationen über das FreeBSD Sicherheitsteam und den unterstützten Versionen finden Sie auf der Webseite link:https://www.FreeBSD.org/security[FreeBSD Security].

Zu den Aufgaben des Sicherheitsteams zählt es, auf gemeldete Sicherheitslücken im FreeBSD-Betriebssystem zu reagieren. Sobald eine Sicherheitslücke bestätigt wird, überprüft das Sicherheitsteam die notwendigen Schritte, um die Schwachstelle zu beheben und den Quellcode mit der Korrektur zu aktualisieren. Anschließend veröffentlicht es die Details in einem Sicherheitshinweis (Security Advisory). Die Sicherheitshinweise werden auf der link:https://www.FreeBSD.org/security/advisories/[FreeBSD Webseite] und auf den Mailinglisten {freebsd-security-notifications}, {freebsd-security} und {freebsd-announce} veröffentlicht.

Dieser Abschnitt beschreibt das Format eines FreeBSD Sicherheitshinweises.

=== Format eines Sicherheitshinweis

Hier ist ein Beispiel für einen FreeBSD Sicherheitshinweis:

[.programlisting]
....
=============================================================================
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

=============================================================================
FreeBSD-SA-14:04.bind                                       Security Advisory
                                                          The FreeBSD Project

Topic:          BIND remote denial of service vulnerability

Category:       contrib
Module:         bind
Announced:      2014-01-14
Credits:        ISC
Affects:        FreeBSD 8.x and FreeBSD 9.x
Corrected:      2014-01-14 19:38:37 UTC (stable/9, 9.2-STABLE)
                2014-01-14 19:42:28 UTC (releng/9.2, 9.2-RELEASE-p3)
                2014-01-14 19:42:28 UTC (releng/9.1, 9.1-RELEASE-p10)
                2014-01-14 19:38:37 UTC (stable/8, 8.4-STABLE)
                2014-01-14 19:42:28 UTC (releng/8.4, 8.4-RELEASE-p7)
                2014-01-14 19:42:28 UTC (releng/8.3, 8.3-RELEASE-p14)
CVE Name:       CVE-2014-0591

For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:http://security.FreeBSD.org/>.

I.   Background

BIND 9 is an implementation of the Domain Name System (DNS) protocols.
The named(8) daemon is an Internet Domain Name Server.

II.  Problem Description

Because of a defect in handling queries for NSEC3-signed zones, BIND can
crash with an "INSIST" failure in name.c when processing queries possessing
certain properties.  This issue only affects authoritative nameservers with
at least one NSEC3-signed zone.  Recursive-only servers are not at risk.

III. Impact

An attacker who can send a specially crafted query could cause named(8)
to crash, resulting in a denial of service.

IV.  Workaround

No workaround is available, but systems not running authoritative DNS service
with at least one NSEC3-signed zone using named(8) are not vulnerable.

V.   Solution

Perform one of the following:

1) Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.

2) To update your vulnerable system via a source code patch:

The following patches have been verified to apply to the applicable
FreeBSD release branches.

a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.

[FreeBSD 8.3, 8.4, 9.1, 9.2-RELEASE and 8.4-STABLE]
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-release.patch
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-release.patch.asc
# gpg --verify bind-release.patch.asc

[FreeBSD 9.2-STABLE]
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-stable-9.patch
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-stable-9.patch.asc
# gpg --verify bind-stable-9.patch.asc

b) Execute the following commands as root:

# cd /usr/src
# patch < /path/to/patch

Recompile the operating system using buildworld and installworld as
described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.

Restart the applicable daemons, or reboot the system.

3) To update your vulnerable system via a binary patch:

Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:

# freebsd-update fetch
# freebsd-update install

VI.  Correction details

The following list contains the correction revision numbers for each
affected branch.

Branch/path                                                      Revision
- -------------------------------------------------------------------------
stable/8/                                                         r260646
releng/8.3/                                                       r260647
releng/8.4/                                                       r260647
stable/9/                                                         r260646
releng/9.1/                                                       r260647
releng/9.2/                                                       r260647
- -------------------------------------------------------------------------

To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:

# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base

Or visit the following URL, replacing NNNNNN with the revision number:

<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>

VII. References

<URL:https://kb.isc.org/article/AA-01078>

<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0591>

The latest revision of this advisory is available at
<URL:http://security.FreeBSD.org/advisories/FreeBSD-SA-14:04.bind.asc>
-----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJS1ZTYAAoJEO1n7NZdz2rnOvQP/2/68/s9Cu35PmqNtSZVVxVG
ZSQP5EGWx/lramNf9566iKxOrLRMq/h3XWcC4goVd+gZFrvITJSVOWSa7ntDQ7TO
XcinfRZ/iyiJbs/Rg2wLHc/t5oVSyeouyccqODYFbOwOlk35JjOTMUG1YcX+Zasg
ax8RV+7Zt1QSBkMlOz/myBLXUjlTZ3Xg2FXVsfFQW5/g2CjuHpRSFx1bVNX6ysoG
9DT58EQcYxIS8WfkHRbbXKh9I1nSfZ7/Hky/kTafRdRMrjAgbqFgHkYTYsBZeav5
fYWKGQRJulYfeZQ90yMTvlpF42DjCC3uJYamJnwDIu8OhS1WRBI8fQfr9DRzmRua
OK3BK9hUiScDZOJB6OqeVzUTfe7MAA4/UwrDtTYQ+PqAenv1PK8DZqwXyxA9ThHb
zKO3OwuKOVHJnKvpOcr+eNwo7jbnHlis0oBksj/mrq2P9m2ueF9gzCiq5Ri5Syag
Wssb1HUoMGwqU0roS8+pRpNC8YgsWpsttvUWSZ8u6Vj/FLeHpiV3mYXPVMaKRhVm
067BA2uj4Th1JKtGleox+Em0R7OFbCc/9aWC67wiqI6KRyit9pYiF3npph+7D5Eq
7zPsUdDd+qc+UTiLp3liCRp5w6484wWdhZO6wRtmUgxGjNkxFoNnX8CitzF8AaqO
UWWemqWuz3lAZuORQ9KX
=OQzQ
-----END PGP SIGNATURE-----
....

Jeder Sicherheitshinweis verwendet das folgende Format:

* Jeder Sicherheitshinweis wird mit dem PGP-Schlüssel des Sicherheitsbeauftragten unterzeichnet. Der öffentliche Schlüssel des Sicherheitsbeauftragten kann in crossref:pgpkeys[pgpkeys,OpenPGP-Schlüssel] überprüft werden.
* Der Name des Sicherheitshinweises beginnt immer mit `FreeBSD-SA-` (für FreeBSD Security Advisory), gefolgt vom Jahr im zweistelligen Format (`14:`), gefolgt von der Anzahl von Sicherheitshinweisen für dieses Jahr (`04.`), gefolgt vom Namen der Anwendung oder des betroffenen Subsystems (`bind`). Der hier gezeigte Sicherheitshinweis ist der vierte Hinweis für das Jahr 2014 und betrifft die Anwendung BIND.
* Das Feld `Topic` enthält eine Beschreibung der Schwachstelle.
* Das Feld `Category` beschreibt den betroffenen Systemteil. Mögliche Werte für dieses Feld sind `core`, `contrib` oder `ports`. Die Kategorie `core` gilt für Komponenten des FreeBSD-Betriebssystems, die Kategorie `contrib` beschreibt zum Basissystem gehörende Software Dritter, beispielsweise BIND. Die Kategorie `ports` beschreibt Software, die Teil der Ports-Sammlung ist.
* Das Feld `Module` beschreibt die betroffene Komponente. Im diesem Beispiel ist das `bind`-Modul betroffen, dass heißt dieses Problem betrifft eine Anwendung aus dem Betriebssystem.
* Das Feld `Announced` gibt den Zeitpunkt der Bekanntgabe des Sicherheitshinweises an. Das bedeutet, dass das Sicherheitsteam das Problem bestätigt hat und das eine entsprechende Korrektur bereits im FreeBSD Quellcode-Repository zur Verfügung steht .
* Das Feld `Credits` gibt die Person oder Organisation an, die das Sicherheitsproblem bemerkt und gemeldet hat.
* Das Feld `Affects` listet die FreeBSD-Releases auf, die von dem Problem betroffen sind.
* Das Feld `Corrected` zeigt an, wann das Problem in welchem Release behoben wurde. Der Teil in Klammern zeigt an, in welchem Zweig die Aktualisierung eingeflossen ist und die entsprechende Versionsnummer und Patch-Level des Release. Der Patch-Level besteht aus dem Buchstaben `p`, gefolgt von einer Nummer. Dies erlaubt es dem Benutzer festzustellen, welche Korrekturen bereits auf dem System eingespielt wurden.
* Reserviert für Informationen, über die auf http://cve.mitre.org[ cve.mitre.org] nach Sicherheitslücken gesucht werden kann.
* Im Feld `Background` wird das betroffene Modul beschrieben.
* Im Feld `Problem Description` wird das Sicherheitsproblem beschrieben. Hier wird fehlerhafter Code beschrieben oder geschildert, wie ein Werkzeug ausgenutzt werden könnte.
* Das Feld `Impact` beschreibt die Auswirkungen des Sicherheitsproblems auf ein System.
* Im Feld `Workaround` wird eine Umgehung des Sicherheitsproblems beschrieben. Die Umgehung ist für Administratoren gedacht, die das System aus Zeitnot, Netzwerk-technischen oder anderen Gründen nicht aktualisieren können.
* Das Feld `Solution` enthält eine getestete Schritt-für-Schritt Anleitung, die das Sicherheitsproblem behebt.
* Das Feld `Correction Details` enthält die Subversion-Tags der betroffenen Dateien zusammen mit zugehörigen Revisionsnummern, in denen das Problem behoben wurde.
* Im Feld `References` finden sich Verweise auf weitere Informationsquellen.

[[security-accounting]]
== Prozess-Überwachung

Prozess-Überwachung (Process accounting) ist ein Sicherheitsverfahren, bei dem ein Administrator verfolgt, welche Systemressourcen verwendet werden und wie sich diese auf die einzelnen Anwender verteilen. Dadurch kann das System überwacht werden und es ist sogar möglich, zu kontrollieren, welche Befehle ein Anwender eingibt.

Die Überwachung von Prozessen hat sowohl Vor- als auch Nachteile. Positiv ist, dass man einen Einbruchsversuch bis an den Anfang zurückverfolgen kann. Von Nachteil ist allerdings, dass durch diesen Prozess Unmengen an Protokolldateien erzeugt werden, die auch dementsprechenden Plattenplatz benötigen. Dieser Abschnitt beschreibt die Grundlagen der Prozess-Überwachung.

[NOTE]
====
Wenn Sie eine differenzierte Prozess-Überwachung benötigen, lesen Sie crossref:audit[audit,Security Event Auditing].
====

=== Die Prozess-Überwachung aktivieren und konfigurieren

Bevor Sie die Prozess-Überwachung verwenden können, müssen Sie diese über die folgenden Befehle aktivieren:

[source,shell]
....
# sysrc accounting_enable=yes
# service accounting start
....

Die Informationen werden unterhalb von [.filename]#/var/account# gespeichert. Das Verzeichnis wird beim ersten Start des Dienstes automatisch erstellt. Die Dateien enthalten sensible Informationen, einschließlich aller Befehle, die von allen Benutzern ausgeführt wurden. Der Schreibzugriff auf diese Dateien ist auf `root` beschränkt, der Lesezugriff auf `root` und Mitgliedern der Gruppe `wheel`. Um zu verhindern, dass die Mitglieder der Gruppe `wheel` die Dateien lesen können, ändern Sie den Modus des Verzeichnisses [.filename]#/var/account# so, dass der Zugriff nur durch `root` möglich ist.

Einmal aktiviert, wird sofort mit der Überwachung von CPU-Statistiken, Befehlen und anderen Vorgängen begonnen. Protokolldateien werden in einem nur von Maschinen lesbaren Format gespeichert und können mit `sa` aufgerufen werden. Ohne Optionen gibt `sa` Informationen wie die Anzahl der Aufrufe pro Anwender, die abgelaufene Zeit in Minuten, die gesamte CPU- und Anwenderzeit in Minuten und die durchschnittliche Anzahl der Ein- und Ausgabeoperationen aus. man:sa[8] enthält eine Liste der Optionen, welche die Ausgabe steuern.

Benutzen Sie `lastcomm`, um die von den Benutzern ausgeführten Befehle anzuzeigen. Dieses Beispiel zeigt die Nutzung von `ls` durch `trhodes` auf dem Terminal `ttyp1`:

[source,shell]
....
# lastcomm ls trhodes ttyp1
....

Zahlreiche weitere nützliche Optionen finden Sie man:lastcomm[1], man:acct[5] sowie man:sa[8].

[[security-resourcelimits]]
== Einschränkung von Ressourcen

FreeBSD bietet dem Systemadministrator mehrere Möglichkeiten die System-Ressourcen, die ein einzelner Benutzer verwenden kann, einzuschränken. Festplatten-Kontingente schränken den Plattenplatz, der einem Benutzer zur Verfügung steht, ein. Kontingente werden im crossref:disks[quotas,"Disk Quotas"] diskutiert.

Einschränkungen auf andere Ressourcen, wie CPU und Speicher, können über eine Konfigurationsdatei oder über die Kommandozeile konfiguriert werden. Traditionell werden Login-Klassen in [.filename]#/etc/login.conf# definiert. Obwohl diese Methode immer noch untersützt wird, muss nach jeder Änderung an dieser Datei die Ressourcen-Datenbank neu gebaut werden. Zudem müssen Sie die notwendigen Änderungen in [.filename]#/etc/master.passwd# vornehmen und die Passwort-Datenbnak neu bauen. Dieser Prozess kann, abhängig davon, wie viele Benutzer bearbeitet werden müssen, sehr zeitaufwändig sein.

Mit `rctl` Ressourcen für Benutzer sehr detailliert gesteuert werden. Dieser Befehl unterstützt nicht nur die Kontrolle der Ressourcen für Benutzer, sondern auch die Beschränkung auf Prozesse und Jails.

In diesem Abschnitt werden beide Methoden vorgestellt. Angefangen wird mit der traditionellen Methode.

[[users-limiting]]
=== Login-Klassen konfigurieren

Bei der traditionellen Methode werden Login-Klassen und Ressourcenbeschränkungen in [.filename]#/etc/login.conf# definiert. Jeder Benutzer kann einer Login-Klasse zugewiesen werden (standardmäßig `default`) und jede Login-Klasse ist mit einem Satz von Login-Fähigkeiten verbunden. Eine Login-Fähigkeit ist ein `_Name_=_Wert_` Paar, in dem _Name_ die Fähigkeit bezeichnet und _Wert_ ein beliebiger Text ist, der in Abhänigkeit von _Name_ entsprechend verarbeitet wird.

[NOTE]
====
Immer wenn [.filename]#/etc/login.conf# verändert wurde, muss die [.filename]#/etc/login.conf.db# mit dem folgenden Kommando aktualisiert werden:

[source,shell]
....
# cap_mkdb /etc/login.conf
....

====

Ressourcenbeschränkungen unterscheiden sich von normalen Login-Fähigkeiten zweifach. Erstens gibt es für jede Beschränkung ein aktuelles und ein maximales Limit. Das aktuelle Limit kann vom Benutzer oder einer Anwendung beliebig bis zum maximalen Limit verändert werden. Letzteres kann der Benutzer nur heruntersetzen. Zweitens gelten die meisten Ressourcenbeschränkungen für jeden vom Benutzer gestarteten Prozess.

<<resource-limits>> listet die gebräuchlichen Ressourcenbeschränkungen auf. Alle verfügbaren Ressourcenbeschränkungen und Fähigkeiten sind im Detail in man:login.conf[5] beschrieben.

[[resource-limits]]
.Ressourcenbeschränkungen für Login-Klassen
[cols="30%,70%", frame="none", options="header"]
|===
| Ressourcenbeschränkung
| Beschreibung

|coredumpsize
|Das Limit der Größe einer core-Datei, die von einem Programm generiert wird, unterliegt aus offensichtlichen Gründen anderen Limits der Festplattenbenutzung, zum Beispiel `filesize` oder Festplattenkontingenten. Es wird oft als weniger harte Methode zur Kontrolle des Festplattenplatz-Verbrauchs verwendet. Da Benutzer die core-Dateien selbst nicht erstellen und sie oft nicht löschen, kann diese Option davor schützen, dass kein Festplattenspeicher mehr zur Verfügung steht, sollte ein großes Programm abstürzen.

|cputime
|Die maximale Rechenzeit, die ein Prozess eines Benutzers verbrauchen darf. Überschreitet ein Prozess diesen Wert, wird er vom Kernel beendet. Beachten Sie, dass die Rechen__zeit__ limitiert wird, nicht die prozentuale Prozessorenbenutzung, wie es in einigen Feldern von `top` und `ps` dargestellt wird.

|filesize
|Hiermit lässt sich die maximale Größe einer Datei bestimmen, die der Benutzer besitzen darf. Im Gegensatz zu crossref:disks[quotas,Festplattenkontingenten] ist diese Beschränkung nur für jede einzelne Datei gültig und nicht für den Platz, den alle Dateien eines Benutzers verwenden.

|maxproc
|Das ist die maximale Anzahl von Prozessen, die ein Benutzer starten darf, und beinhaltet sowohl Vordergrund- als auch Hintergrundprozesse. Dieser Wert nicht höher sein als das System-Limit, das in `kern.maxproc` angegeben ist. Vergessen Sie nicht, dass ein zu kleiner Wert den Benutzer in seiner Produktivität einschränken könnte, wenn beispielsweise ein großes Programm übersetzt wird oder viele Prozesse gestartet sind.

|memorylocked
|Dieses Limit gibt an, wie viel virtueller Speicher von einem Prozess maximal im Arbeitsspeicher festgesetzt werden kann (siehe auch man:mlock[2]). Ein paar systemkritische Programme, wie man:amd[8], verhindern damit einen Systemzusammenbruch, der auftreten könnte, wenn sie aus dem Speicher genommen werden.

|memoryuse
|Bezeichnet den maximalen Speicher, den ein Prozess benutzen darf und beinhaltet sowohl Arbeitsspeicher-, als auch Swap-Benutzung. Es ist kein allübergreifendes Limit für den Speicherverbrauch, aber ein guter Anfang.

|openfiles
|Mit diesem Limit lässt sich die maximale Anzahl der von einem Prozess des Benutzers geöffneten Dateien festlegen. In FreeBSD werden Dateien auch verwendet, um Sockets und >IPC>-Kanäle darzustellen. Setzen Sie es deshalb nicht zu niedrig. Das System-Limit ist in `kern.maxfiles` definiert.

|sbsize
|Dieses Limit beschränkt den Netzwerk-Speicher, den ein Benutzer verbrauchen darf. Es kann generell dazu benutzt werden Netzwerk-Verbindungen zu beschränken.

|stacksize
|Das ist die maximale Größe, auf die der Stack eines Prozesses heranwachsen darf. Das allein ist natürlich nicht genug, um den Speicher zu beschränken, den ein Programm verwenden darf. Es sollte deshalb in Verbindung mit anderen Limits verwendet werden.
|===

Beim Setzen von Ressourcenbeschränkungen sind noch andere Dinge zu beachten:

* Von [.filename]#/etc/rc# beim Hochfahren des Systems gestartete Prozesse werden der `daemon` Login-Klasse zugewiesen.
* Obwohl die voreingestellte [.filename]#/etc/login.conf# sinnvolle Limits enthält, sind sie evtl. nicht für jedes System geeignet. Ein zu hohes Limit kann das System für Missbrauch anfällig machen, und ein zu niedriges Limit kann der Produktivität schaden.
* Xorg beansprucht selbst eine Menge Ressourcen und verleitet die Benutzer dazu, mehrere Programme gleichzeitig laufen zu lassen.
* Bedenken Sie, dass viele Limits für einzelne Prozesse gelten und nicht für den Benutzer selbst. Setzt man zum Beispiel `openfiles` auf `50`, kann jeder Prozess des Benutzers bis zu `50` Dateien öffnen. Dadurch ist die maximale Anzahl von Dateien, die von einem Benutzer geöffnet werden können, `openfiles` mal `maxproc`. Das gilt auch für den Speicherverbrauch.

Weitere Informationen über Ressourcenbeschränkungen, Login-Klassen und -Fähigkeiten finden Sie in man:cap.mkdb[1], man:getrlimit[2] und man:login.conf[5].

=== Einschränkung von Ressourcen aktivieren und konfigurieren

Die Variable `kern.racct.enable` muss auf einen Wert ungleich Null eingestellt sein. Angepasste Kernel benötigen eine spezielle Konfiguration:

[.programlisting]
....
options           RACCT
options         RCTL
....

Sobald das System mit dem neuen Kernel gestartet wird, kann `rctl` benutzt werden, um die Regeln für das System festzulegen.

Die Syntax der Regeln wird durch _subject_, _subject-id_, _resource_ und _action_ gesteuert, wie in diesem Beispiel zu sehen ist:

[.programlisting]
....
user:trhodes:maxproc:deny=10/user
....

Diese Regel zeigt den grundlegenden Aufbau, hier mit dem Subjekt `user` und der Subjekt-ID `trhodes`. `maxproc` definiert die Anzahl der Prozesse. Die "Aktion" `deny` verhindert, dass neue Prozesse erstellt werden. Im vorherigen Beispiel wurde für den Benutzer `trhodes` eine Beschränkung von `10` Prozessen konfiguriert. Zu den weiteren Aktionen zählen beispielsweise die Protokollierung auf der Konsole, Benachrichtigungen an man:devd[8] oder das Senden eines `SIGTERM` an einen Prozess.

Beim hinzufügen von Regeln müssen einige Dinge beachtet werden. Das obige Beispiel würde den Benutzer sogar daran hindern, einfachste Dinge zu tun, nachdem er sich anmeldet und eine `screen` Sitzung gestartet hat. Sobald die Begrenzung für eine Ressource erreicht ist, wird folgende Fehlermeldung ausgegeben:

[source,shell]
....
# man test
/usr/bin/man: Cannot fork: Resource temporarily unavailable
eval: Cannot fork: Resource temporarily unavailable
....

man:rctl[8] kann auch benutzt werden, um einer Jail eine Speichergrenze zuzuweisen. Eine solche Regel könnte wie folgt festgelegt werden:

[source,shell]
....
# rctl -a jail:httpd:memoryuse:deny=2G/jail
....

Damit die Regeln auch nach einem Neustart erhalten bleiben, müssen sie in [.filename]#/etc/rctl.conf# hinzugefügt werden. Dazu schreiben Sie einfach die Regel, ohne das vorhergehende Kommando. Zum Beispiel:

[.programlisting]
....
# Block jail from using more than 2G memory:
jail:httpd:memoryuse:deny=2G/jail
....

Mit `rctl` können auch Regeln entfernt werden:

[source,shell]
....
# rctl -r user:trhodes:maxproc:deny=10/user
....

man:rctl[8] zeigt auch eine Möglichkeit, alle Regeln zu entfernen. Falls es erforderlich ist alle Regeln für einen einzelnen Benutzer zu entfernen, kann dieser Befehl verwendet werden:

[source,shell]
....
# rctl -r user:trhodes
....

Es gibt noch viele weitere Ressourcen, die verwendet werden können, um zusätzliche `subjects` zu kontrollieren. Weitere Informationen zu diesem Thema finden Sie in man:rctl[8].

[[security-sudo]]
== Gemeinsame Administration mit Sudo

Systemadministratoren benötigen häufig die Möglichkeit, Benutzern erweiterte Berechtigungen zu gewähren, damit diese privilegierte Aufgaben ausführen können. Die Idee, dass Teammitglieder einen Zugang zu einem FreeBSD-System zur Verfügung gestellt bekommen, um ihre spezifischen Aufgaben erledigen zu können, stellt den Administrator vor eine große Herausforderung. Diese Teammitglieder benötigen in der Regel nur einen eingeschränkten Zugang. Für manche Aufgaben werden jedoch die Rechte des Superusers benötigt. Zum Glück gibt es keinen Grund, diesen Mitgliedern einen solchen Zugang zu geben, da es Werkzeuge für genau diesen Anwendungsfall gibt.

Bislang wurde in diesem Kapitel immer versucht, den Zugriff für autorisierte Benutzer zu gewähren und den Zugriff für nicht autorisierte Benutzer zu verhindern. Ein weiteres Problem entsteht, sobald autorisierte Benutzer Zugriff auf die Ressourcen des Systems haben. In vielen Fällen benötigen einige Benutzer Zugriff auf Startskripte von Anwendungen. In anderen Fällen muss eine Gruppe von Administratoren das System verwalten. Traditionell wird der Zugriff über Benutzer, Gruppen, Dateiberechtigungen und manchmal sogar man:su[1] verwaltet. Und da immer mehr Anwendungen einen Zugriff brauchen und immer mehr Benutzer Zugriff auf die Systemressourcen benötigen, ist ein besserer Lösungsansatz erforderlich. Die am häufigsten verwendete Anwendung in solchen Fällen ist derzeit Sudo.

Sudo erlaubt dem Administrator eine rigide Konfiguration des Zugriffs auf bestimmte Kommandos und stellt einige erweiterte Protokollfunktionen zur Verfügung. Dieses Werkzeug kann als Port oder Paket package:security/sudo[] installiert werden. Das Paket wird wie folgt installiert:

[source,shell]
....
# pkg install sudo
....

Nach der Installation können Sie `visudo` benutzen, um die Konfiguration in einem Texteditor zu öffnen. Es wird ausdrücklich `visudo` empfohlen, da dieses Programm die Syntax auf Fehler überprüft, bevor die Konfigurationsdatei gespeichert wird.

Die Konfigurationsdatei besteht aus mehreren kleinen Abschnitten, die eine umfangreiche Konfiguration ermöglichen. Im folgenden Beispiel soll der Webentwickler (`user1`) den Dienst _webservice_ starten und stoppen dürfen. Um ihm dieses Recht zu gewähren, fügen Sie folgende Zeile an das Ende von [.filename]#/usr/local/etc/sudoers# ein:

[.programlisting]
....
user1   ALL=(ALL)       /usr/sbin/service webservice *
....

Der Benutzer kann jetzt _webservice_ über dieses Kommando starten:

[source,shell]
....
% sudo /usr/sbin/service webservice start
....

Diese Konfiguration gestattet den Zugriff auf den webservice für einen einzelnen Benutzer. Jedoch ist in den meisten Organisationen ein ganzes Team für die Verwaltung eines solchen Dienstes verantwortlich. Mit einer weiteren Zeile ist es möglich, einer ganzen Gruppe diesen Zugriff zu geben. Die folgenden Schritte erstellen eine Gruppe mit den entsprechenden Benutzern. Der Gruppe wird es dann ermöglicht, diesen Dienst zu verwalten:

[source,shell]
....
# pw groupadd -g 6001 -n webteam
....

Nun werden die Benutzer mit Hilfe von man:pw[8] in die Gruppe _webteam_ hinzugefügt:

[source,shell]
....
# pw groupmod -m user1 -n webteam
....

Zuletzt wird folgende Zeile in [.filename]#/usr/local/etc/sudoers# hinzugefügt, damit jedes Mitglied von _webteam_ den Dienst _webservice_ verwalten kann:

[.programlisting]
....
%webteam   ALL=(ALL)       /usr/sbin/service webservice *
....

Im Gegensatz zu man:su[1], benötigt Sudo nur das Passwort des Benutzers.

Benutzer, die mit Hilfe von Sudo Programme ausführen, müssen lediglich ihr eigenes Passwort eingeben. Dies ist sicherer und bietet eine bessere Kontrolle als man:su[1], wo der Benutzer das `root`-Passwort eingibt und damit alle Rechte von `root` erlangt.

[TIP]
====

Viele Organisationen haben bereits auf eine Zwei-Faktor-Authentifizierung umgestellt. In diesen Fällen hat der Benutzer möglicherweise gar kein Passwort, welches er eingeben könnte. Sudo bietet für solche Fälle die Variable `NOPASSWD`. Wenn die Variable in die obige Konfiguration hinzugefügt wird, dürfen die Mitglieder der Gruppe _webteam_ den Dienst verwalten, ohne ein Passwort eingeben zu müssen:

[.programlisting]
....
%webteam   ALL=(ALL)       NOPASSWD: /usr/sbin/service webservice *
....

====

[[security-sudo-loggin]]
=== Protokollierung

Ein Vorteil von Sudo ist, dass Sitzungen protokolliert werden können. Mit den integrierten Protokollmechanismen und dem Befehl sudoreplay können alle über Sudo ausgelösten Befehle protokolliert und zu einem späteren Zeitpunkt überprüft werden. Um diese Funktion zu aktivieren, fügen Sie einen Eintrag für das Verzeichnis der Protokolle hinzu. Dieses Beispiel verwendet eine Benutzervariable. Weitere Informationen finden Sie in der Manualpage von sudoreplay.

[.programlisting]
....
Defaults iolog_dir=/var/log/sudo-io/%{user}
....

[TIP]
====

Dieses Verzeichnis wird automatisch nach der Konfiguration erstellt. Um auf der sicheren Seite zu sein, ist es am besten, das System die Verzeichnisse mit Standardberechtigungen erstellen zu lassen. Dieser Eintrag wird auch ein Protokoll für Administratoren erstellen, wenn diese den Befehl sudoreplay benutzen. Um dieses Verhalten zu ändern, kommentieren Sie die entsprechenden Zeilen in [.filename]#sudoers# aus.
====

Nachdem dieser Eintrag in die Datei [.filename]#sudoers# hinzugefügt wurde, kann die Konfiguration der Benutzer für die Protokollierung aktualisiert werden. In dem gezeigten Beispiel würde der aktualisierte Eintrag für das _webteam_ zusätzlich folgende Änderung benötigen:

[.programlisting]
....
%webteam ALL=(ALL) NOPASSWD: LOG_INPUT: LOG_OUTPUT: /usr/sbin/service webservice *
....

Von nun an wird jede Änderung am _webservice_ protokolliert, wenn sie von einem Mitglied der Gruppe _webteam_ initiiert wurde. Eine Liste der Sitzungen kann wie folgt angezeigt werden:

[source,shell]
....
# sudoreplay -l
....

Wenn Sie eine bestimmte Sitzung wiedergeben möchten, suchen Sie in der Ausgabe nach dem Eintrag `TSID=` und übergeben Sie den Wert ohne weitere Optionen an sudoreplay. Zum Beispiel:

[source,shell]
....
# sudoreplay user1/00/00/02
....

[WARNING]
====

Obwohl die Sitzungen protokolliert werden, kann ein böswilliger Administrator wahllos die Sitzungsprotokolle löschen. Daher ist es eine gute Idee, eine tägliche Kontrolle mit einem Intrusion Detection System (IDS) oder einer ähnlichen Software durchzuführen, so dass andere Administratoren auf manuelle Änderungen aufmerksam gemacht werden.
====

sudoreplay ist extrem erweiterbar. Lesen Sie die Dokumentation für weitere Informationen.
