Kategorie-Archive: Server & Hosting

Webhosting mit ACLs

Die bekannten Unix-Rechte 644 oder 755 mögen für das Hosting eines einzelnen Projekts oder mehrerer Projekte, auf die man Shell-Zugriff hat, ausreichen. Wenn man aber Usern anbietet, ihre Site zu hosten gelangt man damit schnell an einen Punkt, wo diese Rechte einfach nicht mehr ausreichen.

Wenn zum Beispiel das CMS Joomla eine Komponente oder ein Modul über das Webinterface installiert bekommt so haben die Dateien, die installiert werden, als „Owner“ den User, unter dem der Webserver läuft (meist www-data). Andererseits hat ein manuell über FTP eingespieltes Template als „Owner“ den Hosting-Nutzer. Auf den meisten Systemen kommt dazu eine default-umask von 022, die allen neu erstellten Dateien ausschließlich Schreibrechte für den Ersteller/Besitzer der Datei zugesteht. Das könnte man zwar theoretisch ändern, würde damit aber die Sicherheit bei mehreren Nutzern kompromittieren (z.B. indem man die Nutzer und www-data einer Gruppe zuordnet, die Schreibrechte hat).

Alles in allem eine sehr unbefriedigende Lösung. Aber es gibt Abhilfe: ACLs (Access Control Lists) erlauben die feingranulare Einstellung der Rechte auf Nutzerebene wie auch in Gruppen. Mit ihnen lassen sich Konstrukte schaffen wie „www-data und Hostingnutzer haben rwx-Rechte“ – und das auch für neu erstellte Dateien. Doch der Reihe nach.

Für die Nutzung von ACLs unter Ubuntu/Debian braucht es einen einigermaßen modernen Kernel (>2.5.46, ob man diesen Kernel von 2002 noch „einigermaßen modern“ nennen kann lasse ich jetzt mal dahingestellt ;)) und die Partitionen müssen mit ext2 oder höher formatiert sein. In der /etc/fstab muss bei den Mountoptions aller Partitionen, mit denen ACLs genutzt werden sollen, der Parameter acl hinzugefügt werden, z.B.:

1
2
3
4
5
6
7
# /etc/fstab: static file system information.
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
proc            /proc           proc    defaults        0       0
UUID=c1234f7f-fb32-4199-342a-4a12342f9a9d       /               ext3    defaults,usrquota,acl   0       1
UUID=f12349d1-d7e1-4ce5-4f3w-ddf971234b7       /boot           ext2    defaults        0       2
UUID=a1234b2b-b6bb-4572-33df-9351234335a0       none            swap    sw              0       0

Für die Bootpartition und die Swap-Partition brauchen wir natürlich keine ACLs, daher erfolgt der Eintrag nur auf der ersten Festplatte. Nach einer Änderung an der fstab muss das System neu gestartet werden um die Mountoptions zu übernehmen. Alternativ kann man natürlich auch den entsprechenden Mountpoint aushängen und manuell mit dem zusätzlichen Parameter neu mounten.

Als nächstes gehen wir in das Verzeichnis, welches die neuen ACLs erhalten soll und vergeben sie entsprechend unseren Wünschen:

1
2
3
cd /var/www/vhosts/username/
setfacl -R -m u::rwX,u:www-data:rwX,u:username:rwX .
setfacl -R -d -m u::rwX,u:www-data:rwX,u:username:rwX .

Die Zeile 2 des Codeschnipsels sorgt dafür, dass die User www-data und username Lese-, Schreib- und Ausführungsrechte für bereits bestehende Dateien/Ordner im Verzeichnis und allen Unterverzeichnissen erhalten. Das groß geschriebene „X“ sorgt dabei für eine automatische Berechnung der Maske, ohne die es zu Einschränkungen im Zugriff kommen kann. Zeile 3 macht das Gleiche wie Zeile 2, nur für neu erstellte Objekte (Parameter d = default). Mit Hilfe dieses Konstrukts hat man eine Umgebung geschaffen, in der der Nutzer sich mit FTP und PHP-Fileuploads austoben kann und doch die Sicherheit des Systems gewahrt bleibt. Zugleich haben andere Nutzer nach wie vor keinen Zugriff auf die Dateien und Ordner von Benutzer username.

Für den „Hausgebrauch“ reichen diese Befehle schon aus, um ein komfortables Arbeiten zu ermöglichen. Wer aber noch mehr erfahren möchte, dem sei die Seite über ACLs im Ubuntu-Wiki empfohlen. Dort wird u.a. ausführlich erklärt, wie man mit Gruppenrechten hantiert, wie man erstellte ACLs wieder los wird und wie man ein Backup seiner Listen anlegen kann.

Postfix + Courier unter Debian/Ubuntu oder: einen Mailserver aufsetzen

Vor einigen Tagen habe ich mein Ubuntu-System wegen der vielen Neuerungen und Security-Updates auf die Version 10.04 (Lucid Lynx) gebracht. Vorher natürlich ein Vollbackup erstellt (stolze 16 GB, wusste garnicht dass so viel drauf ist *g*), aber glücklicherweise nicht benötigt. Das Upgrade ging einfach und schnell, ein paar Fragen zu Config-Dateien waren schnell beantwortet und nach einem Neustart mit frischem Kernel 2.6.32-22 lief auf den ersten Blick alles super. Auf den zweiten Blick dann ein (kleiner) Schock: Plesk ging nicht mehr. Es war garnicht mehr installiert. Auf der Website von Parallels findet sich nur der Hinweis, dass maximal Ubuntu 8.04 unterstützt wird (nicht mal 9.10 – schwach). Na ja im Grunde genommen waren mir Systeme wie Plesk schon immer suspekt, man hat manchmal mehr Ärger damit als Nutzen davon und so bin ich nicht zurück zu 8.04 gegangen sondern habe im Internet gesucht wie ich am besten einen Mailserver aufsetze – denn der funktionierte nichtmehr.

Eigentlich wollte ich ja das Courier-Gesamtpaket courier-mta + courier-pop und courier-imap einsetzen. Nach langem Herumprobieren inklusive zu Rate ziehen der Mailingliste von Courier (courier-users) musste ich aber leider zum Schluss kommen, dass die zur Zeit im Lucid Lynx vorhandene Version der courier-mta wohl einen Bug aufweist, der die MTA nicht mit dem Authentifizierungsdaemon kommunizieren lässt. So bekam ich immer beim Eingehen einer Mail den Fehler

courieresmtpd: authdaemon: s_connect() failed: Permission denied

Nachdem ich diesen Fehler also nicht lösen konnte (sogar die selbst kompilierte Variante bockte mit dem gleichen Fehler rum) habe ich mich schweren Herzens (ich hasse ungelöste Probleme^^) entschieden, Postfix als MTA einzusetzen und Courier für den IMAP- und POP-Zugriff.

 

Zuallererst müssen natürlich die erforderlichen Programme installiert werden (als root):

1
apt-get install postfix courier-authdaemon courier-authlib courier-authlib-userdb courier-base courier-imap courier-imap-ssl courier-pop courier-pop-ssl sasl2-bin libsasl2-2 libsasl2-modules

Bei der Installation von Postfix wählt man als Betriebsmodus Internet-Site aus.

adduser vmail einen neuen Benutzer an. Dabei wird auch ein Nutzerverzeichnis /home/vmail angelegt, in dem später alle Mails gespeichert werden. Die User- und Gruppenid merken wir uns für später. Jetzt wechseln wir zu dem angelegten Nutzer vmail, z.B. mit su vmail --preserve-environment (preserve-environment verhindert, dass die default-shell des Nutzers vmail zum Einsatz kommt, die ist normalerweise nämlich nicht was wir wollen). Als User vmail erstellen wir jetzt die Unterverzeichnisse für die einzelnen Domains und Nutzer, also z.B. für 2 Nutzer auf the-enlightened.de:

1
2
3
4
5
cd /home/vmail
mkdir -p the-enlightened.de/amras
maildirmake the-enlightened.de/amras/Maildir
mkdir -p the-enlightened.de/aerith
maildirmake the-enlightened.de/aerith/Maildir

Als Nächses kommt die Postfix-Config dran. Dafür muss man wieder als root angemeldet sein (neues Terminal oder exit als user vmail). Die Config befindet sich in /etc/postfix/main.cf. Hier muss überprüft werden, dass myhostname auf den Rechnernamen gesetzt ist, ansonsten muss das nachgeholt werden. Das Feld mydestination muss meist nicht geändert werden, hier sollten localhost und ebenfalls der Rechnername eingetragen sein. Schlussendlich sollte inet_interfaces auf all stehen, aber das sollte ebenfalls bereits so sein. Wir springen ans Ende des file und fügen folgende Zeilen ein (die Domains sowie die uid und die gid [die wir uns ja gemerkt haben] sind natürlich entsprechend anzupassen):

1
2
3
4
5
6
7
8
9
10
11
12
13
#virtual domains & smtp auth
virtual_mailbox_domains = the-enlightened.de domain2.tld domain3.tld
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 100
virtual_uid_maps = static:1006
virtual_gid_maps = static:1001
virtual_alias_maps = hash:/etc/postfix/virtual          
smtpd_sasl_path = smtpd
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous 
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options

Dann abspeichern und die in der config gerade angebenen files erzeugen:

1
2
touch /etc/postfix/vmailbox
touch /etc/postfix/virtual

Jetzt wird /etc/postfix/vmailbox editiert. Für jede Adresse wird die virtuelle Mailbox, in dem die Mails später landen sollen, angegeben, bei mir also z.B.

1
2
amras@the-enlightened.de        the-enlightened.de/amras/Maildir/
aerith@the-enlightened.de       the-enlightened.de/aerith/Maildir/

Wichtig ist hier der abschließende Slash, dadurch wird Postfix veranlasst, die Maildir-Struktur statt seiner eigenen zu benutzen. Die Angabe erfolgt also als Mailadresse + Leerzeichen/Tab + Pfad zum Maildir unter /home/vmail. Jetzt speichern und folgende Befehle ausführen:

1
2
3
postmap /etc/postfix/virtual
postmap /etc/postfix/vmailbox 
/etc/init.d/postfix reload

Ankommende Mails werden jetzt schonmal richtig einsortiert. Kommen wir also zum 2. Teil des Tutorials, dem Zugriff auf die Mails via Courier.

 

Hier kommen zuerst die Nutzerpasswörter an die Reihe. Dafür muss man weiter als root angemeldet sein. Wir ändern den Eintrag authmodulelist in /etc/courier/authdaemonrc auf
authmodulelist="authuserdb"

und legen mittels der folgenden Befehle die Nutzerpasswörter an:

1
2
3
4
5
6
7
8
9
userdbpw -md5 | userdb -f /etc/courier/userdb/the-enlightened.de amras@the-enlightened.de set systempw
(Passwort 2x eingeben)
userdb -f /etc/courier/userdb/the-enlightened.de amras@the-enlightened.de set home=/home/vmail/the-enlightened.de/amras/ gid=1001 uid=1006
 
userdbpw -md5 | userdb -f /etc/courier/userdb/the-enlightened.de aerith@the-enlightened.de set systempw
(Passwort 2x eingeben)
userdb -f /etc/courier/userdb/the-enlightened.de aerith@the-enlightened.de set home=/home/vmail/the-enlightened.de/aerith/ gid=1001 uid=1006
 
makeuserdb

Nach einem Neustart von courier-authdaemon (kA ob das nötig ist, schädlich ist es aber keinesfalls)
/etc/init.d/courier-authdaemon restart
können sich die eingetragenen Nutzer per POP oder IMAP (ggf. mit SSL) anmelden.

Um Mails versenden zu können (nicht von localhost sondern mit Anmeldung) erfordert es ein paar weitere Schritte. So muss die Datei /etc/postfix/master.cf editiert werden (als root). Hier wird beim ersten Eintrag (smtp) für den Parameter chroot ein „n“ festgelegt. Mit der chrooted-Umgebung habe ich es nach unzähligen Versuchen nämlich nicht zum Laufen bekommen.

1
2
3
4
5
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd

Als finaler Schritt editieren wir nun die /etc/postfix/sasl/smtpd.conf wie folgt:

1
2
3
4
pwcheck_method: authdaemond
mech_list: PLAIN LOGIN
authdaemond_path: /var/run/courier/authdaemon/socket
#autotransition: true

autotransition:true wird meiner Erfahrung nach nur bei der Benutzung von saslauthd benötigt, authdaemond kommt ohne aus. Bei wem es nicht funktioniert möge trotzdem den Parameter mal testweise anstellen (Mailserver scheinen die verschiedensten Macken zu haben, die sie nicht-deterministisch auf diveren Konfigurationen behindern).

Nach einem Neustart von Postfix und ggf. dem Start von courier-authdaemon via /etc/init.d/courier-authdaemon start sollte der Mailserver nun voll funktionstüchtig sein.

VPN-Tunnel mit pptpd

Wenn man in öffentlichen, nicht verschlüsselten Netzwerken unterwegs ist ist es immer eine gute Idee, den gesamten Internetverkehr zu verschlüsseln. Und wenn man schonmal einen Rootserver hat…

Also habe ich mich entschieden pptpd aufzusetzen, weil es nicht nur von Windows nativ unterstützt wird sondern auch von fast allen modernen Mobilgeräten und auch von Linux. Die Konfiguration ist eigentlich sehr simpel, der „Trick-Teil“ kommt am Ende. Für den muss ich mich bei „Lord Gurke“ aus dem Serversupportforum bedanken.

Also, los gehts:

apt-get install pptpd

Das war schon alles, was man installieren muss. Nun folgt die Config. Zunächst kommt /etc/pptpd.conf dran. Hier werden u.a. die IP-Adressen für das neue Netzwerk bestimmt.

1
2
3
4
option /etc/ppp/pptpd-options
logwtmp
localip 192.168.1.1
remoteip 192.168.1.200-253

Das heißt im Klartext, dass mein Rootserver die IP 192.168.1.1 erhält und alle Clients automatisch Adressen von 200 bis 253 zugewiesen bekommen. Sehr komfortabel 🙂

Als nächstes wird /etc/ppp/pptpd-options editiert:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
name pptpd
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
require-mppe-128
ms-dns 192.168.1.1
proxyarp
nodefaultroute
mtu 1490
mru 1490
noipx
lock
nobsdcomp

Neben einigen für das System wichtigen Einstellungen wird hier eingestellt, dass der Rootserver seine Adresse als DNS-Server an die Clients pusht und dass nur das (noch) als sicher geltende MS-CHAPv2 als Authentifizierungsverfahren zum Einsatz kommt.

Die Benutzerdaten liegen bei pptpd leider unverschlüsselt im Keyfile, insofern sollte man vorsichtshalber einen zufälligen Schlüssel nehmen, den man sonst nirgends verwendet. Das Keyfile ist /etc/ppp/chap-secrets und wie folgt aufgebaut:

Username<TAB>*<TAB>Passwort<TAB>*
Das letzte Sternchen kann man dabei auch durch eine IP-Adresse oder einen IP-Adressbereich ersetzen, dann kann man nur aus diesem Netz bzw. von dieser IP auf den Server zugreifen.

Soa, jetzt zum „Trick-Teil“ 😉
PPTPD leitet in der bis jetzt geschaffenen Umgebung keine Internetanfragen weiter. Dazu muss über iproute erst noch eine Route eingerichtet werden:

1
2
3
iptables -A FORWARD -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -P OUTPUT ACCEPT

Das packt man am besten direkt in ein rc-Script damit es beim Serverneustart geladen wird.
Als letztes dann noch die /etc/sysctl.conf bearbeitet werden und die Zeile

net.ipv4.ip_forward = 1

von ihrer Kommentar-Raute befreit werden. Und fertig.

Trafficbeschränkung mit mod_cband unter Debian/Ubuntu

Jeder, der auf seiner Website Downloads anbieten möchte kommt irgendwann zu der Frage „Wie beschränke ich den Traffic“. In Zeiten der Flatrates denk man auf Userseite nur selten an Traffic-Limits. Doch viele Server und vServer haben noch begrenzten Traffic. Und selbst wenn nicht möchte man vielleicht die gleichzeitigen Downloads beschränken oder verhindern, dass Download-Traffic andere (interaktive) Inhalte ausbremst.

Hier kann das Apache-Modul mod_cband (http://codee.pl/cband.html) zum Einsatz kommen. Es ist schlank, sehr performant und bietet eigentlich alles, was man braucht (u.a. VHost-abhängige Limitierung, Limit pro User, Limitierung maximal zugelassener Connections, Ausbremsen oder Umleiten nach Erreichen des Limits etc.).

Um mod_cband zu installieren geht man wie folgt vor:

Als Erstes wird das Paket apache2-prefork-dev (und ggf. noch weitere benötigte Pakete) installiert:

1
apt-get install apache2-prefork-dev gcc build-essential

Danach holt man sich von der Entwicklerwebsite die neueste Version (zzT. 0.9.7.5) von mod_cband, entpackt das heruntergeladene Archiv in ein beliebiges Verzeichnis und führt configure aus:

1
2
3
4
wget http://cband.linux.pl/download/mod-cband-0.9.7.5.tgz
tar xf mod-cband-0.9.7.5.tgz
cd mod-cband-0.9.7.5
./configure

Jetzt muss man eine Änderung am Makefile vornehmen, wenn man ein 64-Bit-System hat. Die Zeile
APXS_OPTS=-Wc,-Wall -Wc,-DDST_CLASS=3
muss um den Parameter lm erweitert werden:
APXS_OPTS=-lm -Wc,-Wall -Wc,-DDST_CLASS=3

Speichern und das Modul kompilieren und installieren:
make && make install

Wenn alles glatt gegangen ist hat man jetzt in /usr/lib/apache2/modules/ eine funktionsfähige mod_cband.so liegen. Diese muss nun noch geladen werden. Dazu nimmt man sich /etc/apache2/httpd.conf oder die /etc/apache2/apache2.conf vor und fügt folgende Zeilen ein:

1
2
3
LoadModule cband_module /usr/lib/apache2/modules/mod_cband.so
CBandScoreFlushPeriod 1
CBandRandomPulse On

Die Config-Parameter sind übrigens für eine gute Performace wichtig. Wer sich gut auskennt kann natürlich auch die Verzeichnisse mods-available und mods-enabled nutzen 😉

 

Als Letztes kommen wir nun zu den Beschränkungseinstellungen selbst. Diese kann man sowohl serverübergreifend (in httpd.conf oder apache2.conf) als auch VirtualHost-basiert vornehmen. Ich habe mich für Variante 2 entschieden, weil ich für meine Downloads die extra Subdomain downloads eingerichtet habe.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<VirtualHost *:80>
  ServerName downloads.yourdomain.com
  ServerAdmin webmaster@yourdomain.com
  DocumentRoot /var/www/downloads
  CBandSpeed 50Mbps 10 30
  CBandLimit 100G
  CBandExceededSpeed 5Mbps 5 15
  CBandScoreboard /var/run/yourdomain.scoreboard
  CBandPeriod 4W
  <Location /cband-status>
    SetHandler cband-status
  </Location>
  <Location /cband-status-me>
    SetHandler cband-status-me
  </Location>
</VirtualHost>

Mit diesen Einstellungen beschränkt man das Download-Volumen auf 100GByte in 4 Wochen. Der Speed liegt für alle Downloads zusammen bei 50 MBit/s, es sind 10 Requests pro Sekunde und 30 offene Verbindungen erlaubt. Falls das Volumen überschritten wird drosselt mod_cband den Speed auf 5 MBit/s, die maximal offenen Verbindungen auf 15 und die Requests pro Sekunde auf 5. Die „History“-Daten werden unter /var/run/yourdomain.scoreboard (diese Datei muss mit touch angelegt werden!) gespeichert. Unter /cband-status und /cband-status-me können Server- bzw. Userstatisikdaten abgerufen werden.

Alle verfügbaren Optionen listet http://codee.pl/cband_documentation.html auf, zusammen bilden sie einen Pool, der für fast jede Serversitaution die richtigen Konfiguration ermöglichen sollte.

mod_rewrite für ein „MVC“-ähnliches Verhalten

mod_rewrite sollte jedem, der schon etwas Erfahrung im Bereich Webprogrammierung hat, ein Begriff sein. Es wird häuftig verwendet, um „SEO-friendly“ – also suchmaschienenoptimierte – URLs für dynamische Websites zu erzeugen. Auch das MVC-Modell sollte als geläufiges Entwurfsmuster bekannt sein. Nun braucht man aber nicht bei jedem Projekt MVC, denn kleine Projekte werden dadurch schnell sperrig; oft reicht auch einfach ein Umschreiben auf bestimmte URLs und die Verwendung einer Template-Engine. Leider konnte ich nirgends im Web ein Beispiel finden wie man jetzt genau http://domain.com/user/add in http://domain.com/user.php?action=add umschreibt.

Daher nun hier mein Bespiel einer .htaccess, die genau das ermöglicht:

1
2
3
4
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule   ^([^/]+)/?([^/]*)/?    /$1.php?action=$2

Die RewriteCond verhindert hier, dass Dateien, die wirklich über diese URL erreichbar sind, ebenfalls umgeschrieben werden (wäre schlecht für Bilder, CSS usw.). Wenn man das Muster ([^/]*)/? wiederholt anhängt kann das genutzt werden, um noch tiefere Pfade in weitere Parameter umzusetzen, z.B. würde

1
2
3
4
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule   ^([^/]+)/?([^/]*)/?([^/]*)/?    /$1.php?action=$2&param=$3

dafür sorgen, dass man auch http://domain.com/user/view/45 in http://domain.com/user.php?action=view¶m=45 umsetzen kann. So sind beliebige Pfadtiefen nutzbar.

Zu beachten ist, dass man im verarbeitenden Script die Parameter in $_GET nicht auf Existenz sondern mit Hilfe der Funktion empty() testen sollte, da automatisch leere Strings als Parameter übergeben werden falls der Pfad nicht die maximale Tiefe erreicht.

Server via VNC einfach fernsteuern (Debian)

VNC ist vielen Admins bekannt – doch meist als zu sperrige ressourcenfressende Lösung angesehen. Zudem hängt VNC der Ruf an, schwer einzurichten zu sein. Dass das nicht so sein muss möchte ich mit diesem kleinen Tutorial zeigen. Das Tutorial ist für Debian, funktioniert aber natürlich wie gewohnt auf allen Debian-Derivaten und mit Nutzung der entsprechenden Paketmanager wahrscheinlich auch auf anderen Linux-Systemen.

Das Tool der Wahl für Debian heißt VNC4Server, es benötigt im Gegensatz zu den meisten anderen VNC-Servern kein installiertes X-System! Neben dem VNC-Server wird natürlich auch noch ein Window-Manager benötigt. Ich habe mich hier der Einfachheit halber und weil es sehr ressourcenschonend ist für Fluxbox entschieden.

Die benötigten Pakete installiert man (als root) also mit

1
apt-get install vnc4server fluxbox

Danach sollte man den root-Account wieder einmotten und per vnc4passwd ein Passwort für die Verbindung vergeben.
Achtung: die Verbindung ist von Haus aus trotzdem nicht verschlüsselt. Dafür nutzen wir später einen SSH-Tunnel. Daher im Startbefehl auch der Parameter localhost – damit wir uns nur per Tunnel verbinden können 😉

Das Setzen des Passworts sollte bereits einen Ordner „.vnc“ (per default ist dieser unsichtbar) im home-Ordner des Nutzers angelegt haben. Dort hinein kommt eine Datei mit dem Namen „xstartup“ und folgendem Inhalt:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/sh
 
# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc
 
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#twm &
fluxbox &

Das Script wird automatisch geladen sobald VNC4Server gestartet wird und sorgt dafür, dass fluxbox und ein xterm-Fenster zur Verfügung stehen. Natürlich kann man hier auch direkt beliebige weitere Programme starten lassen. Das Abspeichern der Datei „xstartup“ nicht vergessen. Danach noch das executable-Recht vergeben:
chmod +x xstartup

Den Server können wir nun mittels

1
vnc4server -geometry 1024x768 -depth 24 -name "MyDesktop" -localhost

starten, die Startparameter sind selbsterklärend. Eine hohe Auflösung und Farbtiefe heißt in jedem Fall natürlich auch höherer Bandbreitenverbrauch. Mit dem obrigen Parameter -localhost wartet VNC4Server auf Verbindungen nur von der lokalen Maschine und zwar auf dem Port 5900+DisplayNummer. Das bedeutet im Normalfall wird das Programm einfach auf 5901 lauschen.

Über SSH können wir uns jetzt mit dem Server verbinden:

unter Linux:
vncviewer -via user@host localhost:0
host steht dabei für die IP-Adresse oder den Hostnamen des Servers, user für den Benutzernamen, mit dem die (SSH-)Anmeldung auf dem Server erfolgen soll.

unter Windows:
Hier muss man zunächst z.B. per Putty einen SSH-Tunnel anlegen (eine Anleitung findet sich zum Beispiel auf dieser Website SSH-Tunneling auf Windows-Computern unter dem Punkt „Einrichtung auf Client-Seite“) und sich dann z.B. mit der kostenlosen VNC Viewer Free Edition 4.1 for Windows zu 127.0.0.1:5901 verbinden.

Apache mit SNI aufsetzen (Debian)

HTTPS ist schön und gut – solange man richtig kräftig dafür zahlt. Denn kostenlose Zertifikate (z.b. bei StartSSL) gibt es nur für eine Domain, Wildcard- oder Multi-Domain-Zertifikate kosten hingegen richtig viel Geld. Nun ist es aber so, dass man eventuell mehrere Domains mit unterschiedlichen Zertifikaten (soll ja kostenlos bleiben) auf einer IP nutzen möchte. Bis vor ein paar Jahren wäre das ein hoffnungsloses Unterfangen gewesen, da bei SSL normalerweise alles außer der IP verschlüsselt übertragen wird, d.h. auch der „Host“-Header, den der Client mit überträgt. Ohne diesen Header ist es dem Server nicht möglich, ein Request einer bestimmten Domain zuzuordnen. Er muss also erst das zur IP gehörende Zertifikat nutzen, um an den verchlüsselten Host-Eintrag zu gelangen. Ergo nur 1 Zertifikat pro IP.

Die Lösung dieses Problems heißt SNI (Server Name Indication) und wird seit ein paar Jahren von allen gängigen Browsern unterstützt:

  • Mozilla Firefox 2.0+
  • Opera 8.0+ (TLS 1.1 muss aktiviert sein)
  • Internet Explorer 7+ (Windows Vista oder neuer)
  • Google Chrome (Windows Vista oder neuer)
  • Safari Safari 3.2.1+ auf Mac OS X 10.5.6+ und Windows (Windows Vista oder neuer)

Durch SNI wird der gewünschte Host als „server_name“-Parameter bereits beim Verbinungsaufbau übergeben – keine Probleme bei der Zuordnung mehr. Das klingt an sich sehr gut, also habe ich mich auf die Suche nach einer Anleitung gemacht und musste feststellen, dass mein Debian Etch nicht die nötige OpenSSL-Version (mindestens 0.9.8f) installiert hat. Aber da gibt es ja noch mod_gnutls, damit soll es ohne Apache oder OpenSSL neu zu kompilieren gehen. Nachdem ich alles eingerichtet hatte dann die Enttäuschung: mod_gnutls funktioniert zwar aber nicht mit den Zertifikaten von StartCom, weil die nämlich „intermediate“ CA-Zertifikate benötigen um verifiziert werden zu können (und mod_gnutls das nicht unterstützt). Somit zeigte er mir immer eine Warnung nach dem Muster „unknown certificate issuer“ an. Toll, das hätte ich auch mit einem selbst signierten Zertifikat hinbekommen.
Nach Überwindung meiner Enttäuschung dachte ich mir dann: Na ja was solls, dist-upgrade wollte ich eh schon lange mal machen also ab zu lenny. Halt… zunächst natürlich noch ein Backup erstellt für den Fall der Fälle.

Alle folgenden Befehle werden als root ausgeführt. Also entweder als root einloggen oder (besser) per su bzw. sudo –s zum root werden.

Danach die /etc/apt/sources.list.d/debian.list bearbeiten:

1
2
3
4
5
6
7
# new lenny packages.
deb http://ftp2.de.debian.org/debian/ lenny main contrib non-free
deb http://security.debian.org/ lenny/updates main contrib non-free
 
# source packages.
deb-src http://ftp2.de.debian.org/debian/ lenny main contrib non-free
deb-src http://security.debian.org/ lenny/updates main contrib non-free

Speichern und

1
2
apt-get update
apt-get dist-upgrade

ausführen. Die Installation hat bei meinem vServer etwa 10 Minuten gedauert. Je nach Anzahl und Umfang der installierten Pakete kann es aber durchaus länger dauern. Die jeweiligen Default-Werte (N) für das beibehalten der Konfiguration sind eigentlich optimal. Ich konnte auch kein Programm feststellen, das ohne neue Config nicht mehr arbeitet. Das wa’s eigentlich schon, jetzt ist aus Etch Lenny geworden und OpenSSL liegt in Version 0.9.8g (Stand: 27.12.09) vor. Damit unterstützt es jetzt von Haus aus SNI. Leider unterstützt Apache in der von Debian Lenny standardmäßig installierten (und wirklich alten!) Version es aber noch nicht. Daher muss hier nochmal Hand angelegt werden. Die Anleitung dazu habe ich bei blog.mellenthin.de gefunden und nur leicht modifiziert, da bereits Apache 2.2.14-4 vorliegt. Die gerade aktuelle Version findet sich immer unter http://packages.debian.org/source/squeeze/apache2 und kann dort auch herunter geladen werden. Zunächst brauchen wir aber noch ein paar Tools (falls sie noch nicht installiert sind):

1
2
apt-get install dpkg-dev build-essential fakeroot libcap2-dev autoconf
apt-get build-dep apache2

Dann den Sourcecode laden:

1
2
3
wget http://ftp.de.debian.org/debian/pool/main/a/apache2/apache2_2.2.14-4.dsc
wget http://ftp.de.debian.org/debian/pool/main/a/apache2/apache2_2.2.14.orig.tar.gz
wget http://ftp.de.debian.org/debian/pool/main/a/apache2/apache2_2.2.14-4.diff.gz

mit dem Befehl

1
dpkg-source -x apache2_2.2.14-4.dsc

wird der Quellcode entpackt und mit

1
2
cd apache2-2.2.14/
dpkg-buildpackage -us -uc -rfakeroot

wird der Kompilier-Vorgang eingeleitet. Der Vorgang selbst kann lange dauern, bei mir waren es über 20 Minuten. Warnings während dieses Prozesses sind normal und können ignoriert werden.
Die fertigen Pakete liegen dann ein Verzeichnis höher zur Installation bereit:

1
2
cd ..
dpkg -i apache2_2.2.14-4_amd64.deb apache2.2-bin_2.2.14-4_amd64.deb apache2.2-common_2.2.14-4_amd64.deb apache2-mpm-event_2.2.14-4_amd64.deb apache2-mpm-itk_2.2.14-4_amd64.deb apache2-mpm-worker_2.2.14-4_amd64.deb apache2-mpm-prefork_2.2.14-4_amd64.deb apache2-suexec_2.2.14-4_amd64.deb apache2-utils_2.2.14-4_amd64.deb

Je nach verwendeter Version und Architektur (x32 oder x64) heißen die Pakete anders, der Namensteil vorn bleibt aber immer gleich. Bei der Installation werden die bestehenden Pakete von Apache durch die neuen 2.2.14er ersetzt, Apache wird dadurch SNI-fähig gemacht.

Jetzt ist es Zeit, den private key und die Zertifikatsanforderung (CSR) zu erzeugen. Das geht ganz einfach und schnell mit openssl:

[Update 2012: StartSSL verlangt nun eine Mindestschlüssellänge von 2048 Bit]

1
2
3
openssl genrsa -des3 2048 > ssl.key.org (hier ist ein Passwort erforderlich)
openssl req -new -key ./ssl.key > ssl.csr
openssl rsa -in ssl.key.org -out ssl.key

Der letzte Befehl schreibt den ungeschützten private key in die Datei ssl.key, das ist notwendig da sonst bei jedem Apache-Start (auch nach Server-Neustart) die Passwortabfrage kommt und der httpd so lange hängt. Daher immer gut auf den ssl.key aufpassen und am besten mittels

1
chmod 400 ssl.key

nur für den root-Account lesbar machen. Den ssl.csr nimmt man dann und übergibt ihn der CA seiner Wahl (bei mir: StartSSL). Diese erzeugt daraus dann die benötigte ssl.crt, welche man ebenfalls auf seinen Server hochladen muss. Damit ist das Zertifikat an sich bereit, nun muss Apache noch konfiguriert werden, es auch zu verwenden.

Falls die Direktive „NameVirtualHost“ noch nicht in der Apache-Config gesetzt ist muss dies nun nachgeholt werden (z.B. in der httpd.conf):

1
NameVirtualHost 196.17.23.52:443

Um zu verhindern, dass nicht-SSI-fähige Browser nur ein 403: forbidden angezeigt bekommen (stattdessen sollte man sie freundlich darauf hinweisen, auch im Interesse ihrer eigenen Sicherheit einen neueren Browser zu verwenden) erstellt man folgenden Eintrag (am besten wieder in der httpd.conf oder in der apache2.conf):

1
SSLStrictSNIVHostCheck off
1
2
3
4
5
6
7
8
<VirtualHost 196.17.23.52:443>
  # Because this virtual host is defined first, it will
  # be used as the default if the hostname is not received
  # in the SSL handshake, e.g. if the browser doesn't support
  # SNI.
  DocumentRoot /www/error/use_new_browser_html
  ServerName www.serverone.tld
</VirtualHost>

Für die einzelnen Adressen, die man jetzt per SSL zugreifbar machen möchte wird nun jeweils ein VirtualHost-Eintrag erstellt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<VirtualHost 196.17.23.52:443>
   ServerName serverone.tld:443
   DocumentRoot /var/www/vhosts/serverone
   #ErrorLog /usr/local/apache/logs/error_log
   #TransferLog /usr/local/apache/logs/access_log
   SSLEngine on
   SSLProtocol all -SSLv2
   SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM
   SSLCertificateFile /usr/local/apache/conf/ssl.crt
   SSLCertificateKeyFile /usr/local/apache/conf/ssl.key
   SSLCertificateChainFile /usr/local/apache/conf/sub.class1.server.ca.pem
   SSLCACertificateFile /usr/local/apache/conf/ca.pem
   SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
   #CustomLog /usr/local/apache/logs/ssl_request_log \
   #   "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

Für die Nutzer von ACP-Oberflächen wie z.B. Plesk ergibt sich hier eine Besonderheit. Die Admin-Systeme überschreiben nämlich gern ihre eigenen Dateien. Bei Plesk werden die Einstellungen für VirtualHosts z.B. in der /var/www/vhosts/serverone/conf/httpd.include liegen. Diese wird aber regelmäßig überschrieben. Als info steht dort, wo man seine Config hinspeichern muss, damit sie dauerhaft erhalten bleibt. Leider kann man dann nur ausgewählte Direktiven setzen (z.B. php-flags), keine vollständigen Einträge (dazu steht übrigens nichts im Handbuch). Daher legt man am besten für jeden zu erstellenden VirtualHost eine nameDesHosts.conf in /etc/apache2/conf.d/ an oder nutzt wieder die httpd.conf/apache2.conf, wobei die erstere Möglichkeit übersichtlicher ist, aber erfordert, dass das Verzeichnis conf.d auch eingelesen wird. Zusätzlich sollte man vorsichtshalber in Plesk das SSL-Hosting für diese Domain ausstellen, damit dessen Settings nicht versehentlich die selbst erstellten überschreiben.

Das SSLCertificateChainFile und das SSLCACertificateFile muss man sich dabei vom Anbieter holen, sofern das erforderlich ist (z.B. bei StartSSL). Anderenfalls lässt man die Einträge einfach weg. Auch der Eintrag für die Logfiles kann natürlich weggelassen werden.

Nach einem Neustart des Apachen kann man jetzt – sofern man alles richtig gemacht hat – alle Domains, für die ein gültiges Zertifikat existiert, ohne Fehlermeldungen aufrufen.

css.php