In diesem Tutorial handelt es sich um die Installation eines Mailservers mit Exim4, Courier und einem vollen MySQL-Backend für virtuelle Benutzer.
Voraussetzung für diese Installation ist ein Debian Wheezy Server.
1.0 Pakete installieren
Wichtige Pakete installieren:
apt-get install exim4-daemon-heavy libsasl2-modules-sql courier-pop courier-imap courier-authlib-mysql maildrop mysql-server php5 php5-mysql
Notiz:
MySQL Root Kennwort sorgfälltig wählen!
2.0 Weitere Datenbank/DB-User für virtuelle Benutzer anlegen
mysql -u root -p
Root Passwort eintippen….
CREATE USER 'maildb'@'maildb' IDENTIFIED BY ''; GRANT USAGE ON * . * TO 'maildb'@'maildb' IDENTIFIED BY '' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ; CREATE DATABASE IF NOT EXISTS `maildb` ; GRANT ALL PRIVILEGES ON `maildb` . * TO 'maildb'@'maildb';
Hier bitte die Variable gegen ein richtiges Passwort für den Benutzer maildb ersetzen und diese gut merken.
Diesen Benutzer werden wir benötigen um unserem Mailserver mitzuteilen mit welchen Logindaten er auf die Datenbank „maildb“ zugreien darf.
[AdSense-A]
2.1 Anlegen der nötigen Tabellen
USE maildb; CREATE TABLE IF NOT EXISTS `domains` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `domain` varchar(255) NOT NULL DEFAULT '', `aliasdomain` int(11) unsigned DEFAULT NULL, PRIMARY KEY (`id`), KEY `domain` (`domain`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `email` varchar(255) NOT NULL DEFAULT '', `username` varchar(255) NOT NULL DEFAULT '', `password` varchar(128) NOT NULL DEFAULT '', `uid` int(11) NOT NULL DEFAULT '2000', `gid` int(11) NOT NULL DEFAULT '2000', `homedir` varchar(255) NOT NULL DEFAULT '/home/mailusers/', `maildir` varchar(255) NOT NULL DEFAULT '', `domainid` int(11) unsigned NOT NULL DEFAULT '0', `quota` bigint(13) NOT NULL DEFAULT '0', `pop3` tinyint(1) NOT NULL DEFAULT '1', `imap` tinyint(1) NOT NULL DEFAULT '1', FOREIGN KEY (domainid) REFERENCES domains(id) ON UPDATE CASCADE ON DELETE CASCADE, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `virtual` ( `id` int(11) NOT NULL AUTO_INCREMENT, `email` varchar(255) NOT NULL DEFAULT '', `email_full` varchar(255) NOT NULL DEFAULT '', `destination` text NOT NULL, `domainid` int(11) unsigned NOT NULL DEFAULT '0', `popaccountid` int(11) unsigned NOT NULL DEFAULT '0', `iscatchall` tinyint(1) unsigned NOT NULL DEFAULT '0', FOREIGN KEY (domainid) REFERENCES domains(id) ON UPDATE CASCADE ON DELETE CASCADE, FOREIGN KEY (popaccountid) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE, PRIMARY KEY (`id`), KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
3.0 Re-Konfiguration von Exim4
Als erstes sollten wir die Standardkonfiguration vom Exim4 ändern. Dazu konfigurieren wir mittels DPKG das Paket um.
Re-Konfiguration von Exm4:
dpkg-reconfigure exim4-config
Konfiguration:
General type of mail configuation: internet site; mail is sent and received directly using smtp System mail name: ihredomain.tld IP-addresses to listen on for incoming SMTP connections: 0.0.0.0 Other destinations for which mail is accepted: Ihre statische IP-Adresse Domains to relay mail for: Keine Angabe Machines to relay mail for: Keine Angabe Keep number of DNS-queries minimal: no Delivery method for local mail: Maildir format in home directory Split configuration into small files?: yes Root and postmaster mail recipient: Keine Angabe
3.1 Verzeichnisse anlegen
Als nächstes legen wir uns das erste Verzeichnis an. example.tld ist ihre Domain sowie „user“ ihr gewünschter Username.
mkdir /home/mailusers/example.tld/user/ maildirmake /home/mailusers/example.tld/user/Maildir
3.2 User anlegen
Hier legen wir uns den Systembenutzer für den Zugriff auf die Emails an und weisen ihm das Verzeichnis
/home/mailusers zu.
groupadd -g 2000 vmail useradd -u 2000 -s /bin/false -d /bin/null -g vmail vmail chown -R 2000:2000 /home/mailusers
3.3 Exim4 auf MySQL umstellen
Als nächstes müssen wir einige Konfigurationen an den Konfigdateien von Exim4 vornehmen:
cd /etc/exim4/conf.d/
nano auth/30_exim4-config
Inhalt einsetzen und als neue Datei speichern:
plain_server: driver = plaintext public_name = PLAIN server_condition = "${if and { \ {!eq{$2}{}} \ {!eq{$3}{}} \ {crypteq{$3}{${lookup mysql{PHPDEV_AUTH_LOGIN}{$value}fail}}} \ } {yes}{no}}" server_set_id = $2 server_prompts = : # .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS # server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}} # .endif login_server: driver = plaintext public_name = LOGIN server_prompts = "Username:: : Password::" server_condition = "${if and { \ {!eq{$1}{}} \ {!eq{$2}{}} \ {crypteq{$2}{${lookup mysql{PHPDEV_AUTH_LOGIN}{$value}fail}}} \ } {yes}{no}}" server_set_id = $1 # .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS # server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}} # .endif
nano main/10_exim4-config_options
Inhalt einfügen und speichern:
hide mysql_servers = 127.0.0.1/maildb/maildb/ PHPDEV_LOCAL_DOMAIN = SELECT domain FROM domains WHERE domain = '${quote_mysql:$domain}' PHPDEV_MAILALIAS = SELECT REPLACE(destination,' ',',') FROM virtual WHERE \ (( email = '${quote_mysql:$local_part}@${quote_mysql:$domain}' ) \ OR ( email = '@${quote_mysql:$domain}' AND iscatchall > 0 )) \ AND destination <> '' AND destination <> ' ' ORDER BY iscatchall ASC LIMIT 1 PHPDEV_MAILUSER = SELECT CONCAT(homedir,maildir) FROM users WHERE \ email = '${quote_mysql:$local_part}@${quote_mysql:$domain}' PHPDEV_PARENT_DOMAIN = SELECT parent.domain FROM `domains` AS parent INNER JOIN domains AS alias \ ON alias.domain = '${quote_mysql:$domain}' AND parent.id = alias.aliasdomain PHPDEV_AUTH_PLAIN = SELECT password FROM users WHERE username = '${quote_mysql:$2}' PHPDEV_AUTH_LOGIN = SELECT password FROM users WHERE username = '${quote_mysql:$1}' domainlist phpdev_domain = mysql;PHPDEV_LOCAL_DOMAIN
Hier sollten Sie gegen das Passwort des Datenbankbenutzers „maildb“ ersetzen.
nano router/180_exim4-config
Inhalt einfügen und speichern:
phpdev_mailalias: debug_print = "R: phpdev_mailalias for $local_part@$domain" driver = redirect domains = +phpdev_domain data = ${lookup mysql {PHPDEV_MAILALIAS}{$value}fail} phpdev_mailuser: debug_print = "R: phpdev_mailuser for $local_part@$domain" driver = redirect domains = +phpdev_domain data = ${lookup mysql {PHPDEV_MAILUSER}{$value}fail} directory_transport = maildir_phpdev no_more
nano transport/30_exim4-config
Inhalt einfügen und speichern:
maildir_phpdev: debug_print = "T: maildir_phpdev for $local_part@$domain" driver = appendfile create_directory delivery_date_add envelope_to_add return_path_add maildir_format directory_mode = 0770 mode = 0660 mode_fail_narrower = false user = 2000 group = 2000
[AdSense-A]
nano acl/30_exim4-config_check_rcpt
Inhalt ersetzen gegen:
### acl/30_exim4-config_check_rcpt ################################# acl_check_rcpt: accept hosts = : warn hosts = +relay_from_hosts control = submission/sender_retain .ifdef CHECK_RCPT_LOCAL_LOCALPARTS deny domains = +local_domains:+phpdev_domain local_parts = CHECK_RCPT_LOCAL_LOCALPARTS message = restricted characters in address .endif .ifdef CHECK_RCPT_REMOTE_LOCALPARTS deny domains = !+local_domains local_parts = CHECK_RCPT_REMOTE_LOCALPARTS message = restricted characters in address .endif accept .ifndef CHECK_RCPT_POSTMASTER local_parts = postmaster .else local_parts = CHECK_RCPT_POSTMASTER .endif domains = +local_domains:+phpdev_domain deny message = sender envelope address $sender_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster !acl = acl_local_deny_exceptions senders = ${if exists{CONFDIR/local_sender_blacklist}\ {CONFDIR/local_sender_blacklist}\ {}} deny message = sender IP address $sender_host_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster !acl = acl_local_deny_exceptions hosts = ${if exists{CONFDIR/local_host_blacklist}\ {CONFDIR/local_host_blacklist}\ {}} .ifdef CHECK_RCPT_VERIFY_SENDER deny message = Sender verification failed !acl = acl_local_deny_exceptions !verify = sender .endif deny !acl = acl_local_deny_exceptions senders = ${if exists{CONFDIR/local_sender_callout}\ {CONFDIR/local_sender_callout}\ {}} !verify = sender/callout deny !acl = acl_local_deny_exceptions recipients = ${if exists{CONFDIR/local_rcpt_callout}\ {CONFDIR/local_rcpt_callout}\ {}} !verify = recipient/callout .ifdef CHECK_RCPT_REVERSE_DNS warn message = X-Host-Lookup-Failed: Reverse DNS lookup failed for $sender_host_address (${if eq{$host_lookup_failed}{1}{failed}{deferred}}) condition = ${if and{{def:sender_host_address}{!def:sender_host_name}}\ {yes}{no}} .endif .ifdef CHECK_RCPT_IP_DNSBLS warn message = X-Warning: $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text) log_message = $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text) dnslists = CHECK_RCPT_IP_DNSBLS .endif .ifdef CHECK_RCPT_DOMAIN_DNSBLS warn message = X-Warning: $sender_address_domain is listed at $dnslist_domain ($dnslist_value: $dnslist_text) log_message = $sender_address_domain is listed at $dnslist_domain ($dnslist_value: $dnslist_text) !senders = ${if exists{CONFDIR/local_domain_dnsbl_whitelist}\ {CONFDIR/local_domain_dnsbl_whitelist}\ {}} dnslists = CHECK_RCPT_DOMAIN_DNSBLS/$sender_address_domain .endif .ifdef CHECK_RCPT_LOCAL_ACL_FILE .include CHECK_RCPT_LOCAL_ACL_FILE .endif accept domains = +local_domains:+phpdev_domain endpass message = unknown user verify = recipient accept domains = +relay_to_domains endpass .ifdef CHECK_RCPT_GIVE_UNKNOWN_USER message = ${if eq{$acl_verify_message}{Unrouteable address}{unknown user}{$acl_verify_message}} .else message = unrouteable address .endif verify = recipient ############ # If control reaches this point, the domain is neither in +local_domains # nor in +relay_to_domains. ############ accept hosts = +relay_from_hosts accept authenticated = * deny message = relay not permitted
Jetzt zu fast guter letzt noch den chmod für die Konfigurationen ändern und Exim4 neustarten.
chmod o-rx /var/lib/exim4 chmod o-rx /etc/exim4/conf.d/main/10_exim4-config_options /etc/init.d/exim4 restart
4.0 Konfiguration von POP und IMAP (Courier)
nano /etc/courier/authdaemonrc
Inhalt ersetzen gegen:
##VERSION: $Id: authdaemonrc.in,v 1.8 2001/10/07 02:16:22 mrsam Exp $ # # Copyright 2000-2001 Double Precision, Inc. See COPYING for # distribution information. # # authdaemonrc created from authdaemonrc.dist by sysconftool # # Do not alter lines that begin with ##, they are used when upgrading # this configuration. # # This file configures authdaemond, the resident authentication daemon. # # Comments in this file are ignored. Although this file is intended to # be sourced as a shell script, authdaemond parses it manually, so # the acceptable syntax is a bit limited. Multiline variable contents, # with the \ continuation character, are not allowed. Everything must # fit on one line. Do not use any additional whitespace for indentation, # or anything else. ##NAME: authmodulelist:0 # # The authentication modules that are linked into authdaemond. The # default list is installed. You may selectively disable modules simply # by removing them from the following list. The available modules you # can use are: authcustom authcram authuserdb authldap authmysql authpam authmodulelist="authmysql" ##NAME: authmodulelistorig:1 # # This setting is used by Courier's webadmin module, and should be left # alone authmodulelistorig="authcustom authcram authuserdb authldap authmysql authpam" ##NAME: daemons:0 # # The number of daemon processes that are started. authdaemon is typically # installed where authentication modules are relatively expensive: such # as authldap, or authmysql, so it's better to have a number of them running. # PLEASE NOTE: Some platforms may experience a problem if there's more than # one daemon. Specifically, SystemV derived platforms that use TLI with # socket emulation. I'm suspicious of TLI's ability to handle multiple # processes accepting connections on the same filesystem domain socket. # # You may need to increase daemons if as your system load increases. Symptoms # include sporadic authentication failures. If you start getting # authentication failures, increase daemons. However, the default of 5 # SHOULD be sufficient. Bumping up daemon count is only a short-term # solution. The permanent solution is to add more resources: RAM, faster # disks, faster CPUs... daemons=5 ##NAME: version:0 # # When you have multiple versions of authdaemond.* installed, authdaemond # just picks the first one it finds. Set "version" to override that. # For example: version=authdaemond.plain version="" ##NAME: authdaemonvar:0 # # authdaemonvar is here, but is not used directly by authdaemond. It's # used by various configuration and build scripts, so don't touch it! authdaemonvar=/var/run/courier/authdaemon
nano /etc/courier/authmysqlrc
Inhalt ersetzen gegen:
MYSQL_SERVER 127.0.0.1 MYSQL_USERNAME maildb MYSQL_PASSWORD MYSQL_PORT 3306 MYSQL_DATABASE maildb MYSQL_USER_TABLE users MYSQL_CRYPT_PWFIELD password MYSQL_UID_FIELD uid MYSQL_GID_FIELD gid MYSQL_LOGIN_FIELD username MYSQL_HOME_FIELD homedir MYSQL_MAILDIR_FIELD maildir MYSQL_QUOTA_FIELD (quota*1024*1024) MYSQL_AUXOPTIONS_FIELD CONCAT("allowimap=",imap,",allowpop3=",pop3)
Auch hier sollten sie den Platzhalter „“ gegen Ihr Passwort des Datenbankbenutzers „maildb“ ändern.
Als nächstes müssen sie Courier neustarten um die Konfigurationen zu übernehmen.
/etc/init.d/courier-authdaemon restart /etc/init.d/courier-pop restart
Sollten Sie jetzt noch das Interesse daran haben das Anlegen von Konten zu erleichtern können Sie mein Konfigurationsscript nutzen:
http://blog.php-dev.info/downloads/create_mail.7z
Nicht vergessen die Verbindungsdaten zum DBMS zu ändern!
Oder hier eine Komplette Konfiguration:
http://blog.php-dev.info/downloads/email.7z
Gude aus Hessen. Hab da mal ein Problem und das schon am Anfang wo ich nicht weiter weiss und wieso und weshalb …
Irgendwie möchte er die Table „virtual“ nicht anlegen. Ich erhalte folgende Meldung von Mysql :
#1005 – Can’t create table ‚maildb.virtual‘ (errno: 150)
Die 2 davor liefen ohne Probleme ab.Nur bei dieser Table kotzt Mysql rum. Da der Fehler 1005 eg errno:150 eher eine allgemeine Fehlerbeschreibung ist, frage ich dich woran das liegen kann…. so pls help me !!:-)
Gruß
innoDB aktiviert (sofern ältere MySQL-Version), ansonsten sollten Sie prüfen, dass Sie die jeweiligen Tabellen korrekt übernommen haben, insbesondere bzgl. der Datentypen der Primary-Keys. Die Fremdschlüssel müssen identisch zu den Primary-Keys sein.