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 "
SSLEngine on
SSLCertificateFile /etc/ssl/certs/server.pem
SSLCertificateKeyFile /etc/ssl/private/privatekey.pem
SSLCipherSuite HIGH
SSLProtocol all -SSLv2Weiter 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 chrootedUm 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
<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.
fetchmail Integration in postfixadmin
Viele Benutzer haben auch Mailboxen bei anderen Anbietern, z.B. bei gmx oder web.de. Damit diese Benutzer ihre E-Mails aggregieren können, wird fetchmail eingerichtet. fetchmail ist bereits in postfixadmin integriert, somit können fetchmail-Einträge über postfixadmin verwaltet werden (derzeit leider nur von Administratoren). Über das mitgelieferte fetchmail.pl-Skript werden die Daten aus der Datenbank ausgelesen, fetchmail aufgerufen, die Mails durch amavisd-new überprüft und an die Mailboxen der Benutzer ausgeliefert. Das perl-Skript wurde etwas angepasst, damit es mit postgres interagieren kann. Des Weiteren wurden die Dateinamen etwas angepasst.
Installation:
aptitude install fetchmail aptitude install liblockfile-simple-perl
Nötige Verzeichnisse für das Skript anlegen:
mkdir /var/run/fetchmail touch /var/run/fetchmail/fetchmail-all.lock
Das Skript:
fetchmail.pl
#!/usr/bin/perl use DBI; use MIME::Base64; # use Data::Dumper; use File::Temp qw/ mkstemp /; use Sys::Syslog; # require liblockfile-simple-perl use LockFile::Simple qw(lock trylock unlock); openlog("fetchmail-all", "pid", "mail"); sub log_and_die { my($message) = @_; syslog("err", $message); die $message; } # read options and arguments $configfile = "/etc/fetchmail/config"; @ARGS1 = @ARGV; while ($_ = shift @ARGS1) { if (/^-/) { if (/^--config$/) { $configfile = shift @ARGS1 } } } # postgres settings $database="postfix"; $hostname="127.0.0.1"; $user="postfix"; $password="XXXXXX"; $run_dir="/var/run/fetchmail"; # use specified config file if (-e $configfile) { do $configfile; } $dsn = "DBI:Pg:database=$database;host=$hostname"; $lock_file=$run_dir . "/fetchmail-all.lock"; $lockmgr = LockFile::Simple->make(-autoclean => 1, -max => 1); $lockmgr->lock($lock_file) || log_and_die "can't lock ${lock_file}"; #postgres connect $dbh = DBI->connect($dsn, $user, $password) || log_and_die "cannot connect the database"; $sql=<<SQL; SELECT id,mailbox,src_server,src_auth,src_user,src_password,src_folder,fetchall,keep,protocol,mda,extra_options,usessl FROM fetchmail WHERE date_part('epoch',now())-date_part('epoch',date) > poll_time*60 SQL my (%config); map{ my ($id,$mailbox,$src_server,$src_auth,$src_user,$src_password,$src_folder,$fetchall,$keep,$protocol,$mda,$extra_options,$usessl)=@$_; syslog("info","fetch ${src_user}@${src_server} for ${mailbox}"); $cmd="user '${src_user}' there with password '".decode_base64($src_password)."'"; $cmd.=" folder '${src_folder}'" if ($src_folder); $cmd.=" mda ".$mda if ($mda); # $cmd.=" mda \"/usr/local/libexec/dovecot/deliver -m ${mailbox}\""; $cmd.=" is '${mailbox}' here"; $cmd.=" keep" if ($keep); $cmd.=" fetchall" if ($fetchall); $cmd.=" ssl" if ($usessl); $cmd.=" ".$extra_options if ($extra_options); $text=<<TXT; set postmaster "postmaster" set nobouncemail set no spambounce set properties "" set syslog poll ${src_server} with proto ${protocol} $cmd TXT ($file_handler, $filename) = mkstemp( "/tmp/fetchmail-all-XXXXX" ) or log_and_die "cannot open/create fetchmail temp file"; print $file_handler $text; close $file_handler; $ret=`/usr/bin/fetchmail -f $filename -i $run_dir/fetchmail.pid`; unlink $filename; $sql="UPDATE fetchmail SET returned_text=".$dbh->quote($ret).", date=now() WHERE id=".$id; $dbh->do($sql); }@{$dbh->selectall_arrayref($sql)}; $lockmgr->unlock($lock_file); closelog();
Damit das Skript regelmäßig ausgeführt wird, legen wir einen Cronjob dafür an (als Benutzer root). In der hier gezeigten Konfiguration wird das Skript alle 5 Minuten ausgeführt.
crontab -e:
*/5 * * * * /PFAD/ZU/fetchmail.pl &> /dev/null
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
