Cheap VPS & Xen Server


Residential Proxy Network - Hourly & Monthly Packages

The Perfect Server – Ubuntu 16.04 (Nginx, MySQL, PHP, Postfix, BIND, Dovecot, Pure-FTPD and ISPConfig 3.1)


This tutorial shows the steps to install an Ubuntu 16.04 (Xenial Xerus) server with Nginx, PHP, MariaDB, Postfix, pure-ftpd, BIND, Dovecot and ISPConfig 3.1. ISPConfig is a web hosting control panel that allows you to configure the installed services through a web browser. This setup provides a full hosting server with web, email (inc. spam and antivirus filter), Database, FTP and DNS services.

1. Preliminary Note

In this tutorial, I will use the hostname server1.example.com with the IP address 192.168.1.100 and the gateway 192.168.1.1 for the network configuration. These settings might differ for you, so you have to replace them where appropriate.  Before proceeding further, you need to have a basic minimal installation of Ubuntu 16.04 as explained in tutorial.

The steps in this tutorial have to be executed as root user, so I will not prepend “sudo” in front of the commands. Either Login as root user to your server before you proceed or run:

sudo -s

to become root when you are logged in as a different user on the shell.

The commands to edit files will use the editor “nano”, you can replace it with an editor of your choice. Nano is an easy to use file editor for the shell. If you like to use nano and haven’t installed it yet, run:

apt-get install nano

2. Update Your Linux Installation

Edit /etc/apt/sources.list. Comment out or remove the installation CD from the file and make sure that the universe and multiverse repositories are enabled. It should look like this:

nano /etc/apt/sources.list

#

# deb cdrom:[Ubuntu-Server 16.04 LTS _Xenial Xerus_ - Release amd64 (20160420)]/ xenial main restricted

#deb cdrom:[Ubuntu-Server 16.04 LTS _Xenial Xerus_ - Release amd64 (20160420)]/ xenial main restricted

# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://de.archive.ubuntu.com/ubuntu/ xenial main restricted
# deb-src http://de.archive.ubuntu.com/ubuntu/ xenial main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb http://de.archive.ubuntu.com/ubuntu/ xenial-updates main restricted
# deb-src http://de.archive.ubuntu.com/ubuntu/ xenial-updates main restricted

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## universe WILL NOT receive any review or updates from the Ubuntu security
## team.
deb http://de.archive.ubuntu.com/ubuntu/ xenial universe
# deb-src http://de.archive.ubuntu.com/ubuntu/ xenial universe
deb http://de.archive.ubuntu.com/ubuntu/ xenial-updates universe
# deb-src http://de.archive.ubuntu.com/ubuntu/ xenial-updates universe

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## multiverse WILL NOT receive any review or updates from the Ubuntu
## security team.
deb http://de.archive.ubuntu.com/ubuntu/ xenial multiverse
# deb-src http://de.archive.ubuntu.com/ubuntu/ xenial multiverse
deb http://de.archive.ubuntu.com/ubuntu/ xenial-updates multiverse
# deb-src http://de.archive.ubuntu.com/ubuntu/ xenial-updates multiverse

## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
deb http://de.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
# deb-src http://de.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
## Uncomment the following two lines to add software from Canonical's
## 'partner' repository.
## This software is not part of Ubuntu, but is offered by Canonical and the
## respective vendors as a service to Ubuntu users.
# deb http://archive.canonical.com/ubuntu xenial partner
# deb-src http://archive.canonical.com/ubuntu xenial partner

deb http://security.ubuntu.com/ubuntu xenial-security main restricted
# deb-src http://security.ubuntu.com/ubuntu xenial-security main restricted
deb http://security.ubuntu.com/ubuntu xenial-security universe
# deb-src http://security.ubuntu.com/ubuntu xenial-security universe
deb http://security.ubuntu.com/ubuntu xenial-security multiverse
# deb-src http://security.ubuntu.com/ubuntu xenial-security multiverse

Then run:

apt-get update

To update the apt package database and then:

apt-get upgrade

to install the latest updates (if there are any). If you see that a new kernel gets installed as part of the updates, you should reboot the system afterward:

reboot

 

3. Change the Default Shell

/bin/sh is a symlink to /bin/dash, however we need /bin/bash, not /bin/dash. Therefore we do this:

dpkg-reconfigure dash

Use dash as the default system shell (/bin/sh)? <– No

If you don’t do this, the ISPConfig installation will fail.

 

4. Disable AppArmor

AppArmor is a security extension (similar to SELinux) that should provide extended security. We will cross check if it is installed and remove it if necessary. In my opinion you don’t need it to configure a secure system, and it usually causes more problems than advantages (think of it after you have done a week of trouble-shooting because some service wasn’t working as expected, and then you find out that everything was ok, only AppArmor was causing the problem). Therefore, I disable it (this is a must if you want to install ISPConfig later on).

We can disable it like this:

service apparmor stop
update-rc.d -f apparmor remove
apt-get remove apparmor apparmor-utils

5. Synchronize the System Clock

It is a good idea to synchronize the system clock with an NTP (network time protocol) server over the Internet. Simply run

apt-get -y install ntp ntpdate

and your system time will always be in sync.

 

6. Install Postfix, Dovecot, MariaDB, phpMyAdmin, rkhunter, Binutils

For installing postfix, we need to ensure that sendmail is not installed and running. To stop and remove sendmail run this command:

service sendmail stop; update-rc.d -f sendmail remove

The error message:

Failed to stop sendmail.service: Unit sendmail.service not loaded.

Is ok, it just means that sendmail was not installed, so there was nothing to be removed.

We can install Postfix, Dovecot, MariaDB (as MySQL replacement), rkhunter, and binutils with a single command:

apt-get -y install postfix postfix-mysql postfix-doc mariadb-client mariadb-server openssl getmail4 rkhunter binutils dovecot-imapd dovecot-pop3d dovecot-mysql dovecot-sieve dovecot-lmtpd sudo

MariaDB is a fork of the MySQL database server, developed by the original MySQL developer Monty Widenius. According to tests found on the internet, MariaDB is faster than MySQL and it’s development is going on with more pace, therefore, most Linux Distributions replaced MySQL with MariaDB as default “MySQL alike” database server. In case that you prefer MySQL over MariaDB, replace “mariadb-client mariadb-server” in the above command with “mysql-client mysql-server”.

You will be asked the following questions:

General type of mail configuration: <– Internet Site
System mail name: <– server1.example.com

Next open the TLS/SSL and submission ports in Postfix:

nano /etc/postfix/master.cf

Uncomment the submission and smtps sections as follows – add the line -o smtpd_client_restrictions=permit_sasl_authenticated,reject to both sections and leave everything thereafter commented:

[...]
submission inet n       -       -       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       -       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
[...]

Restart Postfix afterward:

service postfix restart

We want MariaDB/MySQL to listen on all interfaces, not just localhost. Therefore we edit /etc/mysql/mariadb.conf.d/50-server.cnf (for MariaDB or /etc/mysql/my.cnf (for MySQL) and comment out the line bind-address = 127.0.0.1:

MariaDB

nano /etc/mysql/mariadb.conf.d/50-server.cnf

[...]
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           = 127.0.0.1
[...]

Then we restart MariaDB:

service mysql restart

The systemd service name for MariaDB and MySQL is “mysql”, so the restart command is the same for both database servers.

Now we set a root password in MariaDB. Run:

mysql_secure_installation

You will be asked these questions:

Enter current password for root (enter for none): <– press enter
Set root password? [Y/n] <– y
New password: <– Enter the new MariaDB root password here
Re-enter new password: <– Repeat the password
Remove anonymous users? [Y/n] <– y
Disallow root login remotely? [Y/n] <– y
Reload privilege tables now? [Y/n] <– y

MySQL

nano /etc/mysql/my.cnf

[...]
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           = 127.0.0.1
[...]

Then we restart MySQL:

service mysql restart

The systemd service name for MariaDB and MySQL is “mysql”, so the restart command is the same for both database servers.

For MySQL and MariaDB:

Now check that networking is enabled. Run:

netstat -tap | grep mysql

The output should look like this:

root@server1:~# netstat -tap | grep mysql
tcp6 0 0 [::]:mysql [::]:* LISTEN 13796/mysqld
root@server1:~#

 

7. Install Amavisd-new, SpamAssassin, And ClamAV

To install amavisd-new, SpamAssassin, and ClamAV, we run

apt-get -y install amavisd-new spamassassin clamav clamav-daemon zoo unzip bzip2 arj nomarch lzop cabextract apt-listchanges libnet-ldap-perl libauthen-sasl-perl clamav-docs daemon libio-string-perl libio-socket-ssl-perl libnet-ident-perl zip libnet-dns-perl postgrey

The ISPConfig 3 setup uses amavisd-new which loads the SpamAssassin filter library internally, so we can stop SpamAssassin to free up RAM:

service spamassassin stop
update-rc.d -f spamassassin remove

Edit the clamd configuration file:

nano /etc/clamav/clamd.conf

and change the line:

AllowSupplementaryGroups false

to:

AllowSupplementaryGroups true

And save the file.

To update the ClamAV antivirus signatures and start the Clamd service. The update process can take some time, don’t interrupt it.

service clamav-freshclam restart
service clamav-daemon start

7.1 Install Metronome XMPP Server (optional)

The Metronome XMPP Server provides an XMPP chat server. This step is optional, if you do not need a chat server, then you can skip this step. No other ISPConfig functions depend on this software.

Install the following packages with apt.

apt-get -y install git lua5.1 liblua5.1-0-dev lua-filesystem libidn11-dev libssl-dev lua-zlib lua-expat lua-event lua-bitop lua-socket lua-sec luarocks luarocks

luarocks install lpc

Add a shell user for Metronome.

adduser –no-create-home –disabled-login –gecos ‘Metronome’ metronome

Download Metronome to the /opt directory and compile it.

cd /opt; git clone https://github.com/maranda/metronome.git metronome
cd ./metronome; ./configure –ostype=debian –prefix=/usr
make
make install

Metronome has now be installed to /opt/metronome.

8. Install Nginx, PHP5 (PHP-FPM), and Fcgiwrap

Nginx is available as a package for Ubuntu which we can install with the following command:

apt-get install nginx

When Apache2 is already installed on the system, stop it now…

service apache2 stop

… and remove Apache’s system startup links:

update-rc.d -f apache2 remove

Start nginx afterwards:

service nginx start

(If both Apache2 and nginx are installed, the ISPConfig 3 installer will ask you which one you want to use – answer nginx in this case. If only one of these both is installed, ISPConfig will do the necessary configuration automatically.)

We can make PHP 7 work in nginx through PHP-FPM (PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busier sites) which we install as follows:

apt-get -y install php7.0-fpm

PHP-FPM is a daemon process that runs a FastCGI server on the socket /var/run/php/php7.0-fpm.sock.

To get MySQL support in PHP, we can install the php7.0-mysql package. It’s a good idea to install some other PHP5 modules as well as you might need them for your applications. You can search for available PHP5 modules like this:

apt-cache search php7.0

Pick the ones you need and install them like this:

apt-get -y install php7.0-opcache php7.0-fpm php7.0 php7.0-common php7.0-gd php7.0-mysql php7.0-imap php7.0-cli php7.0-cgi php-pear php-auth php7.0-mcrypt mcrypt imagemagick libruby 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

The mbstring and mcrypt extensions need to be enabled manually.

phpenmod mcrypt
phpenmod mbstring

APCu is a PHP extension for the PHP 7 Opcache which adds a compatibility layer for software that uses PHP APC Cache.

APCu can be installed as follows:

apt-get -y install php-apcu

Next open /etc/php/7.0/fpm/php.ini

nano /etc/php/7.0/fpm/php.ini

… and set cgi.fix_pathinfo=0 and your timezone:

[...]
cgi.fix_pathinfo=0
[...]
date.timezone="Europe/Berlin"
[...]

(You can find all available timezones in the /usr/share/zoneinfo directories and its subdirectories.)

Now reload PHP-FPM:

service php7.0-fpm reload

To get CGI support in nginx, we install Fcgiwrap.

Fcgiwrap is a CGI wrapper that should work also for complex CGI scripts and can be used for shared hosting environments because it allows each vhost to use its own cgi-bin directory.

Install the fcgiwrap package:

apt-get -y install fcgiwrap

After the installation, the fcgiwrap daemon should already be started; its socket is /var/run/fcgiwrap.socket. If it is not running, you can use the /etc/init.d/fcgiwrap script to start it.

That’s it! Now when you create an nginx vhost, ISPConfig will take care of the correct vhost configuration.

 

8.1 Additional PHP Versions

Starting with ISPConfig 3.0.5, it is possible to have multiple PHP versions on one server (selectable through ISPConfig) which can be run through PHP-FPM. To learn how to build additional PHP versions (PHP-FPM) and how to configure ISPConfig, please check this tutorial: How To Use Multiple PHP Versions (PHP-FPM & FastCGI) With ISPConfig 3 (Ubuntu 12.10) (works for Ubuntu 16.04 as well).

 

8.2 Install phpMyAdmin

Install phpMyAdmin as follows:

apt-get -y install phpmyadmin php-mbstring php-gettext

You will see the following questions:

Web server to reconfigure automatically: <– select none (because only apache2 and lighttpd are available as options)
MySQL application password for phpmyadmin: 
<– Press Enter

You can now find phpMyAdmin in the /usr/share/phpmyadmin/ directory.

After you have installed ISPConfig 3, you can access phpMyAdmin as follows:

The ISPConfig apps vhost on port 8081 for nginx comes with a phpMyAdmin configuration, so you can use http://server1.example.com:8081/phpmyadmin or http://server1.example.com:8081/phpMyAdmin to access phpMyAdmin.

If you want to use a /phpmyadmin or /phpMyAdmin alias that you can use from your web sites, this is a bit more complicated than for Apache because nginx does not have global aliases (i.e., aliases that can be defined for all vhosts). Therefore you have to define these aliases for each vhost from which you want to access phpMyAdmin.

To do this, paste the following into the nginx Directives field on the Options tab of the web site in ISPConfig:

        location /phpmyadmin {
               root /usr/share/;
               index index.php index.html index.htm;
               location ~ ^/phpmyadmin/(.+\.php)$ {
                       try_files $uri =404;
                       root /usr/share/;
                       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                       fastcgi_index index.php;
                       fastcgi_param SCRIPT_FILENAME $request_filename;
                       include /etc/nginx/fastcgi_params;
                       fastcgi_param PATH_INFO $fastcgi_script_name;
                       fastcgi_buffer_size 128k;
                       fastcgi_buffers 256 4k;
                       fastcgi_busy_buffers_size 256k;
                       fastcgi_temp_file_write_size 256k;
                       fastcgi_intercept_errors on;
               }
               location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
                       root /usr/share/;
               }
        }
        location /phpMyAdmin {
               rewrite ^/* /phpmyadmin last;
        }

If you use https instead of http for your vhost, you should add the line fastcgi_param HTTPS on; to your phpMyAdmin configuration like this:

        location /phpmyadmin {
               root /usr/share/;
               index index.php index.html index.htm;
               location ~ ^/phpmyadmin/(.+\.php)$ {
                       try_files $uri =404;
                       root /usr/share/;
                       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                       fastcgi_param HTTPS on; # <-- add this line
                       fastcgi_index index.php;
                       fastcgi_param SCRIPT_FILENAME $request_filename;
                       include /etc/nginx/fastcgi_params;
                       fastcgi_param PATH_INFO $fastcgi_script_name;
                       fastcgi_buffer_size 128k;
                       fastcgi_buffers 256 4k;
                       fastcgi_busy_buffers_size 256k;
                       fastcgi_temp_file_write_size 256k;
                       fastcgi_intercept_errors on;
               }
               location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
                       root /usr/share/;
               }
        }
        location /phpMyAdmin {
               rewrite ^/* /phpmyadmin last;
        }

If you use both http and https for your vhost, you need to add the following section to the http {} section in /etc/nginx/nginx.conf (before any include lines) which determines if the visitor uses http or https and sets the $fastcgi_https variable (which we will use in our phpMyAdmin configuration) accordingly:

nano /etc/nginx/nginx.conf

[...]
http {
[...]
        ## Detect when HTTPS is used
        map $scheme $fastcgi_https {
          default off;
          https on;

        }
[...]
}
[...]

Don’t forget to reload nginx afterwards:

service nginx reload

Then go to the nginx Directives field again, and instead of fastcgi_param HTTPS on; you add the line fastcgi_param HTTPS $fastcgi_https; so that you can use phpMyAdmin for both HTTP and HTTPS requests:

        location /phpmyadmin {
               root /usr/share/;
               index index.php index.html index.htm;
               location ~ ^/phpmyadmin/(.+\.php)$ {
                       try_files $uri =404;
                       root /usr/share/;
                       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                       fastcgi_param HTTPS $fastcgi_https; # <-- add this line
                       fastcgi_index index.php;
                       fastcgi_param SCRIPT_FILENAME $request_filename;
                       include /etc/nginx/fastcgi_params;
                       fastcgi_param PATH_INFO $fastcgi_script_name;
                       fastcgi_buffer_size 128k;
                       fastcgi_buffers 256 4k;
                       fastcgi_busy_buffers_size 256k;
                       fastcgi_temp_file_write_size 256k;
                       fastcgi_intercept_errors on;
               }
               location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
                       root /usr/share/;
               }
        }
        location /phpMyAdmin {
               rewrite ^/* /phpmyadmin last;
        }

Ubuntu does not allow logins to MySQL as root user trough PHPMyAdmin anymore. Without root privileges, you can not use PHPMyAdmin to administrate database users or to create databases. To circumvent that problem, I will create a new MySQL user with the name “admin” here which has root privileges. This admin user can be used for database administration in PHPMyAdmin.

Login to the MySQL database as root user on the shell:

mysql -u root

Create a new user “admin” with the password “Kreationnext”. Replace the password “Kreationnext” with a secure password in the commands below!

CREATE USER ‘admin’@’localhost’ IDENTIFIED BY ‘Kreationnext’;
GRANT ALL PRIVILEGES ON *.* TO ‘admin’@’localhost’ WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit

8.3 Install HHVM (HipHop Virtual Machine)

In this step we will install HHVM with apt. HHVM is a fast PHP engine developed by Facebook.

apt-get -y install software-properties-common
apt-key adv –recv-keys –keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449
add-apt-repository “deb http://dl.hhvm.com/ubuntu xenial main”
apt-get update
apt-get -y install hhvm

8.4. Install Let’s Encrypt

ISPConfig 3.1  has built-in support for the free SSL Certificate Authority Let’s encrypt. The Let’s Encrypt function allows you to create free SSL Certificates for your website in ISPConfig.

Now we will add support for Let’s encrypt.

apt-get -y install letsencrypt

9. Install Mailman

ISPConfig also allows you to manage (create/modify/delete) Mailman mailing lists. If you want to make use of this feature, install Mailman as follows:

apt-get -y install mailman

Select at least one language, e.g.:

Languages to support: <– en (English)
Missing site list <– Ok

Before we can start Mailman, a first mailing list called mailman must be created:

newlist mailman

root@server1:~# newlist mailman
Enter the email of the person running the list:
 <– admin email address, e.g. listadmin@example.com
Initial mailman password: <– admin password for the mailman list
To finish creating your mailing list, you must edit your /etc/aliases (or
equivalent) file by adding the following lines, and possibly running the
`newaliases’ program:

## mailman mailing list
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”

Hit enter to notify mailman owner… <– ENTER

root@server1:~#

Open /etc/aliases afterwards…

nano /etc/aliases

… and add the following lines:

[...]
## mailman mailing list
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"

Run

newaliases

afterwards and restart Postfix:

service postfix restart

Then start the Mailman daemon:

service mailman start

After you have installed ISPConfig 3, you can access Mailman as follows:

The ISPConfig apps vhost on port 8081 for nginx comes with a Mailman configuration, so you can use http://server1.example.com:8081/cgi-bin/mailman/admin/<listname> or http://server1.example.com:8081/cgi-bin/mailman/listinfo/<listname> to access Mailman.

If you want to use Mailman from your web sites, this is a bit more complicated than for Apache because Nginx does not have global aliases (i.e., aliases that can be defined for all vhosts). Therefore, you have to define these aliases for each vhost from which you want to access Mailman.

To do this, paste the following into the nginx Directives field on the Options tab of the web site in ISPConfig:

        location /cgi-bin/mailman {
               root /usr/lib/;
               fastcgi_split_path_info (^/cgi-bin/mailman/[^/]*)(.*)$;
               include /etc/nginx/fastcgi_params;
               fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
               fastcgi_param PATH_INFO $fastcgi_path_info;
               fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
               fastcgi_intercept_errors on;
               fastcgi_pass unix:/var/run/fcgiwrap.socket;
        }

        location /images/mailman {
               alias /usr/share/images/mailman;
        }

        location /pipermail {
               alias /var/lib/mailman/archives/public;
               autoindex on;
        }

This defines the alias /cgi-bin/mailman/ for your vhost, which means you can access the Mailman admin interface for a list at http://<vhost>/cgi-bin/mailman/admin/<listname>, and the web page for users of a mailing list can be found at http://<vhost>/cgi-bin/mailman/listinfo/<listname>.

Under http://<vhost>/pipermail you can find the mailing list archives.

10. Install PureFTPd And Quota

PureFTPd and quota can be installed with the following command:

apt-get -y install pure-ftpd-common pure-ftpd-mysql quota quotatool

Edit the file /etc/default/pure-ftpd-common

nano /etc/default/pure-ftpd-common

… and make sure that the start mode is set to standalone and set VIRTUALCHROOT=true:

[...]
STANDALONE_OR_INETD=standalone
[...]
VIRTUALCHROOT=true
[...]

Now we configure PureFTPd to allow FTP and TLS sessions. FTP is a very insecure protocol because all passwords and all data are transferred in clear text. By using TLS, the whole communication can be encrypted, thus making FTP much more secure.

If you want to allow FTP and TLS sessions, run

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

In order to use TLS, we must create an SSL certificate. I create it in /etc/ssl/private/, therefore I create that directory first:

mkdir -p /etc/ssl/private/

Afterwards, we can generate the SSL certificate as follows:

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

Country Name (2 letter code) [AU]: <– Enter your Country Name (e.g., “DE”).
State or Province Name (full name) [Some-State]:
<– Enter your State or Province Name.
Locality Name (eg, city) []:
<– Enter your City.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
<– Enter your Organization Name (e.g., the name of your company).
Organizational Unit Name (eg, section) []:
<– Enter your Organizational Unit Name (e.g. “IT Department”).
Common Name (eg, YOUR name) []:
<– Enter the Fully Qualified Domain Name of the system (e.g. “server1.example.com”).
Email Address []:
<– Enter your Email Address.

Change the permissions of the SSL certificate:

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

Then restart PureFTPd:

service pure-ftpd-mysql restart

Edit /etc/fstab. Mine looks like this (I added ,usrjquota=quota.user,grpjquota=quota.group,jqfmt=vfsv0 to the partition with the mount point /):

nano /etc/fstab

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/server1--vg-root / ext4 errors=remount-ro,usrjquota=quota.user,grpjquota=quota.group,jqfmt=vfsv0 0 1
# /boot was on /dev/sda1 during installation
UUID=39762f15-3a49-4982-add3-139d5040b48a /boot ext2 defaults 0 2
/dev/mapper/server1--vg-swap_1 none swap sw 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0

To enable quota, run these commands:

mount -o remount /

quotacheck -avugm
quotaon -avug

The following error messages are normal for the command and can be ignored:

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 18566 directories and 110119 files
quotacheck: Old file not found.
quotacheck: Old file not found.

11. Install BIND DNS Server

BIND is installed as follows:

apt-get -y install bind9 dnsutils haveged

Enable and start haveged.

systemctl enable haveged
service haveged start

12. Install Vlogger, Webalizer, And AWStats

Vlogger, Webalizer, and AWStats can be installed as follows:

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

Open /etc/cron.d/awstats afterwards…

nano /etc/cron.d/awstats

… and comment out everything in that file:

#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

 

13. Install Jailkit

Jailkit is needed only if you want to chroot SSH users. It can be installed as follows (important: Jailkit must be installed before ISPConfig – it cannot be installed afterwards!):

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

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

You can now install the Jailkit .deb package as follows:

cd ..
dpkg -i jailkit_2.19-1_*.deb
rm -rf jailkit-2.19*

14. Install fail2ban

This is optional but recommended, because the ISPConfig monitor tries to show the log:

apt-get -y install fail2ban

To make fail2ban monitor PureFTPd and Dovecot, create the file /etc/fail2ban/jail.local:

nano /etc/fail2ban/jail.local

[pureftpd]
enabled  = true
port     = ftp
filter   = pureftpd
logpath  = /var/log/syslog
maxretry = 3

[dovecot-pop3imap]
enabled = true
filter = dovecot-pop3imap
action = iptables-multiport[name=dovecot-pop3imap, port="pop3,pop3s,imap,imaps", protocol=tcp]
logpath = /var/log/syslog
maxretry = 5

[postfix-sasl]
enabled  = true
port     = smtp
filter   = postfix-sasl
logpath  = /var/log/syslog
maxretry = 3

Then create the following two filter files:

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

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

nano /etc/fail2ban/filter.d/dovecot-pop3imap.conf

[Definition]
failregex = (?: pop3-login|imap-login): .*(?:Authentication failure|Aborted login \(auth failed|Aborted login \(tried to use disabled|Disconnected \(auth failed|Aborted login \(\d+ authentication attempts).*rip=(?P<host>\S*),.*
ignoreregex =

Add the missing ignoreregex line in the postfix-sasl file:

echo “ignoreregex =” >> /etc/fail2ban/filter.d/postfix-sasl.conf

Restart fail2ban afterwards:

service fail2ban restart

To install the UFW firewall, run this apt command:

apt-get install ufw

15. Install Roundcube Webmail

To install Roundcube Webmail, run:

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

The installer will ask the following questions:

Configure database for roundcube with dbconfig-common? <– Yes
MySQL application password for roundcube: <– Press enter

Then edit the RoundCube config.inc.php configuration file:

nano /etc/roundcube/config.inc.php

and change the default host to localhost:

$config['default_host'] = 'localhost';

This prevents that Roundcube will show server name input field in the login form.

No create a symlibk so that we can use the SquirrelMail configuration in ISPConfig for Roundcube:

ln -s /usr/share/roundcube /usr/share/squirrelmail

After you have installed ISPConfig 3, you can access Roundcube as follows:

The ISPConfig apps vhost on port 8081 for nginx comes with a Roundcube configuration, so you can use http://server1.example.com:8081/webmail to access Roundcube.

If you want to use a /webmail alias that you can use from your web sites, this is a bit more complicated than for Apache because nginx does not have global aliases (i.e., aliases that can be defined for all vhosts). Therefore you have to define these aliases for each vhost from which you want to access Roundcube.

To do this, paste the following into the nginx Directives field on the Options tab of the web site in ISPConfig:

        location /roundcube {
               root /usr/share/;
               index index.php index.html index.htm;
               location ~ ^/roundcube/(.+\.php)$ {
                       try_files $uri =404;
                       root /usr/share/;
                       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                       fastcgi_index index.php;
                       fastcgi_param SCRIPT_FILENAME $request_filename;
                       include /etc/nginx/fastcgi_params;
                       fastcgi_param PATH_INFO $fastcgi_script_name;
                       fastcgi_buffer_size 128k;
                       fastcgi_buffers 256 4k;
                       fastcgi_busy_buffers_size 256k;
                       fastcgi_temp_file_write_size 256k;
                       fastcgi_intercept_errors on;
               }
               location ~* ^/roundcube/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
                       root /usr/share/;
               }
        }
        location /webmail {
               rewrite ^/* /roundcube last;
        }

If you use https instead of http for your vhost, you should add the line fastcgi_param HTTPS on; to your SquirrelMail configuration like this:

        location /roundcube {
               root /usr/share/;
               index index.php index.html index.htm;
               location ~ ^/roundcube/(.+\.php)$ {
                       try_files $uri =404;
                       root /usr/share/;
                       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                       fastcgi_param HTTPS on; # <-- add this line
                       fastcgi_index index.php;
                       fastcgi_param SCRIPT_FILENAME $request_filename;
                       include /etc/nginx/fastcgi_params;
                       fastcgi_param PATH_INFO $fastcgi_script_name;
                       fastcgi_buffer_size 128k;
                       fastcgi_buffers 256 4k;
                       fastcgi_busy_buffers_size 256k;
                       fastcgi_temp_file_write_size 256k;
                       fastcgi_intercept_errors on;
               }
               location ~* ^/roundcube/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
                       root /usr/share/;
               }
        }
        location /webmail {
               rewrite ^/* /roundcube last;
        }

If you use both http and https for your vhost, you need to add the following section to the http {} section in /etc/nginx/nginx.conf (before any include lines) which determines if the visitor uses http or https and sets the $fastcgi_https variable (which we will use in our Roundcube configuration) accordingly:

nano /etc/nginx/nginx.conf

[...]
http {
[...]
        ## Detect when HTTPS is used
        map $scheme $fastcgi_https {
          default off;
          https on;

        }
[...]
}
[...]

Don’t forget to reload nginx afterwards:

service nginx reload

Then go to the nginx Directives field again, and instead of fastcgi_param HTTPS on; you add the line fastcgi_param HTTPS $fastcgi_https; so that you can use Roundcube for both http and https requests:

        location /roundcube {
               root /usr/share/;
               index index.php index.html index.htm;
               location ~ ^/roundcube/(.+\.php)$ {
                       try_files $uri =404;
                       root /usr/share/;
                       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                       fastcgi_param HTTPS $fastcgi_https; # <-- add this line
                       fastcgi_index index.php;
                       fastcgi_param SCRIPT_FILENAME $request_filename;
                       include /etc/nginx/fastcgi_params;
                       fastcgi_param PATH_INFO $fastcgi_script_name;
                       fastcgi_buffer_size 128k;
                       fastcgi_buffers 256 4k;
                       fastcgi_busy_buffers_size 256k;
                       fastcgi_temp_file_write_size 256k;
                       fastcgi_intercept_errors on;
               }
               location ~* ^/roundcube/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
                       root /usr/share/;
               }
        }
        location /webmail {
               rewrite ^/* /roundcube last;
        }

 

16. Install ISPConfig 3.1

Before you start the ISPConfig installation, make sure that Apache is stopped (if it is installed – it is possible that some of your installed packages have installed Apache as a dependency without you knowing). If Apache2 is already installed on the system, stop it now…

service apache2 stop

… and remove Apache’s system startup links:

update-rc.d -f apache2 remove

Make sure that nginx is running:

service nginx restart

(If you have both Apache and nginx installed, the installer asks you which one you want to use: Apache and nginx detected. Select server to use for ISPConfig: (apache,nginx) [apache]:

Type nginx. If only Apache or Nginx are installed, this is automatically detected by the installer, and no question is asked.)

To install ISPConfig 3.1 from GIT stable branch, do this:

cd /tmp
wget -O ispconfig.tar.gz https://git.ispconfig.org/ispconfig/ispconfig3/repository/archive.tar.gz?ref=stable-3.1
tar xfz ispconfig.tar.gz
cd ispconfig3*/install/

The next step is to run

php -q install.php

This will start the ISPConfig 3.1 installer. The installer will configure all services like Postfix, Dovecot, etc. for you.

root@server1:/tmp/ispconfig3-stable-3.1-3f1331062193a94fbd64a7e39c00cb8d77eb7484/install# php install.php

——————————————————————————–
_____ ___________ _____ __ _ ____
|_ _/ ___| ___ \ / __ \ / _(_) /__ \
| | \ `–.| |_/ / | / \/ ___ _ __ | |_ _ __ _ _/ /
| | `–. \ __/ | | / _ \| ‘_ \| _| |/ _` | |_ |
_| |_/\__/ / | | \__/\ (_) | | | | | | | (_| | ___\ \
\___/\____/\_| \____/\___/|_| |_|_| |_|\__, | \____/
__/ |
|___/
——————————————————————————–

>> Initial configuration

Operating System: Ubuntu 16.04.1 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]: <– ENTER

Full qualified hostname (FQDN) of the server, eg server1.domain.tld [server1.example.com]: <– ENTER

MySQL server hostname [localhost]: <– ENTER

MySQL server port [3306]: <– ENTER

MySQL root username [root]: <– ENTER

MySQL root password []: <–enter the MySQL root password here

MySQL database to create [dbispconfig]: <– ENTER

MySQL charset [utf8]: <– ENTER

Configuring Postgrey
Configuring Postfix
Generating a 4096 bit RSA private key
…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..++
…++
writing new private key to ‘smtpd.key’
—–
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 your 2 letter country code, e.g. DE in my case
State or Province Name (full name) [Some-State]: <– Enter your home state
Locality Name (eg, city) []:  <– Enter your city, in my case Lueneburg
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <– Enter your company name, in my case ISPConfig UG
Organizational Unit Name (eg, section) []: <– Enter your Organisational unit name, I use IT here
Common Name (e.g. server FQDN or YOUR name) []: <– Enter the server hostname, in my case server1.example.com
Email Address []: <– Enter an email address, e.g. hostmaster@server1.example.com
Configuring Mailman
Configuring Dovecot
Configuring Spamassassin
Configuring Amavisd
Configuring Getmail
Configuring Jailkit
Configuring Pureftpd
Configuring BIND
Configuring nginx
[INFO] service OpenVZ not detected
Configuring Ubuntu Firewall
Configuring Metronome XMPP Server
writing new private key to ‘localhost.key’
—–
Country Name (2 letter code) [AU]: <– Enter your 2 letter country code, e.g. DE in my case

Locality Name (eg, city) [City Name]: <– Enter your city, in my case Lueneburg

Organization Name (eg, company) [Internet Widgits Pty Ltd]: <– Enter your company name, in my case ISPConfig UG

Organizational Unit Name (eg, section) [Infrastructure]: <– Enter your Organisational unit name, I use IT here

Common Name (e.g. server FQDN or YOUR name) [server1.example.com]: <– Enter the server hostname, in my case server1.example.com

Email Address

<– Enter an email address, e.g. hostmaster@server1.example.com

IMPORTANT:
Localhost Key, Csr and a self-signed Cert have been saved to /etc/metronome/certs
In order to work with all clients, the server must have a trusted certificate, so use the Csr
to get a trusted certificate from your CA or replace Key and Cert with already signed files for
your domain. Clients like Pidgin dont allow to use untrusted self-signed certificates.

Configuring Fail2ban
Configuring Apps vhost
Installing ISPConfig
ISPConfig Port [8080]: <– ENTER

Admin password [admin]: <– Enter your desired admin password

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 your 2 letter country code, e.g. DE in my case
State or Province Name (full name) [Some-State]: <– Enter your home state
Locality Name (eg, city) []:  <– Enter your city, in my case Lueneburg
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <– Enter your company name, in my case ISPConfig UG
Organizational Unit Name (eg, section) []: <– Enter your Organisational unit name, I use IT here
Common Name (e.g. server FQDN or YOUR name) []: <– Enter the server hostname, in my case server1.example.com
Email Address []: <– Enter an email address, e.g. hostmaster@server1.example.com

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
no crontab for getmail
Detect IP addresses
Restarting services …
Installation completed.

The installer automatically configures all underlying services, so there is no manual configuration needed.

Afterwards you can access ISPConfig 3 under http(s)://server1.example.com:8080/ or http(s)://192.168.1.100:8080/ ( http or https depends on what you chose during installation). Log in with the username admin and the password admin (you should change the default password after your first login):

The system is now ready to be used.

 

17. Additional Notes

18.1 OpenVZ

If the Ubuntu server that you’ve just set up in this tutorial is an OpenVZ container (virtual machine), you should do this on the host system (I’m assuming that the ID of the OpenVZ container is 101 – replace it with the correct VPSID on your system):

VPSID=101
for CAP in CHOWN DAC_READ_SEARCH SETGID SETUID NET_BIND_SERVICE NET_ADMIN SYS_CHROOT SYS_NICE CHOWN DAC_READ_SEARCH SETGID SETUID NET_BIND_SERVICE NET_ADMIN SYS_CHROOT SYS_NICE
do
vzctl set $VPSID –capability ${CAP}:on –save
done

18.2 Virtual machine image download of this tutorial

This tutorial is available as ready to use virtual machine image in ovf/ova format that is compatible with VMWare and Virtualbox. The virtual machine image uses the following login details:

SSH / Shell Login

Username: administrator
Password: Kreationnext

This user has sudo rights.

ISPConfig Login

Username: admin
Password: Kreationnext

MySQL Login

Username: admin
Password: Kreationnext

or login with:

sudo mysql

on th shell.

The IP of the VM is 192.168.1.100, it can be changed in the file /etc/network/interfaces. Please change all the above passwords to secure the virtual machine.

 

Comments

comments