Root-Server mit Ubuntu 18.04: Unterschied zwischen den Versionen
Lukas (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
Lukas (Diskussion | Beiträge) |
||
Zeile 125: | Zeile 125: | ||
Dann noch einige Apache-Module aktivieren: | Dann noch einige Apache-Module aktivieren: | ||
a2enmod ssl headers | a2enmod ssl headers cgi rewrite auth_basic authz_groupfile | ||
=== /etc/apache2/sites-available/000-default.conf === | === /etc/apache2/sites-available/000-default.conf === |
Version vom 4. Januar 2020, 20:25 Uhr
Mein alter Server läuft noch mit Ubuntu 16.04. Das ist erstmal kein Problem, der Support läuft noch, allerdings wird die aktuellste PHP-Version nicht unterstützt. Das macht bei einigen Anwendungen nun schon Probleme. Daher habe ich einen zweiten Server in der Serverbörse geordert. Die Rechner sind teurer geworden. Der Rechner ist vergleichbar mit dem alten, kostet aber 6€ mehr. Positiv ist, dass ich dadurch eine Ausfallsicherheit erreichen kann. Ich werde den neuen Server einrichten und anschließend den alten aktualisieren.
Der neue Rechner hat folgende Daten:
- Intel Core i7-2600 8x 3.40GHz (8x 6823.66 Bogomips)
- 16 GB Arbeitsspeicher
- 2x 3 TB im RAID1-Verbund Festplattenspeicher
Der Rechner kostet 30€/Monat.
Installation
Hetzner liefert die Geräte im Rescue-Modus aus. Das ist ein Minimal-Linux mit Tools zur Rettung und dem Skript installimage, mit dem eine Betriebssystem-Installation vorgenommen werden kann. Das ist schon mal ein großer Unterschied zu Strato, die die Rechner selber installieren und dann zur Verfügung stellen.
Der Robot (Kundencenter) von Hetzner bietet allerlei Möglichkeiten, so kann der Rechner bequem mit einem Strg + Alt + Entf-Befehl gefüttert werden oder per ACPI neugestartet werden. Zudem bietet Hetzner die Möglichkeit eines Weckens über LAN (WOL) und man kann bequem eigene Monitoring-Dienste für den Rechner anlegen, sodass man bei Unregelmäßigkeiten per Mail informiert wird.
Die Installation des Rechners erfolgt dann über den Befehl installimage
. Nach einer Auswahl des Betriebssystems kann man über eine Textdatei die RAID-Einstellungen, Festplattenpartitionierung und den Hostnamen konfigurieren. Das macht es besonders einfach, mehrere Rechner zu installieren oder sich die Konfiguration noch einmal abzuspeichern.
Nach dem Verlassen des Editors installiert der Rechner dann das Grundsystem, während man zugucken kann:
Hetzner Online GmbH - installimage Your server will be installed now, this will take some minutes You can abort at any time with CTRL+C ... : Reading configuration done : Loading image file variables done : Loading ubuntu specific functions done 1/16 : Deleting partitions done 2/16 : Test partition size done 3/16 : Creating partitions and /etc/fstab done 4/16 : Creating software RAID level 1 done 5/16 : Formatting partitions : formatting /dev/md/0 with swap done : formatting /dev/md/1 with ext2 done : formatting /dev/md/2 with ext4 done : formatting /dev/md/3 with xfs done : formatting /dev/md/4 with ext4 done : formatting /dev/md/5 with ext4 done 6/16 : Mounting partitions done 7/16 : Sync time via ntp done : Importing public key for image validation done 8/16 : Validating image before starting extraction done 9/16 : Extracting image (local) done 10/16 : Setting up network config done 11/16 : Executing additional commands : Setting hostname done : Generating new SSH keys done : Generating mdadm config done : Generating ramdisk done : Generating ntp config done 12/16 : Setting up miscellaneous files done 13/16 : Configuring authentication : Fetching SSH keys done : Disabling root password done : Disabling SSH root login without password done : Copying SSH keys done 14/16 : Installing bootloader grub done 15/16 : Running some ubuntu specific functions done 16/16 : Clearing log files done INSTALLATION COMPLETE You can now reboot and log in to your new system with the same password as you logged in to the rescue system. root@rescue ~ # reboot
Nach dem Neustart steht dann das neue System zur Verfügung. Die Installation hat letztlich mit Lektüre etwa 7 Minuten gedauert. Das ist ein enormer Fortschritt zu anderen Providern.
Grundlegendes
Die Installationsimages sind nicht unbedingt tagesaktuell, daher aktualisieren wir nach der Anmeldung als root erstmal die Software:
apt-get update apt-get dist-upgrade
Und ein paar Tools:
apt-get install vim htop whois aptitude needrestart git unzip
Firewall
Als Firewall lässt sich ufw nutzen. Das Paket muss nachinstalliert werden:
apt-get install ufw
und lässt sich dann einfach konfigurieren. ufw kann mit Softwarepaketen und einzelnen Ports umgehen:
ufw allow 22 ufw allow OpenSSH
Obiges zu setzen bevor die Firewall aktiviert wird, ist wichtig, da man sich sonst aus dem System aussperrt. Nach einer Aktivierung mittels
ufw enable
zeigt die Firewall auch automatisch Wirkung.
Überprüfen lässt sich der Status mit
ufw status
bzw.
ufw status numbered
So können auch Regeln gelöscht werden:
ufw delete 1
Hetzner bietet in der KonsoleH ebenfalls Möglichkeiten zur Firewallkonfiguration. Vielleicht kann man so sogar noch Last vom Rechner abwenden. Ich probiere das mal aus.
Damit nicht die syslog mit Firewall-Messages überläuft, deaktivieren wir das Logging in /etc/rsyslog.d/20-ufw.conf, letzte Zeile:
& stop
Webserver Apache2
Zur Bereitstellung von Webseiten nutze ich Apache als Webserver mit PHP. Da der Server unter mehreren Namen erreichbar sein wird, richten wir VirtualHosts ein.
Die Installation läuft denkbar einfach über
sudo apt-get update sudo apt-get install apache2 apache2-utils apache2-doc php php-mysql php-pear
Neben Apache gibt es ein paar Tools, Doku und neben PHP schon die Anbindung für MySQL und Apache. Apache kommt in der Version 2.4.29, bei PHP wird Version 7.2 installiert.
Nach der Installation geht es an die eigentliche Konfiguration des Webservers. Ziel ist es, das eine Reihe von Anwendungen (Roundcube, PHPMyAdmin, etc.) nur einmal installiert werden müssen und dann allen eingerichteten Domains zur Verfügung stehen. Gleichzeitig sollen Dummies, die den Server über seine IP oder einen nicht vorhandenen Namen ansprechen, keine Dienste nutzen können, sondern lediglich eine Fehler-Seite sehen. Die folgende Konfiguration habe ich in Teilen in ihrer Version vom 12. November 2014 aus dem Debacher-Wiki entnommen (CC-BY-SA). Wir legen also eine Grundkonfiguration für jeden "dummen" Aufruf an.
Die VHosts werden später unter /var/www/vhosts/ angelegt. Unter /var/www/vhosts/default/htdocs/ findet sich dann die Fehlerseite und unter /var/www/htdocs/ die entsprechenden Anwendungen. Die Ordner erstellen wir nun einmal. Dazu kopieren wir auch die Standard-Seite in das entsprechende Verzeichnis:
mkdir /var/www/htdocs mkdir /var/www/vhosts mkdir /var/www/vhosts/default mv /var/www/html /var/www/vhosts/default/htdocs
Wichtig ist, dass wir die Datei vorher einmal sichern:
cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/000-default.conf.org cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf.org
Dann noch einige Apache-Module aktivieren:
a2enmod ssl headers cgi rewrite auth_basic authz_groupfile
/etc/apache2/sites-available/000-default.conf
ServerName default ServerAdmin webmaster@example.org ServerTokens Prod DocumentRoot /var/www/htdocs <Directory /var/www/htdocs/> Options SymLinksIfOwnerMatch MultiViews AllowOverride None Order allow,deny allow from all </Directory> Alias /webmail /var/www/htdocs/roundcube Alias /roundcube /var/www/htdocs/roundcube Alias /pma /var/www/htdocs/pma Alias /webftp /var/www/htdocs/webftp <VirtualHost *:80> ServerName default ServerAdmin webmaster@example.org DocumentRoot /var/www/vhosts/default/htdocs <Directory /var/www/> Options -Indexes +SymLinksIfOwnerMatch +MultiViews AllowOverride None Order allow,deny allow from all </Directory> # Verhindern des Zugriffs auf die CGI-Skripte <Directory "/var/www/cgi-bin/"> AllowOverride None Options None Order allow,deny Deny from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined Alias /cgi-bin /var/www/htdocs/dummy Alias /roundcube /var/www/htdocs/dummy Alias /webmail /var/www/htdocs/dummy Alias /pma /var/www/htdocs/dummy Alias /webftp /var/www/htdocs/dummy </VirtualHost> # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
SSL
Die zentrale Konfiguration von SSL nehmen wir in der /etc/mods-available/ssl.conf vor. Hier besonders:
SSLCipherSuite SSLCipherSuite EECDH+AESGCM+AES256:EECDH+AES256 SSLCompression Off SSLProtocol TLSv1.2 SSLHonorCipherOrder On
/etc/apache2/sites-available/000-default-ssl.conf
<IfModule mod_ssl.c> <VirtualHost _default_:443> ServerAdmin webmaster@example.org DocumentRoot /var/www/htdocs <Directory /var/www/> Options -Indexes +SymLinksIfOwnerMatch +MultiViews AllowOverride None Order allow,deny allow from all </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined # Blocken der Anfragen an eingerichtete Dienste Alias /webmail /var/www/htdocs/dummy Alias /roundcube /var/www/htdocs/dummy Alias /pma /var/www/htdocs/dummy Alias /webftp /var/www/htdocs/dummy <IfDefine MAILMAN> ScriptAlias /mailman/ /var/www/htdocs/dummy Alias /mailmanicons/ /var/www/htdocs/dummy Alias /pipermail/ /var/www/htdocs/dummy </IfDefine> Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews SymLinksIfOwnerMatch AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Includes,Indexes,SymLinksIfOwnerMatch Order deny,allow Deny from all Allow from 127.0.0.0/255.0.0.0 ::1/128 </Directory> SSLEngine on SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key # Add six earth month HSTS header for all users... Header add Strict-Transport-Security "max-age=15768000" </VirtualHost> </IfModule>
Verzeichnisse
Anschließend verlinken wir beide Dateien:
ln -s /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-enabled/000-default.conf ln -s /etc/apache2/sites-available/000-default-ssl.conf /etc/apache2/sites-enabled/000-default-ssl.conf
Anschließend müssen die Verzeichnisse anlegt werden:
mkdir /var/www/htdocs/ mkdir /var/www/vhosts/ mkdir /var/www/vhosts/default mkdir /var/www/vhosts/default/htdocs
Und übertragen:
chown -R www-data.www-data /var/www/htdocs chown -R www-data.www-data /var/www/vhosts
Configtest:
apache2ctl configtest
Neustart:
service apache2 restart
Firewall:
ufw allow 'Apache Full'
Damit läuft Apache, man kann jetzt testweise eine index.html in /var/www/vhosts/default/htdocs legen und sollte sie beim Aufruf der Serveradresse (IP oder Hostname) sehen.
VHosts
Für jede Domain, unter der der Webserver erreichbar sein soll, erstellen wir einen VirtualHost. Dafür stehen zwei Konfigurationsdateien zur Verfügung (reines HTTP und HTTP/HTTPS-Mix). Zur Generierung von Zertifikaten mittels Let's Encrypt nutzen wir den ersten Dummy und ersetzen ihn danach mit dem zweiten. In beiden Dateien muss jeweils der Platzhalter mit der Domain ersetzt werden (in vim: %s/dummy.domain/example.org).
Die Problematik von SymLinks, die einem nicht gehören, habe ich von Jonas Pasche übernommen.
HTTP-Dummy
<VirtualHost *:80> ServerAdmin webmaster@dummy.domain ServerName dummy.domain ServerAlias www.dummy.domain dummy.domain.example.org DocumentRoot /var/www/vhosts/dummy.domain/htdocs <Directory /var/www/vhosts/dummy.domain/htdocs/> Options SymLinksIfOwnerMatch MultiViews AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Includes,Indexes,SymLinksIfOwnerMatch Order allow,deny allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/dummy.domain.error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/dummy.domain.access.log combined </VirtualHost>
HTTPS-Dummy
<VirtualHost *:80> ServerAdmin webmaster@dummy.domain ServerName dummy.domain ServerAlias www.dummy.domain dummy.domain.example.org DocumentRoot /var/www/vhosts/dummy.domain/htdocs Redirect permanent / https://www.dummy.domain/ # Setze Alias, um die Generierung von Zertifikaten unabhängig vom bisherigen Zertifikat möglich zu machen Alias /.well-known /var/www/vhosts/dummy.domain/htdocs/.well-known ErrorLog ${APACHE_LOG_DIR}/dummy.domain.error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/dummy.domain.access.log combined </VirtualHost> <VirtualHost *:443> ServerAdmin webmaster@dummy.domain ServerName dummy.domain ServerAlias www.dummy.domain dummy.domain.lt42.de SSLEngine on SSLCertificateFile /etc/letsencrypt/live/dummy.domain/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/dummy.domain/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/dummy.domain/chain.pem DocumentRoot /var/www/vhosts/dummy.domain/htdocs <Directory /var/www/vhosts/dummy.domain/htdocs/> Options SymLinksIfOwnerMatch MultiViews AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Includes,Indexes,SymLinksIfOwnerMatch Order allow,deny allow from all </Directory> # Add six earth month HSTS header for all users... Header add Strict-Transport-Security "max-age=15768000" ErrorLog ${APACHE_LOG_DIR}/dummy.domain.error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/dummy.domain.access.log combined </VirtualHost>
Datenbank-Server
Als Datenbank-Server benutze ich MariaDB, um von proprietären Anbietern wegzukommen:
sudo apt-get install mariadb-server php-zip php-bz2 php-mbstring
Nach einem Hinweis von Michael Kofler ist es empfehlenswert, die Standardkonfiguration, die eine Anmeldung von root außerhalb der root-Shell unter Linux verbietet, zu belassen. Wir legen also einen zweiten Administrationsuser an:
mysql MariaDB [(none)]> GRANT ALL ON *.* 'rooter'@'localhost' IDENTIFIED BY 'newpwd' WITH GRANT OPTION;
Damit können wir uns dann auch über PHPMyAdmin anmelden. Hier wird zusätzlich der root-Login in der Config verboten:
$cfg['Servers'][$i]['AllowRoot'] = false;
Mailserver
Die Einrichtung des Mailservers ist immer wieder spannend, da bei Updates immer wieder kleine Änderungen durchgeführt werden. Ich verwende Postfix als MTA und Dovecot als IMAP-Server. Zusätzlich arbeiten wir mit Virtuellen Hosts, damit ein Mailserver für mehrere Domains verantwortlich sein kann. Die Domains und ihre Mail-Accounts können dann über den Postfixadmin bequem im Netz verwaltet werden. Außerdem werden die Mails natürlich gefiltert.
Zunächst installieren wir Postfix und dessen Anbindung an MySQL:
sudo apt-get install postfix postfix-mysql php-imap
Falls bei der Installation ein Konfigurations-Dialog auftritt, wählen wir hier einfach erstmal "Keine Konfiguration" aus.
Dann erstellen wir im MySQL-Server eine neue Datenbank "mail" und einen neuen Benutzer "mail" mit allen Rechten:
root@server:/# mysql MariaDB [(none)]> CREATE DATABASE mail; mysql> GRANT ALL PRIVILEGES ON mail.* TO 'mail'@'localhost' IDENTIFIED BY 'mail'; mysql> quit
Die Konfiguration liegt in /etc/postfix wir wechseln also in das Verzeichnis und bearbeiten die (vielleicht neue) Datei main.cf
root@server:/# cd /etc/postfix root@server:/# vi main.cf
Dann richten wir die Datei wie folgt ein (denken Sie dran myhostname und myorigin an Ihre eigenen Bedürfnisse anzupassen). Mit Dovecot 2.0 hat sich einiges an der SASL-Authentifizierung geändert; das ist hier schon eingearbeitet:
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) biff = no append_dot_mydomain = no #delay_warning_time = 4h myhostname = mail.example.com myorigin = /etc/mailname mydestination = mydestination = $myhostname, mail.example.com, h23XXXXX.stratoserver.net, localhost.stratoserver.net, localhost relayhost = mynetworks = 127.0.0.0/8 [::1]/128 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all inet_protocols = ipv4 alias_maps = hash:/etc/aliases virtual_mailbox_domains = proxy:mysql:$config_directory/mysql_virtual_domains_maps.cf virtual_mailbox_base = /var/vmail virtual_mailbox_maps = proxy:mysql:$config_directory/mysql_virtual_mailbox_maps.cf virtual_alias_maps = proxy:mysql:$config_directory/mysql_virtual_alias_maps.cf virtual_minimum_uid = 150 virtual_uid_maps = static:150 virtual_gid_maps = static:8 virtual_transport = dovecot smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_auth_enable = yes smtpd_delay_reject = yes smtpd_helo_required = yes smtpd_client_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_rbl_client cbl.abuseat.org, reject_rbl_client ix.dnsbl.manitu.net, reject_rbl_client bl.spamcop.net, reject_rbl_client dul.dnsbl.sorbs.net, reject_unknown_client smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname smtpd_sender_restrictions = reject_unknown_sender_domain smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination # tls config #smtpd_use_tls = yes #smtp_tls_note_starttls_offer = yes #smtpd_tls_key_file = /etc/letsencrypt/live/example.com/privkey.pem #smtpd_tls_cert_file = /etc/letsencrypt/live/example.com/fullchain.pem #smtpd_tls_loglevel = 1 #smtpd_tls_received_header = yes #smtpd_tls_session_cache_timeout = 3600s #smtpd_tls_mandatory_protocols=!SSLv2, !SSLv3 #tls_random_source = dev:/dev/urandom #tls_random_prng_update_period = 3600s #dovecot_destination_recipient_limit = 1 ## Verschlüsselung der Transportebene #smtpd_tls_security_level = may #smtp_tls_security_level = may
Der Modus "may" bedeutet hier "Opportunistic TLS", d.h., dass eine TLS-Verbindung genutzt wird, sofern beide Server sich damit verstehen. Bietet der gegenübersprechende Server kein TLS an, wird auch keins genutzt. Postfix-Doku
Diese Konfiguration legt die Mails in /var/vmail ab und benutzt den Benutzer vmail mit der UID 150 (legen wir gleich an):
sudo useradd -r -u 150 -g mail -d /var/vmail -s /sbin/nologin -c 'Virtual mailbox' vmail sudo mkdir /var/vmail sudo chmod 770 /var/vmail/ sudo chown vmail:mail /var/vmail/
Jetzt fangen wir an, die Maps zu konfigurieren. Hiermit bringen wir Postfix bei, wir er die Datenbank nach Mail-Adressen abfragen muss. Dafür müssen wir einige Dateien anlegen:
sudo touch /etc/postfix/mysql_virtual_alias_maps.cf sudo touch /etc/postfix/mysql_virtual_domains_maps.cf sudo touch /etc/postfix/mysql_virtual_mailbox_limit_maps.cf sudo touch /etc/postfix/mysql_virtual_mailbox_maps.cf
/etc/postfix/mysql_virtual_alias_maps.cf
user = mail password = mail hosts = localhost dbname = mail table = alias select_field = goto where_field = address additional_conditions = and active = '1' #query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
/etc/postfix/mysql_virtual_domains_maps.cf
user = mail password = mail hosts = localhost dbname = mail table = domain select_field = domain where_field = domain additional_conditions = and backupmx = '0' and active = '1' #query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
user = mail password = mail hosts = localhost dbname = mail table = mailbox select_field = quota where_field = username additional_conditions = and active = '1' #query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'
/etc/postfix/mysql_virtual_mailbox_maps.cf
user = mail password = mail hosts = localhost dbname = mail table = mailbox select_field = CONCAT(domain,'/',maildir) where_field = username additional_conditions = and active = '1' #query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'
Wichtig ist es, hier den Benutzernamen und das Passwort an die MySQL-Einstellungen anzupassen.
Als letzte Postfix-Konfiguration müssen wir in der master.cf ganz unten die Pipe für Dovecot einrichten:
dovecot unix - n n - - pipe flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/deliver -d $(recipient) submission inet n - - - - smtpd -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=private/auth -o smtpd_sasl_security_options=noanonymous -o smtpd_sasl_local_domain=$myhostname -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_sender_login_maps=hash:/etc/postfix/virtual -o smtpd_sender_restrictions=reject_sender_login_mismatch -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject
Nachdem ich Probleme hatte, Mails mit Thunderbird ordentlich abzuliefern und immer wieder auf den Fehler:
5.7.1 <mail@domain.tld>: Sender address rejected: not owned by user mail@domain.tld
gestoßen bin, ist mir aufgefallen, dass folgende Zeile in der master.cf den Fehler zu verursachen scheint:
-o smtpd_sender_restrictions=reject_sender_login_mismatch
Sollte der Fehler also auftreten, kommentieren wir diese Zeile einfach aus.
Gegen die Fehlermeldung, dass die /etc/aliases nicht gefunden wurde, führen wir einmal
sudo newaliases
aus.
Dovecot
Nun beginnen wir, den zweiten Teil des Mailservers anzupassen. Hierfür installieren wir Dovecot über apt:
sudo apt-get install dovecot-imapd dovecot-pop3d dovecot-mysql
Wir können hier auch das Paket "dovecot-pop3d" weglassen, wenn wir keine POP3-Anmeldung am Server brauchen.
Die Abfrage nach einem SSL-Zertifikat können wir entweder mit Ja beantworten. Dann richtet Dovecot ein selbstsigniertes SSL-Zertifikat ein. Falls wir eines haben, sagen wir Nein.
Zur Sicherheit sichern wir die originale Konfigurationsdatei via
sudo mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.org
Anschließend können wir mit der Konfiguration von Dovecot unter /etc/dovecot/dovecot.conf beginnen. Diese Konfiguration kann einfach so kopiert werden. Es bringt auch eine SSL-Unterstützung mit, die aber von Haus aus deaktiviert ist. Natürlich müssen der Hostname und der Postmaster angepasst werden.
auth_mechanisms = plain login disable_plaintext_auth = no first_valid_uid = 150 hostname = mail.example.org last_valid_uid = 150 log_timestamp = "%Y-%m-%d %H:%M:%S " mail_location = maildir:/var/vmail/%d/%u passdb { args = /etc/dovecot/dovecot-sql.conf driver = sql } postmaster_address = xxx@example.com service auth { unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0660 user = postfix } unix_listener auth-userdb { group = mail mode = 0600 user = vmail } } service imap-login { executable = imap-login inet_listener imap { port = 143 } } service pop3-login { executable = pop3-login inet_listener pop3 { port = 110 } } # Hier kann bei Bedarf die SSL-Verschlüsselung eingeschaltet werden. ssl = no #ssl_cert = </etc/letsencrypt/live/example.org/fullchain.pem #ssl_key = </etc/letsencrypt/live/example.org/privkey.pem userdb { args = /etc/dovecot/dovecot-sql.conf driver = sql } protocol imap { mail_max_userip_connections = 10 } protocols = imap pop3
Nun müssen wir Dovecot nur noch sagen, wie sich Dovecot die Anmelde-Daten beschaffen kann. Dafür bearbeiten wir die Datei /etc/dovecot/dovecot-sql.conf:
driver = mysql connect = host=localhost dbname=mail user=mail password=mail # The new name for MD5 is MD5-CRYPT so you might need to change this depending on version default_pass_scheme = MD5 # Get the mailbox user_query = SELECT '/var/vmail/%d/%n' as home, 'maildir:/var/vmail/%d/%n' as mail, 150 AS uid, 8 AS gid, concat('dirsize:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = '1' # Get the password password_query = SELECT username as user, password, '/var/vmail/%d/%n' as userdb_home, 'maildir:/var/vmail/%d/%n' as userdb_mail, 150 as userdb_uid, 8 as userdb_gid FROM mailbox WHERE username = '%u' AND active = '1' # If using client certificates for authentication, comment the above and uncomment the following #password_query = SELECT null AS password, '%u' AS user
Hier müssen wir möglicherweise die Felder user= und password= an unsere Zwecke anpassen.
Dann setzen wir noch die Rechte für Dovecot:
sudo chmod 600 /etc/dovecot/*.conf sudo chown vmail /etc/dovecot/*.conf
Dovecot ist jetzt konfiguriert. Momentan noch ohne SSL, aber das kommt später.
Postfix Admin
Zum Anlegen der Domains und Postfächer nutzen wir den Postfixadmin, der passenderweise auch gleich das Datenbank-Schema für die gerade erstellte Konfiguration mitbringt.
Wir laden den PostfixAdmin von der Webseite herunter und entpacken ihn in ein eingerichtetes Verzeichnis z.B. einer Subdomain (z.B. mail.<domain>)
sudo mkdir /var/www/vhosts/mail.<domain>/htdocs cd /var/www/vhosts/mail.<domain>/htdocs wget -O pfa.tgz https://sourceforge.net/projects/postfixadmin/files/latest/download tar xfz pfa.tgz
Nun passen wir noch den Postfix Admin an unsere Zwecke an. Dazu wechseln wir in das vorhin angelegte Verzeichnis postfixadmin-X.X.X/ und editieren die Standardkonfiguration:
cd ./postfixadmin-X.X.X/ vi config.inc.php
Hier passen wir folgende Parameter an:
$CONF['postfix_admin_url'] = ‘'var/www/vhosts/mail.<domain>/postfixadmin/'; $CONF['database_type'] = 'mysqli'; $CONF['database_user'] = 'mail'; $CONF['database_password'] = 'mail'; $CONF['database_name'] = 'mail';
(Natürlich an die eigenen Zwecke angepasst)
Sind wir mit der Konfiguration fertig, setzen wir den Parameter
$CONF['configured'] = false;
auf true und können unter der angelegten Domain den Installer starten. (postfixadmin/setup.php)
Hier müssen zwei PHP-Pakete nachinstalliert werden:
sudo apt-get install php-mbstring php-imap
Danach einmal Apache neu laden:
sudo service apache2 reload
Ist alles installiert, können wir einen Super-Admin einrichten, der alle Domains, Accounts und Administrator-Account im Postfixadmin konfigurieren kann.
Nun ist der Mailserver eingerichtet. Wir starten nun die Services neu:
service postfix restart service dovecot restart service apache2 restart service mysql restart
Nun können wir unter http://mail.example.org/postfixadmin/ einen neuen Benutzer und eine neue Domain anlegen und einige Tests durchführen. Damit ist der Mailserver eingerichtet.
Roundcube
RoundCube könnte prinzipiell über die Paketquellen installiert werden. Ich bin hängen geblieben und installiere immer noch manuell mit den Paketen von www.roundcube.net. Wir entpacken das Verzeichnis nach /var/www/htdocs/roundcube, da die Installation ja von allen Domains aus erreichbar sein soll. Seit Version 3.1 bietet Postfix endlich auch eine lokale Installationsdatei an. Dann kann man bequemer Updates einspielen.
/var/www/htdocs/roundcube/config/config.local.php
<?php $CONF['configured'] = true; // on submission it will be echoed out to you as a hashed value. $CONF['setup_password'] = 'changeme'; $CONF['default_language'] = 'de'; // Database Config $CONF['database_type'] = 'mysqli'; $CONF['database_host'] = 'localhost'; $CONF['database_user'] = '<benutzer>'; $CONF['database_password'] = '<passwort>'; $CONF['database_name'] = '<datenbank>'; $CONF['admin_email'] = 'postmaster@example.de'; $CONF['page_size'] = '20'; $CONF['default_aliases'] = array ( 'abuse' => 'abuse@example.de', 'hostmaster' => 'hostmaster@example.de', 'postmaster' => 'postmaster@example.de', 'webmaster' => 'webmaster@example.de' ); $CONF['quota'] = 'YES'; $CONF['footer_text'] = 'Zurück zu example.de'; $CONF['footer_link'] = 'http://example.de'; // Welcome Message // This message is send to every newly created mailbox. // Change the text between EOM. $CONF['welcome_text'] = <<<EOM Herzlich Willkommen, zum neuen E-Mail Postfach. Bei Fragen oder Problemen bitte Lukas Thiel ansprechen EOM; $CONF['show_undeliverable_exceptions']=array("example.de","lt42.de"); $CONF['used_quotas'] = 'YES'; $CONF['maxquota'] = '2048'; $CONF['domain_quota_default'] = '0';
Beim ersten Aufruf erschien
ERROR: the templates_c directory doesn't exist or isn't writeable for the webserver
Nach einem Erstellen des Verzeichnissen und der Anpassung der Rechte an www-data, klappt das aber auch.
Sieve
Ich wollte meine Mails gerne mit Hilfe von Sieve filtern. Bisher habe ich die Abwesenheitsbenachrichtigungen immer mit dem Postfixadmin-Virtual-Vacation realisiert, das ist aber unschön. Sieve klingt da schöner und kann auch mehr.
Zuerst installieren wir das Paket mit APT:
apt-get update apt-get install dovecot-managesieved
Dann geht es an die Einrichtung von Dovecot. Dafür bearbeiten wir die Datei /etc/dovecot/dovecot.conf und fügen folgende Zeilen an:
managesieve_notify_capability = mailto managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date
# Mail-Filterung mit Sieve service managesieve-login { inet_listener sieve { port = 4190 } } protocol lda { mail_plugins = $mail_plugins sieve } plugin { sieve = /var/vmail/%d/%n/.dovecot.sieve sieve_dir = /var/vmail/%d/%n/sieve }
Falls Sie Ihre Mails mit LMTP zustellen, muss in der Zeile "protocol lda" natürlich "protocol lmtp" stehen.
Nun fügen wir sieve noch als Protokoll für Dovecot hinzu. Dazu fügen wir an die Zeile
protocols = imap pop3
noch sieve an, also
protocols = imap pop3 sieve
Nach einem Neustart von Dovecot, sollte alles funktionieren. Nun geht es an die Erstellung der Filter. Dazu bringt beispielweise Thunderbird ein Tool mit, allerdings finde ich die Lösung per Webmailer wesentlich schöner. Passenderweise bringt auch Roundcube von Haus aus eine Möglichkeit zur Bearbeitung von Sieve-Scripten mit.
Zum Aktivieren wechseln wir in das Roundcube-Installationsverzeichnis und bearbeiten die config/config.inc.php. Dort muss lediglich folgendes Array erweitert werden:
$config['plugins'] = array();
wird zu
$config['plugins'] = array('managesieve');
Wichtig ist, dass der Name mit dem Namen des Ordners in plugins/ übereinstimmt. Nach der Installation können wir im Roundcube unter Einstellungen/Filter die Filter bearbeiten.
Passwort ändern mit Roundcube
Ich wollte schon lange alle möglichen Einstellungen für Benutzer unter ein Dach bringen. Bisher habe ich Benutzern immer einen Link zum Webmailer und einen für den Postfixadmin gegeben, damit sie ihr Passwort ändern können. Doch Roundcube bringt einige spannende Plugins (s.o. Sieve) mit, die diese Arbeit ebenso übernehmen können.
Für das Ändern des Passwort bedienen wir uns dem mitgelieferten Plugin password. Zuerst kopieren wir uns die Datei plugins/password/config.inc.php.dist (von der Roundcube-Wurzel aus) in plugins/password/config.inc.php und bearbeiten die folgenden zwei Zeilen:
$config['password_db_dsn'] = 'mysql://benutzer:passwort@localhost/db'; $config['password_query'] = 'UPDATE mailbox SET password=%c WHERE username=%u';
Die Zugangsdaten sind in diesem Fall die gleichen, wie bei Postfix und Dovecot, was naheliegt, da wir ja an die Mail-Datenbank heran wollen. In unserem Fall waren das mail, mail und mail. Im password_query tragen wir dann den SQL-Befehl zum Update des Passwortes ein. Dieses lässt sich aus dem Datenbank-Aufbau erahnen.
Zum Abschluss speichern wir die Datei und binden das Plugin wie oben auch in der config/config.inc.php in dem Array $config['plugins'] ein. Dann können wir unser Passwort im Roundcube ändern.
Amavis
Natürlich sollen die Mails auf SPAM und Viren überprüft werden. Dafür kommt Amavis mit ClamAV (Virenscanner) und SpamAssassin (Spamscanner) zum Einsatz. Die Konfiguration ist trivial und orientiert sich an dieser. Zuerst installieren wir mit
sudo apt-get update sudo apt-get install amavis clamav clamav-daemon spamassassin
Die Konfiguration muss an einigen Stellen gedreht werden. Zuerst werden die Programme gegenseitig in ihre Gruppen aufgenommen:
adduser clamav amavis adduser amavis clamav
Dann wird die Datei /etc/clamav/clamd.conf etwas angepasst
# Needed to allow things to work with Amavis, when both amavis and clamav # users are added to one another's groups. AllowSupplementaryGroups true
Viren- und Spamprüfung aktivieren wir dann in /etc/amavis/conf.d/15-content_filter_mode
use strict; # You can modify this file to re-enable SPAM checking through spamassassin # and to re-enable antivirus checking. # # Default antivirus checking mode # Please note, that anti-virus checking is DISABLED by # default. # If You wish to enable it, please uncomment the following lines: @bypass_virus_checks_maps = ( %bypass_virus_checks, @bypass_virus_checks_acl, $bypass_virus_checks_re); # # Default SPAM checking mode # Please note, that anti-spam checking is DISABLED by # default. # If You wish to enable it, please uncomment the following lines: @bypass_spam_checks_maps = ( %bypass_spam_checks, @bypass_spam_checks_acl, $bypass_spam_checks_re); 1; # ensure a defined return
Zusätzlich wird SpamAssassin in einen Daemon-Modus gefahren und es werden nächtliche Aktualisierungen via cron aktiviert:
/etc/default/spamassassin:
# /etc/default/spamassassin # Duncan Findlay # WARNING: please read README.spamd before using. # There may be security risks. # If you're using systemd (default for jessie), the ENABLED setting is # not used. Instead, enable spamd by issuing: # systemctl enable spamassassin.service # Change to "1" to enable spamd on systems using sysvinit: ENABLED=1 # Options # See man spamd for possible options. The -d option is automatically added. # SpamAssassin uses a preforking model, so be careful! You need to # make sure --max-children is not set to anything higher than 5, # unless you know what you're doing. OPTIONS="--create-prefs --max-children 5 --helper-home-dir" # Pid file # Where should spamd write its PID to file? If you use the -u or # --username option above, this needs to be writable by that user. # Otherwise, the init script will not be able to shut spamd down. PIDFILE="/var/run/spamd.pid" # Set nice level of spamd #NICE="--nicelevel 15" # Cronjob # Set to anything but 0 to enable the cron job to automatically update # spamassassin's rules on a nightly basis CRON=1
Nun noch /etc/amavis/conf.d/50-user anpassen, damit die lokalen Domains aus der Datenbank genommen werden:
use strict; # # Place your configuration directives here. They will override those in # earlier files. # # See /usr/share/doc/amavisd-new/ for documentation and examples of # the directives you can use in this file # # Three concurrent processes. This should fit into the RAM available on an # AWS micro instance. This has to match the number of processes specified # for Amavis in /etc/postfix/master.cf. $max_servers = 3; # Add spam info headers if at or above that level - this ensures they # are always added. $sa_tag_level_deflt = -9999; # Check the database to see if mail is for local delivery, and thus # should be spam checked. @lookup_sql_dsn = (['DBI:mysql:database=postfix;host=127.0.0.1;port=3306', 'postfix', 'assword']); $sql_select_policy = 'SELECT domain from domain WHERE CONCAT("@",domain) IN (%k)'; $sql_select_white_black_list = undef; # Uncomment to bump up the log level when testing. # $log_level = 2; #------------ Do not modify anything below this line ------------- 1; # ensure a defined return
Spielkram bietet /etc/amavis/conf.d/20-debian_defaults, wo wir mit
# SPAM-Tag in der Betreff-Zeile $sa_spam_subject_tag = '[AlphaCentauri-Trash SPAM] '; # Empfänger für Virus-Benachrichtigungen $virus_admin = "virusadmin\@example.org"; # due to D_DISCARD default # und die X-Virus-Scanned-Zeile in den Mails beeinflussen können: $X_HEADER_LINE = "by Thiel-SpamAndVirusFilter Debian $myproduct_name at $mydomain";
Nach einem Neustart der Dienste mittels
service clamav-freshclam restart service clamav-daemon restart service amavis restart service spamassassin restart
sollte das System laufen.
Bei mir mussten noch das Perl-Modul DBD::mysql mittels
sudo cpan cpan[1] install DBD::mysql
und eine Bibliothek für MySQL mittels
sudo apt-get install libmysqlclient-dev
nachinstalliert werden.
Dann geben wir die Ports in der Firewall frei:
sudo ufw allow Postfix sudo ufw allow "Postfix SMTPS" sudo ufw allow "Postfix Submission" sudo ufw allow "Dovecot IMAP" sudo ufw allow "Dovecot Secure IMAP"