logo_header

icon_bubbles Forum

icon_bubbles Wiki

icon_bubbles Planet

RootForum Community » Wiki

FreeBSD System einrichten

From RootForum Community » Wiki

Jump to:navigation, search

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 unicode

Nach 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.