Teil 2 – Der Web Server – Der perfekte ISPConfig Multi-Server mit Web-, Mail-, Datenbank-, NS1- und NS2- Server

Teil 2 der ISPConfig Multi-Server Anleitung auf Ubuntu 16.04 mit Dediziertem Web-, Mail-, NS1-, NS2-, Datenbank-Server

  1. Einleitung & Vorbereitung der ISPConfig Multi Server
  2. ISPConfig Web Server installieren
  3. ISPConfig NS1 DNS Server installieren
  4. ISPConfig NS2 DNS Server installieren
  5. ISPConfig MariaDB Datenbank Server installieren
  6. ISPConfig Mail Server installieren

Auf dieser Seite beschreibe ich, wie ich den Web-, und damit auch Master-Server installiere. Folgende Inhalte werden hier beschrieben:

Apache / php7.0

Ich installiere Apache und php7 in einem Durchgang mit:

apt install apache2 apache2-doc apache2-utils libapache2-mod-php libapache2-mod-geoip php7.0 php7.0-common php7.0-gd php7.0-mysql php7.0-imap php7.0-cli php7.0-cgi libapache2-mod-fcgid apache2-suexec-pristine php-pear php-auth php7.0-mcrypt mcrypt  imagemagick libruby libapache2-mod-python php7.0-curl php7.0-intl php7.0-pspell php7.0-recode php7.0-sqlite3 php7.0-tidy php7.0-xmlrpc php7.0-xsl memcached php-memcache php-imagick php-gettext php7.0-zip php7.0-mbstring php7.0-opcache php-apcu libapache2-mod-fastcgi php7.0-fpm

Um sicher zu stellen, dass alle notwendigen Module aktiviert sind, schicke ich einmal ab:

a2enmod suexec rewrite ssl actions include cgi suexec rewrite ssl actions include cgi actions fastcgi alias headers expires cache geoip

Jetzt will ich noch den httpoxy Bug umgehen. Dazu öffne ich:

sudo nano /etc/apache2/conf-available/httpoxy.conf

und trage da folgendes ein:

<IfModule mod_headers.c>
RequestHeader unset Proxy early
</IfModule>

Anschließend aktiviere ich die Konfiguration mit:

a2enconf httpoxy

Mod Pagespeed

Weil ich Mod Pagespeed gerne auf meinem Webserver verfügbar haben möchte, installiere ich es wie folgt:

cd /tmp/
wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_amd64.deb
dpkg -i mod-pagespeed-stable_current_amd64.deb

Um mögliche Konflikte mit anderen Services zu vermeiden, schalte ich Pagespeed zunächst einmal Server weit aus. Dazu:

nano /etc/apache2/mods-available/pagespeed.conf

Und bei „ModPagespeed on“ stelle ich um auf:

[…]
    # Turn on mod_pagespeed. To completely disable mod_pagespeed, you
    # can set this to "off".
    ModPagespeed off

    # VHosts should inherit global configuration.
    # This option is only for backwards compatibility and will be removed
    # in the next major mod_pagespeed release.
[…]

Mod Pagespeed kann dann für jede Seite separat in der .htaccess mit einem „ModPagespeed on“ aktiviert werden.

GEOIP

Anschließend will ich, dass Apache auch goeip zur Verfügung stellt. Dazu erstelle ich erst ein Backup der original Datei mit:

mv /etc/apache2/mods-enabled/geoip.conf /etc/apache2/mods-enabled/geoip.conf.back

dann öffne ich die Konfiguration mit:

nano /etc/apache2/mods-enabled/geoip.conf

und füge folgendes in die Konfiguration:

<IfModule mod_geoip.c>
GeoIPEnable On
GeoIPDBFile /usr/share/GeoIP/GeoLiteCity.dat
GeoIPDBFile /usr/share/GeoIP/GeoIP.dat

# SetEnvIf GEOIP_COUNTRY_CODE AE BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE AF BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE AL BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE AM BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE AZ BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE BA BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE BD BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE BG BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE BY BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE CD BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE CF BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE CN BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE GR BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE HK BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE IL BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE IQ BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE IR BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE JO BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE KE BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE KG BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE KR BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE KZ BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE LB BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE LY BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE MA BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE MD BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE ME BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE MN BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE OM BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE PK BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE SA BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE SD BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE SN BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE SY BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE TJ BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE TM BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE TN BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE TW BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE UA BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE UZ BlockCountry
# SetEnvIf GEOIP_COUNTRY_CODE VN BlockCountry
</Ifmodule>

Für den Fall, dass einem Land der Zugriff auf eine Seite verwehrt wird, kann dann einfach in der .htaccess folgendes eingetragen werden:

SetEnvIf GEOIP_COUNTRY_CODE XX BlockCountry
Deny from env=BlockCountry

Und schon liefert Apache nur eine 403 Forbidden aus wenn man die Seite aus dem Land ansurft. Man muss hier nochmal einen Link von /usr/share nach /usr/local/share setzen mit:

ln -s /usr/share/GeoIP /usr/local/share/

Roundcube

Roundcube, und alles was dazu gehört, installiere ich mit:

apt install roundcube roundcube-core roundcube-mysql roundcube-plugins roundcube-plugins-extra javascript-common libjs-jquery-mousewheel php-net-sieve tinymce

und bei der Konfiguration mache ich folgende Angaben.

Configure database for roundcube with dbconfig-common? <== YES
MySQL application password for roundcube: <== Enter

In der Apache Konfiguration für Roundcube kann eingestellt werden, unter welcher URL Roundcube erreichbar sein soll. Dazu ändert man einfach den wert, der nach Alias / kommt. Als Beispiel: Falls webmail gewünscht ist, sollte es so aussehen „Alias /webmail /var/lib/roundcube“. Man kann hier auch mehrere aliases untereinander plazieren, um Roundcube unter mehreren URLs zu erreichen. Der Fantasie sind da fast keine Grenzen gesetzt. Um jedoch Brutforce Attacken minimal zu halten, sollte die URL vielleicht auch wie ein Key oder sowas aussehen. „Alias /a5c2171c96b2c7674efdecc2c9599046 /var/lib/roundcube“. Oder so. Die Konfiguration ist zu finden mit:

nano /etc/apache2/conf-enabled/roundcube.conf

Passt die Roundcube URL nach Wunsch an, und setzt ein: „AddType application/x-httpd-php .php“ direkt unter: „<Directory /var/lib/roundcube>“.

[…]
Alias /roundcube /var/lib/roundcube
[…]
<Directory /var/lib/roundcube>
 AddType application/x-httpd-php .php
[…]

Jetzt muss ich Roundcube noch mitteilen, dass ich einen SMTP / IMAP auf einem anderen Server haben. Dazu bearbeite ich die config.inc.php mit:

nano /etc/roundcube/config.inc.php

Folgende Änderungen mache ich in dieser Datei:

$config['default_host'] = 'ssl://mx.ispconfig-server.space';
$config['smtp_server'] = 'ssl://%h';
$config['smtp_port'] = 465;
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';

$config[‘default_host’] = ”; definiert hier den IMAP Server, den ich gerne verwenden möchte.
„ssl://“ definiert, dass die Verbindung SSL Verschlüsselt erfolgen soll.

$config[‘smtp_server’] = ”; definiert den SMTP Server. Da SMTP und IMAP dieselben sind, setze ich die Variable „%h“ (gleich Server wie auch in default_host). Mit „ssl://“ vorangestellt, definiere ich hier, auch wieder, dass die Verbindung SSL Verschlüsselt erfolgen soll.

$config[‘smtp_port’] = 465; definiert über welchen Port die Kommunikation erfolgen soll.

$config[‘smtp_user’] = ‘%u’; und $config[‘smtp_pass’] = ‘%p’; definieren, dass zum anmelden auf dem SMTP die gleichen Zugangsdaten verwendet werden sollen, die der Nutzer verwendet um sich via Roundcube auf dem IMAP anzumelden. Es sind also die Zugangsdaten, die beim erstellen des Mail Accounts vergeben wurden.

phpMyAdmin

phpMyAdmin wird separat installiert mit:

apt install phpmyadmin

und bei der Konfiguration mache ich folgende Angaben.

Configure database for phpmyadmin with dbconfig-common? <-- NO
Web server to reconfigure automatically: <-- apache2

Anschließend muss ich phpMyAdmin mitteilen, dass ich gerne die Datenbank eines anderen Servers nutzen würden. In der Konfiguration unter:

nano /etc/phpmyadmin/config.inc.php

füge ich am Ende der Datei diese zwei Zeilen ein:

$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['host'] = 'db.ispconfig-server.space';
$cfg['Servers'][$i]['hide_db'] = '(mysql|information_schema|phpmyadmin)';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
$cfg['Servers'][$i]['extension'] = 'mysqli';

Damit phpMyAdmin ein kleines bisschen vor Bruteforce geschützt ist, sollte auch hier, die Standard-URL /phpmyadmin in etwas anderes umgestellt werden. Die Apache Konfiguration für phpMyAdmin ist zu finden unter:

nano /etc/phpmyadmin/apache.conf

Achtet darauf, die „#“ vor der Zeile

Alias /phpmyadmin /usr/share/phpmyadmin

zu entfernen. Wie auch oben bei Roundcube, sollte hier /phpmyadmin in etwas anderes, z.b. /da-ten-bank-en oder so geändert werden. Jetzt habe ich soweit alles eingestellt und angepasst und starte Apache einmal neu mit:

service apache2 restart

phpMyAdmin und Roundcube sollten jetzt ebenfalls erreichbar sein unter: xxx.xxx.xxx.xxx/phpmyadmin bzw. xxx.xxx.xxx.xxx/roundcube falls Ihr die werte nicht geändert habt. xxx.xxx.xxx.xxx ist die Master Server IP Adresse. Jedoch werden Anmeldeversuche scheitern.

Let’s Encrypt

Let’s Encrypt ist auch in seiner letzten Version voll mit ISPConfig kompatibel. Ich installiere es mit einem einfachen:

apt install letsencrypt -y

Das wars. Let’s Encrypt muss nicht gestartet oder konfiguriert werden.

PureFTPD

PureFTPD installiere ich mit:

apt install pure-ftpd-common pure-ftpd-mysql

In der PureFTPD Konfiguration müssen zwei werte angepasst / geprüft werden. Dazu öffne ich die Konfiguration mit:

nano /etc/default/pure-ftpd-common

Ich will, dass PureFTP alleinstehend arbeitet und prüfe ob der wert „standalone“ bei „STANDALONE_OR_INETD=“ eingetragen ist. Ebenfalls will ich, dass jeder FTP Nutzer nur innerhalb seiner Verzeichnisse spielen darf, und stelle dafür den Wert hinter „VIRTUALCHROOT=“ auf „true“.

[…]
STANDALONE_OR_INETD=standalone
[…]
VIRTUALCHROOT=true
[…]

Ich will, dass PureFTP nur verschlüsselt kommuniziert und aktiviere es mit einem kurzen:

echo 1 > /etc/pure-ftpd/conf/TLS

Damit ich keine Fehlermeldungen erhalte, erstelle ich auch gleich ein selbst signiertes Zertifikat für PureFTP. Später werden wir dieses Zertifikat mit einem echten austauschen.

mkdir -p /etc/ssl/private/
openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem

Hier könnt ihr euch einfach mit Enter durch schalten.

Country Name (2 letter code) [AU]: <== Enter.
State or Province Name (full name) [Some-State]:<== Enter.
Locality Name (eg, city) []:<== Enter.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:<== Enter.
Organizational Unit Name (eg, section) []:<== Enter.
Common Name (eg, YOUR name) []:<== Enter.
Email Address []:<== Enter.

Dann bekommt das Zertifikat noch die notwendigen Rechte mit:

chmod 600 /etc/ssl/private/pure-ftpd.pem

Damit es weniger Probleme mit einer Firewall gibt, schränke ich die Ports die PureFTPD verwenden kann ein. Dazu öffne ich:

nano /etc/pure-ftpd/conf/PassivePortRange

und trage da:

29799 29899

ein. Damit definiere ich, dass PureFTPD nur die Ports 29799 bis 29899 zur Datenübertragung verwenden soll. Das sind 100 Ports die zur Verfügung stehen, und erlauben es 50 FTP Nutzern gleichzeitig auf dem Server Daten hin und hier zu schieben. Sollte es zu wenig sein, dann können die Ports natürlich erweitert werden. In der Firewall müssen dann später auch diese Ports geöffnet werden. PureFTPD kann jetzt einmal neu gestartet werden mit:

service pure-ftpd-mysql restart

Quota

Um quota zu aktivieren (ist kein Muss) solltet Ihr sicher stellen, dass der Kernel auf der Maschine es auch unterstützt. Der Kernel auf den Maschinen von Digital Ocean unterstützt es nicht, jedoch hier einmal die Schritte wie es aussehen sollte. Dazu installiert die Pakete quota quotatool mit:

apt install quota quotatool -y

und fügt ihr folgendes in die fstab für die root partition (/) ein. Öffnet die fstab mit:

nano /etc/fstab

Und setzt da ein: „,usrjquota=quota.user,grpjquota=quota.group,jqfmt=vfsv0 0 1“ ein.

/dev/mapper/server1--vg-root / ext4 errors=remount-ro,usrjquota=quota.user,grpjquota=quota.group,jqfmt=vfsv0 0 1

Anschließend muss / wieder neu eingebunden werden mit:

mount -o remount /

Das ganze prüft ihr einmal mit:

quotacheck -avugm

Die ausgabe sollte ca. so aussehen:

root@host:~# quotacheck -avugm
quotacheck: Scanning /dev/mapper/server1--vg-root [/] done
quotacheck: Cannot stat old user quota file //quota.user: No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old group quota file //quota.group: No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old user quota file //quota.user: No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old group quota file //quota.group: No such file or directory. Usage will not be subtracted.
quotacheck: Checked 11642 directories and 81307 files
quotacheck: Old file not found.
quotacheck: Old file not found.

Um Quota zu aktivieren, muss einmal ein:

quotaon -avug

ausgeführt werden. Falls alles sauber gelaufen ist, dann solltet ihr folgende Ausgabe sehen. Falls nicht, dann werden da Fehlermeldungen angezeigt.

root@server1:~# quotaon -avug
/dev/mapper/server1--vg-root [/]: group quotas turned on
/dev/mapper/server1--vg-root [/]: user quotas turned on

Webalizer Vlogger AWStats

Um Nutzern einige Statistik Tools in die Hand zu geben, installiere ich Webalizer, Vlogger & AWStats mit:

apt install vlogger webalizer awstats geoip-database libclass-dbi-mysql-perl

Den AWStats Cron stelle ich vollständig ab weil ISPConfig das Handling übernimmt.

nano /etc/cron.d/awstats

und kommentiere alle Zeilen aus:

#MAILTO=root
#*/10 * * * * www-data [ -x /usr/share/awstats/tools/update.sh ] && /usr/share/awstats/tools/update.sh
# Generate static reports:
#10 03 * * * www-data [ -x /usr/share/awstats/tools/buildstatic.sh ] && /usr/share/awstats/tools/buildstatic.sh

Jailkit

Um Jailkit installieren zu können, brauche ich noch einige Hilfstools. Dazu ein:

apt install build-essential autoconf automake1.11 libtool flex bison debhelper binutils

Anschließend installiere ich es wie folgt:

cd /tmp/
wget http://olivier.sessink.nl/jailkit/jailkit-2.19.tar.gz
tar xvfz jailkit-2.19.tar.gz
cd jailkit-2.19
./debian/rules binary
cd ..
dpkg -i jailkit_2.19-1_*.deb
rm -rf jailkit-2.19*

Fail2Ban Konfiguration für SSH, PureFTPD & WordPress

Fail2Ban inspiziert log files des Servers auf verdächtige eingaben und fehlgeschlagene Passwort eingaben und sperrt dann anschließend die IP nach definition. Zuerst erstelle ich ein Backup der ursprünglichen jail.conf mit:

mv /etc/fail2ban/jail.local /etc/fail2ban/jail.local-back

Dann erstelle ich die Datei einmal neu mit:

nano /etc/fail2ban/jail.local

Und definiere da folgende Werte:

[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1/8 10.135.50.182 10.135.14.243 10.135.49.117 10.135.1.181 138.68.100.36 46.101.150.61 46.101.142.124 46.101.132.69 165.227.152.75
bantime  = 43200
maxretry = 3
action = %(action_mwl)s
findtime = 3600

[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log

[pure-ftpd]
enabled  = true
port     = ftp
filter   = pureftpd
logpath  = /var/log/syslog

[wordpress-hard]
enabled = true
filter = wordpress-hard
logpath = /var/log/auth.log
maxretry = 3
port = http,https
bantime  = 600
findtime = 600

[framework-ddos]
enabled = true
port = 80,443
protocol = tcp
filter = framework-ddos
logpath = /var/log/apache2/other_vhosts_access.log
maxretry = 50
# findtime: 10 mins
findtime = 600
# bantime: 1 week
bantime  = 604800

Unter [DEFAULT], werden Grundwerte definiert. Hier einmal eine kurze Beschreibung dazu. ignoreip = legt fest welche IP Adressen ignoriert werden sollen. Ich habe da die internen und externen IP Adressen aller Server eingetragen, um sicher zu stellen, dass diese sich nicht gegenseitig ausboxen, falls es mal zu einer Fehlkonfiguration kommen sollte. bantime = definiert in Sekunden, für wie lange eine IP jeweils gesperrt werden soll. 43200 Sek. Sind ca. 12 Stunden. maxretry = definiert wie oft ein Ereignis wiederholt werden kann. Mit maxretry = 3 werden z.B. 3 gescheiterte Anmeldeversuche gestattet. findtime = definiert den Zeitraum. 3600 ist eine Stunde. Bedeutet also, drei falsche Passwort eingaben, innerhalb von einer Stunde, würden die IP für 12 Stunden sperren. Die Einstellungen zu [default] regeln das grundsätzliche Verhalten, was aber von Filter zu Filter unterschiedliche eingestellt werden kann. Die Filter zu PureFTPD, WordPress und Framework DDOS müssen noch erstellt werden. Dazu trage ich bei:

nano /etc/fail2ban/filter.d/pureftpd.conf

folgendes ein:

[Definition]
failregex = .*pure-ftpd: \(.*@<HOST>\) \[WARNING\] Authentication failed for user.*
ignoreregex =

Den WordPress Filter definiere ich in:

nano /etc/fail2ban/filter.d/wordpress-hard.conf

indem ich folgendes eintrage:

# Fail2Ban filter for WordPress hard failures
#
[INCLUDES]
before = common.conf
[Definition]
_daemon = (?:wordpress|wp)
failregex = ^%(__prefix_line)sAuthentication attempt for unknown user .* from <HOST>$
            ^%(__prefix_line)sBlocked user enumeration attempt from <HOST>$
            ^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$
            ^%(__prefix_line)sPingback error .* generated from <HOST>$
            ^%(__prefix_line)sSpam comment \d+ from <HOST>$
            ^%(__prefix_line)sXML-RPC authentication attempt for unknown user .* from <HOST>$
            ^%(__prefix_line)sXML-RPC multicall authentication failure from <HOST>$
ignoreregex =
# DEV Notes:
# Requires the 'WP fail2ban' plugin:
# https://wordpress.org/plugins/wp-fail2ban/
#
# Author: Charles Lecklider

Damit WordPress via Fail2Ban geschützt ist, muss das Plugin: https://wordpress.org/plugins/wp-fail2ban/ bei jeder WordPress Seite installiert sein. Und um den Framework DDOS filter zu definieren, öffne ich:

nano /etc/fail2ban/filter.d/framework-ddos.conf

und trage da folgendes ein:

[Definition]
failregex = .*:(80|443) <HOST> .*(GET|POST) .*/xmlrpc.php
            .*:(80|443) <HOST> .*(GET|POST) .*/wp-login.php
            .*:(80|443) <HOST> .*(GET|POST) /administrator/index.php HTTP

Der Framwork DDOS Filter schützt zusätzlich gegen Bruteforce artiges aufrufen der xmlrpc.php / wp-login.php. Fail2Ban braucht jetzt noch einen neu start mit:

service fail2ban restart

MySQL Root login für die anderen Server erstellen

Jetzt müssen die anderen Server noch einen root Zugang zur MySQL Datenbank auf dem Master Server erhalten. Bitte achtet darauf, dass ich hier die internen IP‘s der anderen Server nutze. Ändert bitte die Passwörter, IP Adressen und die subdomains / hostnames. Bitte achtet darauf, dass ihr da wirklich nur die IP Adressen, Domains & Passwörter ändert. Den ganzen Vorgang kann man direkt im Terminal erledigen. Dazu einfach mysql aufrufen, und dann Zeile für Zeile die Befehle eintragen und abschicken.

mysql
CREATE USER 'root'@'10.135.50.182' IDENTIFIED BY '20XduringXPLAINSXwindowX52';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.135.50.182' IDENTIFIED BY '20XduringXPLAINSXwindowX52' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE USER 'root'@'ns1.ispconfig-server.space' IDENTIFIED BY '20XduringXPLAINSXwindowX52';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'ns1.ispconfig-server.space' IDENTIFIED BY '20XduringXPLAINSXwindowX52' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE USER 'root'@'10.135.14.243' IDENTIFIED BY '92XkeptXQUITEXcontrolX01';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.135.14.243' IDENTIFIED BY '92XkeptXQUITEXcontrolX01' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE USER 'root'@'ns2.ispconfig-server.space' IDENTIFIED BY '92XkeptXQUITEXcontrolX01';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'ns2.ispconfig-server.space' IDENTIFIED BY '92XkeptXQUITEXcontrolX01' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE USER 'root'@'10.135.49.117' IDENTIFIED BY '90XbookXFORESTXpaidX86';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.135.49.117' IDENTIFIED BY '90XbookXFORESTXpaidX86' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE USER 'root'@'db.ispconfig-server.space' IDENTIFIED BY '90XbookXFORESTXpaidX86';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'db.ispconfig-server.space' IDENTIFIED BY '90XbookXFORESTXpaidX86' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE USER 'root'@'10.135.1.181' IDENTIFIED BY '15XfullXROOTXplayX71';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.135.59.191' IDENTIFIED BY '15XfullXROOTXplayX71' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE USER 'root'@'mx.ispconfig-server.space' IDENTIFIED BY '15XfullXROOTXplayX71';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'mx.ispconfig-server.space' IDENTIFIED BY '15XfullXROOTXplayX71' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
quit;

Zum Testen, habe ich mich mit dem NS1 Server und dessen Zugangsdaten auf dem Master Server eingeloggt, um zu sehen ob die Verbindung aufgebaut werden kann. Sah bei mir so aus:

root@ns1:~# mysql -h host.ispconfig-server.space -uroot -p20XduringXPLAINSXwindowX52
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 33
Server version: 10.0.31-MariaDB-0ubuntu0.16.04.2 Ubuntu 16.04

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>
quit;
Bye

Also alles super.

ISPConfig installieren

Dazu wechsel ich erst nach /tmp/, lade das Packet runter und entpacke es mit:

cd /tmp
wget http://www.ispconfig.org/downloads/ISPConfig-3-stable.tar.gz
tar xfz ISPConfig-3-stable.tar.gz
cd ispconfig3_install/install/

Die Installation starte ich dann mit:

php -q install.php

Hier einmal die Ausgabe, wie es aussieht und welche Angaben ich gemacht habe:

root@host:/tmp/ispconfig3_install/install# php -q install.php


--------------------------------------------------------------------------------
 _____ ___________   _____              __ _         ____
|_   _/  ___| ___ \ /  __ \            / _(_)       /__  \
  | | \ `--.| |_/ / | /  \/ ___  _ __ | |_ _  __ _    _/ /
  | |  `--. \  __/  | |    / _ \| '_ \|  _| |/ _` |  |_ |
 _| |_/\__/ / |     | \__/\ (_) | | | | | | | (_| | ___\ \
 \___/\____/\_|      \____/\___/|_| |_|_| |_|\__, | \____/
                                              __/ |
                                             |___/
--------------------------------------------------------------------------------


>> Initial configuration

Operating System: Ubuntu 16.04.3 LTS (Xenial Xerus)

    Following will be a few questions for primary configuration so be careful.
    Default values are in [brackets] and can be accepted with <ENTER>.
    Tap in "quit" (without the quotes) to stop the installer.


Select language (en,de) [en]: <== Enter
Installation mode (standard,expert) [standard]: expert
Full qualified hostname (FQDN) of the server, eg server1.domain.tld  [host.ispconfig-server.space]: <== Enter
MySQL server hostname [localhost]: <== Enter
MySQL server port [3306]: <== Enter
MySQL root username [root]: <== Enter
MySQL root password []: 33XthingXHEALTHXcakeX42
MySQL database to create [dbispconfig]: <== Enter
MySQL charset [utf8]: <== Enter

The next two questions are about the internal ISPConfig database user and password.
It is recommended to accept the defaults which are 'ispconfig' as username and a random password.
If you use a different password, use only numbers and chars for the password.
ISPConfig mysql database username [ispconfig]: <== Enter
ISPConfig mysql database password [7d131f301294643a8ad17deff75c4cbf]: <== Enter
Shall this server join an existing ISPConfig multiserver setup (y,n) [n]: <== Enter
Adding ISPConfig server record to database.
Configure Mail (y,n) [y]: <== n
Configuring Jailkit
Configuring Pureftpd
Configure DNS Server (y,n) [y]: <== n
The Web Server option has to be enabled when you want run a web server or when this node shall host the ISPConfig interface.
Configure Web Server (y,n) [y]: <== Enter
Configuring Apache
Configuring vlogger
[WARN] autodetect for OpenVZ failed
Force configure OpenVZ (y,n) [n]: <== Enter
Skipping OpenVZ
Configure Firewall Server (y,n) [y]: <== Enter
Configuring Ubuntu Firewall
[WARN] autodetect for Metronome XMPP Server failed
Force configure Metronome XMPP Server (y,n) [n]: <== Enter
Skipping Metronome XMPP Server
Configuring Fail2ban
Configuring Apps vhost
Install ISPConfig Web Interface (y,n) [y]: <== Enter
Installing ISPConfig
ISPConfig Port [8080]: <== Enter
Admin password [admin]: <== Enter (Hier könnt ihr aber auch direkt ein Password für das ISPConfig Interface erstellen. Falls nicht, dann ist es admin und sollte im Interface geändert werden.)
Do you want a secure (SSL) connection to the ISPConfig web interface (y,n) [y]: <== Enter
Generating RSA private key, 4096 bit long modulus
......................................................................++
............................................++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:<== Enter
State or Province Name (full name) [Some-State]:<== Enter
Locality Name (eg, city) []:<== Enter
Organization Name (eg, company) [Internet Widgits Pty Ltd]:<== Enter
Organizational Unit Name (eg, section) []:<== Enter
Common Name (e.g. server FQDN or YOUR name) []:<== Enter
Email Address []:<== Enter
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <== Enter
An optional company name []: <== Enter
writing RSA key
_
Configuring DBServer
Installing ISPConfig crontab
Installing ISPConfig crontab
no crontab for root
Detect IP addresses
Restarting services …
Installation completed.

Sehr gut. ISPConfig ist jetzt auf dem Master Server installiert.

Let‘s Encrypt Zertifikat für ISPConfig Web-Interface und PureFTPD

Damit ich jetzt schon das Zertifikat für das ISPConfig Interface & PureFTPD erstellen kann, melde ich mich auf dem ISPConfig Master Server an, und erstelle direkt die Seite: host.ispconfig-server.space und aktiviere die Let‘s Encrypt Box. Ich deaktiviere alles andere was nicht notwendig ist, speichere und warte auf das Feedback. Sobald ISPConfig den Befehl ausgeführt hat, sollte ich die domain: host.ispconfig-server.space via https erreichen können. Und ein kurzer Test hat es bestätigt, also ist das Zertifikat da. Zurück im Terminal mache ich folgendes:

mv /usr/local/ispconfig/interface/ssl/ispserver.bundle /usr/local/ispconfig/interface/ssl/ispserver.bundle-back
mv /usr/local/ispconfig/interface/ssl/ispserver.crt /usr/local/ispconfig/interface/ssl/ispserver.crt-back
mv /usr/local/ispconfig/interface/ssl/ispserver.key /usr/local/ispconfig/interface/ssl/ispserver.key-back

Um ein Backup der ISPConfig Zertifikate zu erstellen. Anschließend setze ich einen SymLink von den Let‘s Encrypt Zertifikaten, zum ISPConfig SSL Ordner mit:

ln -s /etc/letsencrypt/live/host.ispconfig-server.space/chain.pem /usr/local/ispconfig/interface/ssl/ispserver.bundle
ln -s /etc/letsencrypt/live/host.ispconfig-server.space/cert.pem /usr/local/ispconfig/interface/ssl/ispserver.crt
ln -s /etc/letsencrypt/live/host.ispconfig-server.space/privkey.pem /usr/local/ispconfig/interface/ssl/ispserver.key

Damit PureFTPD das Zertifikat ebenfalls ausliefert, erstelle ich erst ein Backup des selbst signierten Zertifikats mit:

mv /etc/ssl/private/pure-ftpd.pem /etc/ssl/private/pure-ftpd.pem-back

Anschließend füge ich die privkey.pem und die fullchain.pem zusammen zu einer pure-ftpd.pem für PureFTPD mit:

cat /etc/letsencrypt/live/host.ispconfig-server.space/privkey.pem /etc/letsencrypt/live/host.ispconfig-server.space/fullchain.pem > /etc/ssl/private/pure-ftpd.pem

Damit ich das nicht immer und immer wieder machen muss wenn das Zertifikat verlängert wurde, erstelle ich dafür einen Cronjob der einmal täglich läuft mit:

crontab -e

und füge am Ende der Datei folgendes ein:

@daily cat /etc/letsencrypt/live/host.ispconfig-server.space/privkey.pem /etc/letsencrypt/live/host.ispconfig-server.space/fullchain.pem > /etc/ssl/private/pure-ftpd.pem && service pure-ftpd-mysql restart > /dev/null 2>&1

Jetzt starte ich Apache und PureFTPD einmal neu mit:

service apache2 restart
service pure-ftpd-mysql restart

Wunderbar. Der Masterserver ist jetzt eingerichtet. Weiter geht es mit ISPConfig NS1 DNS Server installieren

4 Replies to “Teil 2 – Der Web Server – Der perfekte ISPConfig Multi-Server mit Web-, Mail-, Datenbank-, NS1- und NS2- Server”

    • Hi Jürgen.
      Ja, du hast Recht. Die Verbindungen zu MariaDB wären in diesem Setup unverschlüsselt. Dennoch würden die Daten nur im Internen Netzwerk übertragen.

      Für eine TLS verschlüsselte Verbindung müsste auf dem DB Server ein Zertifikat installiert werden und MariaDB mit SSL konfiguriert werden.

      • Hallo Dimitri,
        erst mal danke für die Antwort. Es ist natürlich ein Unterschied, ob diese Server in einem abgeschirmten Netzwerk oder quer durch’s Internet verbunden sind (solltest du evtl. als Hinweis mit aufnehmen).
        Bei mir ist es natürlich letzteres. Die Standardpakete der Distri (Ubuntu) sind obendrei noch ohne OpenSSL kompiliert:

        MariaDB [(none)]> show variables like ‘%ssl%’;
        +—————+———-+
        | Variable_name | Value |
        +—————+———-+
        | have_openssl | NO |
        | have_ssl | DISABLED |
        | ssl_ca | |
        | ssl_capath | |
        | ssl_cert | |
        | ssl_cipher | |
        | ssl_crl | |
        | ssl_crlpath | |
        | ssl_key | |
        +—————+———-+
        9 rows in set (0.01 sec)

        Ich werde mir die Anleitungen zur Verschlüsselung von mysql-Verbindungen genauer anschauen und ggf dann wieder hier berichten.

  • So, ein bißchen recherchiert. Das mit der mysql-Verschlüsselung wird wohl nichts, solange ISPConfig selbst sie nicht unterstützt. Da müsste an mehrern Core-Dateien gepatcht werden, und hier endet das, was ich zu tun bereit bin.
    Ein Weg ist jedoch, zwischen den Servern eine (Open)VPN-Verbindung zu schaffen. Dann geht schlicht alles kryptografisch gesichert rüber. Das scheint derzeit der einzige Weg zu sein, das Multi-Server-Konzept außerhalb eines geschlossenen Netzwerkes verantwortungsvoll betreiben zu können.

Leave a Reply to Dimitri Enns Cancel reply

Your email address will not be published. Required fields are marked *

*