Der folgende Beitrag beschreibt die Installation des Grundsystems auf Basis des Gentoo 2008.0 Minimalsystems von EUserv. Das Minimalsystem enthält direkt nach Installation, wie im letzten Beitrag beschrieben, lediglich den Inhalt eines Stage 3 Tarballs und einen laufenden OpenSSH-Daemon.
Damit das System nutzbar und an meine Anforderungen angepast wird, sind noch einige Schritte notwendig. Die Installation hält sich im Wesentlichen an die Anleitung zu Installation eines Gentoo Hardened Systems aus dem RootForum.de Wiki. Da die Möglichkeiten zum Austausch des Betriebssystems auf einem virtuellen Server beschränkt sind, wird kein gehärteter Kernel installiert. Die Zugangsdaten des virtuellen Servers sind im Kundenmenü von EUserv sehr gut zu finden. Im Auslieferungszustand existiert nur ein Benutzer mit Loginshell auf dem Server: root. Hier könnte der Provider automatisch einen unpriviligierten Benutzer anlegen und der Gruppe wheel zuordnen, um das Login als root unnötig zu machen. Der unpriviligierte Benutzer kann dann mit dem Kommando
su root
Rootrechte erlangen.
Um dieses Manko zu beheben, erstellen wir einen entsprechenden Benutzer mit dem Kommando useradd. Die Gruppe ssh, welche wir mit groupadd angelegen, wird später noch benötigt, um bequem festlegen zu können, welche Benutzer sich überhaupt via SSH einloggen dürfen:
# groupadd ssh # useradd -g users -G wheel,ssh -m# passwd -u
Der Platzhalter
Nun erstellen wir uns ein Schlüsselpaar, mit dem wir uns in Zukunft auf dem virtuellen Server einloggen können. Generell ist eine schlüsselbasierte Authentifizierung aus Sicherheitsüberlegungen heraus gegenüber einer reinen Passwortauthentifizierung vorzuziehen. Bei der Erstellung des Schlüsselpaares sollte auf eine ausreichend starke Passphrase geachtet werden.
$ ssh-keygen -f ~/.ssh/id_euserv
Damit das Login in Zukunft schneller von der Hand geht, werden für den virtuellen Server noch ein paar Einträge in der SSH-Konfiguration auf dem Client eingetragen. Ich gehe hier von OpenSSH auf einem unixoiden System aus (Linux, *BSD, …). Wenn ein anderer SSH-Client verwendet wird, wie etwa PuTTY unter Windows, muss die Konfiguration in der jeweiligen Dokumentation nachgeschlagen werden.
$ $ cat>>~/.ssh/config<<"EOF" Host <HOSTNAME> User <USERNAME> IdentityFile ~/.ssh/id_euservEOF
Durch diese drei Zeilen sagen wir unserem SSH-Client, dass er beim Zugriff auf
Nachdem das Schlüsselpaar erstellt wurde, muss der öffentliche Schlüssel (die Datei mit der Endung .pub) auf den Server in die Datei ~/.ssh/authorized_keys kopiert werden. Da mit dem angelegten Benutzer noch kein SSH-Login möglich ist, kann der Kopiervorgang nicht mit ssh-copy-id durchgeführt werden. Stattdessen muss der Upload durch folgendes Kommando über den noch freigeschalteten Benutzer root erfolgen:
$ cat ~/.ssh/id_euserv.pub | ssh root@'umask 077; mkdir /home/ /.ssh; cat >>/home/ /.ssh/authorized_keys; chown -R :users /home/ /.ssh'
Im Einzelnen erstellt das Kommando das Verzeichnis /home/
Nun sollte es möglich sein, sich mit dem angelegten Benutzer und seinem SSH-Schlüssel auf dem Server anzumelden:
$ ssh
War das erste Login erfolgreich, kann mit
su -
zum Benutzer root gewechselt und die Konfiguration des OpenSSH-Servers angepasst werden:
# cat>>/etc/ssh/sshd_config<<"EOF" PasswordAuthentication no UsePAM no ChallengeResponseAuthentication no PermitRootLogin no AllowGroups ssh EOF
Im Einzelnen erlaubt der sshd nach der Konfigurationsänderung einem Benutzer nur dann noch ein Login, wenn dieser der Gruppe ssh angehört und einen bekannten privaten Schlüssel (wie wir ihn erstellt haben) besitzt. Details zu jeder Direktive finden sich in sshd_config(5)
Um zu testen, ob die Konfigurationsänderung erfolgreich war, muss der OpenSSH-Server neugestartet werden.
# /etc/init.d/sshd restart
Die aktuell offene Sitzung bleibt trotz des Neustarts bestehen. Das ist sehr wichtig, falls die Konfigurationsänderung nicht erfolgreich war. Wir testen das einfach von unserem Client aus mit
$ ssh root@<HOSTNAME>Permission denied (publickey).
Die Meldung besagt nun eindeutig, dass der Benutzer root keinen Zugang mehr zu dem virtuellen Server via SSH erhält. Ein Login mit dem angelegten Benutzer muss natürlich weiterhin klappen! Sobald das Funktionieren des normalen Logins verifiziert wurde, kann es mit der Konfiguration weitergehen.
Das Paketsystem von Gentoo Linux basiert auf Portage, einem an die von FreeBSD bekannte Ports-Kollektion angelehnten Paketsystem. Ich empfehle Eine Einführung in Portage bzw. allgemein das Gentoo Linux x86 Handbuch zu lesen, bevor die Installation fortgesetzt wird.
Damit das erste Synchronisieren mit dem aktuellen Portage-Baum nicht zu lange dauert, laden wir uns einen der nächtlichen Snapshots herunter und entpacken ihn auf unserem virtuellen Server
# wget -q -O - http://gentoo.osuosl.org/snapshots/portage-latest.tar.bz2 | tar -xvjpf - -C /usr/
Danach wird die /etc/make.conf angepasst.
# cat>/etc/make.conf<<"EOF"
CHOST="i686-pc-linux-gnu"
CFLAGS="-Os -march=prescott -pipe"
CXXFLAGS="${CFLAGS}"
MAKEOPTS="-j2"
ACCEPT_KEYWORDS="~x86"
CONFIG_PROTECT = /sbin/rc
FEATURES="parallel-fetch suidctl userpriv usersandbox usersync"
USE="-* acl bash-completion berkdb bzip2 crypt cgi fastcgi gdbm hardened iconv idn imap lzma mmx ncurses nls nptl pcre readline session spl sse sse2 ssl tcpd threads unicode vim-syntax xml zlib"
EOF
Die USE-Flags am Ende der make.conf bestimmen, welche Features unser System später unterstützen wird und sollten sehr individuell festgelegt werden. Spätere Änderungen an den compiler-spezifischen Einstellungen $CHOST, $CFLAGS und $CXXFLAGS sollten wenn möglich ganz vermieden werden, da dies zu erheblichen Problemen führen kann. In unserem Fall wird allerdings später noch die $CFLAGS-Variable angepasst, sobald eine aktuelle Version des GCC installiert wurde.
Der Wert ~x86 Variable $ACCEPT_KEYWORDS besagt, dass mit dieser make.conf auch als unstable markierte Pakete des x86 Baums installiert werden sollen. Normalerweise würde man hier nur x86 eintragen und je nach Bedarf die als unstable markierten Pakete ebuild-spezifisch über /etc/portage/portage.keywords freischalten. In diesem Fall kommt es mir aber auf aktuelle Pakete an, so dass ich das Risiko eingehe, ein unbrauchbares System zu erhalten.
Allgemein gilt: man sollte wissen, was man an dem System macht und wie man es wieder flott bekommt, falls einmal etwas schief geht. Gentoo an sich wurde nicht für blutige Anfänger konzipiert.
Nun werden noch einige ebuild-spezifische USE-Flags in der Datei /etc/portage/package.use gesetzt:
# cat>/etc/portage/package.use<<"EOF" sys-devel/gcc mudflap sys-libs/glibc glibc-omitfp nptlonly userlocales sys-apps/man-pages -nls sys-devel/libperl ithreads dev-lang/perl ithreads EOF
Die Vorarbeiten wurden geleistet. Der Erfolg kann mit folgendem Kommando geprüft werden:
# emerge --info
Wichtig sind dabei die Werte der in der /etc/make.conf geänderten Variablen.
Auf meinem virtuellen Server liefert das Kommando z. B. folgende Ausgabe (leider nicht mehr im Originalzustand, sondern schon nach einigen Programminstallationen):
# emerge --info Portage 2.1.6.7 (default/linux/x86/2008.0, gcc-4.3.3, glibc-2.9_p20081201-r1, 2.6.18-92.1.18.el5.028stab060.2 i686) ================================================================= System uname: Linux-2.6.18-92.1.18.el5.028stab060.2-i686-Pentium-R-_Dual-Core_CPU_E5200_@_2.50GHz-with-glibc2.0 Timestamp of tree: Sun, 01 Feb 2009 15:00:01 +0000 app-shells/bash: 3.2_p48 dev-lang/python: 2.5.4-r2 sys-apps/baselayout: 2.0.0 sys-apps/openrc: 0.4.2 sys-apps/sandbox: 1.3.3 sys-devel/autoconf: 2.63 sys-devel/automake: 1.10.2 sys-devel/binutils: 2.19 sys-devel/gcc-config: 1.4.1 sys-devel/libtool: 2.2.6a virtual/os-headers: 2.6.28-r1 ACCEPT_KEYWORDS="x86 ~x86" CBUILD="i686-pc-linux-gnu" CFLAGS="-Os -march=core2 -pipe" CHOST="i686-pc-linux-gnu" CONFIG_PROTECT="/etc /sbin/rc" CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/eselect/postgresql /etc/gconf /etc/gentoo-release /etc/php/apache2-php5/ext-active/ /etc/php/cgi-php5/ext-active/ /etc/php/cli-php5/ext-active/ /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo /etc/udev/rules.d" CXXFLAGS="-Os -march=core2 -pipe" DISTDIR="/usr/portage/distfiles" FEATURES="distlocks fixpackages parallel-fetch protect-owned sandbox sfperms strict suidctl unmerge-orphans userfetch userpriv usersandbox usersync" GENTOO_MIRRORS="http://distfiles.gentoo.org http://distro.ibiblio.org/pub/linux/distributions/gentoo" LANG="en_US.utf8" LC_ALL="en_US.utf8" LDFLAGS="-Wl,-O1" LINGUAS="de" MAKEOPTS="-j2" PKGDIR="/usr/portage/packages" PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages" PORTAGE_TMPDIR="/var/tmp" PORTDIR="/usr/portage" SYNC="rsync://rsync.gentoo.org/gentoo-portage" USE="acl bash-completion berkdb bzip2 cgi crypt fastcgi gdbm hardened iconv idn imap lzma mmx ncurses nls nptl pcre readline session spl sse sse2 ssl tcpd threads unicode vim-syntax x86 xml zlib" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci emu10k1 emu10k1x ens1370 ens1371 es1938 es1968 fm801 hda-intel intel8x0 intel8x0m maestro3 trident usb-audio via82xx via82xx-modem ymfpci" ALSA_PCM_PLUGINS="adpcm alaw asym copy dmix dshare dsnoop empty extplug file hooks iec958 ioplug ladspa lfloat linear meter mmap_emul mulaw multi null plug rate route share shm softvol" APACHE2_MODULES="actions alias auth_basic authn_alias authn_anon authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache dav dav_fs dav_lock deflate dir disk_cache env expires ext_filter file_cache filter headers include info log_config logio mem_cache mime mime_magic negotiation rewrite setenvif speling status unique_id userdir usertrack vhost_alias" ELIBC="glibc" INPUT_DEVICES="keyboard mouse evdev" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LINGUAS="de" USERLAND="GNU" VIDEO_CARDS="fbdev glint i810 intel mach64 mga neomagic nv r128 radeon savage sis tdfx trident vesa vga via vmware voodoo" Unset: CPPFLAGS, CTARGET, EMERGE_DEFAULT_OPTS, FFLAGS, INSTALL_MASK, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS, PORTDIR_OVERLAY
Wenn die Ausgabe in Ordnung ist, kann nun der Portage-Tree aktualisiert werden:
# emerge --sync
Wenn ein Upgrade für Portage verfügbar ist (was sehr wahrscheinlich ist), sollte zunächst dieses installiert werden. Im gleichen Zug installieren wir auch eine aktuelle Version des GCC:
# emerge -1 portage binutils gcc
Der Vorgang dauert eine Weile, so dass es jetzt erstmal Zeit für einen Kaffee ist. ;)
Nachdem die Installation erfolgreich abgeschlossen wurde, wird der neue GCC (in diesem Fall der GCC 4.3.3) als Haupt-Compiler eingetragen:
# gcc-config -l [1] i686-pc-linux-gnu-4.1.2 * [2] i686-pc-linux-gnu-4.3.3 # gcc-config i686-pc-linux-gnu-4.3.3 # source /etc/profile
Der neue GCC unterstützt auch direkt den in dem Wirtssystem verbauten CPU-Typ. Daher ändern wir in der /etc/make.conf den $CFLAGS-Eintrag ab:
CFLAGS="-Os -march=core2 -pipe"
Wenn der CPU-Typ nicht bekannt ist oder nicht direkt von GCC unterstützt wird (siehe 3.17.14 Intel 386 and AMD x86-64 Options), ist es auch möglich, generischen (x86- bzw. i686-) Code erzeugen zu lassen:
CFLAGS="-Os -mtune=i686 -pipe"
Nun kommt die erste und letzte Installationsorgie. Die Reihenfolge der Kommandos sollte weitgehend beibehalten werden, da das System ursprünglich mit PAM-Unterstützung kompiliert wurde, welche durch die Einstellungen in der /etc/make.conf nun wegfällt.
# emerge -1 udev baselayout # emerge -C cracklib pambase pam # emerge -1 shadow openssh busybox # emerge -C sys-libs/ss sys-libs/com_err sys-fs/e2fsprogs # emerge -De world
Das letzte Kommando sorgt dafür, dass alle installierten Pakete mit den neuen Compiler-Einstellungen erneut gebaut werden.
Am Ende dieses langen Vorgangs ist das System auf einem aktuellen Stand. Überreste des alten Compilers können nun entfernt werden:
# rm -rf /etc/env.d{,/*}/*i486-pc-linux-gnu* /usr{,/bin}/*i486-pc-linux-gnu*
Im nächsten Schritt wird die für das System gültige Zeitzone gesetzt, die Standard Locale US-Englisch eingestellt sowie eine Liste der zu erzeugenden Locales erstellt:
# ln /usr/share/zoneinfo/Europe/Berlin /etc/localtime # cat > /etc/env.d/02locale << "EOF" LC_ALL="en_US.utf8" LANG="en_US.utf8" EOF # cat > /etc/locale.gen << "EOF" en_US ISO-8859-1 en_US.UTF-8 UTF-8 de_DE ISO-8859-1 de_DE@euro ISO-8859-15 de_DE.UTF-8 UTF-8 EOF # locale-gen -c /etc/locale.gen # env-update # source /etc/profile
Der Hostname des Systems wurde von EUserv auf einen recht generischen Namen gesetzt. Sofern ein anderer Hostname gewünscht wird, kann dieser in den Dateien /etc/conf.d/hostname und /etc/conf.d/hosts gesetzt werden.
Nun folgt der letzte "Aufräumschritt". Die nicht mehr benötigten Pakete werden entfernt und mit dem in dem Paket app-portage/gentoolkit enthaltenen Programm revdep-rebuild geprüft, ob alle benötigten Bibliotheken installiert wurden.
# emerge -P # emerge gentoolkit # revdep-rebuild
Für den sinnvollen Betrieb eines Servers sind einige Standarddienste erforderlich, etwa ein Syslog-Daemon, ein Cron-Daemon sowie logrotate, um alte Logdateien aufzuräumen und zu sichern.
# emerge syslog-ng logrotate vixie-cron iproute2 # rc-update add syslog-ng default # rc-update add vixie-cron default
Weitere nützliche Programme sind der Editor vim sowie der Terminalmultiplexer screen. Diese sollten auf keinem System fehlen. ;)
# emerge vim screen
Der nächste Beitrag wird sich voraussichtlich um die Einrichtung eines Mailsystems mit MTA, IMAP-Server und Spamfilter drehen.