Der neue Server: Teil X Sonstiges

Der Entwurf zu diesem Beitrag ist schon fast ein Jahr alt. Ich will ihn nun endlich mal veröffentlichen in der Hoffnung, dass er einigen Leuten hilft und ihnen Arbeit abnimmt.

——————

In diesem Beitrag sind alle Dinge zusammengefasst, die thematisch nicht direkt zusammenpassen oder nicht direkt in einen einzigen Beitrag passen, da sie mehrere Themen streifen.

ssl-Zertifikat erstellen

Jetzt erstellen wir ein ssl-Zertifikat, welches wir bei cacert.org signieren lassen. Dies bietet einige Vorteile gegenüber dem Selbst-Signieren (self-signing). Leider ist das cacert.org Root-Zertifikat noch nicht in Firefox aufgenommen und somit erhält man immer diese lästige Warnung, wenn man eine cacert-zertifizierte Webseite aufruft, bis man deren Root-Zertifikat in Firefox importiert.
Am Besten geht man nach dieser Anleitung vor zum Erstellen eines Zertifikats: http://wiki.cacert.org/wiki/CSRGenerator. Danach verschiebt man den Private-Key nach “/etc/ssl/private” und den Public-Key nach “/etc/ssl/certs“. Nun kann man das Zertifikat z.B. in Apache verwenden, aber auch für den Mailserver, IMAP-/POP-Server, svn, … Sollte eine Applikation nicht auf den Private-Key zugreifen können, benötigt aber Zugriff darauf, so muss man den Benutzer unter der die Applikation läuft in die Gruppe “ssl-cert” aufnehmen (ACHTUNG: Dies könnte ein Sicherheitsrisiko darstellen!).

Diffie-Hellman-Code erzeugen

Dies wird z.B. für postfix gebraucht, aber auch für einige IMAP-Server, deshalb erzeugen wir hier diesen Code und speichern ihn unter “/etc/ssl/private/”:

openssl gendh -out /etc/ssl/private/dh_1024.pem -2 -rand /dev/urandom 1024
openssl gendh -out /etc/ssl/private/dh_512.pem -2 -rand /dev/urandom 512

SSL-vHost in apache erstellen

Um in apache einen SSL-vHost erstellen kann, muss man die Datei ports.conf unter “/etc/apache2” ändern und die folgende Zeilen hinzufügen/ergänzen:

<IfModule mod_ssl.c>
    # SSL name based virtual hosts are not yet supported, therefore no
    # NameVirtualHost statement here
    NameVirtualHost *:443
    Listen 443
</IfModule>

Danach können wie gehabt vHosts erstellt werden, mit dem Unterschied, dass die Zeile “” in “” geändert werden und folgende Zeilen hinzugefügt werden:

        SSLEngine on
        SSLCertificateFile /etc/ssl/certs/server.pem
        SSLCertificateKeyFile /etc/ssl/private/privatekey.pem
        SSLCipherSuite HIGH
        SSLProtocol all -SSLv2

Weiter unten stelle ich ein Skript vor, mit welchem man bequem vHosts (sowohl mit und ohne SSL) erstellen kann und automatisch von Port 80 auf Port 443 weiterleiten, wenn der vHost SSL unterstützt.

Quellen:
http://wiki.cacert.org/wiki/CSRGenerator
http://cacert.org/

sftp-Gastzugang

Oft möchte man Leuten einen Zuganz zu seinem Server verschaffen, damit man etwas in ein bestimmtes Verzeichnis hochladen, bzw. daraus herunterladen darf, aber nicht aus diesem Verzeichnis herausnavigieren darf und evtl. Schaden anrichten kann. Dies kann man mit openSSH 5.0 sehr einfach lösen, da es eingebaute chroot-Mechanismen hat. So kann man z.B. eine ganze Gruppe auf ihr Home-Laufwerk oder einen anderen Ordner beschränken oder aber auch nur einen einzigen Benutzer. Im Folgenden legen wir eine Gruppe “chrooted” an, welche auf ihr Home-Laufwerk beschränkt sein wird. Alle Home-Laufwerke dieser Gruppe werden standardmäßig unter “/home/chrooted” liegen. Für unseren Gastbenutzer legen wir darunter ein Verzeichnis “upload” an und ändern die Rechte entsprechend:

mkdir upload
chown <uploaduser>:users /home/chrooted/upload
chmod 775 /home/chrooted/upload

Will man Ordner außerhalb des Home-Laufwerks zugänglich machen, kann man diese mit “mount -o bind” temporär einbinden, bzw. über die “/etc/fstab” dauerhaft:

/pfad/zum/quellverzeichnis /pfad/zum/zielverzeichnis none rw,bind 0 0

Gruppe “chrooted” anlegen:

addgroup --system chrooted

Um einen Benutzer in die Gruppe “chrooted” aufzunehmen, führt man folgenden Befehl aus:

adduser <uploaduser> chrooted

Danach muss man die sshd_config anpassen, bzw. erweitern:

#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp
 
Match group chrooted
        # chroot all users of these group to their homes
        # %h will be substituted by the user's home
        # %u will be substituted with the user's user name
        ChrootDirectory %h
        AllowTcpForwarding no
        ForceCommand internal-sftp

Wichtig ist, dass das Home-Verzeichnis des Benutzers root gehören muss (“chown root: /pfad/zu/home”). Die Unterordner sollten dann wieder dem Benutzer gehören, damit das ganze auch Sinn macht und er Dateien hoch-/runterladen kann. In unserem Beispiel bedeutet das, dass “/home/chrooted” root gehören muss und “/home/chrooted/upload” dem .
Zusätzlich kann man nun noch unter “/etc/passwd” die Standardkonsole des auf “/bin/false” setzen, denn der Benutzer darf sich nur via sftp anmelden und nicht über die Konsole:

<uploaduser>:x:1666:1666:Guest upload-account,,,:/home/chrooted:/bin/false

Quellen:
http://binblog.wordpress.com/2008/04/06/openssh-chrooted-sftp-eg-for-webhosting/
http://www.debian-administration.org/articles/590

Tauschverzeichnis anlegen

Da alle Konsolenbenutzer auch Mitglied in der Gruppe “users” sind, ist es ein leichtes ein Tausch-Verzeichnis unter “/home/shared” anzulegen. Darunter legen wir – der Benutzerfreundlichkeit zuliebe – einen Symlink nach “/home/chrooted/upload” an (siehe vorheriges Kapitel):

mkdir /home/shared
chown root:users /home/shared
chmod 775 /home/shared
ln -s /home/chrooted/upload upload

Nun können sich alle Konsolenbenutzer über dieses Verzeichnis austauschen und auf die Dateien des Gast-Accounts zugreifen, welche für ihn bereitstellen bzw. je nach Rechten auch welche löschen.

vHosts-Skript

Um einem die Arbeit etwas zu erleichtern habe ich schnell ein kleines bash-Skript runtergehackt, mit welchem man bequem vHosts unter apache2 anlegen kann. Ist man nach Der neue Server: Teil 4 apache vorgegangen, so müssen im Skript normalerweise keine Änderungen vorgenommen werden, anderfalls braucht das Skript evtl. ein paar Anpassungen.

Hier das Skript:

createVhost.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/bin/bash
 
# createVhost.sh - Creates an Apache2 vHost configuration
#
# Copyright (C) 2009 johker
#
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License v2 as published by the Free Software Foundation
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License v2 for more details.
 
 
### CHANGE ME! ###
 
WWW_ROOT="/var/www"
SITES_ROOT="/etc/apache2/sites-available"
 
CHANGE_PHP_INI="no"
 
EXAMPLE_ROOT="$WWW_ROOT/example"
SITES_EXAMPLE="$SITES_ROOT/example"
SITES_EXAMPLE_SSL="$SITES_EXAMPLE-ssl"
 
SSL_PRIV_DEFAULT="/etc/ssl/private/privatekey.pem"
SSL_PUB_DEFAULT="/etc/ssl/certs/publickey.pem"
 
PHP_INI_TEMPLATE="/etc/php5/cgi/php.ini"
 
### END CHANGE ME! ###
 
#############################################################
########## DO NOT CHANGE ANYTHING BELOW THIS LINE! ##########
#############################################################
 
# Make sure only root can run our script
if [ "$(id -u)" != "0" ]; then
	echo "ERROR: This script must be run as root!" 1>&2
	exit 1
fi
 
# Query the user for some details
read -p "Domain name: " SRV_NAME
read -p "Domain aliases (leave blank if no aliases available, separated by blank): " SRV_ALIAS
read -p "Admin e-mail address: " SRV_ADMIN
read -p "vHost owner (system user): " USER
read -p  "Use SSL (yes/no)[no]: " SSL
if [ -z $SSL ]; then
	# set default value
	SSL="no"
fi
 
if [ $SSL == "yes" ]; then
	read -p "SSL private key[$SSL_PRIV_DEFAULT]: " CERT_PRIV
	read -p "SSL public key[$SSL_PUB_DEFAULT]: " CERT_PUB
	if [ -z $CERT_PRIV ]; then
		# set default value
		CERT_PRIV=$SSL_PRIV_DEFAULT
	fi
	if [ -z $CERT_PUB ]; then
		# set default value
		CERT_PUB=$SSL_PUB_DEFAULT
	fi
fi
 
VHOST_ROOT="$WWW_ROOT/$SRV_NAME"
DOC_ROOT="$VHOST_ROOT/docs"
CONF_ROOT="$VHOST_ROOT/conf"
LOG_ROOT="$VHOST_ROOT/logs"
TMP_ROOT="$VHOST_ROOT/tmp"
 
PHP_FCGI="$CONF_ROOT/php-fcgi.conf"
PHP_INI="$CONF_ROOT/php.ini"
 
VHOST_CONF="$SITES_ROOT/$SRV_NAME"
 
# GROUP equals USER
GROUP=$USER
 
function changeFcgiConfig {
	# adjust fcgi config
	sed "s!{SRV_NAME}!$SRV_NAME!g" -i $PHP_FCGI
	# ... php.ini
	if [ $CHANGE_PHP_INI == "yes" ]; then
		sed "s!;upload_tmp_dir =!upload_tmp_dir = $TMP_ROOT!g" -i $PHP_INI
		sed "s!;open_basedir =!open_basedir = $DOC_ROOT:$TMP_ROOT!g" -i $PHP_INI
		sed "s!;session.save_path = /var/lib/php5!session.save_path = $TMP_ROOT!g" -i $PHP_INI
	fi
}
 
function createDirs {
	# create the directory structure
 
	cp -R $EXAMPLE_ROOT $VHOST_ROOT
 
	if [ $CHANGE_PHP_INI == "yes" ]; then
		# don't put a symlink to php.ini in $CONF_ROOT, but copy it there
		rm $CONF_ROOT/php.ini
		cp $PHP_INI_TEMPLATE $CONF_ROOT
	fi
 
	changeFcgiConfig
 
	chown $USER:$GROUP -R $VHOST_ROOT
 
	chattr +i $CONF_ROOT/php-fcgi.conf
	# as $CONF_ROOT/php.ini is just a symlink most of the time, chattr will usually fail
	chattr +i $CONF_ROOT/php.ini 2> /dev/null
}
 
function createApacheConfig {
	# now let's adjust the apache vHost-configuration
	if [ $SSL == "yes" ]; then
		cp $SITES_EXAMPLE_SSL $VHOST_CONF
	else
		cp $SITES_EXAMPLE $VHOST_CONF
	fi
 
	# now do sed operations on $VHOST_CONF
	sed "s!{SRV_NAME}!$SRV_NAME!g" -i $VHOST_CONF
	if [ -z "$SRV_ALIAS" ]; then
		sed "s!{SRV_ALIAS}!!g" -i $VHOST_CONF
	else
		sed "s!{SRV_ALIAS}!$SRV_ALIAS!g" -i $VHOST_CONF
		sed "s!#	ServerAlias!	ServerAlias!g" -i $VHOST_CONF
	fi
	sed "s!{SRV_ADMIN}!$SRV_ADMIN!g" -i $VHOST_CONF
	sed "s!{USER}!$USER!g" -i $VHOST_CONF
	sed "s!{GROUP}!$GROUP!g" -i $VHOST_CONF
 
	sed "s!{DOC_ROOT}!$DOC_ROOT!g" -i $VHOST_CONF
	sed "s!{CONF_ROOT}!$CONF_ROOT!g" -i $VHOST_CONF
	sed "s!{LOG_ROOT}!$LOG_ROOT!g" -i $VHOST_CONF
 
	if [ $SSL == "yes" ]; then
		sed "s!{CERT_PUB}!$CERT_PUB!g" -i $VHOST_CONF
		sed "s!{CERT_PRIV}!$CERT_PRIV!g" -i $VHOST_CONF
	fi
}
 
createDirs
createApacheConfig
 
exit 0

Die dazugehörenden Ordnerstruktur unter “/var/www/example“:

mkdir /var/www/example
mkdir /var/www/example/conf
mkdir /var/www/example/docs
mkdir /var/www/example/tmp
mkdir /var/www/example/logs
touch /var/www/example/logs/access.log
touch /var/www/example/logs/error.log
ln -s /etc/php5/cgi/php.ini /var/www/example/conf/php.ini

Hier noch die Datei “php-fcgi.conf“, welche nach “/var/www/example/conf/” gehört:

php-fcgi.conf:

#!/bin/sh
PHPRC="/var/www/{SRV_NAME}/conf"
export PHPRC
PHP_FCGI_CHILDREN=3
export PHP_FCGI_CHILDREN
exec /usr/bin/php5-cgi

Dazu noch die vHost-configs “example”, sowie “example-ssl” unter /etc/apache2/sites-available”:

  • example:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    <VirtualHost *:80>
            SuExecUserGroup {USER} {GROUP}
     
            ServerName {SRV_NAME}
    #	ServerAlias {SRV_ALIAS}
            ServerAdmin {SRV_ADMIN}
     
            DocumentRoot {DOC_ROOT}
            AddHandler fcgid-script .php
            <Directory {DOC_ROOT}>
                    FCGIWrapper {CONF_ROOT}/php-fcgi.conf .php
                    Options +SymLinksIfOwnerMatch +MultiViews +ExecCGI -Indexes
                    AllowOverride FileInfo AuthConfig
                    Order allow,deny
                    allow from all
            </Directory>
     
            ErrorLog {LOG_ROOT}/error.log
            CustomLog {LOG_ROOT}/access.log combined
            LogLevel warn
            ServerSignature Off
    </VirtualHost>
  • example-ssl:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    
    <VirtualHost *:80>
            ServerName {SRV_NAME}
    #	ServerAlias {SRV_ALIAS}
            ServerAdmin {SRV_ADMIN}
     
    	<IfModule mod_ssl.c>
              RewriteEngine   on
    	  RewriteCond     %{SERVER_PORT} ^80$
              RewriteRule     ^(.*)$ https://%{SERVER_NAME}$1 [L,R]
     
    	  RewriteLog      {LOG_ROOT}/rewrite.log
              RewriteLogLevel 2
    	</IfModule>
     
            ErrorLog {LOG_ROOT}/error.log
            CustomLog {LOG_ROOT}/access.log combined
            LogLevel warn
     
            ServerSignature Off
    </VirtualHost>
     
    <VirtualHost *:443>
            SuExecUserGroup {USER} {GROUP}
     
            ServerName {SRV_NAME}
    #	ServerAlias {SRV_ALIAS}
            ServerAdmin {SRV_ADMIN}
     
            SSLEngine on
            SSLCertificateFile {CERT_PUB}
            SSLCertificateKeyFile {CERT_PRIV}
            SSLCipherSuite HIGH
            SSLProtocol all -SSLv2
     
            DocumentRoot {DOC_ROOT}
            AddHandler fcgid-script .php
            <Directory {DOC_ROOT}>
                    FCGIWrapper {CONF_ROOT}/php-fcgi.conf .php
                    Options +SymLinksIfOwnerMatch +MultiViews +ExecCGI -Indexes
                    AllowOverride FileInfo
                    Order allow,deny
                    allow from all
            </Directory>
     
            ErrorLog {LOG_ROOT}/error.log
            CustomLog {LOG_ROOT}/access.log combined
            LogLevel warn
     
            ServerSignature Off
    </VirtualHost>

Das Skript kann als Benutzer root ausgeführt werden. Es fragt nach ein paar Parametern (default-Werte stehen in eckigen Klammern und können durch Drücken der Eingabetaste übernommen werden) und erstellt dann den vHost und die dazugehörige Konfiguration. Nach Ausführen des Skripts muss der vHost noch mittels des “a2ensite“-Befehls aktiviert werden und die apache-Konfiguration muss neu eingelesen werden.

Funambol Installation

Heute geht’s um Funambol – einen Synchronisationsserver für Mobiltelefone, PIM Programme, … Funambol bietet unter anderem auch Unterstützung für Push-Mail, Kalender-, Aufgaben- und Kontaktsynchronisation für viel Plattformen. Mehr Informationen gibts unter http://www.funambol.com/opensource.
Dieses Howto beschreibt die Installation von Funambol mit postgres als Datenbank-Backend.

Installation

Als Erstes laden wir den JDBC Treiber für postgres herunter: http://jdbc.postgresql.org/download/postgresql-8.3-605.jdbc3.jar
Danach das Funambol Installationspackage: http://funambol.com/opensource/download.php?file_id=funambol-7.1.1.bin&_=d
Danach führen wir das Funambol Paket mit folgendem Befehl aus:

1
sh funambol-7.1.1.bin

Wir wählen den Standard-Installationspfad, verneinen aber die Frage, ob wir den Server starten wollen.

Konfiguration

Danach kopieren wir den postgres JDBC-Treiber nach “/opt/Funambol/tools/jre-1.5.0/jre/lib/ext/” und legen einen postgres-Benutzer für Funambol an:

1
2
3
su - postgres
createuser -P
createdb funambol

Bei “createuser” geben wir als Namen “funambol” an und verneinen alle drei Fragen.
Nun müssen die Datenbank-Einstellungen von Funambol geändert werden. Dazu editieren wir “/opt/Funambol/ds-server/install.properties“:

1
2
3
4
5
jdbc.classpath=../tools/jre-1.5.0/jre/lib/ext/postgresql-8.3-605.jdbc3.jar
jdbc.driver=org.postgresql.Driver
jdbc.url=jdbc:postgresql:funambol
jdbc.user=funambol
jdbc.password=<PASSWORD>

Die Datei “com/funambol/server/db/db.xml” wird nach dem gleichen Schema bearbeitet. Danach muss “/opt/Funambol/bin/install” ausgeführt werden (ggf. zuvor die Umgebungsvariable JAVA_HOME setzen). Jetzt kann funambol per “/opt/Funambol/bin/funambol start” gestartet werden.

Funambol in runlevel eintragen

1
2
cp /opt/Funambol/bin/funambol /etc/
update-rc.d funambol defaults

Funambol Admin-Tool

Das Funambol Admin-Tool kann von der Funambol-Homepage heruntergeladen werden. Hier kann man das initiale Admin-Passwort ändern.
Des Weiteren muss man im “Server Settings”-Tab die Server URI ändern. Sie sollte dieses Format haben:

1
http://<SERVER>:<PORT>/funambol/ds

Testen

Nun kann man sich mit URL, Benutzername und Passwort am Server anmelden und synchronisieren. Da Autoprovisioning aktiviert ist, kann man Benutzername und Passwort frei wählen. Dies sollte jedoch in einem Produktivsystem geändert werden, da sich sonst jeder am Server anmelden kann. Dazu muss man den Officer im “Server Settings”-Tab ändern.

Der neue Server: Teil 9 Backup

Der Server ist zwar nicht mehr neu, aber dieser Beitrag ist evtl. dennoch für einige hilfreich. Deshalb: Viel Spaß!

Heute widme ich mich dem Thema Backup. Das habe ich viel zu stark vernachlässigt und will das jetzt nachholen. Das Tool der Wahl ist duplicity mit dem c’t Wrapper-Skript ftplicity. Duplicity benutzt unter der Decke rsync zur Erkennung der Deltas. Das Skript wird so konfiguriert, dass es täglich ein inkrementelles Backup macht und monatlich ein volles Backup und dabei die alten Backups löscht. Während des Backup-Prozesses werden auch Backups der MySQL- und postgreSQL-Datenbanken mit den mitgelieferten Tools erstellt (nicht einfach durch Kopieren der Datenbankdateien, da man dabei einen inkonsistenten Zustand erwischen könnte und die Datenbank unbrauchbar ist).

Installation

Zuerst die Installation der benötigten Pakete:

1
2
3
4
5
6
aptitude install duplicity ncftp
wget http://downloads.sourceforge.net/project/ftplicity/ftplicity/1.5.0.2/ftplicity_1.5.0.2.tgz?use_mirror=switch
tar xvfz ftplicity_1.5.0.2.tgz
mv ftplicity_1.5.0.2/ftplicity /usr/local/bin/
chown root: /usr/local/bin/ftplicity
chmod 755 /usr/local/bin/ftplicity

Konfiguration

Erstellung eines GPG-Schlüssel für Backups

Da ftplicity Backups automatisch verschlüsselt ablegt, ist es nötig einen GPG-Schlüssel zu erstellen:

1
gpg --gen-key


root@domain.tld:~# gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: keyring `/root/.gnupg/secring.gpg' created
Please select what kind of key you want:
(1) DSA and Elgamal (default)
(2) DSA (sign only)
(5) RSA (sign only)
Your selection? <-- ENTER
DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) <-- ENTER
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0) <-- ENTER
Key does not expire at all
Is this correct? (y/N) <-- y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
"Heinrich Heine (Der Dichter) "

Real name: Musterserver Backup
Email address: backup@domain.tld
Comment: Key for System Backups on domain.tld
You selected this USER-ID:
"domain.tld Backup (Key for System Backups on domain.tld) "

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? <-- O
You need a Passphrase to protect your secret key.

Enter passphrase: <-- Passwort eingeben
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++.+++++++++++++++.++++++++++++++++++++.+++++..+++++++++++++++>++++++++++>.+++++...........<+++++>+++++..<.+++++.....................................................>.+++++.....+++++

gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 123ABC45 marked as ultimately trusted
public and secret key created and signed.

...

Die achtstellige ID (im Beispiel 123ABC45) bitte merken, da diese später benötigt wird. Ebenso das Passwort.

Danach legen exportieren wir noch unsere Schlüssel (public/private), damit wir diese an einem sicheren Ort speichern können, damit unsere Daten nicht verloren gehen, sollte die Festplatte sich verabschieden:

1
2
root@domain.tld:~/gpg-key# gpg --output backup_pub.gpg --armor --export 123ABC45
root@domain.tld:~/gpg-key# gpg --output backup_sec.gpg --armor --export-secret-key 123ABC45

ftplicity

Nun starten wir ftplicity einmal, damit eine Standardkonfiguration angelegt wird, die wir an unsere Wünsche anpassen können:

1
ftplicity system create

Nun editieren wir die Datei “/root/.ftplicity/system/conf“:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# gpg key data (for symmetric encryption comment out GPG_KEY)
GPG_KEY='123ABC45'
GPG_PW='PASSWORD'
# gpg options passed from duplicity to gpg process (default='')
# e.g. "--trust-model pgp|classic|direct|always" 
#   or "--compress-algo=bzip2 --bzip2-compress-level=9"
#GPG_OPTS=''
 
# credentials & server address of the backup target (URL-Format)
# syntax is
#   scheme://user[:password]@host[:port]/[/]path
# probably one out of
#   file:///some_dir
#   ftp://user[:password]@other.host[:port]/some_dir
#   hsi://user[:password]@other.host/some_dir
#   cf+http://container_name
#   imap://user[:password]@host.com[/from_address_prefix]
#   imaps://user[:password]@host.com[/from_address_prefix]
#   rsync://user[:password]@other.host[:port]::/module/some_dir
#   rsync://user[:password]@other.host[:port]/relative_path
#   rsync://user[:password]@other.host[:port]//absolute_path
#   s3://host/bucket_name[/prefix]
#   s3+http://bucket_name[/prefix]
#   scp://user[:password]@other.host[:port]/some_dir
#   ssh://user[:password]@other.host[:port]/some_dir
#   tahoe://alias/directory
#   webdav://user[:password]@other.host/some_dir
#   webdavs://user[:password]@other.host/some_dir 
###
# TARGET='scheme://user[:password]@host[:port]/[/]path'
TARGET='ftp://<USER>:<PASS>@<HOST>/<DIR>'
# optionally the password can be defined as extra variable
# if password is set already in TARGET, this setting replaces it
#TARGET_PW='_backend_password_'
 
# base directory to backup
SOURCE='/'
 
# Time frame for old backups to keep, Used for the "purge" command.  
# see duplicity man page, chapter TIME_FORMATS)
# defaults to 1M, if not set
#MAX_AGE=1M
 
# Number of full backups to keep. Used for the "purge-full" command. 
# See duplicity man page, action "remove-all-but-n-full".
# defaults to 1, if not set 
#MAX_FULL_BACKUPS=1
 
# verbosity of output (5 for gpg errors, 9 for bug fixing)
# default is 4, if not set
#VERBOSITY=5
 
# temporary file space. at least the size of the biggest file in backup
# for a successful restoration process. (default is '/tmp', if not set)
#TEMP_DIR=/tmp
 
# sets duplicity --time-separator option (since v0.4.4.RC2) to allow users 
# to change the time separator from ':' to another character that will work 
# on their system.  HINT: For Windows SMB shares, use --time-separator='_'.
# NOTE: '-' is not valid as it conflicts with date separator.
# ATTENTION: only use this with duplicity < 0.5.10, since then default file 
#            naming is compatible and this option is pending depreciation 
#DUPL_PARAMS="$DUPL_PARAMS --time-separator _ "
 
# activates duplicity --short-filenames option, when uploading to a file
# system that can't have filenames longer than 30 characters (e.g. Mac OS 8)
# or have problems with ':' as part of the filename (e.g. Microsoft Windows)
# ATTENTION: only use this with duplicity < 0.5.10, since then default file 
#            naming is compatible and this option is pending depreciation  
#DUPL_PARAMS="$DUPL_PARAMS --short-filenames "
 
# activates duplicity --full-if-older-than option (since duplicity v0.4.4.RC3) 
# forces a full backup if last full backup reaches a specified age, for the 
# format of MAX_FULLBKP_AGE see duplicity man page, chapter TIME_FORMATS
#MAX_FULLBKP_AGE=1M
#DUPL_PARAMS="$DUPL_PARAMS --full-if-older-than $MAX_FULLBKP_AGE " 
 
# sets duplicity --volsize option (available since v0.4.3.RC7)
# set the size of backup chunks to VOLSIZE MB instead of the default 5MB.
# VOLSIZE must be number of MB's to set the volume size to. 
#VOLSIZE=50
#DUPL_PARAMS="$DUPL_PARAMS --volsize $VOLSIZE "
 
# more duplicity command line options can be added in the following way
# don't forget to leave a separating space char at the end
#DUPL_PARAMS="$DUPL_PARAMS --put_your_options_here "

Und nun noch die Datei “/root/.ftplicity/system/exclude“:

1
2
3
4
5
6
7
/dev
/proc
/sys
/tmp
/var/cache
/var/tmp
/var/run

Danach erstellen wir unter “/usr/local/sbin/” die Datei db_backup mit Rechten “700″:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash
 
# Script to backup MySQL and postgreSQL databases
# author: johker
 
############### CHANGE THESE VARIABLE IF NECESSARY ####################
 
MYSQL_USER="MYSQL_USER"
MYSQL_PW="MYSQL_PASSWORD"
POSTGRES_USER="POSTGRES_USER"
POSTGRES_PW="POSTGRES_PASSWORD"
TMP="/tmp/"
FINAL_LOC="/var/backups/"
 
################ DON'T CHANGE ANYTHING BELOW THIS LINE ################
 
echo "Creating backup of MySQL databases"
mysqldump -u$MYSQL_USER -p$MYSQL_PW --all-databases > $FINAL_LOC"mysql.sql"
gzip -f $FINAL_LOC"mysql.sql"
 
echo "Creating backup of postgreSQL databases"
su -c "cd $TMP && pg_dumpall > $TMP'postgres.out'" $POSTGRES_USER
gzip -f $TMP'postgres.out' 
mv -f $TMP'postgres.out.gz' $FINAL_LOC
 
chmod 640 $FINAL_LOC"mysql.sql.gz" $FINAL_LOC"postgres.out.gz"
chown root: $FINAL_LOC"mysql.sql.gz" $FINAL_LOC"postgres.out.gz"
 
exit 0

Und in die Datei “/root/.ftplicity/system/pre” fügen wir folgende Zeile ein:

1
2
3
#!/bin/bash
 
/usr/local/sbin/db_backup

Testen

Mit folgendem Befehl kann man die ftplicity-Konfiguration testen:

ftplicity system status

Wenn alles o.k. ist, kann man mit folgedem Befehl ein initiales Backup anlegen:

ftplicity system backup

Erstellen eines Cronjobs

Da wir das Backup nicht jedes mal händisch anstoßen wollen, hier einträge für die crontab von root (editierbar per “crontab -e” als Benutzer root):

1
2
3
4
# run the (incremental) backup each night at 03:23h
23 3 * * * /usr/local/bin/ftplicity system backup
# do a full backup once per month & delete old backups at 04:47h
47 4 1 * * /usr/local/bin/ftplicity system purge --force && /usr/local/bin/ftplicity system purge-full --force && /usr/local/bin/ftplicity system full

Quellen

http://www.howtoforge.com/ftp-backups-with-duplicity-ftplicity-debian-etch

http://maff.ailoo.net/2009/07/backup-virtual-machines-lvm-snapshots-ftplicity-duplicity/

http://robert.penz.name/161/howto-backup-your-dedicated-server-to-a-foreign-ftp-server/

Der neue Server: Teil 8 Monitoring mit munin

Munin ist ein Tool zum System-Monitoring, ist einfach in der Konfiguration, bietet eine Vielfalt an Plugins und stellt die Ergebnisse über ein Webinterface grafisch dar. Im folgenden wird die Installation und eine beispielhafte Basiskonfiguration geschildert. Munin hat die Möglichkeit Daten von mehreren Systemen zu sammeln und diese alle zentral zugänglich zu machen. Hier wird nur darauf eingegangen Server und Client auf dem gleichen System zu installieren, doch die Erweiterung gestaltet sich sehr einfach und die Projekthomepage bietet mit ihrem Wiki eine gute Anlaufstelle für Fragen.

Installation:

aptitude install munin munin-node munin-plugins-extra

Konfiguration:
/etc/munin/munin.conf:

[domain.tld]
    address 127.0.0.1
    use_node_name yes

Evtl. muss man auch die Variable “htmldir” anpassen.

/etc/munin/munin.conf:

#host *
host 127.0.0.1

Munin aktualisiert die Daten in der Standardkonfiguration alle 5 Minuten, d.h. man muss evtl. etwas warten, bis die ersten Daten über die Weboberfläche verfügbar sind. Die Weboberfläche kann über die Adresse, die man in “htmldir” in der Datei munin.conf definiert hat, aufgerufen werden. Man kann/sollte dieses Verzeichnis passwortschützen, damit nicht jeder darauf zugreifen kann.

Falls man Ausschau nach weiteren Plugins hält, dann ist http://muninexchange.projects.linpro.no/?about eine gute Anlaufstelle. Des Weiteren liegen unter “/usr/share/munin/plugins/” weitere Plugins, die man einfach nach “/etc/munin/plugins” linken kann und danach noch in “/etc/munin/plugin-conf.d/munin-node” konfigurieren kann.

apache Plugin

Damit das apache-Plugin funktioniert, muss mod_status aktiviert werden:

a2enmod status

Danach muss der Zugriff auf die Status-Seite aktiviert und geregelt werden:
/etc/apache2/mods-enabled/status.conf:

<IfModule mod_status.c>
#
# Allow server status reports generated by mod_status,
# with the URL of http://servername/server-status
# Uncomment and change the ".example.com" to allow
# access from other hosts.
#
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from localhost ip6-localhost
#    Allow from .example.com
</Location>
 
</IfModule>

Quellen:

http://www.debuntu.org/how-to-monitoring-a-server-with-munin

http://munin.projects.linpro.no/wiki/plugin-conf.d

Der neue Server: Teil 7 roundcube

Oft hat man nicht die Möglichkeit mit einen E-Mail Client – wie z.B. Evolution oder Thunderbird – arbeiten zu können, deshalb wird hier darauf eingegangen wie man einen Webmailer – in diesem Fall roundcube – inkl. postfixadmin-Integration und Sieve-Plugin installiert.

imapproxy

Da http ein “stateless”-Protokoll ist, kann es – anders als IMAP-Clients – keine Verbindungen offen halten und stellt deshalb sehr viele unnötige “LOGIN”-Anfragen. Um dies zu verhindern wird ein imapproxy installiert. Dieser wird dem Webmailer vorgeschaltet und hält die Verbindungen geöffnet. Stellt der Webmailer nun eine Anfrage an den Proxy, sucht dieser die Verbindung raus und benutzt die bestehende Verbindung anstatt eine neue aufzubauen. Der Proxy hält die Verbindung nicht für eine unbestimmte Zeit offen, sondern schließt sie nachdem ein Timeout abgelaufen ist.

Installation:

aptitude install imapproxy

Konfiguration:

listen_address 127.0.0.1

Wir ändern nur die oben genannte Zeile, den Rest belassen wir wie er ist. Da der IMAP-Proxy auf dem gleichen System wie der Mailserver läuft, lassen wir nur lokale Verbindungen zu.
Wenn nun ein Programm/Skript den IMAP-Proxy nutzen soll, gibt man Port 1143 an, anstatt Port 143.

roundcube

Für roundcube brauchen wir zunächst einen vHost. Im Weiteren wird davon ausgegangen, dass roundcube unter https://webmail.domain.tld/ verfügbar ist.
Zunächst muss die neueste roundcube Version von http://roundcube.net/ heruntergeladen und in den vHost entpackt werden, damit es über https://webmail.domain.tld/ verfügbar ist.
Nun legen wir eine Datenbank inkl. Benutzer für roundcube an und importieren das postgres-Schema:

su - postgres
psql template1
CREATE USER roundcube WITH PASSWORD 'password';
CREATE DATABASE roundcube WITH OWNER roundcube ENCODING 'UNICODE';
\c - roundcube
\i /PFAD/ZU/ROUNDCUBE/SQL/postgres.initial.sql
\q

Nun rufen wir im Browser roundcube auf, hängen der URL aber noch “/installer” an und folgen danach den Anweisungen. Nachden wir die Konfigurationsdateien kopiert und am aufgeforderten Ort gespeichert haben, können wir roundcube über den Browser aufrufen und uns mit unserem IMAP-Benutzernamen und -passwort anmelden. Jedoch sollte man damit noch warten, bis postfixadmin-bridge installiert ist, denn dann wird automatisch der vollständige Name aus den postfixadmin-Tabellen übernommen.

postfixadmin-bridge

Zur Installation von rcpfa (= postfixadmin-bridge) wird patch benötigt:

aptitude install patch

Danach entpackt man rcpfa in den roundcube Ordner, wechselt in das neue Unterverzeichnis und führt folgenden Befehl aus:

sh INSTALL.TXT

Sollten während des Patch-Vorgangs Probleme auftreten, kann man sich die *.rej-Dateien anschauen und die Probleme ggf. händisch lösen. Nach der Installation muss noch die roundcube-Konfiguration angepasst werden (beim Patchen wurden neue Variablen in der Konfiguration hinzugefügt) und danach kann man im Einstellungs-Tab von roundcube Einstellungen aus postfixadmin ändern.

sieve rules

Das sieve-Plugin für roundcube kann man hier herunterladen: http://www.tehinterweb.co.uk/roundcube/#ptsieverules und anschließend mit

patch -ul -d /PFAD/ZU/ROUNDCUBE/ -p1 < /PFAD/ZUM/PATCH

installieren.
Die parallele Installation von rcpfa und sieve rules ist problematisch, da der Patch-Vorgang sehr wahrscheinlich an einer Stelle fehlschlägt und man selbst Hand anlegen muss.
Auch dieses Plugin hat Variablen zur roundcube-Konfiguration hinzugefügt, die angepasst werden müssen, bevor das Plugin benutzt werden kann.

mutt

Um auch über die Konsole auf E-Mails zugreifen kann, installieren wir zusätzlich noch mutt. Manche Leute fragen sich vielleicht, wozu man einen Konsolenmailer braucht, bzw. brauchen könnte. Ein interessanter Punkt ist, dass mutt einen weitaus größeren Funktionsumfang als ein Webmailer bietet und außerdem sieht es auch schick aus, wenn man seine Mails auf der Konsole liest.

Installation:

aptitude install mutt

Eine einfache Konfiguration (“~/.muttrc“):

set folder="imap://localhost"
set spoolfile="imap://localhost/INBOX"
set imap_authenticators="LOGIN"
set imap_user="username"
set imap_pass="password"
set move=no
 
set editor='vim -c "set t_Co=8" -c "syntax on" -c "/^$" -c "set tw=72" -c "set number"'
set header_cache=~/.mutt_header

Die mutt-Konfiguration ist sehr rudimentär und sollte zusätzlich noch an die eigenen Bedürfnisse angepasst werden, z.B. Sent-Ordner definieren, GPG-Schlüssel definieren, …

Quellen:

http://roundcube.net/

http://nejc.skoberne.net/projects/rcpfa/

http://www.tehinterweb.co.uk/roundcube/#ptsieverules

Der neue Server: Teil 6 Spambekämpfung

Nachfolgend wird erklärt, wie man policyd-weight, amavisd-new, clamav, spamassassin, dspam installiert, konfiguriert und in das bestehende Setup integriert.

policyd-weight

policyd-weight ist ein effektives Tool zur Spambekämpfung schon vor der Annahme einer E-Mail. Es überprüft das “Envelope” und gleicht die Absenderadresse gegen mehrere DNS-Blacklists ab.

aptitude install policyd-weight

Danach erstellen wir noch eine Standardkonfiguration für policyd-weight:

policyd-weight defaults > /etc/policyd-weight.conf

Folgende Zeile in “/etc/postfix/main.cf” ändern:

###  check_policy_service inet:127.0.0.1:12525,

… zu:

check_policy_service inet:127.0.0.1:12525,

Jetzt muss die postfix-Konfiguration neu geladen werden und policyd-weight neu gestartet werden:

/etc/init.d/policyd-weight restart
postfix reload

amavisd-new

Amavisd-new ist ein Content-Filter, der sich in fast jeden MTA integrieren lässt. Über amavisd-new lassen sich viele verschiedene Tools, wie z.B. ClamAV zur Virenprüfung, Spamassassin zur Spamfilterung oder dspam – ebenfalls zu Spamfilterung – integrieren.
Wenn eine E-Mail in postfix ankommt, wird diese an amavis weitergeleitet, überprüft und wieder – mit zusätzlichen Headern – an postfix zur Auslieferung zurückgesendet. Natürlich kann man amavis auch so konfigurieren, dass bestimmte Nachrichtentypen, z.B. Virusmails oder Spammails, sofort geblockt werden. Sobald die Nachricht von amavis an postfix zurückgegeben wurde, kann eine automatische Einsortierung in Ordner über sieve folgen (z.B. Spam-Mails nach Junk).

Installation:
Zu “/etc/apt/sources.list” hinzufügen:

# volatile repository (e.g. for clamav)
deb http://volatile.debian.org/debian-volatile lenny/volatile main contrib non-free
aptitude install amavisd-new spamassassin clamav clamav-daemon clamav-freshclam pax lha arj bzip2 unrar zoo nomarch cpio lzop cabextract apt-listchanges libauthen-sasl-perl libdbi-perl dspam libmail-dkim-perl razor pyzor dcc-client libdbd-pg-perl

Nun folgt die Konfiguration von amavis (Konfigurationsdateien sind unter “/etc/amavis/conf.d/” zu finden). Ich führe jeweils nur geänderte Zeilen auf:

01-debian:

$unrar      = ['rar', 'unrar']; #disabled (non-free, no security support)
#$unrar         = undef;
$lha    = 'lha'; #disabled (non-free, no security support)
#$lha   = undef;

05-domain_id:

@local_domains_acl = ( "." );

05-node_id:

$myhostname = "mail.domain.tld";

15-content_filter_mode:

@bypass_virus_checks_maps = ( 
   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
@bypass_spam_checks_maps = (
   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

20-debian_defaults:

$final_virus_destiny      = D_DISCARD;  # (data not lost, see virus quarantine)
$final_banned_destiny     = D_PASS;   # D_REJECT when front-end MTA
$final_spam_destiny       = D_PASS;
$final_bad_header_destiny = D_PASS;     # False-positive prone (for spam)
 
# $sa_spam_subject_tag = '***SPAM*** ';
$sa_tag_level_deflt  = undef;

50-user:

$max_servers = 2;
 
$policy_bank{'MYNETS'} = {   # mail originating from @mynetworks
  originating => 1,  # is true in MYNETS by default, but let's make it explicit
  os_fingerprint_method => undef,  # don't query p0f for internal clients
};
 
$recipient_delimiter = '+';
 
$warnvirusrecip = 1;
 
$mailfrom_notify_admin = "postmaster\@$mydomain";
$mailfrom_notify_recip = "postmaster\@$mydomain";
$mailfrom_notify_spamadmin = "postmaster\@$mydomain";

Jetzt fügen wir noch den clamav-Nutzer der amavis-Gruppe hinzu:

adduser clamav amavis

Danach müssen wir Änderungen an der postfix-Konfiguration vornehmen:

Zu main.cf hinzufügen:

content_filter = amavis:[127.0.0.1]:10024
receive_override_options = no_address_mappings

Zu master.cf hinzufügen:

amavis       unix  -       -       n       -       2       lmtp 
    -o lmtp_data_done_timeout=1200
    -o lmtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20
127.0.0.1:10025 inet n  -       n       -       -       smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o relay_recipient_maps=
    -o smtpd_delay_reject=no
    -o smtpd_restriction_classes=
    -o smtpd_client_restrictions=
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining
    -o smtpd_end_of_data_restrictions=
    -o mynetworks=127.0.0.0/8    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

Zuletzt werden postfix, amavis und clamav neu gestartet:

/etc/init.d/postfix restart
/etc/init.d/amavis restart
/etc/init.d/clamav-daemon restart

Testen der Konfiguration

Zum Testen genügt es eine Mail an den Mailserver zu schicken und sich danach die Header-Informationen anzuschauen. Finden sich ähnliche Header wie die folgenden in der Mail wieder, so wird amavis aufgerufen.

X-virus-scanned: Debian amavisd-new at domain.tld
X-spam-flag: NO
X-spam-score: 2.898
X-spam-level: **
X-spam-status: No, score=2.898 required=6.31 tests=[SPF_PASS=-0.001, TVD_SPACE_RATIO=2.899]

Des Weiteren kann man mit folgendem Befehl testen, ob Spam erkannt wird:

sendmail john@example.com < /usr/share/doc/spamassassin/examples/sample-spam.txt

… oder Viren:

telnet localhost 25
HELO localhost
MAIL FROM: <user@change_to_my_domain.tld>
RCPT TO: <user@change_to_my_domain.tld>
DATA
From: virus-tester
To: undisclosed-recipients:;
Subject: amavisd test - simple - spam test pattern
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
.
 
quit

Spamassassin Konfiguration

Ans Ende der Datei “/etc/spamassassin/local.cf” anfügen:

use_bayes 1
use_bayes_rules 1
bayes_auto_learn 1
bayes_auto_expire 0
 
# pyzor
use_pyzor 1
pyzor_path /usr/bin/pyzor
 
# razor
use_razor2 1
razor_config /etc/razor/razor-agent.conf

/etc/spamassassin/v312.pre:

loadplugin Mail::SpamAssassin::Plugin::DKIM

/etc/spamassassin/v320.pre:

loadplugin Mail::SpamAssassin::Plugin::Shortcircuit
loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody

Razor konfigurieren:

su - amavis
razor-admin -create

Spamassassin-Regeln neu laden:

sa-update

Automatische Updates

Um spamassassin voll auszureizen, richten wir einen cronjob ein über welchen jede Nacht die Regeln auf den neuesten Stand gebracht werden (als root ausführen!):

/usr/local/sbin/updateSpamassassin:

#!/bin/bash
 
sa-update &> /dev/null
sa-compile &> /dev/null
 
exit 0
crontab -e
42 3 * * * /usr/local/sbin/updateSpamassassin &> /dev/null

Ham/Spam aus /var/vmail lernen

Nun erstellen wir noch ein Skript, welches Spam, bzw. Ham aus den Mailboxen der Benutzer lernt (aus den Ordnern “INBOX” und “Junk”). Dieses Skript rufen wir wöchentlich über einen Cronjob auf.

/usr/local/sbin/trainSpamassassin:

#!/bin/bash
 
VMAILDIR="/var/vmail"
SADIR="/var/lib/amavis/.spamassassin"
DBPATH="/var/lib/amavis/.spamassassin/bayes"
 
cd $VMAILDIR
for domain in $(find ./ -maxdepth 1 -not -name "." -type d); do
        domaindir="$VMAILDIR/$domain"
        cd $domaindir
        for user in $(find ./ -maxdepth 1 -not -name "." -type d); do
                maildir="$domaindir/$user/maildir"
                inbox="$maildir/cur"
                junk="$maildir/.Junk/cur"
 
                echo "Learning ham from $inbox"
                sa-learn --ham --showdots --dbpath $DBPATH $inbox
                echo "Learning junk from $junk"
                sa-learn --spam --showdots --dbpath $DBPATH $junk
        done
done
 
chown -R amavis:amavis $SADIR

Nun noch das Skript in die crontab aufnehmen (als root ausführen!):

crontab -e
33 4 * * 0 /usr/local/sbin/trainSpamassassin &> /dev/null

Globale sieve-Regeln

Um dem Benutzer das Erstellen von sieve-Regeln für Spam zu ersparen, fügen wir in die Datei “/var/vmail/default.sieve” folgende Zeile ein, um Spam-Mails automatisch in den Ordner “Junk” zu verschieben (sieve wurde schon in Teil 5 dieser Serie konfiguriert):

require ["fileinto"];
# Move spam to spam folder
if header :contains "X-Spam-Flag" ["YES"] {
  fileinto "Junk";
  stop;
}

dspam

Die Konfiguration von dspam wird nachgereicht.

Quellen:

http://workaround.org/articles/ispmail-etch/#step-5-deliver-emails-through-the-dovecot-lda

http://www200.pair.com/mecham/spam/spamfilter20090215.html#amavisconfig

http://wiki.rootforum.de/mailserver/postfix/clamav_amavisd

http://www.howtoforge.com/virtual-users-domains-postfix-courier-mysql-squirrelmail-debian-lenny-p3

http://www.tuxj0b.de/HOWTO_Mailserver_mit_Postfix_Dovecot_Antispam_und_PostgreSQL_Backend

Der neue Server: Teil 5 postfix

Hier wird erklärt wie man postfix mit postgreSQL-Backend installiert, dovecot inkl. sieve konfiguriert, sowie postfixadmin einrichtet, um postfix bequem über ein Webinterface verwalten zu können.

Datenbank anlegen

Als Erstes legen wir einen Datenbankbenutzer inkl. Datenbank für postfix an:

su - postgres
psql template1
CREATE USER postfix WITH PASSWORD 'password';
CREATE DATABASE postfix WITH OWNER postfix ENCODING 'UNICODE';
\q

Verzeichnis anlegen

Später werden alle Mailboxen unter “/var/vmail/DOMAIN/BENUTZERNAME/maildir/” liegen, deshalb erstellen wir nun den Ordner “/var/vmail” und vergeben entsprechende Rechte. Die Einsortierung nach “/var/vmail/DOMAIN/BENUTZERNAME/maildir/” geschieht später über SQL-Queries automatisch.

useradd -r -u 150 -g mail -d /var/vmail -s /sbin/nologin -c 'Virtual mailbox' vmail
mkdir /var/vmail
chmod 770 /var/vmail/
chown vmail:mail /var/vmail/

postfixadmin

postfixadmin installieren wir direkt aus deren svn-Repository, um mit der aktuellste Version zu arbeiten. Sollte es zu Problemen kommen, kann man über http://postfixadmin.sourceforge.net/ die neueste stabile Version herunterladen.

cd /var/www/
svn co https://postfixadmin.svn.sourceforge.net/svnroot/postfixadmin/trunk postfixadmin-svn
ln -s postfixadmin-svn postfixadmin

Danach passt man die Konfigurationsdatei “/var/www/postfixadmin/config.inc.php” an seine Wünsche und Anforderungen an. Nach Ausführen des “setup.php”-Skripts im Browser (und anschließendem Löschen/Umbenennen) ist postfixadmin einsatzbereit.

postfix

postfix installieren:

aptitude install postfix postfix-pgsql postfix-pcre

Während der Installation von postfix wird man gefragt, wie man postfix konfigurieren will, dort wählt man “Internet Site” aus (wobei dies später irrelevant ist, da wir die Konfiguration komplett selbst schreiben).

Datenbankverbindung konfigurieren

Damit postfix mit den Accounts, die in postfixadmin angelegt werden zusammenarbeitet, müssen wir verschiedene SQL-Queries anlegen:

relay-domains.cf:

user            = postfix
password        = xxxxxxx
dbname          = postfix
hosts           = localhost
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = true

virtual-alias-maps.cf:

user             = postfix
password         = xxxxxxxx
dbname           = postfix
hosts            = localhost
query = SELECT goto FROM alias WHERE address='%s' AND active = true

virtual-domain-maps.cf:

user             = postfix
password         = xxxxxxxx
dbname           = postfix
hosts            = localhost
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = false AND active = true

virtual-mailbox-limit-maps.cf:

user             = postfix
password         = xxxxxxxx
dbname           = postfix
hosts            = localhost
query = SELECT quota FROM mailbox WHERE username = '%s' AND active = true

virtual-mailbox-maps.cf:

user             = postfix
password         = xxxxxxxx
dbname           = postfix
hosts            = localhost
query = SELECT maildir || 'maildir' || '/' FROM mailbox WHERE username='%s' AND active = true

recipient checks

Mit recipient checks kann man E-Mailadressen anhand von regulären Ausdrücken prüfen und dadurch Mails entweder annehmen oder ablehnen. Hier werden invalide E-Mailadressen, bzw. welche mit “seltsamer” Syntax abgewiesen und E-Mails an postmaster, hostmaster, webmaster und abuse immer angenommen.

/etc/postfix/recipient_checks.pcre:

/^\@/             550 Invalid address format.
/[!%\@].*\@/      550 This server disallows weird address syntax.
/^postmaster\@/   OK
/^hostmaster\@/   OK
/^webmaster\@/    OK
/^abuse\@/        OK

mx access

Über diese Datei werden E-Mails von Gegenstellen aus privaten IP-Blöcken, bzw. von Broadcast- und Multicast-Netzen von vorneherein abgewiesen, da diese im Internet prinzipiell nicht geroutet werden und es sich dabei mit extrem hoher Wahrscheinlichkeit um Spam handelt.

/etc/postfix/mx_access:

0.0.0.0/8         REJECT Domain MX in broadcast network
10.0.0.0/8        REJECT Domain MX in RFC 1918 private network
127.0.0.0/8       REJECT Domain MX in loopback network
169.254.0.0/16    REJECT Domain MX in link local network
172.16.0.0/12     REJECT Domain MX in RFC 1918 private network
192.0.2.0/24      REJECT Domain MX in TEST-NET network
192.168.0.0/16    REJECT Domain MX in RFC 1918 private network
224.0.0.0/4       REJECT Domain MX in class D multicast network
240.0.0.0/5       REJECT Domain MX in class E reserved network
248.0.0.0/5       REJECT Domain MX in reserved network

Nun muss daraus noch eine postfix-lookup table erstellt werden:

postmap /etc/postfix/mx_access

main.cf

Nun müssen wir noch postfix konfigurieren und alle Teilkonfigurationen, die wir gerade erstellt haben zusammenfügen. Dies geschieht über die Datei “/etc/postfix/main.cf“:

# -------------------- GENERAL PART START --------------------
allow_percent_hack = no
biff = no
disable_vrfy_command = yes
 
mydestination = $myhostname, $mydomain, localhost
mydomain = domain.tld
myhostname = mail.domain.tld
mynetworks_style = host
myorigin = $mydomain
 
#home_mailbox = Maildir/
#mailbox_size_limit = 2147483648
#message_size_limit = 209715200
local_transport = dovecot
masquerade_exceptions = root
recipient_delimiter = +
# -------------------- GENERAL PART END --------------------
 
# -------------------- VIRTUAL PART START --------------------
virtual_mailbox_base = /var/vmail
relay_domains = proxy:pgsql:/etc/postfix/pgsql/relay-domain-maps.cf
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/pgsql/virtual-mailbox-maps.cf
virtual_mailbox_domains = proxy:pgsql:/etc/postfix/pgsql/virtual-domain-maps.cf
virtual_alias_maps = proxy:pgsql:/etc/postfix/pgsql/virtual-alias-maps.cf
virtual_minimum_uid = 150
virtual_uid_maps = static:150
virtual_gid_maps = static:8
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
unknown_local_recipient_reject_code = 550
# -------------------- VIRTUAL PART END --------------------
 
# -------------------- RESTRICTIONS PART START --------------------
smtpd_delay_reject = yes
smtpd_helo_required = yes
 
smtpd_client_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unknown_reverse_client_hostname,
  permit
smtpd_data_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unauth_pipelining,
  permit
smtpd_helo_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_invalid_helo_hostname,
  reject_non_fqdn_helo_hostname,
  permit
smtpd_recipient_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_non_fqdn_recipient,
  reject_unknown_recipient_domain,
  check_recipient_mx_access cidr:/etc/postfix/mx_access,
  reject_unauth_destination,
  check_recipient_access pcre:/etc/postfix/recipient_checks.pcre,
###  check_policy_service inet:127.0.0.1:12525,
  permit
smtpd_sender_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_non_fqdn_sender,
  reject_unknown_sender_domain,
  permit
# -------------------- RESTRICTIONS PART END --------------------
 
# -------------------- SASL PART START --------------------
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl2_auth_enable = yes
smtpd_sasl_local_domain = 
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
# -------------------- SASL PART END --------------------
 
# -------------------- TLS PART START --------------------
smtpd_use_tls = yes
smtpd_tls_security_level = may
#smtpd_tls_auth_only = yes
smtpd_tls_CAfile = /etc/postfix/ssl/demoCA/cacert.pem
smtpd_tls_cert_file = /etc/postfix/ssl/server-crt.pem
smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem
smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem
smtpd_tls_key_file = /etc/postfix/ssl/server-key.pem
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_tls_session_cache
# -------------------- TLS PART END --------------------

master.cf

Ans Ende der “/etc/postfix/master.cf” anhängen:

# Dovecot LDA
dovecot unix - n n - - pipe
flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/deliver -d ${recipient}

Will man auch smtps (Port 465) zulassen, so entfernt man die Raute-Zeichen vor den untenstehenden Zeilen, damit sie wie folgt aussehen (die Leerzeichen vor der zweiten Zeile sind essentiell):

smtps     inet  n       -       -       -       -       smtpd
  -o smtpd_tls_wrappermode=yes

smpts kann nützlich sein, wenn Port 25 aus irgend einem Grund gesperrt sein sollte, denn es operiert auf Port 465, welcher seltener gesperrt ist (zumindest in Studentenwohnheimen und Universitäten), zusätzlich bietet es einen höheren Schutz als plaintext-smtp (doch einen geringeren als smtp+tls).

dovecot

Nun folgt die Konfiguration des dovecot E-Mail-Servers. Zunächst wird dovecot über aptitude:

aptitude install dovecot-imapd dovecot-pop3d

Jetzt wird dovecot noch konfiguriert:

/etc/dovecot/dovecot.conf:

## Dovecot configuration file
 
base_dir = /var/run/dovecot/
 
# imap imaps pop3 pop3s (use imaps and pop3s if configured for SSL)
protocols = imaps imap pop3s pop3 managesieve
 
# Uncomment the ssl_listen statements and comment out listen if using SSL
protocol imap {
  listen = *:143
  ssl_listen = *:993
}
 
protocol pop3 {
  listen = *:110
  ssl_listen = *:995
}
 
protocol managesieve {
  listen = *:2000
}
 
log_timestamp = “%Y-%m-%d %H:%M:%S ”
syslog_facility = mail
 
# Where the mailboxes are located
mail_location = maildir:/var/vmail/%d/%n/maildir
mail_access_groups = vmail
mail_debug = yes
first_valid_uid = 150
last_valid_uid = 150
maildir_copy_with_hardlinks = yes
 
protocol imap {
  login_executable = /usr/lib/dovecot/imap-login
  mail_executable = /usr/lib/dovecot/imap
  imap_max_line_length = 65536
  mail_plugins = quota imap_quota
  imap_client_workarounds = outlook-idle delay-newmail
}
 
protocol pop3 {
  login_executable = /usr/lib/dovecot/pop3-login
  mail_executable = /usr/lib/dovecot/pop3
  pop3_uidl_format = %08Xu%08Xv
  mail_plugins = quota
  pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
 
protocol lda {
  postmaster_address = postmaster@ibutho.de
  sendmail_path = /usr/lib/sendmail
  auth_socket_path = /var/run/dovecot/auth-master
  mail_plugins = quota cmusieve
  sieve_global_path = /var/vmail/default.sieve
  log_path = /var/log/dovecot-deliver.log
  info_log_path = /var/log/dovecot-deliver.log
}
 
protocol managesieve {
  sieve = /var/vmail/%d/%n/dovecot.sieve
  sieve_storage = /var/vmail/%d/%n/sieve
}
 
auth_verbose = no
auth_debug = yes
#auth_debug_passwords = yes
 
auth default {
 mechanisms = plain login
 
 passdb sql {
   args = /etc/dovecot/dovecot-sql.conf
 }
 
 userdb sql {
   args = /etc/dovecot/dovecot-sql.conf
 }
 
 userdb prefetch {
 }
 
 user = nobody
 
 socket listen {
  master {
    path = /var/run/dovecot/auth-master
    mode = 0660
    user = vmail
    group = mail
  }
 
  client {
    path = /var/spool/postfix/private/auth
    mode = 0660
    user = postfix
    group = postfix
  }
 }
}
 
dict {
}
 
plugin {
  acl = vfile:/etc/dovecot/acls
  sieve = /var/vmail/%d/%n/dovecot.sieve
}
 
# Uncomment these if using SSL
ssl_cert_file = /etc/ssl/certs/ibutho_server.pem
ssl_key_file = /etc/ssl/private/ibutho_privatekey.pem
ssl_ca_file = /etc/ssl/certs/root.pem
ssl_parameters_regenerate = 168
verbose_ssl = no
# If you want client certificates, use these lines
# ssl_verify_client_cert = yes
# ssl_require_client_cert = yes
# ssl_username_from_cert = yes

Damit das logging nach “/var/log/dovecot-deliver.log” funktioniert, muss die Datei mit entsprechenden Rechten ausgestattet sein:

touch /var/log/dovecot-deliver.log
chmod 640 /var/log/dovecot-deliver.log
chown vmail:mail /var/log/dovecot-deliver.log

/etc/dovecot/dovecot-sql.conf:

driver = pgsql
connect = host=localhost dbname=postfix user=postfix password=xxxxxxxx
default_pass_scheme = MD5
 
user_query = SELECT '/var/vmail/' || maildir AS home, 'maildir:/var/vmail/' || maildir || 'maildir' AS mail, 150 AS uid, 8 AS gid, 'maildir:storage=' || quota AS quota FROM mailbox WHERE local_part = split_part('%n', '+', 1) AND domain = '%d'  AND active = true
 
password_query = SELECT username AS user, password, '/var/vmail/' || maildir AS userdb_home, 'maildir:/var/vmail/' || maildir || 'maildir' AS userdb_mail, 150 as userdb_uid, 8 as userdb_gid FROM mailbox WHERE username = '%u' AND active = true

Testen der Konfiguration

Zuerst kann man serverseitig mittels “netstat -tulpen” testen, ob der Server auf allen beabsichtigten Ports lauscht (110, 143, 993, 995, 2000). Danach kann man mittels “telnet SERVER_IP 143“, bzw. “telnet SERVER_IP 110” testen, ob man eine Verbindung bekommt. Ist dies der Fall, bietet es sich an auszuprobieren, ob man mit einem Mailprogramm auf das Postfach zugreifen kann (es muss natürlich eins in postfixadmin angelegt sein), bzw. ob man auch Mails empfangen und versenden kann.
Ein weiterer wichtiger Test, den man durchführen sollte, ist, ob der Mailserver als “open relay” missbraucht werden kann (kurz und knapp heißt das, ob der Server möglicherweise eine “Spam-Schleuder” ist). Dies kann man u.a. hier testen: http://www.abuse.net/relay.html. Sollten alle Tests Erfolg haben, hat man einen funktionsfähigen Mailserver.

Quellen:
postfixadmin/DOCUMENTS/POSTFIX_CONF.txt

http://blog.schalanda.name/archives/178-EUserv-vServer-Active-Installation-des-Mailsystems.html

http://codepoets.co.uk/postfixadmin-postgresql-courier-squirrelmail-debian-etch-howto-tutorial

http://wiki.rootforum.de/mailserver/postfix

http://wiki.rootforum.de/mailserver/postfix/postfix-admin

http://forum.rootforum.de/viewtopic.php?f=111&t=46643

http://www.postfix.org/postconf.5.html

http://wiki.dovecot.org/MainConfig

http://wiki.dovecot.org/ManageSieve

http://wiki.dovecot.org/LDA/Sieve

http://wiki.dovecot.org/HowTo/DovecotLDAPostfixAdminMySQL

Der neue Server: Teil 4 apache

Nachfolgend stelle ich vor, wie man apache2 inkl. php, sowie ruby über fastcgi installiert. php, bzw. ruby über fastcgi einzubinden bietet den Vorteil, dass die Skripts immer mit Benutzerrechten und nicht mit den rechten des Webserver ausgeführt werden. Zudem kann man so für jeden vHost eine eigene php.ini anlegen.

Installation und Konfiguration

aptitude install apache2 apache2-suexec libapache2-mod-fcgid php5-cgi

Dieser Befehl installiert das apache2- und php5-Grundsystem. Ruby werden wir später installieren, sobald apache und php funktionieren.
Nun aktivieren wir einige apache2-mods:

a2enmod ssl
a2enmod rewrite
a2enmod suexec
a2enmod fcgid
/etc/init.d/apache2 force-reload

Nun legen wir noch einen Benutzer an, unter dem Skripts ausgeführt werden, die nicht direkt einem bestimmten Benutzer zugeordnet werden können (wichtig ist, dass dieser Benutzer eine GID>100 hat):

adduser --system --group --no-create-home www-user

Jetzt ist es an der Zeit die vHost-Strukturen unter “/var/www/” anzulegen. Für jeden vHost wird ein eigener Ordner erstellt und enthält mehrere Unterordner:

  • conf – enthält die php.ini, sowie die fcgi-Konfiguration
  • docs – das Webroot
  • log – enthält die Log-Dateien
  • tmp – für temporäre Dateien
mkdir /var/www/example.com
cd /var/www/example.com/
mkdir conf
mkdir docs
mkdir logs
mkdir tmp
cd /var/www/
chmod 755 -R example.com

Als Nächstes legen wir unter “/var/www/example.com/conf” einen Symlink auf “/etc/php5/cgi/php.ini” an:

ln -s /etc/php5/cgi/php.ini /var/www/example.com/conf/php.ini

Das hat den Vorteil, dass alle vHosts standardmäßig die gleiche php.ini benutzen, man diese aber sehr leicht austauschen kann, falls man bestimmte vHost-spezifische Anpassungen vornehmen muss.
Dann legen wir noch einen fcgi-Starter an:

/var/www/example.com/conf/php-fcgi.conf:

#!/bin/sh
PHPRC="/var/www/example.com/conf"
export PHPRC
#PHP_FCGI_CHILDREN=3
#export PHP_FCGI_CHILDREN
exec /usr/bin/php5-cgi
chmod 755 /var/www/example.com/conf/php-fcgi.conf

Wenn man nun einen neuen vHost erstellt, muss nur dieser komplette Ordner kopiert werden, die Zeile “PHPRC=”/var/www/example.com/conf” angepasst werden, sowie das immutable-bit für die Datei php-fcgi.conf, bzw. php.ini gesetzt werden.

chattr +i /var/www/<ORDNERNAME>/conf/php-fcgi.conf
chattr +i /var/www/<ORDNERNAME>/conf/php.ini

Jetzt muss nur noch eine vHost-Konfiguration für apache angelegt werden. Hierfür legen wir unter “/etc/apache2/sites-available/example.com” ein Template an, welches dann kopiert und angepasst werden kann:

<VirtualHost *:80>
        SuExecUserGroup {USER} {GROUP}
 
        ServerName {SRV_NAME}
#       ServerAlias {SRV_ALIAS}
        ServerAdmin {SRV_ADMIN}
 
        DocumentRoot {DOC_ROOT}
        AddHandler fcgid-script .php
        <Directory {DOC_ROOT}>
                FCGIWrapper {CONF_ROOT}/php-fcgi.conf .php
                Options +SymLinksIfOwnerMatch +MultiViews +ExecCGI -Indexes
                AllowOverride FileInfo
                Order allow,deny
                allow from all
        </Directory>
 
        ErrorLog {LOG_ROOT}/error.log
        CustomLog {LOG_ROOT}/access.log combined
        LogLevel warn
        ServerSignature Off
</VirtualHost>

Um den vHost zu aktivieren, muss man noch folgenden Befehl absetzen:

a2ensite <VHOST_NAME>

Danach noch die apache-Konfiguration neu einlesen und der vHost ist einsatzbereit.

Quellen:
http://wiki.hetzner.de/index.php/Apache_PHP5_fcgi_und_SuExec

php-Addons

aptitude install php5-gd php5-imagick php5-mcrypt php5-mysql php5-pgsql php5-imap php5-suhosin

gd und imagick sind hierbei Bibliotheken zur Bildmanipulation, mcrypt bietet Verschlüsselungsfunktionen, mysql und pgsql sind für den Datenbankzugriff, imap bietet Funktionen zur Interaktion mit einem IMAP-Server und suhosin ist eine Sicherheitserweiterung für php.

ruby

Nun folgt noch die Installation von ruby und ruby on rails – ebenfalls als fastcgi:

 aptitude install ruby rdoc irb rubygems libfcgi-ruby1.8 libmysql-ruby libpgsql-ruby rails libopenssl-ruby1.8

Da fastcgi schon konfiguriert ist, funktioniert ruby, bzw. RoR ohne weitere Konfiguration.

rails über gem installieren

Alternativ kann man rails auch über gem, anstatt über aptitude installieren. Dazu führt man diesen Befehl aus:

gem install rails

Und ändert anschließend “/etc/profile” und nimmt “/var/lib/gems/1.8/bin” in $PATH mit auf (vor “export PATH” hinzufügen):

# add rails to path
PATH="$PATH:/var/lib/gems/1.8/bin"

Quellen:
http://howtoforge.net/ruby_on_rails_debian_etch

Der neue Server: Teil 3 svn, mysql, postgres

Mit diesem Beitrag beginnt nun eine kleine Reihe, wie man verschiedene Serverdienste installiert und konfiguriert. Angefangen wird mit dem Versionskontrollsystem svn (auch unter dem Namen subversion bekannt) und zwei verschiedenen Datenbanksystemen: mysql und postgreSQL.

subversion

SVN wird über den Internet-Superserver xinetd betrieben und hört standardmäßig auf Port 3690. Die Repositories samt ihrer Konfigurationsdateien werden später unter “/var/svn” liegen und der Server wird unter dem Benutzer “svn” laufen.

Zunächst installieren wir xinetd und svn:

aptitude install xinetd subversion

Danach erstellen wir den svn-Benutzer:

adduser --system --group --no-create-home svn

Jetzt registrieren wir Port 3690 für svn:

/etc/services:

# Local services
svn 3690/tcp # subversion
svn 3690/udp # subversion

… erstellen den Ordner “/var/svn”:

mkdir /var/svn/
chown svn: /var/svn/
chmod 755 /var/svn/

… und konfigurieren xinetd, damit er auf Port 3690 Verbindungen für svn entgegennimmt und sie an den svnserve-Server weitergibt:

/etc/xinetd.d/svn

# default: on
# description: Subversion server process
service svn
{
    disable             = no
    socket_type         = stream
    protocol            = tcp
    user                = svn
    wait                = no
    port                = 3690
    server              = /usr/bin/svnserve
    server_args         = -i -r /var/svn/
}

Nun kann man mit dem telnet-Befehl von einem anderen Rechner aus testen, ob svn auf Port 3690 lauscht:

telnet SERVER_IP 3690

Die Ausgabe sollte dann so aussehn:

Trying SERVER_IP...
Connected to SERVER_IP.
Escape character is '^]'.
( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops partial-replay ) ) ) Connection closed by foreign host.

Mittels des svnadmin-Tools kann man nun Repositories anlegen, verändern, löschen, …

svnadmin create --fs-type fsfs /var/svn/testRepo

Was man mit svn alles anstellen kann, wird hier sehr ausführlich beschrieben: http://svnbook.red-bean.com/. Dieses Buch ist wohl das Standardwerk, wenn es um svn geht und ein weiterer Stern am O’Reilly-Himmel und das Tollste ist: die Online-Version kostet nicht einmal was.

mysql

Man mag von mysql halten, was man will, doch es ist (leider) das Standard-Datenbanksystem für Web-Anwendungen (ein paar Gedanken zu mysql kann man hier finden). Der Vorteil von mysql ist, dass es sehr einfach in der Installation und Handhabung ist, die Nachteile…. naja, findets selbst heraus.

aptitude install mysql-server

Während der Installation wird man nach einem Passwort für den mysql-root Benutzer gefragt. Danach kann man ggf. noch die Konfiguration anpassen (liegt unter “/etc/mysql/my.cnf“). Ein gutes Beispiel für eine mysql-Konfiguration kann man hier finden: http://forum.rootforum.de/viewtopic.php?f=104&t=36343. Eine Anmerkung: wenn man die empfohlene Konfiguration auf rootforum.de benutzt und über phpMyAdmin auf die Datenbank zugreifen will, sollte man die Zeile “skip_show_database” auskommentieren, ansonsten sehen die Benutzer (root ausgenommen) ihre Datenbanken nicht.

Da wir nicht nur eine optimierte Installation, sondern auch eine sichere wollen, führen wir nun noch das “mysql_secure_installation”-Skript aus und beantworten alle Fragen, abgesehen von der über das mysql-root Passwort, mit der Standardantwort.

Quellen:

http://forum.rootforum.de/viewtopic.php?f=104&t=36343

postgres

Kommen wir zu einem richtigen Datenbanksystem: postgres. postgres ist ein freies, quelloffenes (open-source auf “Neudeutsch”) Datenbanksystem, welches komplett ANSI-SQL92 konform ist (das kann manch kommerzielles Datenbanksystem nicht einmal von sich behaupten), unterstützt unter anderem ACID-Transaktionen und Stored Procedures und weitere fortgeschrittene Datenbank-Konzepte. Es erfreut sich einer immer größer werdenden Beliebtheit und löst mysql in vielen Gebieten ab. Dennoch will ich hier nicht zu viel Werbung machen. Jeder sollte sich selbst Gedanken über das Datenbanksystem machen, das er einsetzt und warum er es einsetzt. Doch wenn man ein Projekt hochziehen will, bei dem man auf fortschrittliche Datenbank-Konzepte zurückgreift, bleiben im open-source Umfeld nicht viele Lösungen übrig.
Die Installation gestaltet sich ähnlich einfach wie bei mysql:

aptitude install postgresql-8.3

Die Konfiguration gestaltet sich etwas anders als die von mysql. Sie ist im wesentlichen mehr an Oracle angelehnt. Über die Datei “pg_hba.conf” kann man Zugriffsrechte vergeben. Wenn man einen Benutzer anlegt, wird standardmäßig auch eine Datenbank mit dem selben Namen erstellt, autoincrement-Werte werden etwas anders definiert als bei mysql, des Weiteren heißen einige Datentypen geringfügig anders, doch die postgres-Dokumentation hilft hier weiter: http://www.postgresql.org/docs/current/static/.
Beispielhaft hier noch Code, wie man einen Benutzer anlegen kann:

su - postgres
createuser -P

Danach wird man nach dem Passwort und der Benutzerrolle gefragt und man kann mit folgendem Code auf die postgres-Konsole zugreifen:

psql -W <Tabellenname>

In einem weiteren Teil gehe ich dann darauf ein, wie man phpMyAdmin und phpPgAdmin einrichtet.