FreeBSD System einrichten
From RootForum Community » Wiki
Contents |
Einleitung
Unter dem Stichwort „Einrichtung“ kann man sich so ziemlich alles vorstellen, und jeder wird dazu auch seine eigenen Wünsche und Vorstellungen dazu haben. Ich kann daher nur beschreiben, was ich persönlich aus dem in FreeBSD_manuelle_Installation_(de) erstellten Rohbau zu machen pflege.
Zeitzone setzen und NTP-Synchronisierung einrichten
Dies ist eine der leichtesten Übungen, aber Voraussetzung dafür, dass alle im weiteren Verlauf erläuterten Schritte auch korrekte Ergebnisse liefern:
tzsetup
Die NTP-Synchronisierung kann mit einem einfachen Eintrag in der Crontab bewerkstelligt werden:
echo '*/10 * * * * root /usr/sbin/ntpdate -b -s -p 4 -t 0.1 ptbtime1.ptb.de' >> /etc/crontab
System aktualisieren
Nach erfolgter Installation von einem Release-Medium sollte das System so schnell wie möglich auf den aktuellen Stand gebracht werden. Dazu muss zunächst die Entscheidung getroffen werden, welcher FreeBSD „Flavour“ verwendet werden soll. Zur Erklärung: Es gibt drei verschiedene Flavours mit den Namen RELEASE, STABLE und CURRENT:
- CURRENT ist der Hauptentwicklungszweig, in den auch größere Änderungen einfließen. Dieser Zweig ist hauptsächlich für Basissystem-Entwickler gedacht; er enthält häufig fehlerhaften, nicht-stabile Code. Es kann sogar vorkommen, dass sich Code aus dem CURRENT-Zweig gar nicht erst kompilieren lässt. Der CURRENT-Zweig dient der Entwicklung des jeweils nächsten Major Release.
- STABLE ist ein Entwicklungszweig eines Major Release. Zu den 7.x-Releases gehört der STABLE-Zweig „RELENG_7“ im Versionsverwaltungssystem. STABLE ist nicht stabil im Sinne von ausgereift, sondern stabil im Hinblick auf die ABI (Commits, die diese Verändern, dürfen nur in CURRENT einfließen).
- RELEASE sind veröffentlichte Zweige. Offiziell werden auch nur diese supported (z. B. mit Security Fixes versorgt). In diese Zweige fließen nach einem Release ausschließlich Errata- und Security Fixes ein. Zu FreeBSD 7.2 gehört z. B. der RELEASE-Zweig „RELENG_7_2“.
Normalerweise sollte man auf einem Produktivsystem aussschließlich Code aus einem RELEASE-Zweig verwenden. Vom Einsatz der Legacy-Releases aus dem 6.x-Zweig kann ich nur abraten, da sie auf SMP-Systemen eine ungleich schlechtere Performance zeigen als die aktuellen Versionen aus dem 7.x-Zweig. Am besten geeignet für den Serverbetrieb ist also derzeit die Version 7.2. Möchte man ZFS einsetzen, gilt jedoch eine kleine Ausnahme: FreeBSD 7.2 enthält noch die recht alte ZFS-Version 6, mit der es einige bekannte Stabilitätsprobleme gibt. In RELENG_7 (STABLE) findet sich jedoch bereits die aktuelle ZFS-Version 13, wie sie auch von OpenSolaris verwendet wird. Diese Version behebt sämtliche bekannten Deadlock-Probleme und läuft unter amd64 auch ohne mühsames Tuning[1] sehr stabil. ZFS v13 verwendet jedoch ein neues, zu v6 nicht abwärtskompatibles Zpool-Format. Ausnahmsweise sollte man daher RELENG_7 verwenden – zumindest bis FreeBSD 7.3 erscheint, das dann ZFS auch in der aktuellen Version enthalten wird.
Source Tree auschecken
Am besten funktioniert bei FreeBSD immer noch die Aktualisierung über die System-Sourcen. Auf diesem Wege kann man ein System über viele Release-Generationen hinweg aktuell halten, ohne eine Neuinstallation durchzuführen. Das Verfahren ist zwar etwas zeitaufwändig, aber erprobt und führt bei richtiger Anwendung zu einem sauberen, aktuellen System.
Zunächst wird hierzu das Quellenverzeichnis von FreeBSD benötigt. Da ich im folgenden die Aktualisierung auf 7-STABLE (RELENG_7) beschreibe, können die Quellen eigentlich nur aus dem CVS ausgecheckt werden. Glücklicherweise liefert FreeBSD hierzu das Tool csup[2] mit, das diesen Arbeitsschritt stark vereinfacht.
Als erstes benötigen Sie eine Konfigurationsdatei für csup:
cp /usr/share/examples/cvsup/stable-supfile /etc/source-supfile
Passen sie die Datei an, so dass sie verwendbar wird und auf RELENG_7 verweist:
*default host=cvsup.FreeBSD.org *default release=cvs tag=RELENG_7 src-all
Sie können natürlich auch einen näher gelegenen Spiegel-Server eintragen; als Source Collection sollte aber auf jeden Fall src-all eingetragen sein. Nun können Sie den Quellenbaum bequem per csup initial herunterladen und jederzeit aktualisieren:
csup /etc/source-supfile
Konfiguration anpassen
In FreeBSD_manuelle_Installation_(de)#Kernel_erstellen habe ich bereits beschrieben, wie eine geeignete make.conf und eine individuelle Kernel-Konfiguration aussehen können. Außerdem möchte ich an dieser Stelle nochmals auf das FreeBSD-Handbuch verweisen. Insbesondere Kapitel 8 (Kernel selbst erstellen) und Kapitel 24.6 (Basissystem komplett aktualisieren) seien Ihnen ans Herz gelegt.
Außerdem empfehle ich Ihnen dringend, /usr/src/UPDATING zu lesen. Alle Angaben und Hinweise in dieser Datei sind aktueller und zutreffender als das Handbuch oder gar Wiki-Artikeln und sollten unbedingt befolgt werden.
Vorbereitende Arbeiten
Zunächst müssen eventuell noch vorhandene Object-Dateien gelöscht werden, damit make später wirklich das gesamte System neu erstellt:
cd /usr/obj chflags -R noschg * rm -rf *
Für die spätere Installation des Basissystems darf /tmp nicht mit der Option noexec gemounted sein. Da zwischendrin noch mal ein Reboot erfolgt, können Sie jetzt aber schon mal die entsprechende Zeile(n) in Ihrer fstab anpassen:
#/dev/ufs/tmp /tmp ufs rw,noatime,noexec,nosuid 2 2 /dev/ufs/tmp /tmp ufs rw,noatime 2 2
Außerdem sollte mergemaster[3] im Prä-Build-Mode angeworfen werden, damit es während der Aktualisierung nicht zu Fehlern kommt, weil z. B. bestimmte User oder Gruppen noch nicht vorhanden sind:
cd /usr/src/usr.sbin/mergemaster ./mergemaster.sh -p
Basissystem übersetzen
cd /usr/src make -j6 buildworld
Auf Dual-Core Systemen hat es sich bei mir bewährt, 6 parallele Prozesse arbeiten zu lassen. Auf Single Core Systemen sollten es aber nicht mehr als 4 werden, da sich die Prozesse sonst gegenseitig behindern.
Kernel übersetzen und installieren
Wenn die eigene Kernel-Konfiguration bereits in make.conf eingetragen ist, wird sie automatisch verwendet:
cd /usr/src make buildkernel make installkernel
Normalerweise wäre nun ein Reboot in den Single User Mode an der Reihe. Da sich ein Remote-System in diesem Modus ohne KVM-Lösung aber nicht bedienen lässt, begnügen wir uns damit, das System neu zu starten. Wenn Sie Ihr System zu einem späteren Zeitpunkt nochmals aktualisieren, würde ich Ihnen empfehlen, dazu alle Dienste außer OpenSSH sowie sämtliche Jails in der Datei /etc/rc.conf zu deaktivieren.
Basissystem installieren
Prüfen Sie zunächst mit mount[4], ob /tmp jetzt ohne noexec-Option gemounted ist.
cd /usr/src make installworld
Als letzten Schritt müssen nun noch Neuerungen in Konfigurationsdateien gemerged werden. Dabei unterstützt Sie das Tool mergemaster:
/usr/sbin/mergemaster -i -F
Anschließend müssen Sie noch die für die Installation ggf. vorgenommenen Änderungen in der fstab sowie rc.conf rückgängig machen und das System nochmals durchstarten. Nachdem Sie sich erneut am System angemeldet haben, können Sie sich davon überzeugen, dass sie jetzt mit einem STABLE-System arbeiten:
uname -sir FreeBSD 7.2-STABLE CUSTOM
ZFS einrichten
Ein paar Worte zu ZFS unter FreeBSD
ZFS[5] ist ein äußerst flexibles und attraktives Dateisystem. Wenn man ZFS einsetzen möchte, sind jedoch einige Dinge zu beherzigen. Zunächst: ZFS unter FreeBSD gilt immer noch als experimentelles Feature (dies gilt jedoch nicht mehr für das im Entstehen begriffene FreeBSD 8.0, selbiges kann sogar von ZFS booten[6]). In den derzeitig unterstützten RELEASE-Versionen von FreeBSD (7.1, 7.2) ist mit ZFS v6 eine veraltete Version enthalten, die etliche Bugs aufweist (u. a. extremer Speicherhunger und häufige Deadlocks). Erst im aktuellen STABLE-Zweig (RELENG_7) sowie im RELENG_8 und CURRENT-Zweig findet sich die aktuelle ZFS-Version v13, mit der die meisten dieser Probleme behoben sind.
Nicht behoben werden kann jedoch ein Problem, das mit den i386-Kerneln von FreeBSD besteht: Der Adresspool, den der FreeBSD-Kernel nutzen kann, um Kernelspeicher zu adressieren, reicht für gerade mal ~300MB. Das ist für ZFS viel zu wenig; selbst die aktuelle Version v13 fliegt einem damit regelmäßig um die Ohren. Abhilft schafft nur intensives Kernel-Tuning[7]. Mit einem aktuellen amd64-Kernel besteht dieses Problem im Übrigen nicht.
Ebenfalls zu beachten wäre, dass ZFS langsamer als ein klassisches Dateisystem ist (was u. a. an den Parity-Informationen und CoW liegen dürfte). In einem Benchmark (mit iozone) erwies sich ZFS bei Schreiboperationen um bis zu Faktor 10 langsamer als UFS, glänzt aber im Gegenzug natürlich mit enormer Flexibilität und Skalierbarkeit.
Empfehlung: mit einem aktuellen RELENG_7 (7.2-STABLE) lässt sich ZFS (v13) auf einer amd64-Installation hinreichend sicher, performant und stabil betreiben. Unter i386 und in der alten Version v6 ist es nicht mehr als ein Proof-of-Concept und sollte für den produktiven Einsatz nicht in Erwägung gezogen werden.
ZFS ZPool erstellen
Aus den beiden ungenutzen Slices soll nun ein ZFS Zpool erzeugt werden. Bei nur zwei Slices ist mirror der am besten geeignete Modus; raidz funktioniert zwar, macht aber erst ab drei Devices richtig Sinn.
zpool create pool mirror ad0s3 ad1s3 zfs set atime=off pool
Den Zustand und die Eigenschaften des eben erstellten ZPools lassen sich mit den zpool-Befehlen get und status anzeigen; die Dateisystem-Eigenschaften zeigt der get-Befehl des zfs-Kommandos:
zpool status pool zpool get "all" pool zfs get "all" pool
Für ZFS ZPools und Datasets müssen keine Einträge in der fstab angelegt werden; sie werden automatisch gemounted. Der mount-Befehl zeigt sie allerdings dennoch an:
mount | grep 'pool' pool on /pool (zfs, local, noatime)
Portstree einrichten
Der Portstree soll so abgelegt werden, dass er später auch in den Jails genutzt werden kann. Entsprechend müssen die Distfiles und Arbeitsverzeichnisse für das Basis-Systems an eine Stelle außerhalb des Portstree verlagert werden. Dazu verwenden wir den eben angelegten ZPool:
zfs create pool/ports zfs create pool/local zfs set mountpoint=/local pool/local mkdir -p /local/distfiles mkdir -p /local/portbuild
Nun kann der Portstree heruntergeladen und entpackt werden (kann bis zu einer Stunde dauern):
portsnap -p /pool/ports fetch extract
Nun müsssen wir noch dafür Sorge tragen, dass der Portstree auch unter /usr/ports verfügbar gemacht wird:
mkdir -p /pool/ports echo "/pool/ports /usr/ports nullfs ro,late 0 0" >> /etc/fstab kldload nullfs mount -al
Temporäre Daten, die beim Übersetzen eines Ports anfallen, sollen unter /local/portbuild abgelegt werden, anstatt in einem work-Verzeichnis innerhalb des Portstree zu landen. Um diese Änderung global bekannt zu machen, bedarf es einer kleinen Änderung an der Datei make.conf:
echo "WRKDIRPREFIX?=/local/portbuild" >> /etc/make.conf
Heruntergeladene Quellcode-Archive sollen im Verzeichnis /local/distfiles abgelegt werden, anstatt in einem zentralen distfiles-Verzeichnis im Portstree gespeichert zu werden. Dies lässt sich mit einem einfachen relativen Symlink erreichen:
cd /usr/ports rm -rf distfiles ln -s ../../local/distfiles
Damit ist der Portstree einsatzbereit. Um den Tree künftig zu aktualisieren, genügt der folgende Befehl:
portsnap -p /pool/ports fetch update
Software installieren
So ganz ohne komfortablere Tools ist das Basis-System etwas mühselig zu administrieren. Deshalb werden aus den Ports einige häufig benötigte Anwendungen installiert:
cd /usr/ports/lang/perl5.10 make config && make config-recursive make install clean cd /usr/ports/ports-mgmt/portaudit make install clean cd /usr/ports/ports-mgmt/portmaster make install clean rehash portaudit -Fda portmaster --force-config -dB editors/vim-lite portmaster --force-config -dB ports-mgmt/pkg_cutleaves portmaster --force-config -dB sysutils/most portmaster --force-config -dB sysutils/cpdup portmaster --force-config -dB sysutils/pwgen2 portmaster --force-config -dB sysutils/sysinfo portmaster --force-config -dB sysutils/smartmontools portmaster --force-config -dB misc/tmux cd /usr/local/etc sed 's/^DEVICESCAN/#DEVICESCAN/' smartd.conf.sample > smartd.conf echo "/dev/ad0 -a -o on -S on -s (S/../.././02|L/../../6/03)" >> smartd.conf echo "/dev/ad1 -a -o on -S on -s (S/../.././02|L/../../6/03)" >> smartd.conf echo 'smartd_enable="YES"' >> /etc/rc.conf /usr/local/etc/rc.d/smartd start cd ~
Wenn Sie die vorgeschlagenen Programme nicht kennen, so finden Sie zu jedem Port eine Datei pkg-descr, die eine kurze Beschreibung sowie (meistens) einen Link zur Projekt-Homepage der Software enthält. Für tmux zum Beispiel würden Sie die Beschreibung also unter /usr/ports/misc/tmux/pkg-descr finden.
Locale einrichten
Auf Servern verwende ich gerne eine englische locale mit Unicode (UTF-8). Zunächst einmal muss eine passende Login-Klasse erzeugt werden, in der die Verwendung eine Unicode-locale festgelegt wird. Fügen Sie dazu folgende Zeilen in die Datei /etc/login.conf ein:
unicode|Unicode Users Accounts:\
:charset=UTF-8:\
:lang=en_US.UTF-8:\
:tc=default:
Anschließend muss die Datei noch umgewandelt werden:
cap_mkdb /etc/login.conf
Um nun diese Login-Klasse für einen User zu aktivieren, können Sie das pw-Kommando benutzen; hier im Beispiel für den User admin:
pw usermod admin -L unicodeNach dem nächsten Login mit diesem User sollte der Befehl locale folgende Ausgabe liefern:
LANG=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_ALL=
Shell einrichten
Unter FreeBSD ist die Tenex C Shell (TCSH) die Standard-Shell. Für Bash-gewohnte Linux-User ist diese Shell etwas gewöhnungsbedürftig, und natürlich kann man sie auch gegen eine andere Shell austauschen (im Basis-System ist neben der TCSH auch eine ASH enthalten). Skripte würde ich für die TCSH nicht schreiben, aber für die tägliche Administrationsarbeit ist die TCSH ein sehr brauchbares Werkzeug – wenn man sie erst mal vernünftig konfiguriert hat.
cat > /home/admin/.cshrc << EOF # $FreeBSD: src/share/skel/dot.cshrc,v 1.14.8.1 2009/04/15 03:14:26 kensmith Exp $ # # .cshrc - csh resource script, read at beginning of execution by each shell # # see also csh(1), environ(7). # # A righteous umask umask 27 set path = (/bin /usr/bin /usr/games /usr/local/bin $HOME/bin) setenv EDITOR vim setenv PAGER most setenv BLOCKSIZE K if ($?prompt) then # An interactive shell -- set some stuff up set prompt = "%{\033[33m%}%n@%m %{\033[36m%}%~ %%%{\033[0m%} " set filec set history = 100 set savehist = 100 set mail = (/var/mail/$USER) if ( $?tcsh ) then bindkey "^W" backward-delete-word bindkey -k up history-search-backward bindkey -k down history-search-forward bindkey ^[[3~ delete-char endif endif EOF cat > /root/.cshrc << EOF # $FreeBSD: src/etc/root/dot.cshrc,v 1.30 2007/05/29 06:37:58 dougb Exp $ # # .cshrc - csh resource script, read at beginning of execution by each shell # # see also csh(1), environ(7). # # A righteous umask umask 22 set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin) setenv EDITOR vim setenv PAGER most setenv BLOCKSIZE K if ($?prompt) then # An interactive shell -- set some stuff up set prompt = "%{\033[35m%}%m %{\033[36m%}%~ #%{\033[0m%} " set filec set history = 100 set savehist = 100 set mail = (/var/mail/$USER) if ( $?tcsh ) then bindkey "^W" backward-delete-word bindkey -k up history-search-backward bindkey -k down history-search-forward bindkey ^[[3~ delete-char endif endif alias portrefresh 'portsnap -p /pool/ports fetch update' EOF cat > /etc/csh.cshrc << EOF # $FreeBSD: src/etc/csh.cshrc,v 1.3 1999/08/27 23:23:40 peter Exp $ # # System-wide .cshrc file for csh(1). setenv LSCOLORS "Dxfxcxdxbxegedabagacad" alias h history 25 alias j jobs -l alias ls ls -GF alias la ls -a alias lf ls -FA alias ll ls -lA alias l ls -lha EOF
Systemsicherheit verstärken
Die hier vorgestellten Maßnahmen sind äußerst simple Basis-Maßnahmen, die auf jedem System aus Hygienegründen selbstverständlich sein sollten. Um ein FreeBSD-System richtig zu härten, kommt man jedoch nicht an komplexeren Methoden wie Security Event Auditing und Mandatory Access Control vorbei. Diese Themen werden im FreeBSD-Handbuch recht ausführlich besprochen; für den Einstieg empfehle ich die Lektüre von Kapitel 14, für die weiterführenden Themen die Kapitel 16 (Mandatory Access Control) und 17 (Security Event Auditing).
/etc/sysctl.conf anpassen
cat > /etc/sysctl.conf << EOF # $FreeBSD: src/etc/sysctl.conf,v 1.8 2003/03/13 18:43:50 mux Exp $ # # This file is read when going to multi-user and its contents piped thru # ``sysctl'' to adjust kernel values. ``man 5 sysctl.conf'' for details. # # Uncomment this to prevent users from seeing information about processes that # are being run under another UID. security.bsd.see_other_uids=0 security.bsd.see_other_gids=0 net.inet.ip.random_id=1 net.inet.tcp.icmp_may_rst=0 net.inet.tcp.blackhole=2 net.inet.udp.blackhole=1 EOF
Stärkere Passwort-Hashes verwenden
Bearbeiten Sie in der Datei /etc/login.conf die Klasse default:
default:\
:passwd_format=blf:\
:copyright=/etc/COPYRIGHT:\
...
Anschließend muss die Datei in eine Systemdatenbank umgewandelt werden:
cap_mkdb /etc/login.conf
Die neuen Einstellungen werden erst wirksam, wenn das Passwort eines Benutzers geändert wird. Deshalb sollten Sie jetzt die Passwörter für root und alle anderen von Ihnen angelegten User ändern.
Terminals absichern
Um zu verhindern, dass das System im Single User Mode ohne jeglichen Schutz benutzbar ist, ändern Sie in der Datei /etc/ttys die Zeile console none... wie folgt ab:
console none unknown off insecure
Dadurch wird die Eingabe des root-Kennworts erforderlich, um das System im Single User Mode booten zu können.
Außerdem können Sie in derselben Datei nicht benötigte Terminals deaktivieren. Setzen Sie dazu die Terminals ttyv1 bis ttyv8, ttyd0 bis ttyd3 sowie dcons auf off. ttyv0 sowie die network-Terminals sollten Sie jedoch unverändert lassen.
Zusätzlich können Sie veranlassen, dass die Konsole bei jedem Logout gelöscht wird, so dass nicht versehentlich vertrauliche Informationen auf dem Bildschirm sichtbar bleiben. Dazu müssen Sie die Datei /etc/gettytab bearbeiten. Suchen Sie folgenden Eintrag:
P|Pc|Pc console:\
:ht:np:sp#115200:
und ändern Sie ihn wie folgt ab:
P|Pc|Pc console:\
:ht:np:sp#115200:\
:cl=\E[H\E[2J:
Wie geht es weiter?
Das System kann nun entweder direkt mit typischen Server-Anwendungen wie Apache, MySQL, einem MTA etc. ausstaffiert werden – alternativ baut man sich eine FreeBSD_Jail_Infrastruktur_(de) auf, um die einzelnen Dienste voneinander trennen zu können.