Dedicated Server (Rootserver) als Webserver und Mailserver einrichten

Technischer Stand: Jahr 2004. Dieser Artikel wurde aufgrund von Leserkommentaren und eigenen Erfahrungen im April 2004 komplett überarbeitet und wird jetzt nicht mehr aktualisiert.

Inhalt:

Wozu?

Wer nur mal eben drei Seiten, ein Dutzend Photos und ein schwach frequentiertes Gästebuch ins Internet stellen will, ist sicher mit einem Webhosting-Angebot für EUR 9,95 gut versorgt. Wer einen größeren Auftritt will, mehr Flexibilität braucht und auch seinen Mailverkehr nicht in fremde Hände legen will, bekommt seinen eigenen Server im Internet heute zu phantastisch günstigen Preisen.

Ich selbst habe Erfahrungen mit einem amerikanischen Anbieter von Dedicated Servern gemacht, der offenbar mit jeder Facette seines Geschäfts erhebliche Probleme hatte. Ich bin kurzerhand umgestiegen zu einem deutschen Anbieter, der sehr erfolgreicher Vorreiter im Lowcost-Segment ist, und zwar nicht der allerbilligste ist, aber gute Kritiken in der Presse bekommen hat. Soviel vorweg: Ich hatte bisher keinen Grund zu klagen.

Einige Dinge sind zu beachten:

  1. Man muß ein wenig von Linux verstehen.

  2. Die eingesetzten Hardwarekomponenten sind für diesen Preis kaum Erste Wahl. Man sollte seine Daten gut sichern und auch etwa wissen, was man zum Einrichten des Servers alles getan hat, ohne bei der zweiten Installation wieder alle Howtos suchen und studieren zu müssen. Es ist auch immer empfehlenswert, das Verzeichnis /etc mit seinen Unterverzeichnissen aufzuheben.

  3. Man sollte seinen Server im Auge behalten. Wer sich überhaupt nicht erlauben kann, im Internet nicht erreichbar zu sein, kommt mit einem Dedicated Server-Billigangebot nicht aus. Wer nicht länger als 6 Stunden offline sein will, sollte die Anwesenheit seines Servers und die korrekten Grundfunktionen des Mailsystems und des Webservers automatisiert prüfen. (Das ist aber nicht Gegenstand dieses Artikels.)

  4. Man muß sehr achtgeben, daß man nicht durch einen unbedachten Schritt seinen Server außer Betrieb setzt. Fehler beim Konfigurieren des Paketfilters sind dafür bevorzugte Kandidaten. Wirklich ärgerlich ist es, wenn solche Fehlkonfigurationengleich nach dem Neustart wieder wirksam werden.

Als Betriebssystem empfehle ich Debian. Auf dem Schreibtischarbeitsplatz taugt es überhaupt nichts, die Debian-Leute haben bislang andere Prioritäten als die graphische Oberfläche und Treiberunterstützung. Für Debian spricht die konservative Entwicklungsphilosophie, die ich auch bei OpenBSD schätze, und das ausgefeilte Paketkonzept, das aber nicht RPM-kompatibel ist. Für Server ist Debian hervorragend.

Grundinstallation

Wir haben vom Provider einen SSH-Zugang mit Root-Paßwort bekommen. Darüber erfolgen die ersten Schritte. Unter Windows gibt es als SSH-Client das empfehlenswerte freie Programm "putty".

In Zukunft soll sich nur noch ein normaler User einloggen, und zwar ausschließlich über Protokollversion 2 der Secure Shell. Die Authentifizierung erfolgt auch nicht mehr über ein Paßwort, sondern durch Vorweisen des gültigen Schlüssels. Diese normale Nutzer wird dann Root durch das Kommando

$ su -

Nutzer

Zuerst wird ein normaler Nutzer angelegt. Das Root-Paßwort wird dabei auch gleich mit geändert.

$ groupadd -g 1000 mygroup
$ adduser --gid 1000 --uid 1000 myself
$ passwd myself
$ passwd root

Der Shell-Prompt wird mit einigen nützlichen Informationen versehen, die die Orientierung auf dem vollgepflasterten Bildschirm erlauben:

$ cd /root
$ vi .bash_profile
PATH=/usr/local/bin:/usr/bin:/bin
[ X$USER = Xroot ] && PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH
export PATH HOME TERM
umask 022
alias ll='ls -laF'
PS1A=`hostname|sed -e "s/\([^.]*\).*/\1/"`
PS1="$PS1A $USER "'`date +%H:%M` $PWD'
[ X$USER = Xroot ] && PS1="$PS1 # " || PS1="$PS1 $ "
$ cp .bash_profile ~myself
$ chown myself.mygroup ~myself/.bash_profile

SSH-Zugang

Zu putty gehört "puttygen", mit dem ein Schlüsselpaar generiert wird.

Um den Linux-Server auf SSH vorzubereiten, fügt man in dem SSH-Konfigurationsfile ein paar Zeilen ein bzw. ändert einige Zeilen:

$ vi /etc/ssh/sshd_config
Protocol 2
LoginGraceTime 120
PermitRootLogin no
StrictModes yes
AllowUsers myself
ClientAliveInterval 15
ClientAliveCountMax 3

Nur der Nutzer myself ist zugelassen. Für diesen muß noch etwas in seinem Heimatverzeichnis getan werden:

$ cd ~myself
$ mkdir .ssh
$ cd .ssh
$ vi authorized_keys
ssh-rsa AAAAdhjdnei487tzn?cuoc/hwgdhwgvjkh/IUZHGOIUUN/oiun897m095876ghm9gh395p086gNfbugbujzn87n98g
    ohnbIhiguo94c85moiubnmpo5ij3m*9hhm590ghpo5ibnm3pcv comment myself@mydomain.net

Die Zugriffsrechte sind wichtig:

$ chown myself.myself * .
$ chmod 600 *
$ chmod 700 .

Jetzt wird der neue SSH-Zugang durch myself mit öffentlichem Schlüssel getestet. Danach wird der Zugang zum Server nur noch für den Besitzer des richtigen Schlüssels erlaubt:

$ vi /etc/ssh/sshd_config
PasswordAuthentication no

Bevor das funktioniert hat, wird das aktuelle Putty-Terminalfenster nicht geschlossen. Wenn etwas schief läuft, kann man sich leicht aussperren und muß beim ISP um Reboot ersuchen oder gar eine Neuinstallation bezahlen.

Paketfilter

Als nächste dringende Sicherheitsmaßnahme werden Paketfilterregeln angelegt. Welche benötigt werden, hängt natürlich von den verwendeten Protokollen ab. In dem hier beschriebenen Einsatzszenario reicht folgendes:

$ vi /etc/iptables.active.sh
#!/bin/sh
iptables -F INPUT
iptables -F FORWARD
iptables -F OUTPUT
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp -m icmp --icmp-type 5 -j DROP
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp --dport 995 -j ACCEPT

sowie:

$ vi /etc/iptables.inactive.sh
#!/bin/sh
iptables -F INPUT
iptables -F FORWARD
iptables -F OUTPUT
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

Aktiviert wird das mit einer Reihe von Kommandos:

$ chmod 750 /etc/iptables.active.sh
$ /etc/iptables.active.sh
$ /etc/init.d/iptables save active
$ chmod 750 /etc/iptables.inactive.sh
$ /etc/iptables.inactive.sh
$ /etc/init.d/iptables save inactive
$ /etc/init.d/iptables start
$ cd /etc/rc2.d
$ ln -s ../init.d/iptables S95iptables

Achtung: Nie die iptables-Kommandos einzeln eingeben, sondern immer nur en bloc als Shellscript. Sonst hat man sich schnell ausgesperrt und ist auf die gute Laune des Providers angewiesen.

Überhaupt kann man sich leicht vertun bei Firewallregeln. Wer sich lieber gegen eigene Dummheit rückversichert, trägt in crontab ein regelmäßiges Rücksetzen der Firewallregeln auf einen sicheren Stand ein:

$ crontab -l
0    */6  *    *    *    /etc/init.d/iptables start 1>/dev/null 2>/dev/null

Damit wird alle 6 Stunden der Stand hergestellt, der mit /etc/init.d/iptables save active freigegeben wurde. Zwischendurch kann man mit neuen Regelsätzen experimentieren, legt seinen Server aber nur für maximal 6 Stunden lahm.

Zusatzpakete

Es ist an der Zeit, etwas Software nachzuinstallieren.

$ dselect

Es wird ausgewählt:

kernel-source-2.4.xx
less

Nach Auslösen des Installationsvorgangs wird möglicherweise eine größere Anzahl abhängiger Packages installiert. Das ist Sinn dieser Übung. Ansonsten brauchen wir die Kernelquellen in unserem Anwendungsfall nicht. Der Neubau eines Kernels ist auf einem Rechner, bei dem man keinen Zugang zur Konsole hat, ein unterhaltsames Abenteuer mit ungewissem Ausgang.

Es folgen im nächsten Durchgang weitere Softwarepakete:

$ dselect
ntp-refclock
openssl
postfix-tls
libsasl-digestmd5-plain
krb5-user
courier-pop-ssl
apache
spamassassin
procmail
fetchmail
vsftpd

Uhrzeit

Der Server sollte immer die korrekte Uhrzeit haben. Das ist, wie es sich für Server gehört, nicht die lokale Ortszeit oder gar eine Sommerzeit, sondern UTC. Die Einstellung erfolgt mit

$ tzconfig
...
UTC

und das Datum wird in der Form MMDDhhmm eingegeben.

$ date 12312359

Der NTP-Dämon sorgt für regelmäßige Synchronisation mit Timeservern im Internet.

$ vi /etc/ntp.conf
server ptbtime1.ptb.de version 3
server ptbtime2.ptb.de version 3
server ntps1-0.cs.tu-berlin.de version 3
server ntps1-0.uni-erlangen.de version 3
server ntp0.fau.de version 3
$ /etc/init.d/ntp restart

Sie können sich Ihre Lieblingsserver aussuchen.

Logging

Logging ist ein geeignetes Mittel, um die Gesundheit des Servers da draußen zu überwachen. Man kann lokal auf den Server loggen und regelmäßig nachsehen. Man kann auch auf einen Server loggen, der zuhause über eine dynamische IP-Adresse erreichbar ist.

Um die Logdaten nicht unverschlüsselt übertragen zu müssen, sollte manzwischen dem Heimatnetz und dem Dedicated Server einen Tunnel einrichten. Für sichere Tunnel gibt es mehrere Möglichkeiten; ich habe mich für Zebedee entschieden, weil es sehr leicht zu konfigurieren ist. Weiterhin muß das Standard-Syslog durch das flexiblere Syslog-ng ersetzt werden, das es als Debian-Paket gibt (mit dselect auswählen).

Zebedee wird übersetzt, wie in der Distribution angegeben. Sowohl auf dem Logserver (zuhause) als auch auf dem Logclient (dem Dedicated Server) wird dieselbe Steuerdatei erzeugt:

$ vi /etc/zebedee.sh
#!/bin/sh
trap "" HUP INT TERM
while true
do
  /usr/local/sbin/zebedee -f /etc/zebedee.conf 2>&1 | logger -t zebedee
  logger -t zebedee "/usr/local/sbin/zebedee exited, looping"
  sleep 10
done

Diese Steuerdatei wird über ein Init-Skript unter /etc/init.d als Hintergrund-Job gestartet (/etc/zebedee.sh &). Den Link unter /etc/rc2.d auf dieses Init-Skript nicht vergessen. Auf dem Logclient kommt folgende Steuerdatei hinzu:

$ vi /etc/zebedee.conf
server false
localsource true
serverhost beimir.dnsalias.net
tunnel 10514:beimir.dnsalias.net:514
ipmode both
logfile SYSLOG
detached false

... und auf dem Logserver (zuhause) diese:

$ vi /etc/zebedee.conf
server true
target localhost:514
ipmode both
logfile SYSLOG
detached false

Auf dem Logclient wird Syslog-ng so konfiguriert:

$ vi /etc/syslog-ng/syslog-ng.conf
source src { unix-dgram("/dev/log"); internal(); };
destination loghost { udp("127.0.0.1" port(10514)); };
log { source(src); destination(loghost); };

... und auf dem Logserver (zuhause) so:

$ vi /etc/syslog-ng/syslog-ng.conf
source src { unix-dgram("/dev/log"); internal(); udp(); };
destination messages { file("/var/log/messages" owner("root")
group("root") perm(0600)); };
log { source(src); destination(messages); };

Viel Spaß beim Kontrollieren des Logfiles. Sie werden sicher bald beginnen, die Filtermöglichkeiten von Syslog-ng zu erforschen.

Prinzipiell kann natürlich der Log-Port im Heimatnetz (hier: 10514) Ziel von DoS-Attacken oder versuchten Angriffen auf Zebedee werden. Immer schön wachsam bleiben.

Email

Sie betreiben Ihren Mailserver als vollwertigen SMTP-Relay. Freilich könnten Sie Ihre Post auch über den Mailserver der Telekom schicken. Aber die freie Wählbarkeit der Absenderadresse kostet extra. Und zumindest früher war nicht zu vermeiden, daß die Telekom Ihre T-Online-Kennung einfach mit in den Email-Header einfügte. Wir beugen uns keinem Diktat und haben ja schon einen Dedicated Server dafür bezahlt, autark sein zu dürfen.

Dieser Relay ist natürlich nur für Sie und andere authentifizierte Benutzer zugänglich. Sonst haben Spammer nach spätestens zwei Tagen das weit offene Scheunentor entdeckt, Ihre Domain gerät in Verruf, und Sie können sich damit unter anständigen Menschen nicht mehr sehen lassen. Also müssen Sie sich nicht nur dann Authentifizieren, wenn Sie Mails abrufen, sondern auch, wenn Sie senden wollen.

Weiter: Damit Emailinhalte und Paßworte nicht im Klartext durch das Netz geistern, wird jede Verbindung über SSL bzw. TLS verschlüsselt. Wenn Sie Outlook benutzen, brauchen Sie sich keine Sorgen zu machen, ob das alles auch von Ihrem Arbeitsplatz aus funktioniert: Outlook beherrscht Paßworte, Verschlüsselung etc.

Als SMTP-Server kommt hier Postfix zum Einsatz. Der POP3-Dämon ist Courier, das Ihnen auch mit minimalen Abwandlungen als IMAP-Server zur Verfügung stehen kann. Den sollten Sie aber nicht nutzen, denn man lagert keine größeren Mengen Post im feindlichen Internet.

Das Konzept externer und interner Server

Ich selbst betreibe zwei Mailserver: einen "draußen", der im Artikel "Kampf gegen Spam" detailliert beschrieben ist, und einen "drin" hinter der Firewall. Das Konzept ist aber auf den internen zweiten Mailserver nicht angewiesen. Man kann auf seinen Mailserver "draußen" auch durch die Firewall oder mit dem Notebook von irgendwo unterwegs zugreifen.

Mailserver Konfiguration

Der interne Mailserver ist allen Rechnern im Haus ohne besondere Sicherheitsmechanismen zugänglich. Gegenüber dem externen Mailserver tritt er als Client auf, d.h. der externe Mailserver ist für ihn ein Mailrelay. Der externe Mailserver vertraut dem internen, da dieser sich über einen registrierten SSL-Schlüssel ausweist (TLS-Authentifizierung). Alle fremden Nutzer des externen Mailservers greifen wie im oberen Bild gezeigt direkt auf den Server zu und müssen sich jeweils authentifizieren.

Der externe Mailserver

Lesen Sie hier die Beschreibung des externen Mailservers mit allen benötigten Konfigurationsdateien.

Es gibt übrigens eine Reihe verschiedener Speichermöglichkeit für die Informationen, die ein Mailserver braucht (Nutzernamen, Paßworte, Aliase, Mailboxnamen etc.). Ich habe in früheren Versionen dieses Artikels ein Verfahren beschrieben, das fast ausschließlich auf MySQL als Speichermedium setzte. Ich bin davon wieder abgekommen, da ich den Weg dann doch weniger komfortabel fand, als ich erwartet hatte. Ich bin wieder auf die einfachen Konfigurationsdateien umgestiegen und verwalte sie mit einem Script.

Der interne Mailserver

Wenn Sie einen internen Mailserver verwenden, müssen seine Einstellungen natürlich zu denen des externen passen. (Hier sind nur die Zeilen des Konfigurationsfiles gezeigt, die in diesem Zusammenhang interessant sind.)

$ vi /etc/postfix/main.cf
myhostname = mail.intra.mydomain.net
mydestination = intra.mydomain.net, mail.intra.mydomain.net, beimir.dnsalias.net,
localhost
    
# Hier wird die feste IP-Adresse unseres Mailservers in der DMZ eingetragen:
relayhost = nnn.nnn.nnn.nnn
mynetworks = 10.0.0.0/8, 127.0.0.0/8
local_recipient_maps =
luser_relay = spam@mail.intra.mydomain.net
    
smtp_use_tls        = yes
smtp_tls_key_file   = /usr/share/ssl/private/iserver.key
smtp_tls_cert_file  = /usr/share/ssl/certs/iserver.crt
smtp_tls_CAfile     = /usr/share/ssl/certs/ca.crt
smtp_tls_CApath     = /usr/share/ssl/certs
smtp_tls_loglevel   = 1
smtp_tls_per_site   = hash:/etc/postfix/tls_per_site
tls_random_source   = dev:/dev/urandom

Und schließlich:

$ vi /etc/postfix/ tls_per_site
mail.mydomain.net MUST_NOPEERMATCH
$ postmap hash:/etc/postfix/tls_per_site

Webserver

Zur Konfiguration des Webservers folgt hier nur ein kleiner Ausschnitt. Der Vorgang ist bei weitem nicht so fehlerträchtig wie die Einrichtung eines Mailservers.

Apache 2 kann ich noch nicht empfehlen.

$ vi /etc/apache/httpd.conf
...
 
NameVirtualHost www.mydomain.net
    
<VirtualHost www.mydomain.net>
    ServerName www.mydomain.net
    DocumentRoot /home/apache/html
    <Directory "/home/apache/html">
        Options FollowSymLinks ExecCGI
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
    </Directory>
    ServerAdmin webmaster@mydomain.net
    Alias /myself /home/myself/html
    <Directory /home/myself/html>
        Options FollowSymLinks ExecCGI
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>
    
<VirtualHost www.myself.mydomain.net>
    ServerName www.myself.mydomain.net
    DocumentRoot /home/myself/html
    <Directory "/home/myself/html">
        Options FollowSymLinks ExecCGI
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
    </Directory>
    ServerAdmin webmaster@mydomain.net
</VirtualHost>
< VirtualHost www.virtual.mydomain.net>
    ServerName www.virtual.mydomain.net
    DocumentRoot /home/virtual/html
    <Directory "/home/virtual/html">
        Options FollowSymLinks ExecCGI
        AllowOverride AuthConfig
        Order allow,deny
        Allow from all
    </Directory>
    ServerAdmin webmaster@virtual.mydomain.net
</VirtualHost>
$ mkdir /home/apache
$ mkdir /home/apache/html
$ mkdir /home/apache/cgi-bin
$ chown -R myself.www-data /home/apache
$ chmod -R 750 /home/apache
$ mkdir /home/myself/html
$ mkdir /home/myself/cgi-bin
$ chown -R myself.www-data /home/myself/html
$ chmod -R 750 /home/myself/html

Filetransfer

Filetransfer ist über das SSH-Protokoll mit SFTP möglich. Zu Putty gehört ein Kommandozeilen-Client. Für private Anwendung frei ist der sehr gute SSH Client von www.ssh.com in der älteren Version 3.2. Diese Filetransfers sind genauso sicher wie der Shellzugang über SSH.

Wer auf seinem Rechner noch andere Nutzer beherbergt, sollte ihnen keinesfalls Shellzugang zu dem Server gewähren. Diese Nutzer können ihre HTML-Seiten über ein normales FTP hochladen, wobei die Zugangsmöglichkeiten unbedingt auf das Homeverzeichnis des jeweiligen Nutzers beschränkt sein müssen. Zu empfehlen is vsftpd.

$ vi /etc/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
connect_from_port_20=YES
async_abor_enable=YES
ascii_upload_enable=YES
ascii_download_enable=YES
chroot_local_user=YES
text_userdb_names=YES
pasv_min_port=60020
pasv_max_port=60039
local_max_rate=8192

Schlußwort

Erwarten Sie nicht, daß es auf Anhieb funktioniert wie hier beschrieben. Wenn man einen Server konfiguriert, schreibt man sich nicht jeden Schritt parallel auf. Manches habe ich hier vielleicht vergessen zu erwähnen. Für Hinweise bin ich stets dankbar. Dankbar bin ich auch für jeden Kommentar "unnütz", es hilft mir aber noch mehr, wenn ich in wenigen Worten erfahre, wie ich es nützlicher machen könnte.

Viel Erfolg und viel Spaß.