Root-Server mit Ubuntu 16.04

Aus Debacher-Wiki
Wechseln zu: Navigation, Suche

Ich habe nun schon häufiger davor zurück geschreckt auch bei den Servern von OpenSUSE auf Ubuntu umzustellen, obwohl auch Lukas Thiel das immer wieder angeregt hatte. Aktuell wird OpenSUSE aber bei den Strato-Servern nicht mehr supportet, so dass die Entscheidung für Ubuntu 16.04 nun gefallen ist.

Root Server Linux D400

Bei den bisherigen Servern haben wir mit der Hardware eigentlich noch keine Probleme, aber das System ist zu alt. Wenn man neue Typo3-Versionen benutzen will, dann benötigt man PHP7. Also war auf alle Fälle eine Neuinstallation fällig und die ist nun mal einfacher, wenn man auch gleich die Hardware erneuert. So habe ich mehr Zeit für die Konfiguration.

Die technischen Daten:

Intel® Xeon E3-1230v3 (4x6599 Bogomips)
4 x 3,3 GHz
16 GB RAM
2x2 TB Festplatte als Raid1

Die Bereitstellung des Rechners hat fast 48 Stunden gedauert, bestellt am Freitag Nachmittag (27.1.2017), bereit gestellt am Sonntag Nachmittag (29.1.2017. Nach der Bereitstellung ist noch kein System installiert, das löst man dann in der Verwaltungsoberfläche von Strato aus. Mindestlaufzeit bei diesem Server ist 12 Monate.

Strato-2017-01.png

Bei der Partionierung hat man nicht viel Auswahl. Ich habe die Version mit der ausführlichsten Partitionierung gewählt und Ubuntu 16.04. Die Partitionsgrößen kann man nicht weiter beeinflussen, das ist etwas schade, da /home in der Regel viel zu groß eingestellt ist. Aber bisher habe ich trotzdem noch nie Platzprobleme bekommen. Knapp eine Stunde später war das Gerät dann erreichbar, partitioniert:

/dev/md0   /boot  (1GB)
/dev/md1   /      (20GB)
/dev/md2   /home  (1138GB)
/dev/md3   /var   (758GB)

Irritiert hatte mich das Fehlen einer eigenen Partition für /srv, aber Ubuntu legt dort eigentlich keine Dateien ab. Die Datenbanken befinden sich unter /var/lib/mysql und die Webseiten unter /var/www/html und /usr/lib/cgi-bin.

Man kann die Partitionierung natürlich auch noch nachträglich ändern, das ist aber immer mit etwas Aufwand und Bastelei verbunden. Strato bietet dafür eine Minimal-Partitionierung an, gute Hinweise um Umgang mit den Raid-Partitionen findet man unter https://www.thomas-krenn.com/de/wiki/Software_RAID_mit_MDADM_verwalten.

Ubuntu 16.04 kommt mit Apache 2.4.18, PHP 7.0.13, MySQL 5.7.17, Dovecot 2.2.22 und Postfix 3.1.0

Was mir aufgefallen ist

Bei SUSE liefert

hostname

den kurzen Namen ohne Domain, bei der Ubuntu-Version den vollen Namen mit Domain, wie sonst hostname -f . Der kurzen Namen bekomme ich mittels

hostname -s

Das macht in manchen meiner Scripten einen Unterschied.

Grundinstallation

Bevor man mit der eigentlichen Einrichtung beginnt, sollte man den Server unbedingt einmal neu starten.

Benötigt man einmal die Liste aller installierten Pakete, so bekommt man die mit

dpkg --get-selections

Leider steht dann immer noch install hinter dem Paketnamen, aber das lässt sich ja mit Suchen und Ersetzen beseitigen.

In den aktuellen Ubuntu-Versionen läuft das Starten und Stoppen der Netzwerkdienste systemctl, der klassische Runlevel-Editor funktioniert da teilweise auch noch, als Umleitung.

systemctl status|start|stop <daemon>.service
systemctl enable|disable <daemon>.service

Firewall

Gleich nach der ersten Übersicht ist mir aufgefallen, dass keinerlei Firewall aktiv ist. Bei Ubuntu ist dafür efw installiert und muss noch aktiviert werden. Bei efw kann man relativ komfortabel Ports sperren oder freigeben, teilweise sogar über vorkonfigurierte Pakete. Wichtig ist, dass man Port 22 freigibt, bevor man die Firewall aktiviert (https://help.ubuntu.com/lts/serverguide/firewall.html, http://www.savvyadmin.com/ubuntus-ufw/):

ufw allow OpenSSH
ufw allow "Apache Full" 

Wer kommt auf die blöde Idee einen Bezeichner mit Leerzeichen zu wählen?? Nun kann man die Firewall aktivieren mittels:

ufw enable

Würde es die App OpenSSH nicht geben, so würde man Port 22 freigeben mittels:

ufw allow 22

oder

ufw allow ssh

Die Apache App steht erst zur Verfügung, wenn man den Webserver installiert hat. Die Liste der aktuell verfügbaren Apps kann man abrufen mittels:

ufw app list

Da meine Internetverbindung per SSH nicht stabil ist, ich bin O2-Kunde, nutze ich das Programm mosh um die Probleme zu lösen. Also noch einrichten:

apt install mosh

und

ufw allow mosh

Erste Installationen

Ich habe mir dann noch gleich ein paar nützliche Hilfsmittel installiert:

apt install synaptic apt-xapian-index
update-apt-xapian-index -vf

Installiert das grafische Tool zur Paketverwaltung. Dann kann ich relativ leicht nach Paketen suchen.

Auch grafische Tools lassen sich per ssh aufrufen (aber leider nicht mit mosh), wenn man beim Start der Verbindung den Parameter -X mit angibt:

ssh -X root@mein-server.domain

Da ich schon häufiger Probleme mit den Festplatten hatte sind mir die Smartmontools wichtig:

apt install smartmontools

Der Aufruf von

smartctl -A /dev/sda

bzw.

smartctl -A /dev/sdb

Liefert mir die Information, dass die Festplatten schon 18470 Stunden gelaufen sind, also etwas mehr als zwei Jahre. Es gibt aber keine Reallocierten Sektoren und beide Platten haben die gleiche Laufzeit.

Im Netzwerk benötigt man dann oft auch whois Informationen

apt install whois

Datenbank

Zur Installation von Server und Client dient der folgende Aufruf:

apt install mysql-client mysql-server mysql-common

Ich habe dann die Konfigurationsdatei /etc/mysql/mysql.conf.d/mysqld.cnf ergänzt

#ergänzt von U.D.
innodb_flush_log_at_trx_commit = 2

und die Datenbank neu gestartet. Den Datenbankzugriff sollte man nicht über das Netz erlauben, also auch in der Firewall den entsprechenden Port nicht öffnen. Die Datenbank wird ja in der Regel nur über lokale Anwendungen genutzt und über PHPMyAdmin administriert.

Apache-Webserver

Die folgenden grundlegenden Pakete habe ich installiert

apt install apache2 apache2-bin apache2-data apache2-doc apache2-utils		

Dann ein paar Pakete für PHP

apt install libapache2-mod-php libapache2-mod-php7.0 php php-auth php-auth-http php-auth-sasl php-bz2 php-cli php-common php-crypt-chap 
apt install php-db php-gd php-geoip php-gettext php-imap php-log php-mail php-mbstring php-mcrypt php-mdb2 php-mysql php-net-smtp 
apt install php-net-socket php-pear php-phpseclib php-recode php-soap php-tcpdf php-xml php7.0 php7.0-bz2 php7.0-cli php7.0-common 
apt install php7.0-gd php7.0-imap php7.0-json php7.0-mbstring php7.0-mcrypt php7.0-mysql php7.0-opcache php7.0-readline php7.0-recode 
apt install php7.0-soap php7.0-xml php7.0-zip phpmyadmin 

Da sind jetzt eine Reihe von Doppelungen drin, sowohl das Paket, als auch das Metapaket. Es ist aber das, was mir

dpkg --get-selections | grep php

liefert.

Laut https://www.thomaschristlieb.de/mehrere-php-versionen-auf-einem-linux-server-mit-php-fpm/ kann man eventuell php7 und php5 parallel betreiben.

Nun noch ein paar Perl-Pakete:

apt install libapache2-mod-perl2 libapache2-reload-perl libapparmor-perl libarchive-zip-perl libauthen-sasl-perl libbsd-resource-perl 
apt install libcairo-perl libcgi-fast-perl libcgi-pm-perl libdevel-symdump-perl libencode-locale-perl libfcgi-perl libfile-basedir-perl 
apt install libfile-desktopentry-perl libfile-listing-perl libfile-mimeinfo-perl libfont-afm-perl libgd-graph-perl libgd-perl libgd-text-perl 
apt install libglib-perl libgtk2-perl libhtml-form-perl libhtml-format-perl libhtml-parser-perl libhtml-tagset-perl libhtml-template-perl 
apt install libhtml-tree-perl libhttp-cookies-perl libhttp-daemon-perl libhttp-date-perl libhttp-message-perl libhttp-negotiate-perl 
apt install libimage-magick-perl libimage-magick-q16-perl libio-html-perl libio-socket-ssl-perl libipc-system-simple-perl liblocale-gettext-perl 
apt install liblwp-mediatypes-perl liblwp-protocol-https-perl libmailtools-perl libnet-dbus-perl libnet-http-perl libnet-smtp-ssl-perl 
apt install libnet-ssleay-perl libpango-perl libperl5.22:amd64 libtext-charwidth-perl libtext-iconv-perl libtext-wrapi18n-perl 
apt install libtie-ixhash-perl libtimedate-perl liburi-perl libwww-perl libwww-robotrules-perl libx11-protocol-perl libxml-parser-perl 
apt install libxml-twig-perl libxml-xpathengine-perl perl perl-base perl-modules-5.22 libdbi-perl libdbd-mysql libclass-dbi-mysql-perl

Nach erfolgter Konfiguration (s.u.) darf man nicht vergessen die notwendigen Ports in der Firewall frei zu geben:

ufw allow "Apache Full"

letsencrypt

Für die verschlüsselte Übertragung von Webseiten werden Zertifikate benötigt. Für die Installation gemäß http://www.debacher.de/ublog/2016/06/letsencrypt/ benötige ich git:

apt install git

für Typo3

Da ich viel mit Typo3 arbeite habe ich etwas an den PHP-Einstellungen gedreht in der /etc/php/7.0/apache2/php.ini:

post_max_size=10M
upload_max_filesize=10M
max_execution_time=240

Typo3 benötigt unbedingt imagemagick (oder alternativ graphicsmagick)

apt install imagemagick imagemagick-doc
apt install graphicsmagick

/etc/apache2/sites-available/000-default.conf

Im ersten Schritt ändere ich einen Teil der Standardvorgaben in der Datei 000-default.conf. Der Name resultiert aus der Tatsache, dass der Apache die Dateien in alphabetischer Reihenfolge einliest. Diese Datei muss als erste eingelesen werden.

ServerAdmin Webmaster@<dummy>.de

ServerTokens Major

DocumentRoot /var/www/htdocs

Alias /groupoffice /var/www/htdocs/dummy
Alias /squirrelmail /var/www/htdocs/dummy
Alias /webmail       /var/www/dummy
Alias /webstat  /var/www/htdocs/webalizer

<Directory "/var/www/vhosts">
       AllowOverride All
       Options +FollowSymLinks
       Require all granted
</Directory>

<IfModule mod_userdir.c>
       UserDir disabled
</IfModule>

<IfModule mod_expires.c>
 ExpiresActive On
 ExpiresDefault "access plus 1 month"
 ExpiresByType text/html "access plus 1 week"
 ExpiresByType image/gif "access plus 1 week"
 ExpiresByType image/jpeg "access plus 1 week"
 ExpiresByType image/png "access plus 1 week"
 ExpiresByType text/css "access plus 1 week"
 ExpiresByType text/javascript "access plus 1 week"
 ExpiresByType application/x-javascript "access plus 1 week"
 ExpiresByType text/xml "access plus 1 week"
</IfModule>

<IfModule mod_setenvif.c>
  # SEO
  BrowserMatchNoCase (mindUp|meanpathbot|seoscanners|AiHitBot|BLEXBot|DotBot|linkdexbot|MJ12bot|SEOkicks-Robot) ist_ein_bot
  # Sammeln Backlinks & Links
  BrowserMatchNoCase (exabot|Baidu|Haosou|Semrush|MegaIndex|AhrefsBot|BacklinkCrawler|dlcbot|spbot) ist_ein_bot
  # Performance Testing
  BrowserMatchNoCase (200PleaseBot|LoadTimeBot) ist_ein_bot
  # BilderSuche
  BrowserMatchNoCase (psbot|Yandex) ist_ein_bot
  # Harvester & Marketing
  BrowserMatchNoCase (XoviBot|CareerBot|GrapeshotCrawler|iCjobs|magpie-crawler|proximic) ist_ein_bot
  # Nutzlos, Schlecht bzw. unbekannt
  BrowserMatchNoCase (Ezooms|updown_tester|^Java) ist_ein_bot
  # Per IP
  SetEnvIfNoCase Remote_Addr (62\.138\.0\.25) ist_ein_bot
</IfModule>
 
<VirtualHost *:80>
       ServerName default
       UseCanonicalName Off
       DocumentRoot /var/www/vhosts/default/httpdocs
       Alias /groupoffice  /var/www/htdocs/dummy
       Alias /squirrelmail /var/www/htdocs/dummy
       Alias /webmail      /var/www/htdocs/dummy
       Alias /postfixadmin /var/www/htdocs/dummy
       Alias /phpMyAdmin   /var/www/htdocs/dummy
       Alias /roundcube    /var/www/htdocs/dummy
       Alias /.well-known  /var/www/htdocs/.well-known

       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined

       <IfModule mod_ssl.c>
               SSLEngine off
       </IfModule>

       <Directory /var/www/vhosts/default/httpdocs>
               AllowOverride All
               Options None
               Require all granted

               <IfModule mod_php5.c>
                 php_admin_flag engine on
                 php_admin_flag safe_mode off
#                  php_admin_value include_path "/var/www/htdocs/horde/pear:/var/www/htdocs:./"
#                 php_admin_value open_basedir "/var/www/htdocs:/tmp"
               </IfModule>
       </Directory>

</VirtualHost>

Der Ordner /var/www/htdocs/dummy ist hier ein leerer Dummy-Ordner, damit Zugriffe auf die entsprechenden Anwendungen ins Leere laufen. Natürlich müssen die in der Konfiguration genannten Pfade eingerichtet sein, also z.B. /var/www/vhosts/default/httpdocs und /var/www/vhosts/default/httpsdocs. Idealerweise sollte in den Ordnern auch eine Datei index.html liegen, um Fehlermeldungen zu vermeiden.

/etc/apache2/sites-available/default-ssl.conf

Damit die Konfiguration funktionieren kann muss, sofern das Modul SSL aktiviert wurde, an der angegebenen Stelle ein Zertifikat vorliegen. Es kann ruhig ein selbst erstelltes Zertifikat sein. Zur Vereinfachung ist bei Ubuntu gleich ein Zertifikat erstellt.

Dann habe ich mir die vorhandene Datei default-ssl.conf angepasst:

<IfModule mod_ssl.c>

 <VirtualHost _default_:443 >
       ServerAdmin webmaster@<dummy>.de
 
#       ServerName default
       UseCanonicalName Off

       DocumentRoot /var/www/vhosts/default/httpsdocs

       ScriptAlias /cgi-bin/ "/usr/lib/cgi-bin/"
       Alias /groupoffice  /var/www/htdocs/dummy
       Alias /squirrelmail /var/www/htdocs/dummy
       Alias /webmail      /var/www/htdocs/dummy
       Alias /postfixadmin /var/www/htdocs/dummy
       Alias /phpMyAdmin   /var/www/htdocs/dummy
       Alias /roundcube    /var/www/htdocs/dummy

       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined

       SSLEngine on

       SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNUL
       SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
       SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

       <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
       </FilesMatch>
 
       <Directory "/usr/lib/cgi-bin/">
               AllowOverride None
               Options None
               Require all denied
               SSLOptions +StdEnvVars
       </Directory>

       <Directory /var/www/vhosts/default/httpsdocs>
               SSLRequireSSL
               AllowOverride None
               Options None
               Require all granted
       </Directory>
 </VirtualHost>

</IfModule>

Im Prinzip hätte ich auch beides in eine Datei packen können, aber es waren ja schon die beiden vorhanden.

Für alle weiteren https Seiten benutze ich Zertifikat von letsencrypt, aber für Stratoserver-Adressen erstellt letsencrypt keine Zertifikate mehr, weil es schon zuviele für xxx.stratoserver.net gibt.

/etc/apache2/sites-available/stratoserver.net.conf

Ich will einen Unterschied haben zwischen der Seite die bei einem Aufruf über die IP-Adresse oder eine nicht konfigurierte Domain erfolgt und der Seite, die über den korrekten Server-Namen geliefert wird. Daher ein virtueller Server für legale Namen.

<VirtualHost *:80>
   ServerName h2656233.stratoserver.net
   ServerAlias server3.netthelp.de
    
   UseCanonicalName Off
   DocumentRoot /var/www/vhosts/default/httpdocs

   CustomLog  /var/log/apache2/server_access_log combined
   ErrorLog   /var/log/apache2/server_error_log

   ScriptAlias /cgi-bin/ "/var/www/vhosts/default/cgi-bin/"

   Alias /phpMyAdmin    /var/www/htdocs/phpMyAdmin
   Alias /postfixadmin  /var/www/htdocs/postfixadmin
   Alias /webmail       /var/www/roundcubemail
   Alias /webstat       /var/www/vhosts/default/webstat
   Alias /roundcube     /var/www/roundcubemail
   Alias /roundcubemail /var/www/roundcubemail
   Alias /.well-known   /var/www/htdocs/.well-known

   <IfModule mod_ssl.c>
       SSLEngine off
   </IfModule>

   <Directory "/var/www/vhosts/cgi-bin/cgi-bin/">
       AllowOverride None
       Options None
       Require all granted
   </Directory>

   <Directory /var/www/vhosts/default/httpdocs>
       AllowOverride All
       Options None
       Require all granted

       <IfModule mod_php5.c>
         php_admin_flag engine on
         php_admin_flag safe_mode off
#           php_admin_value include_path "/var/www/htdocs/horde/pear:/var/www/htdocs:./"
#           php_admin_value open_basedir "/var/www/htdocs:/tmp"
       </IfModule>
   </Directory>

</VirtualHost>

<IfModule mod_ssl.c>

 <VirtualHost *:443 >
     ServerName h2656233.stratoserver.net

     UseCanonicalName Off
     DocumentRoot /var/www/vhosts/default/httpsdocs

     CustomLog  /var/log/apache2/server_access_log combined
     ErrorLog   /var/log/apache2/server_error_log

     ScriptAlias /cgi-bin/ "/var/www/vhosts/default/cgi-bin/"
     Alias /phpMyAdmin     /var/www/htdocs/phpMyAdmin
     Alias /postfixadmin   /var/www/htdocs/postfixadmin
     Alias /webmail        /var/www/roundcubemail
     Alias  /webstat       /var/www/vhosts/default/webstat
     Alias /roundcube      /var/www/roundcubemail
     Alias /roundcubemail   /var/www/roundcubemail

     SSLEngine on

     SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNUL
     SSLCertificateFile /etc/letsencrypt/live/server3.netthelp.de/fullchain.pem
     SSLCertificateKeyFile /etc/letsencrypt/live/server3.netthelp.de/privkey.pem
#     SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
#     SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

     SSLProtocol All -SSLv2 -SSLv3

       <Directory "/var/www/vhosts/default/cgi-bin/">
               AllowOverride None
               Options None
               Require all granted
       </Directory>

       <Directory /var/www/vhosts/default/httpsdocs>
               SSLRequireSSL
               AllowOverride None
               Options None
               Require all granted
       </Directory>
</VirtualHost>

</IfModule>

Vserver-Konfiguration

Für jeden weiteren VServer erfolgt die Konfiguration in /etc/apache2/vhosts/sites-available/<dummy>.conf nach folgendem System, wobei <dummy> durch z.B. den Domainnamen ersetzt wird. Das zugehörige Verzeichnis wird dann mit diesem Namen unterhalb von /var/www/vhosts/ angelegt.

<VirtualHost *:80>
 ServerName   www.<dummy>:80
 ServerAlias <dummy>
 ServerAlias <dummy>.server3.netthelp.de
 UseCanonicalName Off
 DocumentRoot /var/www/vhosts/<dummy>/httpdocs

 CustomLog  /var/log/apache2-vhosts.d/<dummy>_access.log combined
 ErrorLog   /var/log/apache2-vhosts.d/<dummy>_error.log

 CustomLog /var/log/apache2/vhosts_access.log vhost_combined

 ScriptAlias  /cgi-bin/ /var/www/vhosts/<dummy>/cgi-bin/
 Alias  /webstat       /var/www/vhosts/<dummy>/webstat
 Alias  /.well-known   /var/www/htdocs/.well-known

 <IfModule mod_ssl.c>
       SSLEngine off
 </IfModule>

 <Directory /var/www/vhosts/<dummy>/httpdocs>

   <IfModule mod_php5.c>
       php_admin_flag engine on
       php_admin_flag safe_mode off
       php_admin_value include_path "/var/www/vhosts/<dummy>/httpdocs:.:/tmp:./:/usr/share/php5/PEAR/:/var/www/typo3src"
       php_admin_value open_basedir "/var/www/vhosts/<dummy>/httpdocs:/tmp:.:/usr/share/php5/PEAR/:/var/www/typo3src"
       php_value date.timezone "Europe/Berlin"
   </IfModule>

   <IfModule mod_python.c>
       <Files ~ (\.py$)>
               SetHandler python-program
               PythonHandler   mod_python.cgihandler
       </Files>
   </IfModule>

   Options -Includes +ExecCGI
 </Directory>

 <Directory "/var/www/vhosts/<dummy>/cgi-bin">
      AllowOverride None
      Options +ExecCGI -Includes
      Require all granted
 </Directory>

</VirtualHost>

# soll SSL aktiviert werden das _no entfernen
<IfModule mod_ssl_no.c>

<VirtualHost *:443>
 ServerName   www.<dummy>:443
 ServerAlias <dummy>
 UseCanonicalName Off
 DocumentRoot /var/www/vhosts/<dummy>/httpdocs

 CustomLog  /var/log/apache2-vhosts.d/<dummy>_access.log combined
 ErrorLog   /var/log/apache2-vhosts.d/<dummy>_error.log

 ScriptAlias  /cgi-bin/ /var/www/vhosts/<dummy>/cgi-bin/
 Alias  /webstat /var/www/vhosts/<dummy>/webstat

 SSLEngine on

 <Directory /var/www/vhosts/<dummy>/httpdocs>

   <IfModule mod_php5.c>
       php_admin_flag engine on
       php_admin_flag safe_mode off
       php_admin_value include_path "/var/www/vhosts/<dummy>/httpdocs:.:/tmp:./:/usr/share/php5/PEAR/:/var/www/typo3src"
       php_admin_value open_basedir "/var/www/vhosts/<dummy>/httpdocs:/tmp:.:/usr/share/php5/PEAR/:/var/www/typo3src"
       php_value date.timezone "Europe/Berlin"
   </IfModule>

   <IfModule mod_python.c>
       <Files ~ (\.py$)>
               SetHandler python-program
               PythonHandler   mod_python.cgihandler
       </Files>
   </IfModule>

   Options -Includes +ExecCGI
 </Directory>

 <Directory "/var/www/vhosts/<dummy>/cgi-bin">
      AllowOverride None
      Options +ExecCGI -Includes
      Require all granted
 </Directory>
 
  SSLCertificateFile /etc/letsencrypt/live/<dummy>/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/<dummy>/privkey.pem
  SSLProtocol All -SSLv2 -SSLv3
  SSLHonorCipherOrder On
  SSLCompression off
  # Add six earth month HSTS header for all users...
#   Header add Strict-Transport-Security "max-age=15768000"
  SSLCipherSuite EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA 

  SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
  CustomLog /var/log/apache2-vhosts.d/<dummy>_ssl.log  "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

</VirtualHost>

</IfModule>

Mailsystem

Auf diesem Server soll es möglichst wenig Systembenutzer geben. Alle Mailadressen sollen also virtuell sein. Das System besteht aus folgenden Komponenten:

  • Postfix
  • Dovecot
  • MySQL
  • PostfixAdmin

Mailsystem.png

Eine weitere wichtige Rolle hierbei spielt

  • Roundcube

damit kann der virtuelle Benutzer Mailfilter bearbeiten und sein eigenes Passwort ändern.

Vorweg noch ein paar Informationen, die für das Testen ganz nützlich sind, man kann Mails in der Warteschlange (Abfrage mittels mailq) einzeln oder alle auf einen Schlag löschen.

postsuper -d ALL
postsuper -d 52DBF19F51 (die komische Zeichenkette ist die Queue-ID die mailq mit ausgibt, hier wird diese Mail gelöscht)

Den Inhalt der Mail findet man in

/var/spool/postfix/deferred/5/52DBF19F51

Zustellinformationen bzw. Fehlermeldungen in

/var/spool/postfix/defer/5/52DBF19F51

oder per

postcat -vq 52DBF19F51 (zeigt die Mail mit der angegebenen ID)

Für die folgende Beschreibung wird ein Benutzer vmail (uid 303) und eine Gruppe vmail (gid 303) benutzt. Der Benutzer hat als Homeverzeichnis /var/vmail, wo dann auch die eingehenden Mails liegen.

Da Gruppe und Benutzer nicht vorhanden sind, legt man sie neu an:

groupadd -g 303 vmail
mkdir /var/vmail
chmod a+rxw /var/vmail
useradd -d /var/vmail/ -s /bin/false -u 303 -g 303 vmail 

Zunächst müssen einige Pakete installiert werden

apt install amavisd-new amavisd-new-postfix postfix postfix-mysql postfix-policyd-spf-python postfixadmin dovecot-antispam spamass-milter spamassassin spamc 
apt install roundcube roundcube-core roundcube-mysql roundcube-plugins roundcube-plugins-extra mailutils
apt install dovecot-antispam dovecot-core dovecot-imapd dovecot-lmtpd dovecot-managesieved dovecot-mysql dovecot-pop3d dovecot-sieve dovecot-sqlite     


Postfixadmin

Die Beschreibung geht aus von dem Programmpaket PostfixAdmin, welches die Verwaltung der virtuellen Mail-Adressen über ein kleines nettes Webfrontend erlaubt. Die Homepage dieses Programmes ist http://postfixadmin.sourceforge.net/. Das Programmpaket greift nur auf eine MySQL-Datenbank zu und nicht direkt in das Mailsystem ein.

Das Programm lässt sich ganz einfach über die Paketverwaltung installieren und liegt in der Version 2.3.7 vor (aktuell verfügbar ist 3.0: http://sourceforge.net/projects/postfixadmin/files/latest/download?source=files). Ich habe die Ubuntu-Version benutzt.

Das Programm wird im Verzeichnis /usr/share/postfixadmin eingerichtet und die Konfigurationsdateien sind auf /etc/postfixadmin verlinkt.

Datenbanken

Für das Tool wird eine Datenbank mit folgenden Tabellen benötigt.

CREATE TABLE `admin` (
 `username` varchar(255) NOT NULL,
 `password` varchar(255) NOT NULL,
 `superadmin` tinyint(1) NOT NULL DEFAULT '0',
 `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `active` tinyint(1) NOT NULL DEFAULT '1',
 PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Admins';
CREATE TABLE `alias` (
 `address` varchar(255) NOT NULL,
 `goto` text NOT NULL,
 `domain` varchar(255) NOT NULL,
 `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `active` tinyint(1) NOT NULL DEFAULT '1',
 PRIMARY KEY (`address`),
 KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Aliases';
CREATE TABLE `alias_domain` (
 `alias_domain` varchar(255) NOT NULL,
 `target_domain` varchar(255) NOT NULL,
 `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `active` tinyint(1) NOT NULL DEFAULT '1',
 PRIMARY KEY (`alias_domain`),
 KEY `active` (`active`),
 KEY `target_domain` (`target_domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Domain Aliases';
CREATE TABLE `config` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(20) NOT NULL DEFAULT ,
 `value` varchar(20) NOT NULL DEFAULT ,
 PRIMARY KEY (`id`),
 UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COMMENT='PostfixAdmin settings';
CREATE TABLE `domain` (
 `domain` varchar(255) NOT NULL,
 `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Keine Beschreibung',
 `aliases` int(10) NOT NULL DEFAULT '0',
 `mailboxes` int(10) NOT NULL DEFAULT '0',
 `maxquota` bigint(20) NOT NULL DEFAULT '0',
 `quota` bigint(20) NOT NULL DEFAULT '0',
 `transport` varchar(255) NOT NULL,
 `backupmx` tinyint(1) NOT NULL DEFAULT '0',
 `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `active` tinyint(1) NOT NULL DEFAULT '1',
 PRIMARY KEY (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Domains';
CREATE TABLE `domain_admins` (
 `username` varchar(255) NOT NULL,
 `domain` varchar(255) NOT NULL,
 `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `active` tinyint(1) NOT NULL DEFAULT '1',
 KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Domain Admins';
CREATE TABLE `fetchmail` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `mailbox` varchar(255) NOT NULL,
 `src_server` varchar(255) NOT NULL,
 `src_auth` enum('password','kerberos_v5','kerberos','kerberos_v4','gssapi','cram-md5','otp','ntlm','msn','ssh','any') DEFAULT NU
 `src_user` varchar(255) NOT NULL,
 `src_password` varchar(255) NOT NULL,
 `src_folder` varchar(255) NOT NULL,
 `poll_time` int(11) unsigned NOT NULL DEFAULT '10',
 `fetchall` tinyint(1) unsigned NOT NULL DEFAULT '0',
 `keep` tinyint(1) unsigned NOT NULL DEFAULT '0',
 `protocol` enum('POP3','IMAP','POP2','ETRN','AUTO') DEFAULT NULL,
 `usessl` tinyint(1) unsigned NOT NULL DEFAULT '0',
 `sslcertck` tinyint(1) NOT NULL DEFAULT '0',
 `sslcertpath` varchar(255) CHARACTER SET utf8 DEFAULT ,
 `sslfingerprint` varchar(255) DEFAULT ,
 `extra_options` text,
 `returned_text` text,
 `mda` varchar(255) NOT NULL,
 `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `log` (
 `timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `username` varchar(255) NOT NULL,
 `domain` varchar(255) NOT NULL,
 `action` varchar(255) NOT NULL,
 `data` text NOT NULL,
 KEY `timestamp` (`timestamp`),
 KEY `domain_timestamp` (`domain`,`timestamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Log';
CREATE TABLE `mailbox` (
 `username` varchar(255) NOT NULL,
 `password` varchar(255) NOT NULL,
 `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `maildir` varchar(255) NOT NULL,
 `quota` bigint(20) NOT NULL DEFAULT '0',
 `local_part` varchar(255) NOT NULL,
 `domain` varchar(255) NOT NULL,
 `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `active` tinyint(1) NOT NULL DEFAULT '1',
 PRIMARY KEY (`username`),
 KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Mailboxes';
CREATE TABLE `quota` (
 `username` varchar(255) CHARACTER SET latin1 NOT NULL,
 `path` varchar(100) CHARACTER SET latin1 NOT NULL,
 `current` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`username`,`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `quota2` (
 `username` varchar(100) CHARACTER SET latin1 NOT NULL,
 `bytes` bigint(20) NOT NULL DEFAULT '0',
 `messages` int(11) NOT NULL DEFAULT '0',
 PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `vacation` (
 `email` varchar(255) NOT NULL,
 `subject` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `body` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `activefrom` timestamp NOT NULL DEFAULT '1999-12-31 23:00:00',
 `activeuntil` timestamp NOT NULL DEFAULT '1999-12-31 23:00:00',
 `cache` text NOT NULL,
 `domain` varchar(255) NOT NULL,
 `interval_time` int(11) NOT NULL DEFAULT '0',
 `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `active` tinyint(1) NOT NULL DEFAULT '1',
 PRIMARY KEY (`email`),
 KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Vacation';
CREATE TABLE `vacation_notification` (
 `on_vacation` varchar(255) NOT NULL,
 `notified` varchar(255) NOT NULL,
 `notified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 PRIMARY KEY (`on_vacation`,`notified`),
 CONSTRAINT `vacation_notification_pkey` FOREIGN KEY (`on_vacation`) REFERENCES `vacation` (`email`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Vacation Notifications';

Nicht alle Tabellen werden in meiner Konfiguration wirklich benutzt, aber es ist einfacher alle anzulegen.

/etc/postfixadmin/dbconfig.inc.php

Die Datenbankanbindung wird über diese Datei konfiguriert.

<?php
##
## database access settings in php format
## automatically generated from /etc/dbconfig-common/postfixadmin.conf
## by /usr/sbin/dbconfig-generate-include
##
## by default this file is managed via ucf, so you shouldn't have to
## worry about manual changes being silently discarded.  *however*,
## you'll probably also want to edit the configuration file mentioned
## above too.
##
$dbuser='postfix';
$dbpass='assword';
$basepath=;
$dbname='postfix';
$dbserver='localhost';
$dbport=;
$dbtype='mysqli';

AmaVis

Dieses Programm ist dazu da sich um Spam und Viren zu kümmern. Das geschieht im Zusammenspiel mit dem Clamav und Spamassassin. Hier ist ein wenig Anpassungsarbeit zu leisten, ich orientiere mich dabei an https://www.exratione.com/2016/05/a-mailserver-on-ubuntu-16-04-postfix-dovecot-mysql/

Zuerst werden die Programme gegenseitig in die Gruppen aufgenommen:

adduser clamav amavis
adduser amavis clamav

/etc/postfixadmin/config.inc.php

In dieser Datei sind viele Vor-Einstellungen anders, als ich es von meinen bisherigen Installationen gewohnt war. Hier ein paar Einstellungen, die wohl eine Rolle spielen:

$CONF['configured'] = true;
$CONF['setup_password'] = 'changeme';
$CONF['default_language'] = 'de';
$CONF['admin_email'] = 'postmaster@change-this-to-your.domain.tld';
$CONF['smtp_server'] = 'localhost';
$CONF['smtp_port'] = '25';
$CONF['encrypt'] = 'md5crypt';
$CONF['authlib_default_flavor'] = 'md5raw';
$CONF['dovecotpw'] = "/usr/bin/doveadm pw";
$CONF['min_password_length'] = 5;
$CONF['generate_password'] = 'NO';
$CONF['show_password'] = 'NO';
$CONF['page_size'] = '20';
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
$CONF['maildir_name_hook'] = 'NO';
$CONF['aliases'] = '10';
$CONF['mailboxes'] = '10';
$CONF['maxquota'] = '10240';
$CONF['quota'] = 'YES';
$CONF['quota_multiplier'] = '1024000';
$CONF['transport'] = 'NO';
$CONF['transport_options'] = array (
$CONF['transport_default'] = 'virtual';
$CONF['vacation'] = 'NO';
$CONF['vacation_domain'] = 'autoreply.change-this-to-your.domain.tld';
$CONF['vacation_control'] ='YES';
$CONF['vacation_control_admin'] = 'YES';
$CONF['alias_control'] = 'YES';
$CONF['alias_control_admin'] = 'YES';
$CONF['special_alias_control'] = 'NO';
$CONF['alias_goto_limit'] = '0';
$CONF['alias_domain'] = 'YES';
$CONF['backup'] = 'NO';
$CONF['sendmail'] = 'YES';
$CONF['logging'] = 'YES';
$CONF['fetchmail'] = 'YES';
$CONF['fetchmail_extra_options'] = 'NO';
$CONF['show_header_text'] = 'NO';
$CONF['header_text'] = ':: Postfix Admin ::';
$CONF['show_footer_text'] = 'YES';
$CONF['footer_text'] = 'Return to change-this-to-your.domain.tld';
$CONF['welcome_text'] = <<<EOM
Herzlich Willkommen,

zum Netthelp E-Mail Postfach.

Bei Fragen oder Problemen bitte
Uwe Debacher ansprechen
EOM;
$CONF['emailcheck_resolve_domain']='YES';
$CONF['show_status']='YES';
$CONF['show_status_key']='YES';
$CONF['show_status_text']='  ';
$CONF['show_undeliverable']='YES';
$CONF['show_undeliverable_color']='tomato';
$CONF['show_undeliverable_exceptions']=array("unixmail.domain.ext","exchangeserver.domain.ext","gmail.com");
$CONF['show_popimap']='YES';
$CONF['show_popimap_color']='darkgrey';
$CONF['show_custom_domains']=array("subdomain.domain.ext","domain2.ext");
$CONF['show_custom_colors']=array("lightgreen","lightblue");
$CONF['recipient_delimiter'] = "";
$CONF['create_mailbox_subdirs_prefix']='INBOX.';
$CONF['used_quotas'] = 'YES';
$CONF['new_quota_table'] = 'YES';

AmaVis

Diese Programm ist dazu da sich um Spam und Viren in EMails zu kümmern. Dazu arbeitet es mit Clamav und Spamassasin zusammen.

Für die Zusammenarbeit ist etwas Vorarbeit zu leisten, ich orientiere mich dabei an https://www.exratione.com/2016/05/a-mailserver-on-ubuntu-16-04-postfix-dovecot-mysql/

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

In der Datei /etc/amavis/conf.d/15-content_filter_mode müssen die Checks überhaupt erst einmal aktiviert werden, indem man die Kommentarzeichen vor den Zeilen entfernt.

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

Ob die Anpassung in /etc/default/spamassassin notwendig ist, wurde mir nicht ganz klar.

# Change to one to enable spamd
ENABLED=1

# 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


Zum Abschluss die Dienste neu starten:

service clamav-freshclam restart
service clamav-daemon restart
service amavis restart
service spamassassin restart

Dovecot

Unter http://www.debacher.de/wiki/Root-Server_mit_OpenSuSE_13.2#Dovecot habe ich die schrittweise Entwicklung meiner Dovecot-Konfiguration beschrieben. Diese Konfiguration passt weiterhin und befindet sich in der Datei /etc/dovecot/local.conf

disable_plaintext_auth = no
first_valid_uid = 303
mail_access_groups = postfix
mail_privileged_group = postfix

mail_location = maildir:/var/vmail/%d/%n
mail_home = /var/vmail/%d/%n/home

mail_plugins = $mail_plugins quota

passdb {
 args = /etc/dovecot/dovecot-mysql.conf
 driver = sql
}

plugin {
 sieve = ~/.dovecot.sieve
 sieve_dir = ~/sieve
}

dict {
   sqluserquota = mysql:/etc/dovecot/dovecot-dict-sql-user.conf
}

protocols = imap pop3 lmtp sieve
ssl = yes
#ssl_cert = </etc/letsencrypt/live/server2.netthelp.de/fullchain.pem
#ssl_key = </etc/letsencrypt/live/server2.netthelp.de/privkey.pem
ssl_cert = </etc/ssl/certs/ssl-cert-snakeoil.pem
ssl_key = </etc/ssl/private/ssl-cert-snakeoil.key

userdb {
 args = /etc/dovecot/dovecot-mysql.conf
 driver = sql
}

verbose_proctitle = yes

protocol pop3 {
 pop3_uidl_format = %08Xu%08Xv
 mail_max_userip_connections = 5
}

protocol imap {
 mail_max_userip_connections = 8
 mail_plugins = $mail_plugins imap_quota
}

service auth {
 unix_listener /var/spool/postfix/private/auth {
   group = postfix
   mode = 0660
   user = postfix
 }
}

protocol lmtp {
 mail_plugins = $mail_plugins sieve
}

service lmtp {
 unix_listener lmtp {
 #mode = 0666
 }

 unix_listener /var/spool/postfix/private/dovecot-lmtp {
 #mode = 0666
 user = postfix
 group = postfix
 }
}

service managesieve-login {
 inet_listener sieve {
  port = 4190 
 }
}

plugin {
 #quota_rule = *:storage=1G
 #quota_rule2 = Trash:storage=+100M

 quota_grace = 10%%

 quota_warning = storage=66%% quota-warning 66 %u 
 quota_warning2 = storage=80%% quota-warning 80 %u
 quota_warning3 = storage=95%% quota-warning 95 %u
#  quota = maildir:User quota:noenforcing
 quota = dict:User Quota::noenforcing:proxy::sqluserquota
}

service quota-warning {
  executable = script /usr/local/bin/quota-warning.sh
  user = vmail
  unix_listener quota-warning {
       group = vmail
       mode = 0660
       user = vmail
  }
}

service dict {
   unix_listener dict {
       mode = 0600
       user = vmail
   }
}

auth_mechanisms = plain login

#verbose_proctitle = no
#mail_debug = yes
#auth_debug = yes
auth_debug_passwords = yes
#auth_verbose = yes
auth_verbose_passwords = sha1

Zusätzlich habe ich die Authentisierung per pam deaktiviert, indem ich im Unterordner conf.d die Datei 10-auth.conf editiert und dort am Ende der Datei die einzig aktive Include-Zeile

!include auth-system.conf.ext

durch Voranstellen einer Raute deaktiviert habe. Das spart viel Zeit bei allen Authentifizierungen.

/etc/dovecot/dovecot-mysql.conf

Diese Datei musste ich etwas anpassen, da bei Ubuntu die Mysql-Socket Adresse etwas anders ist.

# Database driver: mysql, pgsql
driver = mysql

# Currently supported schemes include PLAIN, PLAIN-MD5, DIGEST-MD5, and CRYPT.
default_pass_scheme = CRYPT

# Database options
connect = host=/var/run/mysqld/mysqld.sock dbname=postfix user=postfix password=ge11heim

password_query = SELECT password FROM mailbox WHERE username = '%u' AND active = '1'
user_query = SELECT concat('maildir:/var/vmail/',maildir) as mail, \ 
                   303 AS uid, \ 
                   303 AS gid, \ 
                   CONCAT('*:bytes=', \
                    IF(mailbox.quota = 0, domain.maxquota*1024000, mailbox.quota)) \
                   as quota_rule \
            FROM mailbox, domain \
            WHERE username = '%u' AND mailbox.active = '1' AND \
                  domain.domain = '%d' AND domain.active = '1'

iterate_query = SELECT username as user FROM mailbox WHERE active ='1'


/etc/dovecot/dovecot-dict-sql-user.conf

Auch in dieser Datei muss ich der veränderten Socket Rechnung tragen

connect = host=/var/run/mysqld/mysqld.sock dbname=postfix user=postfix password=ge11heim
 
map {
   pattern = priv/quota/storage
   table = quota2
   username_field = username
   value_field = bytes
}

map {
   pattern = priv/quota/messages
   table = quota2
   username_field = username
   value_field = messages
}

Roundcube

Dieses beliebte Webmail-Programm wird standardmäßig im Verzeichnis /var/lib/roundcube/ abgelegt. Hierbei werden einige Unterverzeichnisse und Dateien an andere Stellen verlinkt

  • config -> /etc/roundcube
  • program -> /usr/share/roundcube/program
  • .htaccess -> /etc/roundcube/htaccess
  • logs -> /var/log/roundcube
  • robots.txt -> /usr/share/roundcube/robots.txt

Die Plugins finden sich im Verzeichnis /usr/share/roundcube/plugins/, wobei die Konfigurationsdateien, die auf /etc/roundcube/plugins/ verlinkt wurden, jeweils nahezu leer sind. Ein Muster findet sich dann jeweils unter /usr/share/roundcube/plugins/ in der Datei config.inc.php.dist

Also

cp /usr/share/roundcube/plugins/password/config.inc.php.dist /etc/roundcube/plugins/password/config.inc.php
cp /usr/share/roundcube/plugins/managesieve/config.inc.php.dist /etc/roundcube/plugins/managesieve/config.inc.php

Danach sind dann ein paar Dateien zu editieren.

/etc/roundcube/debian-db.php

<?php
##
## database access settings in php format
## automatically generated from /etc/dbconfig-common/roundcube.conf
## by /usr/sbin/dbconfig-generate-include
##
## by default this file is managed via ucf, so you shouldn't have to
## worry about manual changes being silently discarded.  *however*,
## you'll probably also want to edit the configuration file mentioned
## above too.
##
$dbuser='roundcube';
$dbpass='assword';
$basepath=;
$dbname='roundcube';
$dbserver='localhost';
$dbport=;
$dbtype='mysql';

/etc/roundcube/plugins/password/config.inc.php

ab Zeile 77

// SQL Driver options
// ------------------
// PEAR database DSN for performing the query. By default
// Roundcube DB settings are used.
$config['password_db_dsn'] = 'mysql://postfix:ge11heim@localhost/postfix';

// The SQL query used to change the password.
// The query can contain the following macros that will be expanded as follows:
//      %p is replaced with the plaintext new password
//      %P is replaced with the crypted/hashed new password
//         according to configured password_method
//      %o is replaced with the old (current) password
//      %O is replaced with the crypted/hashed old (current) password
//         according to configured password_method
//      %h is replaced with the imap host (from the session info)
//      %u is replaced with the username (from the session info)
//      %l is replaced with the local part of the username
//         (in case the username is an email address)
//      %d is replaced with the domain part of the username
//         (in case the username is an email address)
// Deprecated macros:
//      %c is replaced with the crypt version of the new password, MD5 if available
//         otherwise DES. More hash function can be enabled using the password_crypt_hash
//         configuration parameter.
//      %D is replaced with the dovecotpw-crypted version of the new password
//      %n is replaced with the hashed version of the new password
//      %q is replaced with the hashed password before the change
// Escaping of macros is handled by this module.
// Default: "SELECT update_passwd(%c, %u)"
$config['password_query'] = 'UPDATE mailbox SET password=%c WHERE username=%u';

// By default the crypt() function which is used to create the %c
// parameter uses the md5 algorithm (deprecated, use %P).
// You can choose between: des, md5, blowfish, sha256, sha512.
$config['password_crypt_hash'] = 'md5';
...


/etc/roundcube/plugins/managesieve/config.inc.php

<?php

// managesieve server port. When empty the port will be determined automatically
// using getservbyname() function, with 4190 as a fallback.
$config['managesieve_port'] = 4190;


/etc/roundcube/config.inc.php

In der hauptkonfigurationsdatei von Roundcube sind zwei Änderungen notwendig.

Ab Zeile 25

// The mail host chosen to perform the log-in.
// Leave blank to show a textbox at login, give a list of hosts
// to display a pulldown menu or set one host as string.
// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
// Supported replacement variables:
// %n - hostname ($_SERVER['SERVER_NAME'])
// %t - hostname without the first part
// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
// %s - domain name after the '@' from e-mail address provided at login screen
// For example %n = mail.domain.tld, %t = domain.tld
$config['default_host'] = 'localhost';


Ab Zeile 74

// List of active plugins (in plugins/ directory)
$config['plugins'] = array(
 'archive',
 'zipdownload',
 'managesieve',
 'password',
);

Postfix

Das zentrale Mailprogramm wird über die Dateien /etc/postfix/master.cf und /etc/postfix/main.cf konfiguriert. An der master.cf habe ich keinerlei Änderungen vorgenommen. Lediglich die main.cf habe ich nach meinen anforderungen erweitert.

/etc/postfix/main.cf

# See /usr/share/postfix/main.cf.dist for a commented, more complete version

# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = server3.netthelp.de
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, server3.netthelp.de, h2656233.stratoserver.net, localhost.stratoserver.net, localhost
relayhost =
#mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
content_filter = smtp-amavis:[localhost]:10024
policy-spf_time_limit = 3600s

relay_domains = $mydestination, hash:/etc/postfix/relay
#virtual_alias_domains = hash:/etc/postfix/virtual
#virtual_alias_maps = hash:/etc/postfix/virtual, hash:/var/lib/mailman/data/virtual-mailman, proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf, proxy:mysql:/etc/postfix/mysql_virtual_alias_domain_maps.cf,proxy:mysql:/etc/postfix/mysql_virtual_alias_domain_catchall_maps.cf
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf, proxy:mysql:/etc/postfix/mysql_virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/mysql_virtual_alias_domain_catchall_maps.cf

broken_sasl_auth_clients = yes
smtpd_sasl_local_domain =
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sasl_auth_enable = yes
smtp_sasl_auth_enable = no
smtp_sasl_security_options =
smtp_sasl_password_maps =

unknown_address_reject_code = 552
unknown_client_reject_code = 551
unknown_hostname_reject_code = 550

virtual_gid_maps = static:303
virtual_mailbox_base = /var/vmail/
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_limit = 0
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/mysql_virtual_alias_domain_mailbox_maps.cf
virtual_minimum_uid = 303
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_uid_maps = static:303
#maps_rbl_reject_code = 451

#canonical_maps = hash:/etc/postfix/canonical
#relocated_maps = hash:/etc/postfix/relocated
#sender_canonical_maps = hash:/etc/postfix/sender_canonical
#transport_maps = hash:/etc/postfix/transport
#mail_spool_directory = /var/mail
message_strip_characters = \0
defer_transports =
mailbox_command =
mailbox_transport =
mailbox_size_limit = 0
message_size_limit = 0
strict_8bitmime = no
strict_rfc821_envelopes = 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.dnsb

smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname

smtpd_sender_restrictions = hash:/etc/postfix/access, reject_unknown_sender_domain

#smtpd_recipient_restrictions = , check_policy_service unix:private/policy-spf
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

# tls config

# eingehende Verbindungen
smtpd_use_tls = yes
smtpd_enforce_tls = no
# Obiges kann zusammengefasst werden zu smtpd_tls_security_level=may
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

# ausgehende Verbindungen
smtp_use_tls = yes
smtp_enforce_tls = no
# Obiges kann zusammengefasst werden zu smtp_tls_security_level=may
smtp_tls_note_starttls_offer = yes
smtp_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtp_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
#smtp_tls_key_file = /etc/letsencrypt/live/server3.netthelp.de/privkey.pem
#smtp_tls_cert_file = /etc/letsencrypt/live/server3.netthelp.de/fullchain.pem
smtp_tls_loglevel = 1
smtp_tls_mandatory_protocols=!SSLv2, !SSLv3

# Limits - neu ab 17.1.17 gegen Spam
smtpd_client_message_rate_limit = 50
smtpd_client_connection_rate_limit = 10
smtpd_client_recipient_rate_limit = 50
smtpd_client_connection_count_limit = 25
bounce_queue_lifetime = 3d
maximal_queue_lifetime = 3d

Postfix und MySQL

Damit Postfix MySQL-Tabellen nutzen kann muss man folgende Dateien einrichten:

/etc/postfix/mysql_virtual_alias_maps.cf
/etc/postfix/mysql_virtual_domains_maps.cf
/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
/etc/postfix/mysql_virtual_mailbox_maps.cf
/etc/postfix/mysql_virtual_alias_domain_maps.cf
/etc/postfix/mysql_virtual_alias_domain_catchall_maps.cf
/etc/postfix/mysql_virtual_alias_domain_mailbox_maps.cf

Diese mysql-Dateien im Verzeichnis /etc/postfix muss man anpassen an die eigenen Datenbankeinstellungen. Muster dazu finden sich in der Datei /usr/share/doc/postfixadmin/DOCUMENTS/POSTFIX_CONF.txt.gz. Im Prinzip wird Postfix hier mitgeteilt, wie die Datenbanktabellen abgefragt werden. Benutzername und Passwort müssen hier an die eigenen Einstellungen angepasst werden.

Für die Dateien kenne ich jeweisl zwei unterschiedliche Formulierungen, hier am Beispiel der mysql_virtual_domains_maps.cf

SuSE-Version

user = postfix
password = password
hosts = localhost
#hosts = 127.0.0.1
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'

Übliche Version.

user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'

Man sieht, dass die SuSE-Version etwas erweitert wurde. Bei Ubuntu findet man jeweils die übliche Form.

mysql_virtual_alias_maps.cf

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

mysql_virtual_domains_maps.cf

user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'

mysql_virtual_mailbox_limit_maps.cf

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

mysql_virtual_mailbox_maps.cf

user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'

mysql_virtual_alias_domain_maps.cf

user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

mysql_virtual_alias_domain_catchall_maps.cf:

# handles catch-all settings of target-domain
user = postfix
password = password
hosts = localhost
dbname = postfix
query  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'


mysql_virtual_alias_domain_mailbox_maps.cf:

user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'

mailman

Mich hat überrascht, wie mühsam es ist eine Beschreibung zu finden, wie man mailman mit virtuellen Postfix-Mail verknüpft. Die hier beschriebene Konfiguration lässt einen Mailinglisten-Namen nur einmalig über alle Domains zu. Wenn es also eine Liste info@virtual1.tld gibt, dann ist es nicht möglich ebenfalls info@virtual2.tld einzurichten.

Weitere Informationen unter:

Zuerst muss man den Mailman installieren, per

apt install mailman

dann muss man ihn in der Apache-Konfiguration aktivieren:

Zuerst muss man die Konfigurationsdatei kopieren:

cp /etc/mailman/apache.conf  /etc/apache2/conf-available/mailman.conf

und dann aktivieren mittels:

a2enconf mailman

Danach den Apache neu starten.

service apache2 reload

Vor dem Neustart habe ich dann noch in jede vhost-Konfiguration die Zugriff auf Mailman bekommen soll die Zeilen

# Mailman-Pfade, ScriptAlias muss vor dem allgemeinen cgi-bin stehen
 ScriptAlias /cgi-bin/mailman/ /usr/lib/cgi-bin/mailman/
 Alias /pipermail/ /var/lib/mailman/archives/public/
 Alias /images/mailman/ /usr/share/images/mailman/

 ScriptAlias /cgi-bin/ "/var/www/vhosts/default/cgi-bin/"

eingefügt. Wichtig ist, dass die drei neuen Zeilen vor der üblichen ScriptAlias-Zeile für cgi-bin stehen, sonst funktioniert der SriptAlias für Mailman nicht.

Eine Änderung erfolgt in der Datei /etc/postfix/main.cf dort muss die Zeile

alias_maps = hash:/etc/aliases

erweitert werden zu

alias_maps = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases

damit die Alias-Einträge vom Mailman berücksichtigt werden. Zusätzlich muss für die virtuellen Domains der Eintrag virtual_alias_maps erweitert werden zu

virtual_alias_maps = hash:/etc/postfix/virtual, hash:/var/lib/mailman/data/virtual-mailman, proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf, proxy:mysql:/etc/postfix/mysql_virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/mysql_virtual_alias_domain_catchall_maps.cf

Außerdem habe ich in der master.cf die mailan-spezifischen Zeilen auskommentiert:

#mailman   unix  -       n       n       -       -       pipe
#  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
#  ${nexthop} ${user}

Dahinter würde ein anderer Ansatz stecken.


Nun legt man das Site-Kennwort fest mit

   /usr/lib/mailman/bin/mmsitepass

In der Datei /usr/lib/mailman/Mailman/mm_cfg.py finden sich einige Grundeinstellungen für den Mailman, die man mit einem Texteditor vornehmen kann, weitere Standardvorgaben findet man in der Datei /usr/lib/mailman/Mailman/Defaults.py.

Also ergänzen wir ein paar Zeilen in der Datei /usr/lib/mailman/Mailman/mm_cfg.py:

##################################################
# Put YOUR site-specific settings below this line.
DEFAULT_SERVER_LANGUAGE = 'de'
DEFAULT_ARCHIVE = Off
DEFAULT_ARCHIVE_PRIVATE = 1
SMTP_MAX_RCPTS = 500
DEFAULT_URL_HOST = 'myserver.tld'
DEFAULT_EMAIL_HOST = 'myserver.tld'
add_virtualhost('virtual1.tld', 'virtual1.tld')
add_virtualhost('virtual2.tld', 'virtual2.tld')
MTA = 'Postfix'
POSTFIX_STYLE_VIRTUAL_DOMAINS = ['virtual1.tld', 'virtual2.tld']
DEFAULT_REQUIRE_EXPLICIT_DESTINATION = No


Jetzt legt man noch die notwendige Standard-Mailingliste "mailman" an mittels

/usr/lib/mailman/bin/newlist -l de mailman postmaster@myserver.tld passwort

Dann kann man den Dienst starten:

systemctl start mailman.service

und dann auch veranlassen, dass er zukünftig automatisch gestartet wird

systemctl enable mailman.service

Wichtig ist jetzt und beim Neuanlegen einer Mailingliste immer ein Blick in das Verzeichnis /var/lib/mailman/data, hier müssen vier Dateien mit aktuellem Zeitstempel auftauchen:

-rw-rw---- 1 root list  1843 Feb 19 15:35 aliases
-rw-r----- 1 root list 12288 Feb 19 15:35 aliases.db
-rw-rw---- 1 root list  1011 Feb 19 15:35 virtual-mailman
-rw-r----- 1 root list 12288 Feb 19 15:35 virtual-mailman.db

Diese Dateien werden automatisch erzeugt vom Programm /usr/lib/mailman/bin/genaliases . Manchmal dauert es etwas, bis die Dateien auftauchen, man kann das Programm auch von Hand aufrufen.

Hinweis: Die Dateien virtual-mailman und virtual-mailman.db werden natürlich erst angelegt, wenn für eine virtuelle Domain eine Mailingliste erzeugt wird. Solange bis die Dateien existieren ist die Postfix-Konfiguration nicht in Ordnung: Das hat mich mal wieder etwas Zeit gekostet.

Hier einmal ein Inhalt der Datei virtual-mailman

# This file is generated by Mailman, and is kept in sync with the binary hash
# file virtual-mailman.db.  YOU SHOULD NOT MANUALLY EDIT THIS FILE unless you
# know what you're doing, and can keep the two files properly in sync.  If you
# screw it up, you're on your own.
#
# Note that you should already have this virtual domain set up properly in
# your Postfix installation.  See README.POSTFIX for details.

# LOOP ADDRESSES START
mailman-loop@apachebuch.de      mailman-loop
# LOOP ADDRESSES END 

# STANZA START: test
# CREATED: Sun Feb 19 15:35:19 2017
test@apachebuch.de              test
test-admin@apachebuch.de        test-admin
test-bounces@apachebuch.de      test-bounces
test-confirm@apachebuch.de      test-confirm
test-join@apachebuch.de         test-join
test-leave@apachebuch.de        test-leave
test-owner@apachebuch.de        test-owner
test-request@apachebuch.de      test-request
test-subscribe@apachebuch.de    test-subscribe
test-unsubscribe@apachebuch.de  test-unsubscribe
# STANZA END: test

Dazu gehört dann folgend aliases-Datei:

# This file is generated by Mailman, and is kept in sync with the
# binary hash file aliases.db.  YOU SHOULD NOT MANUALLY EDIT THIS FILE
# unless you know what you're doing, and can keep the two files properly
# in sync.  If you screw it up, you're on your own.

# The ultimate loop stopper address
mailman-loop: /var/lib/mailman/data/owner-bounces.mbox 

# STANZA START: mailman
# CREATED: Sun Feb 19 15:32:09 2017
mailman:             "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:       "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:     "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:     "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:        "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:       "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:       "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:     "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:   "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe mailman"
# STANZA END: mailman

# STANZA START: test
# CREATED: Sun Feb 19 15:35:19 2017
test:             "|/var/lib/mailman/mail/mailman post test"
test-admin:       "|/var/lib/mailman/mail/mailman admin test"
test-bounces:     "|/var/lib/mailman/mail/mailman bounces test"
test-confirm:     "|/var/lib/mailman/mail/mailman confirm test"
test-join:        "|/var/lib/mailman/mail/mailman join test"
test-leave:       "|/var/lib/mailman/mail/mailman leave test"
test-owner:       "|/var/lib/mailman/mail/mailman owner test"
test-request:     "|/var/lib/mailman/mail/mailman request test"
test-subscribe:   "|/var/lib/mailman/mail/mailman subscribe test"
test-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe test"
# STANZA END: test

Die Dateien mit der Endung .db sind jeweils gehashte Versionen der Klartext-Dateien.

Will man eine neue Mailingliste erstellen, so ist das kein Problem, sofern es für die betreffende Domain schon eine Liste gibt. Dann kann man die einfach über http://server.tld/mailman/create anlegen. Wichtig ist aber, dass man anschließend noch einmal in die Konfiguration der Liste geht Allgemeine Optionen und dort unter Bevorzugter Hostname für E-Mail an diese Liste die zugehörige Domain angibt.

Gibt es für die Domain noch keine Mailingliste, so muss man darauf achten, dass die Domain per postfixadmin eingetragen ist, sonst nimmt das System keinerlei Mails für die Domain an. Dann mauss man in der Datei /usr/lib/mailman/Mailman/mm_cfg.py eine add_virtualhost() Zeile ergänzen und die Domain auch bei POSTFIX_STYLE_VIRTUAL_DOMAINS mit eintragen. Erst danach kann man dann die Liste sinnvoll anlegen.

Kontrollieren kann man noch, ob das Startscript legt die Datei /etc/cron.d/mailman anlegt. Beim Stoppen löscht es diese Datei auch wieder.

Nachtrag vom 1.6.2017

Bei letzten Übertragen von Mailman-Listen vom alten Server2 auf den neuen Server3 hatte ich das Problem, dass an manchen Stellen in Mails und Links plötztlich noch Server2 auftauchte. Ich habe lange verzeweifelt nach der Konfigurationsdatei gesucht.

Gefunden habe ich es dann in:

/var/lib/mailman/lists/<listenname>/config.pck

Hierbei handelt es sich wohl um eine gepackte Konfigurationsdatei. Ich habe hier einfach per Hand die URL korrigiert.

Nachträglich gefunden habe ich noch:

withlist -l -r fix_url <listname> -u mailman.yyy.com

setzt den host in web_page_url auf mailman.yyy.com and host_name auf xxx.com. (Habe ich dann ausprobiert, funktioniert einwandfrei.)


Zusätzlich hatte ich bei dem Ubuntu-System das Problem, dass alle System-Nachrichten auf Englisch waren, trotz entsprechender Konfiguration. Das ließ sich aber beseitigen:

cp -a /usr/share/mailman/de/  /etc/mailman/

vsftpd

Warum soll es immer nur bei SUSE mitgelieferte Probleme geben;-) Bei dem Ubuntu-System konnte ich die Quellen von pam_imap nicht compilieren und das mitgelieferte Modul pam_mysql ist leider defekt (https://bugs.launchpad.net/ubuntu/+source/pam-mysql/+bug/1574900). Beim Einsatz des Modules bekommt man Fehlermeldungen der Art

connected: PAM unable to dlopen(pam_mysql.so): /lib/security/pam_mysql.so: undefined symbol: make_scrambled_password
connected: PAM adding faulty module: pam_mysql.so
connected: pam_unix(vsftpd:auth): check pass; user unknown

Nach längerer Suche habe dafür eine einfache Lösung gefunden und zwar hier https://launchpad.net/~voronov84/+archive/ubuntu/andreyv Der Autor Andrey Voronov hat eine funktionsfähige Version des Moduls erstellt, die einfach nur anstatt der mitgelieferten Version installiert werden muss:

add-apt-repository ppa:voronov84/andreyv
apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 12946919
apt update
apt list --upgradable
apt upgrade

Unter den aktualisierbaren Paketen sollte auch pam_mysql vorhanden sein und beim upgrade aktualisiert werden.

Nun müssen noch am Anfang der Datei /etc/pam.d/vsftpd zwei Zeilen ergänzt werden:

auth sufficient pam_mysql.so user=postfix passwd=asswd host=localhost db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1 where=active="1"
account sufficient pam_mysql.so user=postfix passwd=asswd host=localhost db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1 where=active="1"

# Standard behaviour for ftpd(8).
auth    required        pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
...

Mit den beiden Zeilen wird dem Pam-System (bzw. dem Modul pam_mysql) mitgeteilt, dass es auf die MySQL-Datenbank zugreifen soll und wo es die notwendigen Daten findet. Statt der beiden langen Parameterlisten könnte man auch mit einem config_file arbeiten ( auth required pam_mysql.so config_file=/lib/security/pam_mysql.conf). Das hätte dann folgenden Aufbau:

users.host localhost
users.database postix
users.db_user postfix
users.db_passwd asswd
users.table mailbox
users.user_column username
users.password_column password
users.password_crypt 1
users.where_clause active="1"


Nun habe ich in der Datei /etc/vsftpd.conf noch ein paar Änderungen vorgenommen. Hier eine Liste aller aktiven Einstellungen in alphabetischer Reihenfolge:

allow_writeable_chroot=YES
anon_world_readable_only=YES
anonymous_enable=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
chroot_local_user=YES
connect_from_port_20=YES
dirmessage_enable=YES
dual_log_enable=YES
guest_enable=YES
guest_username=ftp
listen=YES
local_enable=YES
log_ftp_protocol=YES
nopriv_user=ftpsecure
pam_service_name=vsftpd
pasv_max_port=30100
pasv_min_port=30000
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
secure_chroot_dir=/var/run/vsftpd/empty
setproctitle_enable=YES
ssl_enable=NO
use_localtime=YES
user_config_dir=/etc/vsftpd/
vsftpd_log_file=/var/log/vsftpd.log
write_enable=YES
xferlog_enable=YES
xferlog_file=/var/log/xferlog
xferlog_std_format=YES


Erfahrungen

Typo3 6.2 scheint zu laufen. Es gab nur eine Reihe von Warnungen der Art:

[Mon Feb 20 13:00:32.243132 2017] [:error] [pid 28367] [client 141.91.210.10:53370] PHP Warning:  Declaration of TYPO3\\CMS\\Core\\Package \\FailsafePackageManager::registerPackagesFromConfiguration() should be compatible with TYPO3\\CMS\\Core\\Package\\PackageManager::registerPackagesFromConfiguration($registerOnlyNewPackages = false) in /srv/www/typo3src/typo3_src-6.2.30/typo3/sysext/core/Classes/Package/FailsafePackageManager.php on line 24, referer: http://gi-hill.server3.netthelp.de/typo3/sysext/install/Start/Install.php?install[action]=configuration&install[context]=standalone&install[controller]=tool


Dazu habe ich folgende Anleitung unter http://stackoverflow.com/questions/35804678/typo3-ver-6-2-error-at-installation gefunden:

This also happend to me when using Typo3 6.2LTS with php7. I fixed it in file typo3\sysext\core\Classes\Package\FailsafePackageManager.php line 66:

before

protected function registerPackagesFromConfiguration() {

after:

protected function registerPackagesFromConfiguration($registerOnlyNewPackages = false) {


phpmyadmin

Die Software nervte gelegentlich (warum eigentlich nicht immer) mit einer Reihe von Fehlermeldungen der Art:

phpmyadmin Deprecation Notice in ./../php/php-gettext/streams.php#48

Das Problem lässt sich lösen, indem man in das Verzeichnis

/usr/share/php/php-gettext

wechselt und dort die Dateien gettext.php und streams.php bearbeitet. Bei den Konstruktoren muss jeweils der Klassenname durch __construct ersetzt werden.

Aus

 /**
  * Constructor
  *
  * @param object Reader the StreamReader object
  * @param boolean enable_cache Enable or disable caching of strings (default on)
  */
 function gettext_reader($Reader, $enable_cache = true) {
   // If there isn't a StreamReader, turn on short circuit mode.

wird dann

 /**
  * Constructor
  *
  * @param object Reader the StreamReader object
  * @param boolean enable_cache Enable or disable caching of strings (default on)
  */
 function __construct($Reader, $enable_cache = true) {
   // If there isn't a StreamReader, turn on short circuit mode.



Fortsetzung folgt